diff options
Diffstat (limited to 't/open311')
-rw-r--r-- | t/open311/getservicerequests.t | 149 | ||||
-rw-r--r-- | t/open311/getservicerequestupdates.t | 397 | ||||
-rw-r--r-- | t/open311/getupdates.t | 9 | ||||
-rw-r--r-- | t/open311/populate-service-list.t | 403 | ||||
-rw-r--r-- | t/open311/post-service-request-updates.t | 31 |
5 files changed, 820 insertions, 169 deletions
diff --git a/t/open311/getservicerequests.t b/t/open311/getservicerequests.t index 55bb9ba11..672459f3f 100644 --- a/t/open311/getservicerequests.t +++ b/t/open311/getservicerequests.t @@ -17,6 +17,9 @@ my $contact = $mech->create_contact_ok( body_id => $body->id, category => 'Sidew my $body2 = $mech->create_body_ok(2217, 'Buckinghamshire'); my $contact2 = $mech->create_contact_ok( body_id => $body2->id, category => 'Sidewalk and Curb Issues', email => 'sidewalks' ); +my $hounslow = $mech->create_body_ok(2483, 'Hounslow'); +my $hounslowcontact = $mech->create_contact_ok( body_id => $hounslow->id, category => 'Sidewalk and Curb Issues', email => 'sidewalks' ); + my $dtf = DateTime::Format::W3CDTF->new; my $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?> @@ -208,48 +211,6 @@ my $date = DateTime->new( for my $test ( { - start_date => '1', - end_date => '', - desc => 'do not process if only a start_date', - subs => {}, - }, - { - start_date => '', - end_date => '1', - desc => 'do not process if only an end_date', - subs => {}, - }, -) { - subtest $test->{desc} => sub { - my $xml = prepare_xml( $test->{subs} ); - my $o = Open311->new( - jurisdiction => 'mysociety', - endpoint => 'http://example.com', - test_mode => 1, - test_get_returns => { 'requests.xml' => $xml} - ); - - my $update = Open311::GetServiceRequests->new( - start_date => $test->{start_date}, - end_date => $test->{end_date}, - system_user => $user, - ); - my $ret = $update->create_problems( $o, $body ); - - is $ret, 0, 'failed correctly' - }; -} - -$date = DateTime->new( - year => 2010, - month => 4, - day => 14, - hour => 6, - minute => 37 -); - -for my $test ( - { start_date => $date->clone->add(hours => -2), end_date => $date->clone->add(hours => -1), desc => 'do not process if update time after end_date', @@ -469,6 +430,110 @@ for my $test ( }; } +my $hounslow_non_public_xml = qq[<?xml version="1.0" encoding="utf-8"?> +<service_requests> +<request> +<service_request_id>123456</service_request_id> +<status>open</status> +<status_notes></status_notes> +<service_name>Sidewalk and Curb Issues</service_name> +<service_code>sidewalks</service_code> +<description>this is a problem</description> +<agency_responsible></agency_responsible> +<service_notice></service_notice> +<requested_datetime>2010-04-14T06:37:38-08:00</requested_datetime> +<updated_datetime>2010-04-14T06:37:38-08:00</updated_datetime> +<expected_datetime>2010-04-15T06:37:38-08:00</expected_datetime> +<lat>51.482286</lat> +<long>-0.328163</long> +<non_public>1</non_public> +</request> +</service_requests> +]; + +for my $test ( + { + desc => 'Hounslow non_public reports not created', + non_public => 1, + count => 0, + }, + { + desc => 'Hounslow public reports are created', + non_public => 0, + count => 1, + }, +) { + subtest $test->{desc} => sub { + (my $xml = $hounslow_non_public_xml) =~ s/non_public>1/non_public>$test->{non_public}/; + + my $o = Open311->new( + jurisdiction => 'mysociety', + endpoint => 'http://example.com', + test_mode => 1, + test_get_returns => { 'requests.xml' => $xml} + ); + + my $update = Open311::GetServiceRequests->new( + system_user => $user, + start_date => $start_date, + end_date => $end_date + ); + + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + ALLOWED_COBRANDS => [ 'hounslow' ], + }, sub { + $update->create_problems( $o, $hounslow ); + }; + + my $q = FixMyStreet::DB->resultset('Problem')->search( + { external_id => 123456 } + ); + + is $q->count, $test->{count}, 'problem count is correct'; + + $q->first->delete if $test->{count}; + }; +} + +subtest "non_public contacts result in non_public reports" => sub { + + $contact->update({ + non_public => 1 + }); + my $o = Open311->new( + jurisdiction => 'mysociety', + endpoint => 'http://example.com', + test_mode => 1, + test_get_returns => { 'requests.xml' => prepare_xml( {} ) } + ); + + my $update = Open311::GetServiceRequests->new( + system_user => $user, + start_date => $start_date, + end_date => $end_date + ); + + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $update->create_problems( $o, $body ); + }; + + my $p = FixMyStreet::DB->resultset('Problem')->search( + { external_id => 123456 } + )->first; + + ok $p, 'problem created'; + is $p->non_public, 1, "report non_public is set correctly"; + + $p->delete; + $contact->update({ + non_public => 0 + }); + +}; + for my $test ( { test_desc => 'filters out phone numbers', diff --git a/t/open311/getservicerequestupdates.t b/t/open311/getservicerequestupdates.t index f680985a4..4651c38b2 100644 --- a/t/open311/getservicerequestupdates.t +++ b/t/open311/getservicerequestupdates.t @@ -12,6 +12,7 @@ use_ok( 'Open311' ); use_ok( 'Open311::GetServiceRequestUpdates' ); use DateTime; use DateTime::Format::W3CDTF; +use File::Temp 'tempdir'; use FixMyStreet::DB; my $user = FixMyStreet::DB->resultset('User')->find_or_create( @@ -22,6 +23,8 @@ my $user = FixMyStreet::DB->resultset('User')->find_or_create( my %bodies = ( 2237 => FixMyStreet::DB->resultset("Body")->create({ name => 'Oxfordshire' }), + 2494 => FixMyStreet::DB->resultset("Body")->create({ name => 'Bexley' }), + 2636 => FixMyStreet::DB->resultset("Body")->create({ name => 'Isle of Wight' }), 2482 => FixMyStreet::DB->resultset("Body")->create({ name => 'Bromley', send_method => 'Open311', @@ -33,6 +36,8 @@ my %bodies = ( 2651 => FixMyStreet::DB->resultset("Body")->create({ name => 'Edinburgh' }), ); $bodies{2237}->body_areas->create({ area_id => 2237 }); +$bodies{2494}->body_areas->create({ area_id => 2494 }); +$bodies{2636}->body_areas->create({ area_id => 2636 }); my $response_template = $bodies{2482}->response_templates->create({ title => "investigating template", @@ -129,8 +134,10 @@ subtest 'check extended request parsed correctly' => sub { }; my $problem_rs = FixMyStreet::DB->resultset('Problem'); -my $problem = $problem_rs->new( - { + +sub create_problem { + my ($body_id, $external_id) = @_; + my $problem = $problem_rs->create({ postcode => 'EH99 1SP', latitude => 1, longitude => 1, @@ -139,7 +146,7 @@ my $problem = $problem_rs->new( detail => '', used_map => 1, user_id => 1, - name => '', + name => 'Test User', state => 'confirmed', service => '', cobrand => 'default', @@ -148,12 +155,13 @@ my $problem = $problem_rs->new( created => DateTime->now()->subtract( days => 1 ), lastupdate => DateTime->now()->subtract( days => 1 ), anonymous => 1, - external_id => int(rand(time())), - bodies_str => $bodies{2482}->id, - } -); + external_id => $external_id || int(rand(time())), + bodies_str => $body_id, + }); + return $problem; +} -$problem->insert; +my $problem = create_problem($bodies{2482}->id); for my $test ( { @@ -447,27 +455,38 @@ for my $test ( }; } -my $problemOx = $problem_rs->create({ - 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 => int(rand(time())), - bodies_str => $bodies{2237}->id, +my $response_template_vars = $bodies{2482}->response_templates->create({ + title => "a placeholder action scheduled template", + text => "We are investigating this report: {{description}}", + auto_response => 1, + state => "action scheduled" }); +subtest 'Check template placeholders' => sub { + my $local_requests_xml = setup_xml($problem->external_id, $problem->id, 'ACTION_SCHEDULED', 'We will do this in the morning.'); + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', extended_statuses => undef, test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $local_requests_xml } ); + + $problem->lastupdate( DateTime->now()->subtract( days => 1 ) ); + $problem->state( 'fixed - council' ); + $problem->update; + + my $update = Open311::GetServiceRequestUpdates->new; + $update->fetch($o); + + is $problem->comments->count, 1, 'comment count'; + $problem->discard_changes; + + my $c = FixMyStreet::DB->resultset('Comment')->search( { external_id => 638344 } )->first; + ok $c, 'comment exists'; + is $c->text, "We are investigating this report: We will do this in the morning.", 'text correct'; + is $c->mark_fixed, 0, 'mark_closed correct'; + is $c->problem_state, 'action scheduled', 'problem_state correct'; + is $c->mark_open, 0, 'mark_open correct'; + is $c->state, 'confirmed', 'comment state correct'; + is $problem->state, 'action scheduled', 'correct problem state'; + $problem->comments->delete; +}; + +my $problemB = create_problem($bodies{2237}->id); for my $test ( { @@ -486,28 +505,68 @@ for my $test ( }, ) { subtest $test->{desc} => sub { - my $local_requests_xml = setup_xml($problemOx->external_id, $problemOx->id, $test->{comment_status}); + my $local_requests_xml = setup_xml($problemB->external_id, $problemB->id, $test->{comment_status}); my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $local_requests_xml } ); - $problemOx->lastupdate( DateTime->now()->subtract( days => 1 ) ); - $problemOx->state( $test->{start_state} ); - $problemOx->update; + $problemB->lastupdate( DateTime->now()->subtract( days => 1 ) ); + $problemB->state( $test->{start_state} ); + $problemB->update; + + my $update = Open311::GetServiceRequestUpdates->new( + system_user => $user, + current_open311 => $o, + current_body => $bodies{2237}, + ); + $update->process_body; - my $update = Open311::GetServiceRequestUpdates->new( system_user => $user ); - $update->update_comments( $o, $bodies{2237} ); - is $problemOx->comments->count, 1, 'comment count'; - $problemOx->discard_changes; + is $problemB->comments->count, 1, 'comment count'; + $problemB->discard_changes; my $c = FixMyStreet::DB->resultset('Comment')->search( { external_id => 638344 } )->first; ok $c, 'comment exists'; is $c->problem_state, $test->{problem_state}, 'problem_state correct'; - is $problemOx->state, $test->{end_state}, 'correct problem state'; - $problemOx->comments->delete; + is $problemB->state, $test->{end_state}, 'correct problem state'; + $problemB->comments->delete; + }; +} + +for ( + { id => 2494, cobrand => 'bexley' }, + { id => 2636, cobrand => 'isleofwight' } +) { + subtest "Marking report as fixed closes it for updates ($_->{cobrand})" => sub { + my $local_requests_xml = setup_xml($problemB->external_id, $problemB->id, 'CLOSED'); + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $local_requests_xml } ); + + $problemB->update( { bodies_str => $bodies{$_->{id}}->id } ); + + my $update = Open311::GetServiceRequestUpdates->new( + system_user => $user, + current_open311 => $o, + current_body => $bodies{$_->{id}}, + ); + FixMyStreet::override_config { + ALLOWED_COBRANDS => $_->{cobrand}, + }, sub { + $update->process_body; + }; + + $problemB->discard_changes; + is $problemB->comments->count, 1, 'comment count'; + is $problemB->get_extra_metadata('closed_updates'), 1; + $problemB->comments->delete; }; } subtest 'Update with media_url includes image in update' => sub { + my $UPLOAD_DIR = tempdir( CLEANUP => 1 ); + FixMyStreet::override_config { + PHOTO_STORAGE_BACKEND => 'FileSystem', + PHOTO_STORAGE_OPTIONS => { + UPLOAD_DIR => $UPLOAD_DIR, + }, + }, sub { my $guard = LWP::Protocol::PSGI->register(t::Mock::Static->to_psgi_app, host => 'example.com'); my $local_requests_xml = setup_xml($problem->external_id, 1, ""); @@ -519,14 +578,19 @@ subtest 'Update with media_url includes image in update' => sub { $problem->state('confirmed'); $problem->update; - my $update = Open311::GetServiceRequestUpdates->new( system_user => $user ); - $update->update_comments( $o, $bodies{2482} ); + my $update = Open311::GetServiceRequestUpdates->new( + system_user => $user, + current_open311 => $o, + current_body => $bodies{2482}, + ); + $update->process_body; is $problem->comments->count, 1, 'comment count'; my $c = $problem->comments->first; is $c->external_id, 638344; is $c->photo, '74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg', 'photo exists'; $problem->comments->delete; + }; }; subtest 'Update with customer_reference adds reference to problem' => sub { @@ -541,8 +605,12 @@ subtest 'Update with customer_reference adds reference to problem' => sub { $problem->state('confirmed'); $problem->update; - my $update = Open311::GetServiceRequestUpdates->new( system_user => $user ); - $update->update_comments( $o, $bodies{2482} ); + my $update = Open311::GetServiceRequestUpdates->new( + system_user => $user, + current_open311 => $o, + current_body => $bodies{2482}, + ); + $update->process_body; $problem->discard_changes; is $problem->comments->count, 1, 'comment count'; @@ -556,11 +624,15 @@ subtest 'date for comment correct' => sub { my $local_requests_xml = setup_xml($problem->external_id, $problem->id, ""); my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $local_requests_xml } ); - my $update = Open311::GetServiceRequestUpdates->new( system_user => $user ); + my $update = Open311::GetServiceRequestUpdates->new( + system_user => $user, + current_open311 => $o, + current_body => $bodies{2482}, + ); FixMyStreet::override_config { TIME_ZONE => 'Australia/Sydney', }, sub { - $update->update_comments( $o, $bodies{2482} ); + $update->process_body; }; my $comment = $problem->comments->first; @@ -569,29 +641,7 @@ subtest 'date for comment correct' => sub { $problem->comments->delete; }; -my $problem2 = $problem_rs->create( - { - 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(), - lastupdate => DateTime->now(), - anonymous => 1, - external_id => $problem->external_id, - bodies_str => $bodies{2651}->id, - } -); +my $problem2 = create_problem($bodies{2651}->id, $problem->external_id); for my $test ( { @@ -617,8 +667,12 @@ for my $test ( my $local_requests_xml = setup_xml($test->{request_id}, $test->{request_id_ext}, ""); my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $local_requests_xml } ); - my $update = Open311::GetServiceRequestUpdates->new( system_user => $user ); - $update->update_comments( $o, $bodies{$test->{area_id}} ); + my $update = Open311::GetServiceRequestUpdates->new( + system_user => $user, + current_open311 => $o, + current_body => $bodies{$test->{area_id}}, + ); + $update->process_body; is $problem->comments->count, $test->{p1_comments}, 'comment count for first problem'; is $problem2->comments->count, $test->{p2_comments}, 'comment count for second problem'; @@ -629,33 +683,19 @@ subtest 'using start and end date' => sub { my $local_requests_xml = $requests_xml; my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $local_requests_xml } ); - my $start_dt = DateTime->now(); + my $start_dt = DateTime->now(formatter => DateTime::Format::W3CDTF->new); + my $end_dt = $start_dt->clone; $start_dt->subtract( days => 1 ); - my $end_dt = DateTime->now(); my $update = Open311::GetServiceRequestUpdates->new( system_user => $user, start_date => $start_dt, - ); - - my $res = $update->update_comments( $o ); - is $res, 0, 'returns 0 if start but no end date'; - - $update = Open311::GetServiceRequestUpdates->new( - system_user => $user, - end_date => $end_dt, - ); - - $res = $update->update_comments( $o ); - is $res, 0, 'returns 0 if end but no start date'; - - $update = Open311::GetServiceRequestUpdates->new( - system_user => $user, - start_date => $start_dt, end_date => $end_dt, + current_open311 => $o, + current_body => $bodies{2482}, ); - $update->update_comments( $o, $bodies{2482} ); + $update->process_body; my $start = $start_dt . ''; my $end = $end_dt . ''; @@ -713,19 +753,21 @@ subtest 'check that existing comments are not duplicated' => sub { my $update = Open311::GetServiceRequestUpdates->new( system_user => $user, + current_open311 => $o, + current_body => $bodies{2482}, ); - $update->update_comments( $o, $bodies{2482} ); + $update->process_body; $problem->discard_changes; is $problem->comments->count, 2, 'two comments after fetching updates'; - $update->update_comments( $o, $bodies{2482} ); + $update->process_body; $problem->discard_changes; is $problem->comments->count, 2, 're-fetching updates does not add comments'; $problem->comments->delete; - $update->update_comments( $o, $bodies{2482} ); + $update->process_body; $problem->discard_changes; is $problem->comments->count, 2, 'if comments are deleted then they are added'; }; @@ -804,9 +846,11 @@ subtest 'check that external_status_code is stored correctly' => sub { my $update = Open311::GetServiceRequestUpdates->new( system_user => $user, + current_open311 => $o, + current_body => $bodies{2482}, ); - $update->update_comments( $o, $bodies{2482} ); + $update->process_body; $problem->discard_changes; is $problem->comments->count, 2, 'two comments after fetching updates'; @@ -818,6 +862,36 @@ subtest 'check that external_status_code is stored correctly' => sub { is $problem->get_extra_metadata('external_status_code'), "101", "correct external status code"; + $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?> + <service_requests_updates> + <request_update> + <update_id>638364</update_id> + <service_request_id>@{[ $problem->external_id ]}</service_request_id> + <status>open</status> + <description>This is a note</description> + <updated_datetime>UPDATED_DATETIME</updated_datetime> + <external_status_code></external_status_code> + </request_update> + </service_requests_updates> + }; + + $problem->comments->delete; + + my $dt3 = $dt->clone->add( minutes => 1 ); + $requests_xml =~ s/UPDATED_DATETIME/$dt3/; + + $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $requests_xml } ); + + $update = Open311::GetServiceRequestUpdates->new( + system_user => $user, + current_open311 => $o, + current_body => $bodies{2482}, + ); + + $update->process_body; + + $problem->discard_changes; + is $problem->get_extra_metadata('external_status_code'), '', "external status code unset"; }; subtest 'check that external_status_code triggers auto-responses' => sub { @@ -849,15 +923,15 @@ subtest 'check that external_status_code triggers auto-responses' => sub { my $update = Open311::GetServiceRequestUpdates->new( system_user => $user, + current_open311 => $o, + current_body => $bodies{2482}, ); - $update->update_comments( $o, $bodies{2482} ); + $update->process_body; $problem->discard_changes; is $problem->comments->count, 1, 'one comment after fetching updates'; - my $comment = $problem->comments->first; - is $problem->comments->first->text, "Thank you for your report. We will provide an update within 24 hours.", "correct external status code on first comment"; }; @@ -903,9 +977,11 @@ foreach my $test ( { my $update = Open311::GetServiceRequestUpdates->new( system_user => $user, + current_open311 => $o, + current_body => $bodies{2482}, ); - $update->update_comments( $o, $bodies{2482} ); + $update->process_body; $problem->discard_changes; is $problem->comments->count, 2, 'two comments after fetching updates'; @@ -914,6 +990,117 @@ foreach my $test ( { }; } +my $response_template_in_progress = $bodies{2482}->response_templates->create({ + title => "Acknowledgement 1", + text => "Thank you for your report. We will provide an update within 48 hours.", + auto_response => 1, + state => "in progress" +}); + +for my $test ( + { + external_code => '090', + description => 'check numeric external status code in response template override state', + }, + { + external_code => 'futher', + description => 'check alpha external status code in response template override state', + }, +) { + subtest $test->{description} => sub { + my $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?> + <service_requests_updates> + <request_update> + <update_id>638344</update_id> + <service_request_id>@{[ $problem->external_id ]}</service_request_id> + <status>in_progress</status> + <description></description> + <updated_datetime>UPDATED_DATETIME</updated_datetime> + <external_status_code></external_status_code> + </request_update> + <request_update> + <update_id>638345</update_id> + <service_request_id>@{[ $problem->external_id ]}</service_request_id> + <status>in_progress</status> + <description></description> + <updated_datetime>UPDATED_DATETIME2</updated_datetime> + <external_status_code>@{[ $test->{external_code} ]}</external_status_code> + </request_update> + </service_requests_updates> + }; + + my $response_template = $bodies{2482}->response_templates->create({ + # the default ordering uses the title of the report so + # make sure this comes second + title => "Acknowledgement 2", + text => "Thank you for your report. We will provide an update within 24 hours.", + auto_response => 1, + external_status_code => $test->{external_code} + }); + + $problem->comments->delete; + + my $dt2 = $dt->clone->add( minutes => 1 ); + $requests_xml =~ s/UPDATED_DATETIME/$dt/; + $requests_xml =~ s/UPDATED_DATETIME2/$dt2/; + + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $requests_xml } ); + + my $update = Open311::GetServiceRequestUpdates->new( + system_user => $user, + current_open311 => $o, + current_body => $bodies{2482}, + ); + + $update->process_body; + + $problem->discard_changes; + is $problem->comments->count, 2, 'two comment after fetching updates'; + + my @comments = $problem->comments->search(undef, { order_by => 'confirmed' }); + + is $comments[0]->text, "Thank you for your report. We will provide an update within 48 hours.", "correct external status code on first comment"; + is $comments[1]->text, "Thank you for your report. We will provide an update within 24 hours.", "correct external status code on second comment"; + $problem->comments->delete; + $response_template->delete; + }; +} + +subtest 'check that first comment always updates state' => sub { + my $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?> + <service_requests_updates> + <request_update> + <update_id>638344</update_id> + <service_request_id>@{[ $problem->external_id ]}</service_request_id> + <status>in_progress</status> + <description>This is a note</description> + <updated_datetime>UPDATED_DATETIME</updated_datetime> + </request_update> + </service_requests_updates> + }; + + $problem->state( 'confirmed' ); + $problem->lastupdate( $dt->clone->subtract( hours => 1 ) ); + $problem->update; + + $requests_xml =~ s/UPDATED_DATETIME/@{[$dt->clone->subtract( minutes => 62 )]}/; + + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $requests_xml } ); + + my $update = Open311::GetServiceRequestUpdates->new( + system_user => $user, + current_open311 => $o, + current_body => $bodies{2482}, + ); + + $update->process_body; + + $problem->discard_changes; + is $problem->comments->count, 1, 'one comment after fetching updates'; + is $problem->state, 'in progress', 'correct problem status'; + $problem->comments->delete; +}; + foreach my $test ( { desc => 'normally alerts are not suppressed', num_alerts => 1, @@ -968,9 +1155,11 @@ foreach my $test ( { my $update = Open311::GetServiceRequestUpdates->new( system_user => $user, suppress_alerts => $test->{suppress_alerts}, + current_open311 => $o, + current_body => $bodies{2482}, ); - $update->update_comments( $o, $bodies{2482} ); + $update->process_body; $problem->discard_changes; my $alerts_sent = FixMyStreet::DB->resultset('AlertSent')->search( @@ -1030,12 +1219,14 @@ foreach my $test ( { my $update = Open311::GetServiceRequestUpdates->new( system_user => $user, blank_updates_permitted => $test->{blank_updates_permitted}, + current_open311 => $o, + current_body => $bodies{2482}, ); if ( $test->{blank_updates_permitted} ) { - stderr_is { $update->update_comments( $o, $bodies{2482} ) } '', 'No error message' + stderr_is { $update->process_body } '', 'No error message' } else { - stderr_like { $update->update_comments( $o, $bodies{2482} ) } qr/Couldn't determine update text for/, 'Error message displayed' + stderr_like { $update->process_body } qr/Couldn't determine update text for/, 'Error message displayed' } $problem->discard_changes; $problem->comments->delete; @@ -1084,9 +1275,11 @@ subtest 'check matching on fixmystreet_id overrides service_request_id' => sub { my $update = Open311::GetServiceRequestUpdates->new( system_user => $user, + current_open311 => $o, + current_body => $bodies{2482}, ); - $update->update_comments( $o, $bodies{2482} ); + $update->process_body; $problem->discard_changes; is $problem->comments->count, 2, 'two comments after fetching updates'; @@ -1119,10 +1312,12 @@ subtest 'check bad fixmystreet_id is handled' => sub { my $update = Open311::GetServiceRequestUpdates->new( system_user => $user, + current_open311 => $o, + current_body => $bodies{2482}, ); warning_like { - $update->update_comments( $o, $bodies{2482} ) + $update->process_body } qr/skipping bad fixmystreet id in updates for Bromley: \[123456 654321\], external id is 8888888888888/, "warning emitted for bad fixmystreet id"; diff --git a/t/open311/getupdates.t b/t/open311/getupdates.t index 1cbabc5ab..351f17f6f 100644 --- a/t/open311/getupdates.t +++ b/t/open311/getupdates.t @@ -1,5 +1,4 @@ -#!/usr/bin/env perl - +use utf8; use FixMyStreet::Test; use URI::Split qw(uri_split); @@ -220,7 +219,7 @@ my $problem3 = $problem_rs->create( { used_map => 1, name => '', state => 'confirmed', - cobrand => 'fiksgatami', + cobrand => 'fixamingata', user => $user, created => DateTime->now()->subtract( days => 1 ), lastupdate => DateTime->now()->subtract( days => 1 ), @@ -235,7 +234,7 @@ subtest 'test translation of auto-added comment from old-style Open311 update' = my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'requests.xml' => $requests_xml } ); FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'fiksgatami' ], + ALLOWED_COBRANDS => [ 'fixamingata' ], }, sub { ok $updates->update_reports( [ 638346 ], $o, $body ), 'Updated reports'; }; @@ -245,7 +244,7 @@ subtest 'test translation of auto-added comment from old-style Open311 update' = is_deeply(\@qs, [ 'jurisdiction_id=mysociety', 'service_request_id=638346' ], 'query string matches'); is $problem3->comments->count, 1, 'added a comment'; - is $problem3->comments->first->text, "(ikke rapportert til administrasjonen)", 'correct comment text'; + is $problem3->comments->first->text, "Stängd av kommunen", 'correct comment text'; }; END { diff --git a/t/open311/populate-service-list.t b/t/open311/populate-service-list.t index ff4c4cf9d..bd837f203 100644 --- a/t/open311/populate-service-list.t +++ b/t/open311/populate-service-list.t @@ -5,20 +5,11 @@ use parent 'FixMyStreet::Cobrand::Default'; sub council_area_id { 1 } - -package FixMyStreet::Cobrand::TesterGroups; - -use parent 'FixMyStreet::Cobrand::Default'; - -sub council_area_id { 1 } - -sub enable_category_groups { 1 } - - package main; use FixMyStreet::Test; use FixMyStreet::DB; +use Test::Warn; use utf8; use_ok( 'Open311::PopulateServiceList' ); @@ -44,20 +35,23 @@ $bromley->body_areas->create({ } ); my $bucks = FixMyStreet::DB->resultset('Body')->create({ - name => 'Buckinghamshire County Council', + name => 'Buckinghamshire Council', }); $bucks->body_areas->create({ area_id => 2217 }); for my $test ( - { desc => 'groups not set for new contacts', cobrand => 'tester', groups => 0, delete => 1 }, - { desc => 'groups set for new contacts', cobrand => 'testergroups', groups => 1, delete => 1}, - { desc => 'groups removed for existing contacts', cobrand => 'tester', groups => 0, delete => 0 }, - { desc => 'groups added for existing contacts', cobrand => 'testergroups', groups => 1, delete => 0}, + { desc => 'groups not set for new contacts', enable_groups => 0, groups => 0, delete => 1 }, + { desc => 'groups set for new contacts', enable_groups => 1, groups => 1, delete => 1}, + { desc => 'groups removed for existing contacts', enable_groups => 0, groups => 0, delete => 0 }, + { desc => 'groups added for existing contacts', enable_groups => 1, groups => 1, delete => 0}, ) { FixMyStreet::override_config { - ALLOWED_COBRANDS => [ $test->{cobrand} ], + ALLOWED_COBRANDS => [ 'tester' ], + COBRAND_FEATURES => { + category_groups => { tester => $test->{enable_groups} }, + } }, sub { subtest 'check basic functionality, ' . $test->{desc} => sub { FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->delete() if $test->{delete}; @@ -83,6 +77,104 @@ for my $test ( }; } +my $last_update = {}; +for my $test ( + { desc => 'set multiple groups for contact', enable_multi => 1, groups => ['sanitation', 'street'] }, + { desc => 'groups not edited if unchanged', enable_multi => 1, groups => ['sanitation', 'street'], unchanged => 1 }, +) { + subtest $test->{desc} => sub { + FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->delete(); + + my $services_xml = '<?xml version="1.0" encoding="utf-8"?> + <services> + <service> + <service_code>100</service_code> + <service_name>Cans left out 24x7</service_name> + <description>Garbage or recycling cans that have been left out for more than 24 hours after collection. Violators will be cited.</description> + <metadata>false</metadata> + <type>realtime</type> + <keywords>lorem, ipsum, dolor</keywords> + <groups><group>sanitation</group><group>street</group></groups> + </service> + <service> + <service_code>002</service_code> + <metadata>false</metadata> + <type>realtime</type> + <keywords>lorem, ipsum, dolor</keywords> + <group>street</group> + <service_name>Construction plate shifted</service_name> + <description>Metal construction plate covering the street or sidewalk has been moved.</description> + </service> + </services> + '; + + my $service_list = get_xml_simple_object($services_xml); + + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'tester' ], + COBRAND_FEATURES => { + category_groups => { tester => 1 }, + } + }, sub { + my $processor = Open311::PopulateServiceList->new(); + $processor->_current_body( $body ); + $processor->process_services( $service_list ); + }; + my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->count(); + is $contact_count, 2, 'correct number of contacts'; + + my $contact = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id, email => 100 } )->first; + is_deeply $contact->get_extra->{group}, $test->{groups}, "Multi groups set correctly"; + if ($test->{unchanged}) { + is $contact->whenedited, $last_update->{100}, "contact unchanged"; + } + $last_update->{100} = $contact->whenedited; + + $contact = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id, email => '002'} )->first; + is $contact->get_extra->{group}, 'street', "Single groups set correctly"; + if ($test->{unchanged}) { + is $contact->whenedited, $last_update->{002}, "contact unchanged"; + } + $last_update->{002} = $contact->whenedited; + }; +} + +subtest "set multiple groups with groups element" => sub { + FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->delete(); + + my $services_xml = '<?xml version="1.0" encoding="utf-8"?> + <services> + <service> + <service_code>100</service_code> + <service_name>Cans left out 24x7</service_name> + <description>Garbage or recycling cans that have been left out for more than 24 hours after collection. Violators will be cited.</description> + <metadata>false</metadata> + <type>realtime</type> + <keywords>lorem, ipsum, dolor</keywords> + <groups><group>sanitation & cleaning</group><group>street</group></groups> + </service> + </services> + '; + + my $service_list = get_xml_simple_object($services_xml); + + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'tester' ], + COBRAND_FEATURES => { + category_groups => { tester => 1 }, + } + }, sub { + my $processor = Open311::PopulateServiceList->new(); + $processor->_current_body( $body ); + $processor->process_services( $service_list ); + }; + my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->count(); + is $contact_count, 1, 'correct number of contacts'; + + my $contact = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id, email => 100 } )->first; + is_deeply $contact->get_extra->{group}, ['sanitation & cleaning','street'], "groups set correctly"; +}; + subtest 'check non open311 contacts marked as deleted' => sub { FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->delete(); @@ -225,6 +317,153 @@ subtest 'check conflicting contacts not changed' => sub { is $contact_count, 4, 'correct number of contacts'; }; +subtest 'check new category marked non_public' => sub { + FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->delete(); + + my $services_xml = '<?xml version="1.0" encoding="utf-8"?> + <services> + <service> + <service_code>100</service_code> + <service_name>Cans left out 24x7</service_name> + <description>Garbage or recycling cans that have been left out for more than 24 hours after collection. Violators will be cited.</description> + <metadata>false</metadata> + <type>realtime</type> + <keywords>private</keywords> + <group>sanitation</group> + </service> + </services> + '; + + my $service_list = get_xml_simple_object( $services_xml ); + + my $processor = Open311::PopulateServiceList->new(); + $processor->_current_body( $body ); + $processor->process_services( $service_list ); + + my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->count(); + is $contact_count, 1, 'correct number of contacts'; + + my $contact = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->first; + is $contact->email, '100', 'email correct'; + is $contact->category, 'Cans left out 24x7', 'category correct'; + is $contact->non_public, 1, 'contact marked as non_public'; +}; + +subtest 'check protected categories do not have name/group overwritten' => sub { + my $contact = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->first; + $contact->set_extra_metadata('open311_protect', 1); + $contact->set_extra_metadata('group', [ 'sanitation' ]); + $contact->non_public(0); + $contact->update; + + my $services_xml = '<?xml version="1.0" encoding="utf-8"?> + <services> + <service> + <service_code>100</service_code> + <service_name>Cans left out constantly</service_name> + <description>Garbage or recycling cans that have been left out for more than 24 hours after collection. Violators will be cited.</description> + <metadata>false</metadata> + <type>realtime</type> + <keywords>private</keywords> + <group>cleansing</group> + </service> + </services> + '; + + my $service_list = get_xml_simple_object( $services_xml ); + + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'tester' ], + COBRAND_FEATURES => { + category_groups => { tester => 1 }, + } + }, sub { + my $processor = Open311::PopulateServiceList->new(); + $processor->_current_body( $body ); + $processor->process_services( $service_list ); + }; + + my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->count(); + is $contact_count, 1, 'correct number of contacts'; + + $contact->discard_changes; + is $contact->email, '100', 'email correct'; + is $contact->category, 'Cans left out 24x7', 'category unchanged'; + is_deeply $contact->groups, ['sanitation'], 'group unchanged'; + # test that something did change + is $contact->non_public, 1, 'contact marked as non_public'; +}; + + +subtest 'check existing category marked non_public' => sub { + my $contact = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->first; + $contact->update({ + non_public => 0 + }); + is $contact->non_public, 0, 'contact not marked as non_public'; + + my $services_xml = '<?xml version="1.0" encoding="utf-8"?> + <services> + <service> + <service_code>100</service_code> + <service_name>Cans left out 24x7</service_name> + <description>Garbage or recycling cans that have been left out for more than 24 hours after collection. Violators will be cited.</description> + <metadata>false</metadata> + <type>realtime</type> + <keywords>private</keywords> + <group>sanitation</group> + </service> + </services> + '; + + my $service_list = get_xml_simple_object( $services_xml ); + + my $processor = Open311::PopulateServiceList->new(); + $processor->_current_body( $body ); + $processor->process_services( $service_list ); + + my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->count(); + is $contact_count, 1, 'correct number of contacts'; + + $contact->discard_changes; + is $contact->email, '100', 'email correct'; + is $contact->category, 'Cans left out 24x7', 'category correct'; + is $contact->non_public, 1, 'contact changed to non_public'; +}; + +subtest 'check existing non_public category does not get marked public' => sub { + my $contact = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->first; + is $contact->non_public, 1, 'contact marked as non_public'; + + my $services_xml = '<?xml version="1.0" encoding="utf-8"?> + <services> + <service> + <service_code>100</service_code> + <service_name>Cans left out 24x7</service_name> + <description>Garbage or recycling cans that have been left out for more than 24 hours after collection. Violators will be cited.</description> + <metadata>false</metadata> + <type>realtime</type> + <keywords></keywords> + <group>sanitation</group> + </service> + </services> + '; + + my $service_list = get_xml_simple_object( $services_xml ); + + my $processor = Open311::PopulateServiceList->new(); + $processor->_current_body( $body ); + $processor->process_services( $service_list ); + + my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->count(); + is $contact_count, 1, 'correct number of contacts'; + + $contact->discard_changes; + is $contact->email, '100', 'email correct'; + is $contact->category, 'Cans left out 24x7', 'category correct'; + is $contact->non_public, 1, 'contact remains non_public'; +}; + for my $test ( { desc => 'check meta data added to existing contact', @@ -237,7 +476,7 @@ for my $test ( required => 'true', datatype_description => 'Type of bin', order => 1, - description => 'Type of bin' + description => 'Type of <b>bin</b>' } ], meta_xml => '<?xml version="1.0" encoding="utf-8"?> @@ -251,7 +490,7 @@ for my $test ( <required>true</required> <datatype_description>Type of bin</datatype_description> <order>1</order> - <description>Type of bin</description> + <description><type>Type</type> of <b>bin</b></description> </attribute> </attributes> </service_definition> @@ -370,6 +609,134 @@ for my $test ( ', }, { + desc => 'check protected meta data not overwritten', + has_meta => 1, + end_meta => [ { + variable => 'true', + code => 'type', + datatype => 'string', + required => 'true', + datatype_description => 'Bin type', + order => 1, + description => 'Bin type', + protected => 'true' + + } ], + orig_meta => [ { + variable => 'true', + code => 'type', + datatype => 'string', + required => 'true', + datatype_description => 'Bin type', + order => 1, + description => 'Bin type', + protected => 'true' + + } ], + meta_xml => '<?xml version="1.0" encoding="utf-8"?> + <service_definition> + <service_code>100</service_code> + <attributes> + <attribute> + <variable>true</variable> + <code>type</code> + <datatype>string</datatype> + <required>true</required> + <datatype_description>Type of bin</datatype_description> + <order>1</order> + <description>Type of bin</description> + </attribute> + </attributes> + </service_definition> + ', + }, + { + desc => 'check protected meta data retained', + has_meta => 1, + end_meta => [ + { + variable => 'true', + code => 'type2', + datatype => 'string', + required => 'true', + datatype_description => 'Type of bin', + order => 1, + description => 'Type of bin', + + }, + { + variable => 'true', + code => 'type', + datatype => 'string', + required => 'true', + datatype_description => 'Number of bin', + order => 1, + description => 'Number of bin', + protected => 'true' + }, + ], + orig_meta => [ { + variable => 'true', + code => 'type', + datatype => 'string', + required => 'true', + datatype_description => 'Number of bin', + order => 1, + description => 'Number of bin', + protected => 'true' + + } ], + meta_xml => '<?xml version="1.0" encoding="utf-8"?> + <service_definition> + <service_code>100</service_code> + <attributes> + <attribute> + <variable>true</variable> + <code>type2</code> + <datatype>string</datatype> + <required>true</required> + <datatype_description>Type of bin</datatype_description> + <order>1</order> + <description>Type of bin</description> + </attribute> + </attributes> + </service_definition> + ', + }, + { + desc => 'check protected meta data retained on removal of all Open311 extras', + end_meta => [ + { + variable => 'true', + code => 'type', + datatype => 'string', + required => 'true', + datatype_description => 'Number of bin', + order => 1, + description => 'Number of bin', + protected => 'true' + }, + ], + orig_meta => [ { + variable => 'true', + code => 'type', + datatype => 'string', + required => 'true', + datatype_description => 'Number of bin', + order => 1, + description => 'Number of bin', + protected => 'true' + + } ], + meta_xml => '<?xml version="1.0" encoding="utf-8"?> + <service_definition> + <service_code>100</service_code> + <attributes> + </attributes> + </service_definition> + ', + }, + { desc => 'check empty meta data handled', has_meta => 1, orig_meta => [], diff --git a/t/open311/post-service-request-updates.t b/t/open311/post-service-request-updates.t index 57b8f9a2a..adfd4e3c5 100644 --- a/t/open311/post-service-request-updates.t +++ b/t/open311/post-service-request-updates.t @@ -15,8 +15,8 @@ my $params = { endpoint => 'endpoint', jurisdiction => 'home', }; -my $bromley = $mech->create_body_ok(2482, 'Bromley', { %$params, send_extended_statuses => 1, id => 5 }); -my $oxon = $mech->create_body_ok(2237, 'Oxfordshire', { %$params, id => 55 }); +my $bromley = $mech->create_body_ok(2482, 'Bromley', { %$params, send_extended_statuses => 1 }); +my $oxon = $mech->create_body_ok(2237, 'Oxfordshire', { %$params, id => "5" . $bromley->id }); my $bucks = $mech->create_body_ok(2217, 'Buckinghamshire', $params); my $lewisham = $mech->create_body_ok(2492, 'Lewisham', $params); @@ -61,7 +61,8 @@ my $other_user = $mech->create_user_ok('test2@example.com', title => 'MRS'); sub c { my ($p, $user) = @_; - my $c = $mech->create_comment_for_problem($p, $user || $p->user, 'Name', 'Update text', 'f', 'confirmed', 'confirmed', { confirmed => \'current_timestamp' }); + my $c = $mech->create_comment_for_problem($p, $user || $p->user, 'Name', 'Update text', 'f', 'confirmed', 'confirmed'); + $c->discard_changes; return $c; } @@ -96,6 +97,30 @@ subtest 'Send comments' => sub { }; }; +subtest 'Check Bexley munging' => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => ['fixmystreet', 'bexley'], + }, sub { + my $bexley = $mech->create_body_ok(2494, 'Bexley', $params); + $mech->create_contact_ok(body_id => $bexley->id, category => 'Other', email => "OTHER"); + + my $test_res = HTTP::Response->new(); + $test_res->code(200); + $test_res->message('OK'); + $test_res->content('<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>'); + my $o = Open311->new( + fixmystreet_body => $bexley, + test_mode => 1, + test_get_returns => { 'servicerequestupdates.xml' => $test_res }, + ); + my ($p5, $c5) = p_and_c($bexley); + my $id = $o->post_service_request_update($c5); + is $id, 248, 'correct update ID returned'; + like $o->test_req_used->content, qr/service_code=OTHER/, 'Service code included'; + }; +}; + + subtest 'Oxfordshire gets an ID' => sub { FixMyStreet::override_config { ALLOWED_COBRANDS => ['fixmystreet', 'bromley', 'buckinghamshire', 'lewisham', 'oxfordshire'], |