diff options
Diffstat (limited to 't')
-rw-r--r-- | t/app/controller/admin.t | 53 | ||||
-rw-r--r-- | t/app/controller/report_new_open311.t | 167 | ||||
-rw-r--r-- | t/app/model/problem.t | 109 | ||||
-rw-r--r-- | t/open311.t | 24 | ||||
-rw-r--r-- | t/open311/getupdates.t | 198 |
5 files changed, 551 insertions, 0 deletions
diff --git a/t/app/controller/admin.t b/t/app/controller/admin.t index 08cb4fb0d..be3b74cf5 100644 --- a/t/app/controller/admin.t +++ b/t/app/controller/admin.t @@ -205,6 +205,59 @@ subtest 'check contact updating' => sub { $mech->content_like(qr{test2\@example.com[^<]*</td>[^<]*<td><strong>Yes}s); }; +my $open311 = + FixMyStreet::App->model('DB::Open311Conf')->search( { area_id => 2650 } ); +$open311->delete if $open311; + +subtest 'check open311 configuring' => sub { + $mech->get_ok('/admin/council_contacts/2650/'); + $mech->content_lacks('Council contacts configured via Open311'); + + $mech->form_number(3); + $mech->submit_form_ok( + { + with_fields => { + api_key => 'api key', + endpoint => 'http://example.com/open311', + jurisdiction => 'mySociety', + } + } + ); + $mech->content_contains('Council contacts configured via Open311'); + $mech->content_contains('Configuration updated - contacts will be generated automatically later'); + + $open311 = + FixMyStreet::App->model('DB::Open311Conf')->search( { area_id => 2650 } ); + + is $open311->count, 1, 'only one configuration'; + my $conf = $open311->first; + is $conf->endpoint, 'http://example.com/open311', 'endpoint configured'; + is $conf->api_key, 'api key', 'api key configured'; + is $conf->jurisdiction, 'mySociety', 'jurisdiction configures'; + + $mech->form_number(3); + $mech->submit_form_ok( + { + with_fields => { + api_key => 'new api key', + endpoint => 'http://example.org/open311', + jurisdiction => 'open311', + } + } + ); + + $mech->content_contains('Configuration updated'); + + $open311 = + FixMyStreet::App->model('DB::Open311Conf')->search( { area_id => 2650 } ); + + is $open311->count, 1, 'only one configuration'; + $conf = $open311->first; + is $conf->endpoint, 'http://example.org/open311', 'endpoint updated'; + is $conf->api_key, 'new api key', 'api key updated'; + is $conf->jurisdiction, 'open311', 'jurisdiction configures'; +}; + subtest 'check text output' => sub { $mech->get_ok('/admin/council_contacts/2650?text=1'); is $mech->content_type, 'text/plain'; diff --git a/t/app/controller/report_new_open311.t b/t/app/controller/report_new_open311.t new file mode 100644 index 000000000..dc3583e6b --- /dev/null +++ b/t/app/controller/report_new_open311.t @@ -0,0 +1,167 @@ +use strict; +use warnings; +use Test::More; + +use FixMyStreet::TestMech; +use Web::Scraper; + +my $mech = FixMyStreet::TestMech->new; + +my $open311Conf = FixMyStreet::App->model('DB::Open311Conf')->find_or_create( { + area_id => 2651, + endpoint => 'http://example.com/open311', + jurisdiction => 'mySociety', + api_key => 'apikey', +} ); + +my %contact_params = ( + confirmed => 1, + deleted => 0, + editor => 'Test', + whenedited => \'current_timestamp', + note => 'Created for test', +); +# Let's make some contacts to send things to! +my $contact1 = FixMyStreet::App->model('DB::Contact')->find_or_create( { + %contact_params, + area_id => 2651, # Edinburgh + category => 'Street lighting', + email => '100', + extra => [ { description => 'Lamppost number', code => 'number', required => 'True' }, + { description => 'Lamppost type', code => 'type', required => 'False', values => + { value => { Yellow => { key => 'modern' }, 'Gas' => { key => 'old' } } } + } + ], +} ); +my $contact2 = FixMyStreet::App->model('DB::Contact')->find_or_create( { + %contact_params, + area_id => 2651, # Edinburgh + category => 'Graffiti Removal', + email => '101', +} ); +ok $contact1, "created test contact 1"; +ok $contact2, "created test contact 2"; + +# test that the various bit of form get filled in and errors correctly +# generated. +foreach my $test ( + { + msg => 'all fields empty', + pc => 'EH99 1SP', + fields => { + title => '', + detail => '', + photo => '', + name => '', + may_show_name => '1', + email => '', + phone => '', + category => 'Street lighting', + password_sign_in => '', + password_register => '', + remember_me => undef, + }, + changes => { + number => '', + type => 'old', + }, + errors => [ + 'Please enter a subject', + 'Please enter some details', + 'This information is required', + 'Please enter your email', + 'Please enter your name', + ], + submit_with => { + title => 'test', + detail => 'test detail', + name => 'Test User', + email => 'testopen311@example.com', + category => 'Street lighting', + number => 27, + }, + extra => [ + { + name => 'number', + value => 27, + description => 'Lamppost number', + }, + { + name => 'type', + value => 'old', + description => 'Lamppost type', + } + ] + }, + ) +{ + subtest "check form errors where $test->{msg}" => sub { + $mech->log_out_ok; + $mech->clear_emails_ok; + + # check that the user does not exist + my $test_email = $test->{submit_with}->{email}; + my $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } ); + if ( $user ) { + $user->problems->delete; + $user->comments->delete; + $user->delete; + } + + $mech->get_ok('/around'); + + # submit initial pc form + $mech->submit_form_ok( { with_fields => { pc => $test->{pc} } }, + "submit location" ); + is_deeply $mech->form_errors, [], "no errors for pc '$test->{pc}'"; + + # click through to the report page + $mech->follow_link_ok( { text => 'skip this step', }, + "follow 'skip this step' link" ); + + # submit the main form + $mech->submit_form_ok( { with_fields => $test->{fields} }, + "submit form" ); + + # check that we got the errors expected + is_deeply $mech->form_errors, $test->{errors}, "check errors"; + + # check that fields have changed as expected + my $new_values = { + %{ $test->{fields} }, # values added to form + %{ $test->{changes} }, # changes we expect + }; + is_deeply $mech->visible_form_values, $new_values, + "values correctly changed"; + + if ( $test->{fields}->{category} eq 'Street lighting' ) { + my $result = scraper { + process 'div#category_meta div select#form_type option', 'option[]' => '@value'; + } + ->scrape( $mech->response ); + + is_deeply $result->{option}, [ qw/old modern/], 'displayed streetlight type select'; + } + + $new_values = { + %{ $test->{fields} }, + %{ $test->{submit_with} }, + }; + $mech->submit_form_ok( { with_fields => $new_values } ); + + $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } ); + ok $user, 'created user'; + my $prob = $user->problems->first; + ok $prob, 'problem created'; + + is_deeply $prob->extra, $test->{extra}, 'extra open311 data added to problem'; + + $user->problems->delete; + $user->delete; + }; +} + +$contact1->delete; +$contact2->delete; + +done_testing(); diff --git a/t/app/model/problem.t b/t/app/model/problem.t index 4c6be6a8d..ad42c5fdf 100644 --- a/t/app/model/problem.t +++ b/t/app/model/problem.t @@ -152,6 +152,111 @@ for my $test ( }; } +my $user = FixMyStreet::App->model('DB::User')->find_or_create( + { + email => 'system_user@example.com' + } +); + +$problem->user( $user ); +$problem->created( DateTime->now()->subtract( days => 1 ) ); +$problem->lastupdate( DateTime->now()->subtract( days => 1 ) ); +$problem->anonymous(1); +$problem->insert; + +my $tz_local = DateTime::TimeZone->new( name => 'local' ); + +for my $test ( + { + desc => 'request older than problem ignored', + lastupdate => '', + request => { + updated_datetime => DateTime::Format::W3CDTF->new()->format_datetime( DateTime->now()->set_time_zone( $tz_local )->subtract( days => 2 ) ), + }, + council => { + name => 'Edinburgh City Council', + }, + created => 0, + }, + { + desc => 'request newer than problem created', + lastupdate => '', + request => { + updated_datetime => DateTime::Format::W3CDTF->new()->format_datetime( DateTime->now()->set_time_zone( $tz_local ) ), + status => 'open', + status_notes => 'this is an update from the council', + }, + council => { + name => 'Edinburgh City Council', + }, + created => 1, + state => 'confirmed', + mark_fixed => 0, + mark_open => 0, + }, + { + desc => 'update with state of closed fixes problem', + lastupdate => '', + request => { + updated_datetime => DateTime::Format::W3CDTF->new()->format_datetime( DateTime->now()->set_time_zone( $tz_local ) ), + status => 'closed', + status_notes => 'the council have fixed this', + }, + council => { + name => 'Edinburgh City Council', + }, + created => 1, + state => 'fixed', + mark_fixed => 1, + mark_open => 0, + }, + { + desc => 'update with state of open leaves problem as fixed', + lastupdate => '', + request => { + updated_datetime => DateTime::Format::W3CDTF->new()->format_datetime( DateTime->now()->set_time_zone( $tz_local ) ), + status => 'open', + status_notes => 'the council do not think this is fixed', + }, + council => { + name => 'Edinburgh City Council', + }, + created => 1, + start_state => 'fixed', + state => 'fixed', + mark_fixed => 0, + mark_open => 0, + }, +) { + subtest $test->{desc} => sub { + # makes testing easier; + $problem->comments->delete; + $problem->created( DateTime->now()->subtract( days => 1 ) ); + $problem->lastupdate( DateTime->now()->subtract( days => 1 ) ); + $problem->state( $test->{start_state} || 'confirmed' ); + $problem->update; + my $w3c = DateTime::Format::W3CDTF->new(); + + my $ret = $problem->update_from_open311_service_request( $test->{request}, $test->{council}, $user ); + is $ret, $test->{created}, 'return value'; + + return unless $test->{created}; + + $problem->discard_changes; + is $problem->lastupdate, $w3c->parse_datetime($test->{request}->{updated_datetime}), 'lastupdate time'; + + my $update = $problem->comments->first; + + ok $update, 'updated created'; + + is $problem->state, $test->{state}, 'problem state'; + + is $update->text, $test->{request}->{status_notes}, 'update text'; + is $update->mark_open, $test->{mark_open}, 'update mark_open flag'; + is $update->mark_fixed, $test->{mark_fixed}, 'update mark_fixed flag'; + }; +} + for my $test ( { state => 'partial', @@ -240,4 +345,8 @@ for my $test ( }; } +$problem->comments->delete; +$problem->delete; +$user->delete; + done_testing(); diff --git a/t/open311.t b/t/open311.t new file mode 100644 index 000000000..f7a8cd815 --- /dev/null +++ b/t/open311.t @@ -0,0 +1,24 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use Test::More tests => 4; + +use FindBin; +use lib "$FindBin::Bin/../perllib"; +use lib "$FindBin::Bin/../commonlib/perllib"; + +use_ok( 'Open311' ); + +my $o = Open311->new(); +ok $o, 'created object'; + +my $err_text = <<EOT +<?xml version="1.0" encoding="utf-8"?><errors><error><code>400</code><description>Service Code cannot be null -- can't proceed with the request.</description></error></errors> +EOT +; + +is $o->_process_error( $err_text ), "400: Service Code cannot be null -- can't proceed with the request.\n", 'error text parsing'; +is $o->_process_error( '503 - service unavailable' ), 'unknown error', 'error text parsing of bad error'; + + diff --git a/t/open311/getupdates.t b/t/open311/getupdates.t new file mode 100644 index 000000000..03af0b72b --- /dev/null +++ b/t/open311/getupdates.t @@ -0,0 +1,198 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use Test::More; + +use FindBin; +use lib "$FindBin::Bin/../perllib"; +use lib "$FindBin::Bin/../commonlib/perllib"; + +use_ok( 'Open311::GetUpdates' ); +use_ok( 'Open311' ); + +my $user = FixMyStreet::App->model('DB::User')->find_or_create( + { + email => 'system_user@example.com' + } +); + + +my $updates = Open311::GetUpdates->new( system_user => $user ); +ok $updates, 'created object'; + +my $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?> +<service_requests> +<request> +<service_request_id>638344</service_request_id> +<status>open</status> +<status_notes>This is a note.</status_notes> +<service_name>Sidewalk and Curb Issues</service_name> +<service_code>006</service_code> +<description></description> +<agency_responsible></agency_responsible> +<service_notice></service_notice> +<requested_datetime>2010-04-14T06:37:38-08:00</requested_datetime> +UPDATED_DATETIME +<expected_datetime>2010-04-15T06:37:38-08:00</expected_datetime> +<lat>37.762221815</lat> +<long>-122.4651145</long> +</request> +</service_requests> +}; + +my $problem_rs = FixMyStreet::App->model('DB::Problem'); +my $problem = $problem_rs->new( + { + postcode => 'EH99 1SP', + latitude => 1, + longitude => 1, + areas => 1, + title => '', + detail => '', + used_map => 1, + user_id => 1, + name => '', + state => 'confirmed', + service => '', + cobrand => 'default', + cobrand_data => '', + user => $user, + created => DateTime->now()->subtract( days => 1 ), + lastupdate => DateTime->now()->subtract( days => 1 ), + anonymous => 1, + external_id => 638344, + } +); + +$problem->insert; + +for my $test ( + { + desc => 'element missing', + updated_datetime => '', + comment_count => 0, + }, + { + desc => 'empty element', + updated_datetime => '<updated_datetime />', + comment_count => 0, + }, + { + desc => 'element with no content', + updated_datetime => '<updated_datetime></updated_datetime>', + comment_count => 0, + }, + { + desc => 'element with old content', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', DateTime->now->subtract( days => 3 ) ), + comment_count => 0, + }, + { + desc => 'element with new content', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', DateTime->now ), + comment_count => 1, + }, +) { + subtest $test->{desc} => sub { + $problem->comments->delete; + $problem->lastupdate(DateTime->now()->subtract( days => 1 ) ), + $problem->update; + + my $local_requests_xml = $requests_xml; + $local_requests_xml =~ s/UPDATED_DATETIME/$test->{updated_datetime}/; + + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'requests.xml' => $local_requests_xml } ); + + ok $updates->update_reports( [ 638344 ], $o, { name => 'Test Council' } ); + is $o->test_uri_used, 'http://example.com/requests.xml?jurisdiction_id=mysociety&service_request_id=638344', 'get url'; + + is $problem->comments->count, $test->{comment_count}, 'added a comment'; + }; +} + +$requests_xml = qq{<?xml version="1.0" encoding="utf-8"?> +<service_requests> +<request> +<service_request_id>638344</service_request_id> +<status>open</status> +<status_notes>This is a note.</status_notes> +<service_name>Sidewalk and Curb Issues</service_name> +<service_code>006</service_code> +<description></description> +<agency_responsible></agency_responsible> +<service_notice></service_notice> +<requested_datetime>2010-04-14T06:37:38-08:00</requested_datetime> +<updated_datetime>UPDATED_DATETIME</updated_datetime> +<expected_datetime>2010-04-15T06:37:38-08:00</expected_datetime> +<lat>37.762221815</lat> +<long>-122.4651145</long> +</request> +<request> +<service_request_id>638345</service_request_id> +<status>open</status> +<status_notes>This is a for a different issue.</status_notes> +<service_name>Sidewalk and Curb Issues</service_name> +<service_code>006</service_code> +<description></description> +<agency_responsible></agency_responsible> +<service_notice></service_notice> +<requested_datetime>2010-04-14T06:37:38-08:00</requested_datetime> +<updated_datetime>UPDATED_DATETIME2</updated_datetime> +<expected_datetime>2010-04-15T06:37:38-08:00</expected_datetime> +<lat>37.762221815</lat> +<long>-122.4651145</long> +</request> +</service_requests> +}; + +my $problem2 = $problem_rs->new( + { + postcode => 'EH99 1SP', + latitude => 1, + longitude => 1, + areas => 1, + title => '', + detail => '', + used_map => 1, + user_id => 1, + name => '', + state => 'confirmed', + service => '', + cobrand => 'default', + cobrand_data => '', + user => $user, + created => DateTime->now()->subtract( days => 1 ), + lastupdate => DateTime->now()->subtract( days => 1 ), + anonymous => 1, + external_id => 638345, + } +); + +$problem->comments->delete; +subtest 'update with two requests' => sub { + $problem->comments->delete; + $problem->lastupdate(DateTime->now()->subtract( days => 1 ) ), + + my $date1 = DateTime::Format::W3CDTF->new->formate_datetime( DateTime->now() ); + my $date2 = DateTime::Format::W3CDTF->new->formate_datetime( DateTime->now->subtract( hour => 1) ); + my $local_requests_xml = $requests_xml; + $local_requests_xml =~ s/UPDATED_DATETIME2/$date2/; + $local_requests_xml =~ s/UPDATED_DATETIME/$date1/; + + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'requests.xml' => $local_requests_xml } ); + + ok $updates->update_reports( [ 638344,638345 ], $o, { name => 'Test Council' } ); + is $o->test_uri_used, 'http://example.com/requests.xml?jurisdiction_id=mysociety&service_request_id=638344,638345', 'get url'; + + is $problem->comments->count, 1, 'added a comment to first problem'; + is $problem2->comments->count, 1, 'added a comment to second problem'; +}; + +$problem->comments->delete; +$problem->delete; +$user->comments->delete; +$user->problems->delete; +$user->delete; + +done_testing(); |