diff options
-rw-r--r-- | perllib/Open311.pm | 54 | ||||
-rw-r--r-- | t/open311.t | 146 |
2 files changed, 197 insertions, 3 deletions
diff --git a/perllib/Open311.pm b/perllib/Open311.pm index 030e8092c..16576726c 100644 --- a/perllib/Open311.pm +++ b/perllib/Open311.pm @@ -12,8 +12,9 @@ has api_key => ( is => 'ro', isa => 'Str' ); has endpoint => ( is => 'ro', isa => 'Str' ); has test_mode => ( is => 'ro', isa => 'Bool' ); has test_uri_used => ( is => 'rw', 'isa' => 'Str' ); +has test_req_used => ( is => 'rw' ); has test_get_returns => ( is => 'rw' ); -has endpoints => ( is => 'rw', default => sub { { services => 'services.xml', requests => 'requests.xml', service_request_updates => 'update.xml' } } ); +has endpoints => ( is => 'rw', default => sub { { services => 'services.xml', requests => 'requests.xml', service_request_updates => 'update.xml', update => 'update.xml' } } ); has debug => ( is => 'ro', isa => 'Bool', default => 0 ); has debug_details => ( is => 'rw', 'isa' => 'Str', default => '' ); @@ -147,6 +148,48 @@ sub get_service_request_updates { return $requests; } +sub post_service_request_update { + my $self = shift; + my $comment = shift; + + my $params = { + update_id_ext => $comment->id, + updated_datetime => $comment->confirmed, + service_request_id => $comment->problem->external_id, + service_request_id_ext => $comment->problem->id, + status => $comment->problem->is_open ? 'OPEN' : 'CLOSED', + email => $comment->user->email, + description => $comment->text, + public_anonymity_required => $comment->anonymous ? 'TRUE' : 'FALSE', + # also need last_name, title + }; + + my $response = $self->_post( $self->endpoints->{update}, $params ); + + if ( $response ) { + my $obj = $self->_get_xml_object( $response ); + + if ( $obj ) { + if ( $obj->{ request_update }->{ update_id } ) { + my $update_id = $obj->{request_update}->{update_id}; + + # if there's nothing in the update_id element we get a HASHREF back + unless ( ref $update_id ) { + return $obj->{ request_update }->{ update_id }; + } + } else { + my $token = $obj->{ request_update }->{ token }; + if ( $token ) { + return $self->get_service_request_id_from_token( $token ); + } + } + } + + warn sprintf( "Failed to submit comment %s over Open311, response\n: %s\n%s", $comment->id, $response, $self->debug_details ); + return 0; + } +} + sub _get { my $self = shift; my $path = shift; @@ -189,7 +232,14 @@ sub _post { $self->debug_details( $self->debug_details . "\nrequest:" . $req->as_string ); my $ua = LWP::UserAgent->new(); - my $res = $ua->request( $req ); + my $res; + + if ( $self->test_mode ) { + $res = $self->test_get_returns->{ $path }; + $self->test_req_used( $req ); + } else { + $res = $ua->request( $req ); + } if ( $res->is_success ) { return $res->decoded_content; diff --git a/t/open311.t b/t/open311.t index 30de330b6..1c7c7600d 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"; @@ -37,6 +40,147 @@ my $p = FixMyStreet::App->model('DB::Problem')->new( { 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'; +#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/, 'correct error message'; + + 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 }; +} |