diff options
Diffstat (limited to 't')
-rw-r--r-- | t/app/controller/report_new.t | 116 | ||||
-rw-r--r-- | t/open311.t | 317 | ||||
-rw-r--r-- | t/open311/getservicerequestupdates.t | 409 | ||||
-rw-r--r-- | t/open311/populate-service-list.t | 298 |
4 files changed, 1136 insertions, 4 deletions
diff --git a/t/app/controller/report_new.t b/t/app/controller/report_new.t index 625c7531f..1e751997b 100644 --- a/t/app/controller/report_new.t +++ b/t/app/controller/report_new.t @@ -48,6 +48,12 @@ my $contact3 = FixMyStreet::App->model('DB::Contact')->find_or_create( { category => 'Trees', email => 'trees@example.com', } ); +my $contact4 = FixMyStreet::App->model('DB::Contact')->find_or_create( { + %contact_params, + area_id => 2482, # Bromley + category => 'Trees', + email => 'trees@example.com', +} ); ok $contact1, "created test contact 1"; ok $contact2, "created test contact 2"; ok $contact3, "created test contact 3"; @@ -293,7 +299,7 @@ foreach my $test ( 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', }, + $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" ); # submit the main form @@ -473,7 +479,7 @@ subtest "test password errors for a user who is signing in as they report" => su "submit location" ); # click through to the report page - $mech->follow_link_ok( { text => 'Skip this step', }, + $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" ); $mech->submit_form_ok( @@ -520,7 +526,7 @@ subtest "test report creation for a user who is signing in as they report" => su "submit location" ); # click through to the report page - $mech->follow_link_ok( { text => 'Skip this step', }, + $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" ); $mech->submit_form_ok( @@ -614,7 +620,7 @@ foreach my $test ( "submit location" ); # click through to the report page - $mech->follow_link_ok( { text => 'Skip this step', }, + $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" ); # check that the fields are correctly prefilled @@ -725,6 +731,108 @@ subtest "check that a lat/lon off coast leads to /around" => sub { }; +for my $test ( + { + desc => 'title shown for bromley problem on main site', + host => 'http://www.fixmystreet.com', + extra => [ + { + name => 'fms_extra_title', + value => 'Mr', + description => 'FMS_EXTRA_TITLE', + }, + ], + }, + { + desc => + 'title, first and last name shown for bromley problem on cobrand', + host => 'http://bromley.fixmystreet.com', + first_name => 'Test', + last_name => 'User', + extra => [ + { + name => 'fms_extra_title', + value => 'Mr', + description => 'FMS_EXTRA_TITLE', + }, + { + name => 'first_name', + value => 'Test', + description => 'FIRST_NAME', + }, + { + name => 'last_name', + value => 'User', + description => 'LAST_NAME', + }, + ], + }, + ) +{ + subtest $test->{desc} => sub { + $mech->host( $test->{host} ); + + $mech->log_out_ok; + + $mech->get_ok('/around'); + $mech->submit_form_ok( { with_fields => { pc => 'BR1 3UH', } }, + "submit location" ); + $mech->follow_link_ok( + { text_regex => qr/skip this step/i, }, + "follow 'skip this step' link" + ); + + my $fields = $mech->visible_form_values('mapSkippedForm'); + ok exists( $fields->{fms_extra_title} ), 'user title field displayed'; + if ( $test->{first_name} ) { + ok exists( $fields->{first_name} ), 'first name field displayed'; + ok exists( $fields->{last_name} ), 'last name field displayed'; + ok !exists( $fields->{name} ), 'no name field displayed'; + } + else { + ok !exists( $fields->{first_name} ), + 'first name field not displayed'; + ok !exists( $fields->{last_name} ), 'last name field not displayed'; + ok exists( $fields->{name} ), 'name field displayed'; + } + + my $submission_fields = { + title => "Test Report", + detail => 'Test report details.', + photo => '', + email => 'firstlast@example.com', + fms_extra_title => 'Mr', + may_show_name => '1', + phone => '07903 123 456', + category => 'Trees', + password_register => '', + }; + + if ( $test->{first_name} ) { + $submission_fields->{first_name} = $test->{first_name}; + $submission_fields->{last_name} = $test->{last_name}; + } + else { + $submission_fields->{name} = 'Test User'; + } + + $mech->submit_form_ok( { with_fields => $submission_fields }, + "submit good details" ); + + my $user = + FixMyStreet::App->model('DB::User') + ->find( { email => 'firstlast@example.com' } ); + + my $report = $user->problems->first; + ok $report, "Found the report"; + my $extras = $report->extra; + is_deeply $extras, $test->{extra}, 'extra contains correct values'; + + $user->problems->delete; + $user->delete; + }; +} + $contact1->delete; $contact2->delete; $contact3->delete; diff --git a/t/open311.t b/t/open311.t index 30de330b6..83b81d8aa 100644 --- a/t/open311.t +++ b/t/open311.t @@ -5,6 +5,9 @@ use warnings; use Test::More; use Test::Warn; use FixMyStreet::App; +use CGI::Simple; +use HTTP::Response; +use DateTime; use FindBin; use lib "$FindBin::Bin/../perllib"; @@ -39,4 +42,318 @@ my $expected_error = qr{.*request failed: 500 Can.t connect to 192.168.50.1:80 \ warning_like {$o2->send_service_request( $p, { url => 'http://example.com/' }, 1 )} $expected_error, 'warning generated on failed call'; +my $dt = DateTime->now(); + +my $user = FixMyStreet::App->model('DB::User')->new( { + name => 'Test User', + email => 'test@example.com', +} ); + +my $problem = FixMyStreet::App->model('DB::Problem')->new( { + id => 80, + external_id => 81, + state => 'confirmed', + title => 'a problem', + detail => 'problem detail', + category => 'pothole', + latitude => 1, + longitude => 2, + user => $user, +} ); + +subtest 'posting service request' => sub { + my $extra = { + url => 'http://example.com/report/1', + }; + + my $results = make_service_req( $problem, $extra, $problem->category, '<?xml version="1.0" encoding="utf-8"?><service_requests><request><service_request_id>248</service_request_id></request></service_requests>' ); + + is $results->{ res }, 248, 'got request id'; + + my $req = $o->test_req_used; + + my $description = <<EOT; +title: a problem + +detail: problem detail + +url: http://example.com/report/1 + +Submitted via FixMyStreet +EOT +; + + my $c = CGI::Simple->new( $results->{ req }->content ); + + is $c->param('email'), $user->email, 'correct email'; + is $c->param('first_name'), 'Test', 'correct first name'; + is $c->param('last_name'), 'User', 'correct last name'; + is $c->param('lat'), 1, 'latitide correct'; + is $c->param('long'), 2, 'longitude correct'; + is $c->param('description'), $description, 'descritpion correct'; + is $c->param('service_code'), 'pothole', 'service code correct'; +}; + +for my $test ( + { + desc => 'extra values in service request', + extra => [ + { + name => 'title', + value => 'A title', + } + ], + params => [ + [ 'attribute[title]', 'A title', 'extra paramater used correctly' ] + ] + }, + { + desc => 'first and last names in extra used correctly', + extra => [ + { + name => 'first_name', + value => 'First', + }, + { + name => 'last_name', + value => 'Last', + }, + ], + params => [ + [ 'first_name', 'First', 'first name correct' ], + [ 'last_name', 'Last', 'last name correct' ], + [ 'attribute[first_name]', undef, 'no first_name attribute param' ], + [ 'attribute[last_name]', undef, 'no last_name attribute param' ], + ], + }, + { + title => 'magic fms_extra parameters handled correctly', + extra => [ + { + name => 'fms_extra_title', + value => 'Extra title', + } + ], + params => [ + [ + 'attribute[title]', + 'Extra title', + 'fms_extra extra param used correctly' + ] + ], + }, + ) +{ + subtest $test->{desc} => sub { + $problem->extra( $test->{extra} ); + + my $extra = { url => 'http://example.com/report/1', }; + + my $results = make_service_req( $problem, $extra, $problem->category, +'<?xml version="1.0" encoding="utf-8"?><service_requests><request><service_request_id>248</service_request_id></request></service_requests>' + ); + my $req = $o->test_req_used; + my $c = CGI::Simple->new( $results->{req}->content ); + + for my $param ( @{ $test->{params} } ) { + is $c->param( $param->[0] ), $param->[1], $param->[2]; + } + }; +} + +my $comment = FixMyStreet::App->model('DB::Comment')->new( { + id => 38362, + user => $user, + problem => $problem, + anonymous => 0, + text => 'this is a comment', + confirmed => $dt, + extra => { title => 'Mr', email_alerts_requested => 0 }, +} ); + +subtest 'basic request update post parameters' => sub { + my $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>' ); + + is $results->{ res }, 248, 'got update id'; + + my $req = $o->test_req_used; + + my $c = CGI::Simple->new( $results->{ req }->content ); + + is $c->param('description'), 'this is a comment', 'email correct'; + is $c->param('email'), 'test@example.com', 'email correct'; + is $c->param('status'), 'OPEN', 'status correct'; + is $c->param('service_request_id_ext'), 80, 'external request id correct'; + is $c->param('service_request_id'), 81, 'request id correct'; + is $c->param('public_anonymity_required'), 'FALSE', 'anon status correct'; + is $c->param('updated_datetime'), $dt, 'correct date'; + is $c->param('title'), 'Mr', 'correct title'; + is $c->param('last_name'), 'User', 'correct first name'; + is $c->param('first_name'), 'Test', 'correct second name'; + is $c->param('email_alerts_requested'), 'FALSE', 'email alerts flag correct'; +}; + +foreach my $test ( + { + desc => 'comment with fixed state sends status of CLOSED', + state => 'fixed', + anon => 0, + status => 'CLOSED', + }, + { + desc => 'comment with fixed - user state sends status of CLOSED', + state => 'fixed - user', + anon => 0, + status => 'CLOSED', + }, + { + desc => 'comment with fixed - council state sends status of CLOSED', + state => 'fixed - council', + anon => 0, + status => 'CLOSED', + }, + { + desc => 'comment with closed state sends status of CLOSED', + state => 'closed', + anon => 0, + status => 'CLOSED', + }, + { + desc => 'comment with investigating state sends status of OPEN', + state => 'investigating', + anon => 0, + status => 'OPEN', + }, + { + desc => 'comment with planned state sends status of OPEN', + state => 'planned', + anon => 0, + status => 'OPEN', + }, + { + desc => 'comment with in progress state sends status of OPEN', + state => 'in progress', + anon => 0, + status => 'OPEN', + }, + { + desc => 'anonymous commment sets public_anonymity_required to true', + state => 'confirmed', + anon => 1, + status => 'OPEN', + }, +) { + subtest $test->{desc} => sub { + $comment->problem->state( $test->{state} ); + $comment->anonymous( $test->{anon} ); + + my $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>' ); + + my $c = CGI::Simple->new( $results->{ req }->content ); + is $c->param('status'), $test->{status}, 'correct status'; + is $c->param('public_anonymity_required'), $test->{anon} ? 'TRUE' : 'FALSE', 'correct anonymity'; + }; +} + + +for my $test ( + { + desc => 'update name name taken from comment over user', + comment_name => 'First Last', + user_name => 'Personal Family', + extra => undef, + first_name => 'First', + last_name => 'Last' + }, + { + desc => 'update name name taken from user if no comment name', + comment_name => '', + user_name => 'Personal Family', + extra => undef, + first_name => 'Personal', + last_name => 'Family' + }, + { + desc => 'update name taken from extra if available', + comment_name => 'First Last', + user_name => 'Personal Family', + extra => { first_name => 'Forename', last_name => 'Surname' }, + first_name => 'Forename', + last_name => 'Surname' + }, + ) +{ + subtest $test->{desc} => sub { + $comment->name( $test->{comment_name} ); + $user->name( $test->{user_name} ); + $comment->extra( $test->{ extra } ); + + my $results = make_update_req( $comment, +'<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>' + ); + + my $c = CGI::Simple->new( $results->{req}->content ); + is $c->param('first_name'), $test->{first_name}, 'first name correct'; + is $c->param('last_name'), $test->{last_name}, 'last name correct'; + }; +} + +subtest 'No update id in reponse' => sub { + my $results; + warning_like { + $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id></update_id></request_update></service_request_updates>' ) + } qr/Failed to submit comment \d+ over Open311/, 'correct error message'; + + is $results->{ res }, 0, 'No update_id is a failure'; +}; + +subtest 'error reponse' => sub { + my $results; + warning_like { + $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><errors><error><code>400</code><description>There was an error</description</error></errors>' ) + } qr/Failed to submit comment \d+ over Open311.*There was an error/, 'correct error messages'; + + is $results->{ res }, 0, 'error in response is a failure'; +}; + done_testing(); + +sub make_update_req { + my $comment = shift; + my $xml = shift; + + return make_req( $comment, $xml, 'post_service_request_update', 'update.xml' ); +} + +sub make_service_req { + my $problem = shift; + my $extra = shift; + my $service_code = shift; + my $xml = shift; + + return make_req( $problem, $xml, 'send_service_request', 'requests.xml', $extra, $service_code ); +} + +sub make_req { + my $object = shift; + my $xml = shift; + my $method = shift; + my $path = shift; + my @args = @_; + + my $o = + Open311->new( test_mode => 1, end_point => 'http://localhost/o311' ); + + my $test_res = HTTP::Response->new(); + $test_res->code(200); + $test_res->message('OK'); + $test_res->content($xml); + + $o->test_get_returns( { $path => $test_res } ); + + my $res = $o->$method($object, @args); + + my $req = $o->test_req_used; + + return { res => $res, req => $req }; +} diff --git a/t/open311/getservicerequestupdates.t b/t/open311/getservicerequestupdates.t new file mode 100644 index 000000000..063d7e378 --- /dev/null +++ b/t/open311/getservicerequestupdates.t @@ -0,0 +1,409 @@ +#!/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, + 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=> 1, + mark_open => 0, + 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 => 1, + 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 => 1, + 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->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->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'; +}; + +$problem2->comments->delete(); +$problem->comments->delete(); +$problem2->delete; +$problem->delete; +$user->comments->delete; +$user->problems->delete; +$user->delete; + +done_testing(); diff --git a/t/open311/populate-service-list.t b/t/open311/populate-service-list.t index bdb7404f9..63500d6cb 100644 --- a/t/open311/populate-service-list.t +++ b/t/open311/populate-service-list.t @@ -203,6 +203,304 @@ subtest 'check conflicting contacts not changed' => sub { is $contact_count, 4, 'correct number of contacts'; }; +subtest 'check meta data population' => sub { + my $processor = Open311::PopulateServiceList->new( council_list => [] ); + + my $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> + '; + + my $contact = FixMyStreet::App->model('DB::Contact')->find_or_create( + { + area_id => 1, + email => '001', + category => 'Bins left out 24x7', + confirmed => 1, + deleted => 0, + editor => $0, + whenedited => \'ms_current_timestamp()', + note => 'test contact', + } + ); + + my $o = Open311->new( + jurisdiction => 'mysociety', + endpoint => 'http://example.com', + test_mode => 1, + test_get_returns => { 'services/100.xml' => $meta_xml } + ); + + my $council = FixMyStreet::App->model('DB::Open311conf')->new( { + area_id => 2482 + } ); + + $processor->_current_open311( $o ); + $processor->_current_council( $council ); + $processor->_current_service( { service_code => 100 } ); + + $processor->_add_contact_to_meta( $contact ); + + my $extra = [ { + variable => 'true', + code => 'type', + datatype => 'string', + required => 'true', + datatype_description => 'Type of bin', + order => 1, + description => 'Type of bin' + + } ]; + + $contact->discard_changes; + + is_deeply $contact->extra, $extra, 'meta data saved'; +}; + +subtest 'check attribute ordering' => sub { + my $processor = Open311::PopulateServiceList->new( council_list => [] ); + + my $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> + <attribute> + <variable>true</variable> + <code>colour</code> + <datatype>string</datatype> + <required>true</required> + <datatype_description>Colour of bin</datatype_description> + <order>3</order> + <description>Colour of bin</description> + </attribute> + <attribute> + <variable>true</variable> + <code>size</code> + <datatype>string</datatype> + <required>true</required> + <datatype_description>Size of bin</datatype_description> + <order>2</order> + <description>Size of bin</description> + </attribute> + </attributes> +</service_definition> + '; + + my $contact = FixMyStreet::App->model('DB::Contact')->find_or_create( + { + area_id => 1, + email => '001', + category => 'Bins left out 24x7', + confirmed => 1, + deleted => 0, + editor => $0, + whenedited => \'ms_current_timestamp()', + note => 'test contact', + } + ); + + my $o = Open311->new( + jurisdiction => 'mysociety', + endpoint => 'http://example.com', + test_mode => 1, + test_get_returns => { 'services/100.xml' => $meta_xml } + ); + + my $council = FixMyStreet::App->model('DB::Open311conf')->new( { + area_id => 1 + } ); + + $processor->_current_open311( $o ); + $processor->_current_council( $council ); + $processor->_current_service( { service_code => 100 } ); + + $processor->_add_contact_to_meta( $contact ); + + my $extra = [ + { + variable => 'true', + code => 'type', + datatype => 'string', + required => 'true', + datatype_description => 'Type of bin', + order => 1, + description => 'Type of bin' + + }, + { + variable => 'true', + code => 'size', + datatype => 'string', + required => 'true', + datatype_description => 'Size of bin', + order => 2, + description => 'Size of bin' + + }, + { + variable => 'true', + code => 'colour', + datatype => 'string', + required => 'true', + datatype_description => 'Colour of bin', + order => 3, + description => 'Colour of bin' + + }, + ]; + + $contact->discard_changes; + + is_deeply $contact->extra, $extra, 'meta data re-ordered correctly'; +}; + +subtest 'check bromely skip code' => sub { + my $processor = Open311::PopulateServiceList->new( council_list => [] ); + + my $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> + <attribute> + <variable>true</variable> + <code>title</code> + <datatype>string</datatype> + <required>true</required> + <datatype_description>Type of bin</datatype_description> + <order>1</order> + <description>Type of bin</description> + </attribute> + <attribute> + <variable>true</variable> + <code>report_url</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> + '; + + my $contact = FixMyStreet::App->model('DB::Contact')->find_or_create( + { + area_id => 1, + email => '001', + category => 'Bins left out 24x7', + confirmed => 1, + deleted => 0, + editor => $0, + whenedited => \'ms_current_timestamp()', + note => 'test contact', + } + ); + + my $o = Open311->new( + jurisdiction => 'mysociety', + endpoint => 'http://example.com', + test_mode => 1, + test_get_returns => { 'services/100.xml' => $meta_xml } + ); + + my $council = FixMyStreet::App->model('DB::Open311conf')->new( { + area_id => 2482 + } ); + + $processor->_current_open311( $o ); + $processor->_current_council( $council ); + $processor->_current_service( { service_code => 100 } ); + + $processor->_add_contact_to_meta( $contact ); + + my $extra = [ { + variable => 'true', + code => 'type', + datatype => 'string', + required => 'true', + datatype_description => 'Type of bin', + order => 1, + description => 'Type of bin' + + } ]; + + $contact->discard_changes; + + is_deeply $contact->extra, $extra, 'only non std bromley meta data saved'; + + $council->area_id(1); + + $processor->_current_council( $council ); + $processor->_add_contact_to_meta( $contact ); + + $extra = [ + { + variable => 'true', + code => 'type', + datatype => 'string', + required => 'true', + datatype_description => 'Type of bin', + order => 1, + description => 'Type of bin' + + }, + { + variable => 'true', + code => 'title', + datatype => 'string', + required => 'true', + datatype_description => 'Type of bin', + order => 1, + description => 'Type of bin' + + }, + { + variable => 'true', + code => 'report_url', + datatype => 'string', + required => 'true', + datatype_description => 'Type of bin', + order => 1, + description => 'Type of bin' + + }, + ]; + + $contact->discard_changes; + + is_deeply $contact->extra, $extra, 'all meta data saved for non bromley'; +}; + sub get_standard_xml { return qq{<?xml version="1.0" encoding="utf-8"?> <services> |