diff options
Diffstat (limited to 't')
-rw-r--r-- | t/open311.t | 144 | ||||
-rw-r--r-- | t/open311/getservicerequestupdates.t | 266 | ||||
-rw-r--r-- | t/open311/populate-service-list.t | 298 |
3 files changed, 708 insertions, 0 deletions
diff --git a/t/open311.t b/t/open311.t index 30de330b6..2a9d513eb 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,145 @@ 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( { + email => 'test@example.com', +} ); + +my $problem = FixMyStreet::App->model('DB::Problem')->new( { + id => 80, + external_id => 81, + state => 'confirmed', +} ); + +my $comment = FixMyStreet::App->model('DB::Comment')->new( { + id => 38362, + user => $user, + problem => $problem, + anonymous => 0, + text => 'this is a comment', + confirmed => $dt, +} ); + +subtest 'testing posting updates' => 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'; +}; + +foreach my $test ( + { + desc => 'fixed is CLOSED', + state => 'fixed', + anon => 0, + status => 'CLOSED', + }, + { + desc => 'fixed - user is CLOSED', + state => 'fixed - user', + anon => 0, + status => 'CLOSED', + }, + { + desc => 'fixed - council is CLOSED', + state => 'fixed - council', + anon => 0, + status => 'CLOSED', + }, + { + desc => 'closed is CLOSED', + state => 'closed', + anon => 0, + status => 'CLOSED', + }, + { + desc => 'investigating is OPEN', + state => 'investigating', + anon => 0, + status => 'OPEN', + }, + { + desc => 'planned is OPEN', + state => 'planned', + anon => 0, + status => 'OPEN', + }, + { + desc => 'in progress is OPEN', + state => 'in progress', + anon => 0, + status => 'OPEN', + }, + { + desc => 'anonymous set 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'; + }; +} + +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; + + 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( { + 'update.xml' => $test_res + } ); + + my $res = $o->post_service_request_update( $comment ); + + 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..c9f97cd5a --- /dev/null +++ b/t/open311/getservicerequestupdates.t @@ -0,0 +1,266 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use Test::More; + +use FindBin; +use lib "$FindBin::Bin/../perllib"; +use lib "$FindBin::Bin/../commonlib/perllib"; + +use_ok( 'Open311' ); + +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'; + }; +} + +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'; + }; +} +$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> |