diff options
Diffstat (limited to 't/open311/getservicerequestupdates.t')
-rw-r--r-- | t/open311/getservicerequestupdates.t | 537 |
1 files changed, 537 insertions, 0 deletions
diff --git a/t/open311/getservicerequestupdates.t b/t/open311/getservicerequestupdates.t new file mode 100644 index 000000000..7ec8d5ae0 --- /dev/null +++ b/t/open311/getservicerequestupdates.t @@ -0,0 +1,537 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use Test::More; +use CGI::Simple; + +use FindBin; +use lib "$FindBin::Bin/../perllib"; +use lib "$FindBin::Bin/../commonlib/perllib"; + +use_ok( 'Open311' ); + +use_ok( 'Open311::GetServiceRequestUpdates' ); +use DateTime; +use FixMyStreet::App; + +my $user = FixMyStreet::App->model('DB::User')->find_or_create( + { + email => 'system_user@example.com' + } +); + +my $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?> +<service_requests_updates> +<request_update> +<update_id>638344</update_id> +<service_request_id>1</service_request_id> +<service_request_id_ext>1</service_request_id_ext> +<status>open</status> +<description>This is a note</description> +UPDATED_DATETIME +</request_update> +</service_requests_updates> +}; + + +my $dt = DateTime->now; + +# basic xml -> perl object tests +for my $test ( + { + desc => 'basic parsing - element missing', + updated_datetime => '', + res => { update_id => 638344, service_request_id => 1, service_request_id_ext => 1, + status => 'open', description => 'This is a note' }, + }, + { + desc => 'basic parsing - empty element', + updated_datetime => '<updated_datetime />', + res => { update_id => 638344, service_request_id => 1, service_request_id_ext => 1, + status => 'open', description => 'This is a note', updated_datetime => {} } , + }, + { + desc => 'basic parsing - element with no content', + updated_datetime => '<updated_datetime></updated_datetime>', + res => { update_id => 638344, service_request_id => 1, service_request_id_ext => 1, + status => 'open', description => 'This is a note', updated_datetime => {} } , + }, + { + desc => 'basic parsing - element with content', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), + res => { update_id => 638344, service_request_id => 1, service_request_id_ext => 1, + status => 'open', description => 'This is a note', updated_datetime => $dt } , + }, +) { + subtest $test->{desc} => sub { + 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 => { 'update.xml' => $local_requests_xml } ); + + my $res = $o->get_service_request_updates; + is_deeply $res->[0], $test->{ res }, 'result looks correct'; + + }; +} + +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 => time(), + council => 2482, + } +); + +$problem->insert; + +for my $test ( + { + desc => 'element with content', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), + description => 'This is a note', + external_id => 638344, + start_state => 'confirmed', + close_comment => 0, + mark_fixed=> 0, + mark_open => 0, + problem_state => undef, + end_state => 'confirmed', + }, + { + desc => 'comment closes report', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), + description => 'This is a note', + external_id => 638344, + start_state => 'confirmed', + close_comment => 1, + mark_fixed=> 0, + mark_open => 0, + problem_state => 'fixed - council', + end_state => 'fixed - council', + }, + { + desc => 'comment re-opens fixed report', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), + description => 'This is a note', + external_id => 638344, + start_state => 'fixed - user', + close_comment => 0, + mark_fixed => 0, + mark_open => 0, + problem_state => 'confirmed', + end_state => 'confirmed', + }, + { + desc => 'comment re-opens closed report', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), + description => 'This is a note', + external_id => 638344, + start_state => 'closed', + close_comment => 0, + mark_fixed => 0, + mark_open => 0, + problem_state => 'confirmed', + end_state => 'confirmed', + }, + { + desc => 'comment leaves report closed', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), + description => 'This is a note', + external_id => 638344, + start_state => 'closed', + close_comment => 1, + mark_fixed => 0, + mark_open => 0, + end_state => 'closed', + }, +) { + subtest $test->{desc} => sub { + my $local_requests_xml = $requests_xml; + $local_requests_xml =~ s/UPDATED_DATETIME/$test->{updated_datetime}/; + $local_requests_xml =~ s#<service_request_id>\d+</service_request_id>#<service_request_id>@{[$problem->external_id]}</service_request_id>#; + $local_requests_xml =~ s#<service_request_id_ext>\d+</service_request_id_ext>#<service_request_id_ext>@{[$problem->id]}</service_request_id_ext>#; + $local_requests_xml =~ s#<status>\w+</status>#<status>closed</status># if $test->{close_comment}; + + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'update.xml' => $local_requests_xml } ); + + $problem->comments->delete; + $problem->lastupdate( DateTime->now()->subtract( days => 1 ) ); + $problem->state( $test->{start_state} ); + $problem->update; + + my $council_details = { areaid => 2482 }; + my $update = Open311::GetServiceRequestUpdates->new( system_user => $user ); + $update->update_comments( $o, $council_details ); + + is $problem->comments->count, 1, 'comment count'; + $problem->discard_changes; + + my $c = FixMyStreet::App->model('DB::Comment')->search( { external_id => $test->{external_id} } )->first; + ok $c, 'comment exists'; + is $c->text, $test->{description}, 'text correct'; + is $c->mark_fixed, $test->{mark_fixed}, 'mark_closed correct'; + is $c->problem_state, $test->{problem_state}, 'problem_state correct'; + is $c->mark_open, $test->{mark_open}, 'mark_open correct'; + is $problem->state, $test->{end_state}, 'correct problem state'; + }; +} + + +foreach my $test ( + { + desc => 'date for comment correct', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), + external_id => 638344, + }, +) { + subtest $test->{desc} => sub { + my $dt = DateTime->now(); + $dt->subtract( minutes => 10 ); + my $local_requests_xml = $requests_xml; + + my $updated = sprintf( '<updated_datetime>%s</updated_datetime>', $dt ); + $local_requests_xml =~ s/UPDATED_DATETIME/$updated/; + $local_requests_xml =~ s#<service_request_id>\d+</service_request_id>#<service_request_id>@{[$problem->external_id]}</service_request_id>#; + $local_requests_xml =~ s#<service_request_id_ext>\d+</service_request_id_ext>#<service_request_id_ext>@{[$problem->id]}</service_request_id_ext>#; + + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'update.xml' => $local_requests_xml } ); + + $problem->comments->delete; + + my $council_details = { areaid => 2482 }; + my $update = Open311::GetServiceRequestUpdates->new( system_user => $user ); + $update->update_comments( $o, $council_details ); + + my $comment = $problem->comments->first; + is $comment->created, $dt, 'created date set to date from XML'; + is $comment->confirmed, $dt, 'confirmed date set to date from XML'; + }; +} + +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(), + lastupdate => DateTime->now(), + anonymous => 1, + external_id => $problem->external_id, + council => 2651, + } +); + +$problem2->insert(); +$problem->comments->delete; +$problem2->comments->delete; + +for my $test ( + { + desc => 'identical external_ids on problem resolved using council', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), + external_id => 638344, + area_id => 2651, + request_id => $problem2->external_id, + request_id_ext => $problem2->id, + p1_comments => 0, + p2_comments => 1, + }, + { + desc => 'identical external_ids on comments resolved', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), + external_id => 638344, + area_id => 2482, + request_id => $problem->external_id, + request_id_ext => $problem->id, + p1_comments => 1, + p2_comments => 1, + }, +) { + subtest $test->{desc} => sub { + my $local_requests_xml = $requests_xml; + $local_requests_xml =~ s/UPDATED_DATETIME/$test->{updated_datetime}/; + $local_requests_xml =~ s#<service_request_id>\d+</service_request_id>#<service_request_id>$test->{request_id}</service_request_id>#; + $local_requests_xml =~ s#<service_request_id_ext>\d+</service_request_id_ext>#<service_request_id_ext>$test->{request_id_ext}</service_request_id_ext>#; + + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'update.xml' => $local_requests_xml } ); + + + my $council_details = { areaid => $test->{area_id} }; + my $update = Open311::GetServiceRequestUpdates->new( system_user => $user ); + $update->update_comments( $o, $council_details ); + + is $problem->comments->count, $test->{p1_comments}, 'comment count for first problem'; + is $problem2->comments->count, $test->{p2_comments}, 'comment count for second problem'; + }; +} + +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 => { 'update.xml' => $local_requests_xml } ); + + my $start_dt = DateTime->now(); + $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, + ); + + my $council_details = { areaid => 2482 }; + $update->update_comments( $o, $council_details ); + + my $start = $start_dt . ''; + my $end = $end_dt . ''; + + my $uri = URI->new( $o->test_uri_used ); + my $c = CGI::Simple->new( $uri->query ); + + is $c->param('start_date'), $start, 'start date used'; + is $c->param('end_date'), $end, 'end date used'; +}; + +subtest 'check that existing comments are not duplicated' => 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> + <service_request_id_ext>@{[ $problem->id ]}</service_request_id_ext> + <status>open</status> + <description>This is a note</description> + <updated_datetime>UPDATED_DATETIME</updated_datetime> + </request_update> + <request_update> + <update_id>638354</update_id> + <service_request_id>@{[ $problem->external_id ]}</service_request_id> + <service_request_id_ext>@{[ $problem->id ]}</service_request_id_ext> + <status>open</status> + <description>This is a different note</description> + <updated_datetime>UPDATED_DATETIME2</updated_datetime> + </request_update> + </service_requests_updates> + }; + + $problem->comments->delete; + + my $comment = FixMyStreet::App->model('DB::Comment')->new( + { + problem => $problem, + external_id => 638344, + text => 'This is a note', + user => $user, + state => 'confirmed', + mark_fixed => 0, + anonymous => 0, + confirmed => $dt, + } + ); + $comment->insert; + + is $problem->comments->count, 1, 'one comment before fetching updates'; + + $requests_xml =~ s/UPDATED_DATETIME2/$dt/; + $requests_xml =~ s/UPDATED_DATETIME/@{[ $comment->confirmed ]}/; + + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'update.xml' => $requests_xml } ); + + my $update = Open311::GetServiceRequestUpdates->new( + system_user => $user, + ); + + my $council_details = { areaid => 2482 }; + $update->update_comments( $o, $council_details ); + + $problem->discard_changes; + is $problem->comments->count, 2, 'two comments after fetching updates'; + + $update->update_comments( $o, $council_details ); + $problem->discard_changes; + is $problem->comments->count, 2, 're-fetching updates does not add comments'; + + $problem->comments->delete; + $update->update_comments( $o, $council_details ); + $problem->discard_changes; + is $problem->comments->count, 2, 'if comments are deleted then they are added'; +}; + +foreach my $test ( { + desc => 'check that closed and then open comment results in correct state', + dt1 => $dt->subtract( hours => 1 ), + dt2 => $dt, + }, + { + desc => 'check that old comments do not change problem status', + dt1 => $dt->subtract( hours => 2 ), + dt2 => $dt, + } +) { + subtest $test->{desc} => 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> + <service_request_id_ext>@{[ $problem->id ]}</service_request_id_ext> + <status>closed</status> + <description>This is a note</description> + <updated_datetime>UPDATED_DATETIME</updated_datetime> + </request_update> + <request_update> + <update_id>638354</update_id> + <service_request_id>@{[ $problem->external_id ]}</service_request_id> + <service_request_id_ext>@{[ $problem->id ]}</service_request_id_ext> + <status>open</status> + <description>This is a different note</description> + <updated_datetime>UPDATED_DATETIME2</updated_datetime> + </request_update> + </service_requests_updates> + }; + + $problem->comments->delete; + $problem->state( 'confirmed' ); + $problem->lastupdate( $dt->subtract( hours => 3 ) ); + $problem->update; + + $requests_xml =~ s/UPDATED_DATETIME/$test->{dt1}/; + $requests_xml =~ s/UPDATED_DATETIME2/$test->{dt2}/; + + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'update.xml' => $requests_xml } ); + + my $update = Open311::GetServiceRequestUpdates->new( + system_user => $user, + ); + + my $council_details = { areaid => 2482 }; + $update->update_comments( $o, $council_details ); + + $problem->discard_changes; + is $problem->comments->count, 2, 'two comments after fetching updates'; + is $problem->state, 'confirmed', 'correct problem status'; + }; +} + +foreach my $test ( { + desc => 'normally alerts are not suppressed', + suppress_alerts => 0, + }, + { + desc => 'alerts suppressed if suppress_alerts set', + suppress_alerts => 1, + } +) { + subtest $test->{desc} => 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> + <service_request_id_ext>@{[ $problem->id ]}</service_request_id_ext> + <status>closed</status> + <description>This is a note</description> + <updated_datetime>UPDATED_DATETIME</updated_datetime> + </request_update> + </service_requests_updates> + }; + + $problem->comments->delete; + $problem->state( 'confirmed' ); + $problem->lastupdate( $dt->subtract( hours => 3 ) ); + $problem->update; + + my $alert = FixMyStreet::App->model('DB::Alert')->find_or_create( { + alert_type => 'new_updates', + parameter => $problem->id, + confirmed => 1, + user_id => $problem->user->id, + } ); + + $requests_xml =~ s/UPDATED_DATETIME/$dt/; + + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'update.xml' => $requests_xml } ); + + my $update = Open311::GetServiceRequestUpdates->new( + system_user => $user, + suppress_alerts => $test->{suppress_alerts}, + ); + + my $council_details = { areaid => 2482 }; + $update->update_comments( $o, $council_details ); + $problem->discard_changes; + + my $alerts_sent = FixMyStreet::App->model('DB::AlertSent')->search( + { + alert_id => $alert->id, + parameter => $problem->comments->first->id, + } + ); + + if ( $test->{suppress_alerts} ) { + ok $alerts_sent->count(), 'alerts suppressed'; + } else { + is $alerts_sent->count(), 0, 'alerts not suppressed'; + } + + $alerts_sent->delete; + $alert->delete; + } +} + +$problem2->comments->delete(); +$problem->comments->delete(); +$problem2->delete; +$problem->delete; +$user->comments->delete; +$user->problems->delete; +$user->delete; + +done_testing(); |