diff --git a/CHANGELOG.md b/CHANGELOG.md index def0371..687ee1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ # Next Release +* Location is now updated on registration. Customers location is truncated to 2 + decimal places based on their postcode. + +## Bug Fixes + +* Updated Geo::UK::Postcode::Regex dependency to latest version. Fixes postcode + validation errors + # v0.9.4 * **Admin Feature:** Report of transaction data graphs diff --git a/lib/Pear/LocalLoop/Controller/Api/Register.pm b/lib/Pear/LocalLoop/Controller/Api/Register.pm index 822087d..9de39d9 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Register.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Register.pm @@ -2,6 +2,8 @@ package Pear::LocalLoop::Controller::Api::Register; use Mojo::Base 'Mojolicious::Controller'; use DateTime; +use Geo::UK::Postcode::Regex; + has error_messages => sub { return { token => { @@ -80,6 +82,34 @@ sub post_register { return $c->api_validation_error if $validation->has_error; + my $postcode_obj = Geo::UK::Postcode::Regex->parse( + $validation->param('postcode') + ); + + my $location; + + unless ( defined $postcode_obj && $postcode_obj->{non_geographical} ) { + my $pc_result = $c->schema->resultset('GbPostcode')->find({ + incode => $postcode_obj->{incode}, + outcode => $postcode_obj->{outcode}, + }); + if ( defined $pc_result ) { + # Force truncation here as SQLite is stupid + $location = { + latitude => ( + $usertype eq 'customer' + ? int($pc_result->latitude * 100 ) / 100 + : $pc_result->latitude + ), + longitude => ( + $usertype eq 'customer' + ? int($pc_result->longitude * 100 ) / 100 + : $pc_result->longitude + ), + }; + } + } + if ($usertype eq 'customer'){ $c->schema->txn_do( sub { @@ -94,6 +124,7 @@ sub post_register { display_name => $validation->param('display_name'), year_of_birth => $validation->param('year_of_birth'), postcode => $validation->param('postcode'), + ( defined $location ? ( %$location ) : () ), }, user => { email => $validation->param('email'), @@ -118,6 +149,7 @@ sub post_register { town => $validation->param('town'), sector => $validation->param('sector'), postcode => $validation->param('postcode'), + ( defined $location ? ( %$location ) : () ), }, user => { email => $validation->param('email'), diff --git a/lib/Pear/LocalLoop/Controller/Api/User.pm b/lib/Pear/LocalLoop/Controller/Api/User.pm index d85e2d8..85d2be6 100644 --- a/lib/Pear/LocalLoop/Controller/Api/User.pm +++ b/lib/Pear/LocalLoop/Controller/Api/User.pm @@ -49,22 +49,28 @@ sub post_account { my $email = $user_result->email; if ( $user_result->type eq 'customer' ) { - my $full_name = $user_result->entity->customer->full_name; - my $display_name = $user_result->entity->customer->display_name; - my $postcode = $user_result->entity->customer->postcode; + my $customer = $user_result->entity->customer; + my $full_name = $customer->full_name; + my $display_name = $customer->display_name; + my $postcode = $customer->postcode; return $c->render( json => { success => Mojo::JSON->true, full_name => $full_name, display_name => $display_name, email => $email, postcode => $postcode, + location => { + latitude => (defined $customer->latitude ? $customer->latitude * 1 : undef), + longitude => (defined $customer->longitude ? $customer->longitude * 1 : undef), + }, }); } elsif ( $user_result->type eq 'organisation' ) { - my $name = $user_result->entity->organisation->name; - my $postcode = $user_result->entity->organisation->postcode; - my $street_name = $user_result->entity->organisation->street_name; - my $town = $user_result->entity->organisation->town; - my $sector = $user_result->entity->organisation->sector; + my $organisation = $user_result->entity->organisation; + my $name = $organisation->name; + my $postcode = $organisation->postcode; + my $street_name = $organisation->street_name; + my $town = $organisation->town; + my $sector = $organisation->sector; return $c->render( json => { success => Mojo::JSON->true, town => $town, @@ -73,6 +79,10 @@ sub post_account { street_name => $street_name, email => $email, postcode => $postcode, + location => { + latitude => (defined $organisation->latitude ? $organisation->latitude * 1 : undef), + longitude => (defined $organisation->longitude ? $organisation->longitude * 1 : undef), + }, }); } else { return $c->render( diff --git a/lib/Test/Pear/LocalLoop.pm b/lib/Test/Pear/LocalLoop.pm index 961fd55..490aa1a 100644 --- a/lib/Test/Pear/LocalLoop.pm +++ b/lib/Test/Pear/LocalLoop.pm @@ -219,6 +219,8 @@ sub install_fixtures { { entities => 'entities_id_seq', organisations => 'organisations_id_seq', + users => 'users_id_seq', + customers => 'customers_id_seq', } ); } diff --git a/t/api/register/location.t b/t/api/register/location.t new file mode 100644 index 0000000..d01ff1f --- /dev/null +++ b/t/api/register/location.t @@ -0,0 +1,108 @@ +use Mojo::Base -strict; + +use FindBin qw/ $Bin /; + +use Test::More; +use Mojo::JSON; +use Test::Pear::LocalLoop; + +my $framework = Test::Pear::LocalLoop->new( + etc_dir => "$Bin/../../etc", +); +$framework->install_fixtures('full'); + +my $t = $framework->framework; +my $schema = $t->app->schema; + +$schema->resultset('AccountToken')->populate([ + {name => 'test1'}, + {name => 'test2'}, + {name => 'test3'}, +]); + +$t->post_ok('/api/register', + json => { + token => 'test1', + usertype => 'customer', + full_name => 'New Test User', + display_name => 'Testing User New', + email => 'newtest@example.com', + postcode => 'LA2 0AD', + year_of_birth => 2001, + password => 'abc123', + }) + ->status_is(200)->or($framework->dump_error) + ->json_is('/success', Mojo::JSON->true); + +my $session_key = $framework->login({ + email => 'newtest@example.com', + password => 'abc123', +}); + +$t->post_ok('/api/user', json => { session_key => $session_key }) + ->status_is(200) + ->json_is('/success', Mojo::JSON->true) + ->json_is('/location', { + latitude => 54.02, + longitude => -2.80, + } + ); + +$t->post_ok('/api/register', + json => { + token => 'test2', + usertype => 'organisation', + email => 'neworg@example.com', + password => 'abc123', + postcode => 'LA2 0AD', + name => 'New Org', + street_name => '18 Test Road', + town => 'Lancaster', + sector => 'A', + }) + ->status_is(200) + ->json_is('/success', Mojo::JSON->true); + +$session_key = $framework->login({ + email => 'neworg@example.com', + password => 'abc123', +}); + +$t->post_ok('/api/user', json => { session_key => $session_key }) + ->status_is(200) + ->json_is('/success', Mojo::JSON->true) + ->json_is('/location', { + latitude => 54.02432, + longitude => -2.80635, + } + ); + +$t->post_ok('/api/register', + json => { + token => 'test3', + usertype => 'customer', + full_name => 'New Test User', + display_name => 'Testing User New', + email => 'newtest2@example.com', + postcode => 'BX1 1AA', + year_of_birth => 2001, + password => 'abc123', + }) + ->status_is(200)->or($framework->dump_error) + ->json_is('/success', Mojo::JSON->true); + +$session_key = $framework->login({ + email => 'newtest2@example.com', + password => 'abc123', +}); + +$t->post_ok('/api/user', json => { session_key => $session_key }) + ->status_is(200) + ->json_is('/success', Mojo::JSON->true) + ->json_is('/location', { + latitude => undef, + longitude => undef, + } + ); + +done_testing; diff --git a/t/api/user.t b/t/api/user.t index 643165a..acedf1e 100644 --- a/t/api/user.t +++ b/t/api/user.t @@ -40,6 +40,10 @@ $t->post_ok('/api/user', json => { session_key => $session_key }) display_name => 'Testing User', email => $email, postcode => 'LA1 1AA', + location => { + latitude => undef, + longitude => undef, + }, }); #with wrong password @@ -80,6 +84,11 @@ $t->post_ok('/api/user', json => { session_key => $session_key }) display_name => 'Testing User 2', email => 'test50@example.com', postcode => 'LA1 1AB', + location => { + latitude => undef, + longitude => undef, + }, + }); $t->post_ok('/api/user/account', json => { @@ -105,6 +114,11 @@ $t->post_ok('/api/user', json => { session_key => $session_key }) display_name => 'Testing User 3', email => 'test60@example.com', postcode => 'LA1 1AD', + location => { + latitude => undef, + longitude => undef, + }, + }); $session_key = $framework->login({