aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md2
-rw-r--r--perllib/FixMyStreet/App/Controller/Open311.pm26
-rw-r--r--perllib/FixMyStreet/App/Controller/Open311/Updates.pm88
-rw-r--r--perllib/Open311/GetServiceRequestUpdates.pm280
-rw-r--r--t/app/controller/open311.t10
-rw-r--r--t/app/controller/open311_updates.t99
-rw-r--r--t/open311/getservicerequestupdates.t98
7 files changed, 434 insertions, 169 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b16fa561d..fd0fdcaea 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -36,6 +36,8 @@
POST service request.
- Allow description in email template with placeholder.
- Do not store display-only extra fields on new reports.
+ - Support receiving updates from external source.
+ - Improve JSON output of controller.
* v2.6 (3rd May 2019)
- New features:
diff --git a/perllib/FixMyStreet/App/Controller/Open311.pm b/perllib/FixMyStreet/App/Controller/Open311.pm
index 841330e92..b4b5d5e3a 100644
--- a/perllib/FixMyStreet/App/Controller/Open311.pm
+++ b/perllib/FixMyStreet/App/Controller/Open311.pm
@@ -111,8 +111,6 @@ sub get_discovery : Private {
{
'contact' => ["Send email to $contact_email."],
'changeset' => [$prod_changeset],
- # XXX rewrite to match
- 'key_service' => ["Read access is open to all according to our \u003Ca href='/open_data' target='_blank'\u003Eopen data license\u003C/a\u003E. For write access either: 1. return the 'guid' cookie on each call (unique to each client) or 2. use an api key from a user account which can be generated here: http://seeclickfix.com/register The unversioned url will always point to the latest supported version."],
'max_requests' => [ $c->config->{OPEN311_LIMIT} || 1000 ],
'endpoints' => [
{
@@ -195,9 +193,7 @@ sub get_services : Private {
);
}
$c->forward( 'format_output', [ {
- 'services' => [ {
- 'service' => \@services
- } ]
+ 'services' => \@services
} ] );
}
@@ -291,9 +287,7 @@ sub output_requests : Private {
}
$c->forward( 'format_output', [ {
- 'requests' => [ {
- 'request' => \@problemlist
- } ]
+ service_requests => \@problemlist
} ] );
}
@@ -429,7 +423,21 @@ sub format_output : Private {
$c->res->body( encode_json($hashref) );
} elsif ('xml' eq $format) {
$c->res->content_type('application/xml; charset=utf-8');
- $c->res->body( XMLout($hashref, RootName => undef, NoAttr => 1 ) );
+ my $group_tags = {
+ services => 'service',
+ attributes => 'attribute',
+ values => 'value',
+ service_requests => 'request',
+ errors => 'error',
+ service_request_updates => 'request_update',
+ };
+ $c->res->body( XMLout($hashref,
+ KeyAttr => {},
+ GroupTags => $group_tags,
+ SuppressEmpty => undef,
+ RootName => undef,
+ NoAttr => 1,
+ ) );
} else {
$c->detach( 'error', [
sprintf(_('Invalid format %s specified.'), $format)
diff --git a/perllib/FixMyStreet/App/Controller/Open311/Updates.pm b/perllib/FixMyStreet/App/Controller/Open311/Updates.pm
new file mode 100644
index 000000000..105400a8a
--- /dev/null
+++ b/perllib/FixMyStreet/App/Controller/Open311/Updates.pm
@@ -0,0 +1,88 @@
+package FixMyStreet::App::Controller::Open311::Updates;
+
+use utf8;
+use Moose;
+use namespace::autoclean;
+use Open311;
+use Open311::GetServiceRequestUpdates;
+
+BEGIN { extends 'Catalyst::Controller'; }
+
+=head1 NAME
+
+FixMyStreet::App::Controller::Open311::Updates - Catalyst Controller
+
+=head1 DESCRIPTION
+
+=head1 METHODS
+
+=cut
+
+sub receive : Regex('^open311/v2/servicerequestupdates.(xml|json)$') : Args(0) {
+ my ( $self, $c ) = @_;
+ $c->stash->{format} = $c->req->captures->[0];
+
+ $c->detach('bad_request', [ 'POST' ]) unless $c->req->method eq 'POST';
+
+ my $body;
+ if ($c->cobrand->can('council_area_id')) {
+ $body = $c->cobrand->body;
+ } else {
+ $body = $c->model('DB::Body')->find({ id => $c->get_param('jurisdiction_id') });
+ }
+ $c->detach('bad_request', ['jurisdiction_id']) unless $body;
+ my $user = $body->comment_user;
+
+ my $key = $c->get_param('api_key') || '';
+ my $token = $c->cobrand->feature('open311_token') || '';
+ $c->detach('bad_request', [ 'api_key' ]) unless $key && $key eq $token;
+
+ my $request = {
+ media_url => $c->get_param('media_url'),
+ external_status_code => $c->get_param('external_status_code'),
+ };
+ foreach (qw(service_request_id update_id updated_datetime status description)) {
+ $request->{$_} = $c->get_param($_) || $c->detach('bad_request', [ $_ ]);
+ }
+
+ my %open311_conf = (
+ endpoint => $body->endpoint,
+ api_key => $body->api_key,
+ jurisdiction => $body->jurisdiction,
+ extended_statuses => $body->send_extended_statuses,
+ );
+
+ my $cobrand = $body->get_cobrand_handler;
+ $cobrand->call_hook(open311_config_updates => \%open311_conf)
+ if $cobrand;
+
+ my $open311 = Open311->new(%open311_conf);
+ my $updates = Open311::GetServiceRequestUpdates->new(
+ system_user => $user,
+ current_open311 => $open311,
+ current_body => $body,
+ );
+
+ my $p = $updates->find_problem($request);
+ $c->detach('bad_request', [ 'not found' ]) unless $p;
+
+ my $comment = $p->comments->search( { external_id => $request->{update_id} } )->first;
+ $c->detach('bad_request', [ 'already exists' ]) if $comment;
+
+ $comment = $updates->process_update($request, $p);
+
+ my $data = { service_request_updates => { update_id => $comment->id } };
+
+ $c->forward('/open311/format_output', [ $data ]);
+}
+
+sub bad_request : Private {
+ my ($self, $c, $comment) = @_;
+ $c->response->status(400);
+ $c->forward('/open311/format_output', [ { errors => { code => 400, description => "Bad request: $comment" } } ]);
+}
+
+__PACKAGE__->meta->make_immutable;
+
+1;
+
diff --git a/perllib/Open311/GetServiceRequestUpdates.pm b/perllib/Open311/GetServiceRequestUpdates.pm
index 3d593a4eb..7480ba258 100644
--- a/perllib/Open311/GetServiceRequestUpdates.pm
+++ b/perllib/Open311/GetServiceRequestUpdates.pm
@@ -15,6 +15,9 @@ has verbose => ( is => 'ro', default => 0 );
has schema => ( is =>'ro', lazy => 1, default => sub { FixMyStreet::DB->schema->connect } );
has blank_updates_permitted => ( is => 'rw', default => 0 );
+has current_body => ( is => 'rw' );
+has current_open311 => ( is => 'rw' );
+
Readonly::Scalar my $AREA_ID_BROMLEY => 2482;
Readonly::Scalar my $AREA_ID_OXFORDSHIRE => 2237;
@@ -35,6 +38,7 @@ sub fetch {
}
while ( my $body = $bodies->next ) {
+ $self->current_body( $body );
my %open311_conf = (
endpoint => $body->endpoint,
@@ -47,17 +51,20 @@ sub fetch {
$cobrand->call_hook(open311_config_updates => \%open311_conf)
if $cobrand;
- my $o = $open311 || Open311->new(%open311_conf);
+ $self->current_open311( $open311 || Open311->new(%open311_conf) );
$self->suppress_alerts( $body->suppress_alerts );
$self->blank_updates_permitted( $body->blank_updates_permitted );
$self->system_user( $body->comment_user );
- $self->update_comments( $o, $body );
+ $self->process_body();
}
}
-sub update_comments {
- my ( $self, $open311, $body ) = @_;
+sub process_body {
+ my $self = shift;
+
+ my $open311 = $self->current_open311;
+ my $body = $self->current_body;
my @args = ();
@@ -86,143 +93,158 @@ sub update_comments {
return 0;
}
- my $cobrand = $body->get_cobrand_handler;
-
for my $request (@$requests) {
- my $request_id = $request->{service_request_id};
+ next unless defined $request->{update_id};
- # If there's no request id then we can't work out
- # what problem it belongs to so just skip
- next unless $request_id || $request->{fixmystreet_id};
+ my $p = $self->find_problem($request, @args) or next;
+ my $c = $p->comments->search( { external_id => $request->{update_id} } );
+ next if $c->first;
- my $comment_time = eval {
- DateTime::Format::W3CDTF->parse_datetime( $request->{updated_datetime} || "" )
- ->set_time_zone(FixMyStreet->local_time_zone);
- };
- next if $@;
- my $updated = DateTime::Format::W3CDTF->format_datetime($comment_time->clone->set_time_zone('UTC'));
- next if @args && ($updated lt $args[0] || $updated gt $args[1]);
+ $self->process_update($request, $p);
+ }
- my $problem;
- my $criteria = {
- external_id => $request_id,
+ return 1;
+}
+
+sub find_problem {
+ my ($self, $request, @args) = @_;
+
+ my $body = $self->current_body;
+ my $request_id = $request->{service_request_id};
+
+ # If there's no request id then we can't work out
+ # what problem it belongs to so just skip
+ return unless $request_id || $request->{fixmystreet_id};
+
+ my $comment_time = eval {
+ DateTime::Format::W3CDTF->parse_datetime( $request->{updated_datetime} || "" )
+ ->set_time_zone(FixMyStreet->local_time_zone);
+ };
+ return if $@;
+ my $updated = DateTime::Format::W3CDTF->format_datetime($comment_time->clone->set_time_zone('UTC'));
+ return if @args && ($updated lt $args[0] || $updated gt $args[1]);
+ $request->{comment_time} = $comment_time;
+
+ my $problem;
+ my $criteria = {
+ external_id => $request_id,
+ };
+
+ # in some cases we only have the FMS id and not the request id so use that
+ if ( $request->{fixmystreet_id} ) {
+ unless ( $request->{fixmystreet_id} =~ /^\d+$/ ) {
+ warn "skipping bad fixmystreet id in updates for " . $body->name . ": [" . $request->{fixmystreet_id} . "], external id is $request_id\n";
+ return;
+ }
+
+ $criteria = {
+ id => $request->{fixmystreet_id},
};
+ }
- # in some cases we only have the FMS id and not the request id so use that
- if ( $request->{fixmystreet_id} ) {
- unless ( $request->{fixmystreet_id} =~ /^\d+$/ ) {
- warn "skipping bad fixmystreet id in updates for " . $body->name . ": [" . $request->{fixmystreet_id} . "], external id is $request_id\n";
- next;
- }
+ $problem = $self->schema->resultset('Problem')->to_body($body)->search( $criteria );
+ return $problem->first;
+}
- $criteria = {
- id => $request->{fixmystreet_id},
- };
+sub process_update {
+ my ($self, $request, $p) = @_;
+ my $open311 = $self->current_open311;
+ my $body = $self->current_body;
+
+ my $state = $open311->map_state( $request->{status} );
+ my $old_state = $p->state;
+ my $external_status_code = $request->{external_status_code} || '';
+ my $customer_reference = $request->{customer_reference} || '';
+ my $old_external_status_code = $p->get_extra_metadata('external_status_code') || '';
+ my $comment = $self->schema->resultset('Comment')->new(
+ {
+ problem => $p,
+ user => $self->system_user,
+ external_id => $request->{update_id},
+ text => $self->comment_text_for_request(
+ $request, $p, $state, $old_state,
+ $external_status_code, $old_external_status_code
+ ),
+ mark_fixed => 0,
+ mark_open => 0,
+ anonymous => 0,
+ name => $self->system_user->name,
+ confirmed => $request->{comment_time},
+ created => $request->{comment_time},
+ state => 'confirmed',
+ }
+ );
+
+ # Some Open311 services, e.g. Confirm via open311-adapter, provide
+ # a more fine-grained status code that we use within FMS for
+ # response templates.
+ if ( $external_status_code ) {
+ $comment->set_extra_metadata(external_status_code => $external_status_code);
+ $p->set_extra_metadata(external_status_code => $external_status_code);
+ }
+
+ # if the customer reference to display in the report metadata is
+ # not the same as the external_id
+ if ( $customer_reference ) {
+ $p->set_extra_metadata( customer_reference => $customer_reference );
+ }
+
+ $open311->add_media($request->{media_url}, $comment)
+ if $request->{media_url};
+
+ # don't update state unless it's an allowed state
+ if ( FixMyStreet::DB::Result::Problem->visible_states()->{$state} &&
+ # For Oxfordshire, don't allow changes back to Open from other open states
+ !( $body->areas->{$AREA_ID_OXFORDSHIRE} && $state eq 'confirmed' && $p->is_open ) &&
+ # Don't let it change between the (same in the front end) fixed states
+ !( $p->is_fixed && FixMyStreet::DB::Result::Problem->fixed_states()->{$state} ) ) {
+
+ $comment->problem_state($state);
+
+ # if the comment is older than the last update do not
+ # change the status of the problem as it's tricky to
+ # determine the right thing to do. Allow the same time in
+ # case report/update created at same time (in external
+ # system). Only do this if the report is currently visible.
+ if ( $comment->created >= $p->lastupdate && $p->state ne $state && $p->is_visible ) {
+ $p->state($state);
}
+ }
- $problem = $self->schema->resultset('Problem')->to_body($body)->search( $criteria );
-
- if (my $p = $problem->first) {
- next unless defined $request->{update_id};
- my $c = $p->comments->search( { external_id => $request->{update_id} } );
-
- if ( !$c->first ) {
- my $state = $open311->map_state( $request->{status} );
- my $old_state = $p->state;
- my $external_status_code = $request->{external_status_code} || '';
- my $customer_reference = $request->{customer_reference} || '';
- my $old_external_status_code = $p->get_extra_metadata('external_status_code') || '';
- my $comment = $self->schema->resultset('Comment')->new(
- {
- problem => $p,
- user => $self->system_user,
- external_id => $request->{update_id},
- text => $self->comment_text_for_request(
- $request, $p, $state, $old_state,
- $external_status_code, $old_external_status_code
- ),
- mark_fixed => 0,
- mark_open => 0,
- anonymous => 0,
- name => $self->system_user->name,
- confirmed => $comment_time,
- created => $comment_time,
- state => 'confirmed',
- }
- );
-
- # Some Open311 services, e.g. Confirm via open311-adapter, provide
- # a more fine-grained status code that we use within FMS for
- # response templates.
- if ( $external_status_code ) {
- $comment->set_extra_metadata(external_status_code => $external_status_code);
- $p->set_extra_metadata(external_status_code => $external_status_code);
- }
-
- # if the customer reference to display in the report metadata is
- # not the same as the external_id
- if ( $customer_reference ) {
- $p->set_extra_metadata( customer_reference => $customer_reference );
- }
-
- $open311->add_media($request->{media_url}, $comment)
- if $request->{media_url};
-
- # don't update state unless it's an allowed state
- if ( FixMyStreet::DB::Result::Problem->visible_states()->{$state} &&
- # For Oxfordshire, don't allow changes back to Open from other open states
- !( $body->areas->{$AREA_ID_OXFORDSHIRE} && $state eq 'confirmed' && $p->is_open ) &&
- # Don't let it change between the (same in the front end) fixed states
- !( $p->is_fixed && FixMyStreet::DB::Result::Problem->fixed_states()->{$state} ) ) {
-
- $comment->problem_state($state);
-
- # if the comment is older than the last update do not
- # change the status of the problem as it's tricky to
- # determine the right thing to do. Allow the same time in
- # case report/update created at same time (in external
- # system). Only do this if the report is currently visible.
- if ( $comment->created >= $p->lastupdate && $p->state ne $state && $p->is_visible ) {
- $p->state($state);
- }
- }
-
- # If nothing to show (no text, photo, or state change), don't show this update
- $comment->state('hidden') unless $comment->text || $comment->photo
- || ($comment->problem_state && $state ne $old_state);
-
- $cobrand->call_hook(open311_get_update_munging => $comment)
- if $cobrand;
-
- # As comment->created has been looked at above, its time zone has been shifted
- # to TIME_ZONE (if set). We therefore need to set it back to local before
- # insertion. We also then need a clone, otherwise the setting of lastupdate
- # will *also* reshift comment->created's time zone to TIME_ZONE.
- my $created = $comment->created->set_time_zone(FixMyStreet->local_time_zone);
- $p->lastupdate($created->clone);
- $p->update;
- $comment->insert();
-
- if ( $self->suppress_alerts ) {
- my @alerts = $self->schema->resultset('Alert')->search( {
- alert_type => 'new_updates',
- parameter => $p->id,
- confirmed => 1,
- user_id => $p->user->id,
- } );
-
- for my $alert (@alerts) {
- my $alerts_sent = $self->schema->resultset('AlertSent')->find_or_create( {
- alert_id => $alert->id,
- parameter => $comment->id,
- } );
- }
- }
- }
+ # If nothing to show (no text, photo, or state change), don't show this update
+ $comment->state('hidden') unless $comment->text || $comment->photo
+ || ($comment->problem_state && $state ne $old_state);
+
+ my $cobrand = $body->get_cobrand_handler;
+ $cobrand->call_hook(open311_get_update_munging => $comment)
+ if $cobrand;
+
+ # As comment->created has been looked at above, its time zone has been shifted
+ # to TIME_ZONE (if set). We therefore need to set it back to local before
+ # insertion. We also then need a clone, otherwise the setting of lastupdate
+ # will *also* reshift comment->created's time zone to TIME_ZONE.
+ my $created = $comment->created->set_time_zone(FixMyStreet->local_time_zone);
+ $p->lastupdate($created->clone);
+ $p->update;
+ $comment->insert();
+
+ if ( $self->suppress_alerts ) {
+ my @alerts = $self->schema->resultset('Alert')->search( {
+ alert_type => 'new_updates',
+ parameter => $p->id,
+ confirmed => 1,
+ user_id => $p->user->id,
+ } );
+
+ for my $alert (@alerts) {
+ my $alerts_sent = $self->schema->resultset('AlertSent')->find_or_create( {
+ alert_id => $alert->id,
+ parameter => $comment->id,
+ } );
}
}
- return 1;
+ return $comment;
}
sub comment_text_for_request {
diff --git a/t/app/controller/open311.t b/t/app/controller/open311.t
index 79fe159a3..c052605c7 100644
--- a/t/app/controller/open311.t
+++ b/t/app/controller/open311.t
@@ -14,7 +14,7 @@ $mech->content_contains('<status>open</status>');
$mech->get_ok('/open311/v2/requests.json?jurisdiction_id=foo&status=open&agency_responsible=2237');
my $json = decode_json($mech->content);
-my $problems = $json->{requests}[0]{request};
+my $problems = $json->{service_requests};
is @$problems, 2;
like $problems->[0]{description}, qr/Around page Test/;
@@ -25,7 +25,7 @@ subtest "non_public reports aren't available" => sub {
});
$mech->get_ok('/open311/v2/requests.json?jurisdiction_id=foo');
$json = decode_json($mech->content);
- $problems = $json->{requests}[0]{request};
+ $problems = $json->{service_requests};
is @$problems, 1;
like $problems->[0]{description}, qr/Around page Test/;
$mech->content_lacks('This report is now private');
@@ -33,7 +33,7 @@ subtest "non_public reports aren't available" => sub {
my $problem_id = $problem1->id;
$mech->get_ok("/open311/v2/requests/$problem_id.json?jurisdiction_id=foo");
$json = decode_json($mech->content);
- $problems = $json->{requests}[0]{request};
+ $problems = $json->{service_requests};
is @$problems, 0;
};
@@ -45,7 +45,7 @@ subtest "hidden reports aren't available" => sub {
});
$mech->get_ok('/open311/v2/requests.json?jurisdiction_id=foo');
$json = decode_json($mech->content);
- $problems = $json->{requests}[0]{request};
+ $problems = $json->{service_requests};
is @$problems, 1;
like $problems->[0]{description}, qr/Around page Test/;
$mech->content_lacks('This report is now hidden');
@@ -53,7 +53,7 @@ subtest "hidden reports aren't available" => sub {
my $problem_id = $problem1->id;
$mech->get_ok("/open311/v2/requests/$problem_id.json?jurisdiction_id=foo");
$json = decode_json($mech->content);
- $problems = $json->{requests}[0]{request};
+ $problems = $json->{service_requests};
is @$problems, 0;
};
diff --git a/t/app/controller/open311_updates.t b/t/app/controller/open311_updates.t
new file mode 100644
index 000000000..f2db0a02b
--- /dev/null
+++ b/t/app/controller/open311_updates.t
@@ -0,0 +1,99 @@
+use XML::Simple;
+use FixMyStreet::TestMech;
+my $mech = FixMyStreet::TestMech->new;
+
+my $user = $mech->create_user_ok('commentuser@example.com');
+my $body = $mech->create_body_ok(2237, 'Oxfordshire County Council', {
+ comment_user => $user,
+ api_key => 'sending-key',
+ jurisdiction => 'none',
+ endpoint => 'endpoint',
+});
+my ($problem) = $mech->create_problems_for_body(1, $body->id, 'Open311 updates', { external_id => 'p123' });
+
+subtest 'bad requests do not get through' => sub {
+ $mech->get('/open311/v2/servicerequestupdates.xml');
+ is $mech->response->code, 400, 'Is bad request';
+ $mech->content_contains('<description>Bad request: POST</description>');
+
+ $mech->post('/open311/v2/servicerequestupdates.xml');
+ is $mech->response->code, 400, 'Is bad request';
+ my $xml = _get_xml_object($mech->content);
+ is $xml->{error}[0]{description}, 'Bad request: jurisdiction_id';
+};
+
+subtest 'cobrand gets jurisdiction, but needs a token' => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'oxfordshire',
+ }, sub {
+ $mech->post('/open311/v2/servicerequestupdates.xml');
+ is $mech->response->code, 400, 'Is bad request';
+ my $xml = _get_xml_object($mech->content);
+ is $xml->{error}[0]{description}, 'Bad request: api_key';
+ };
+
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'oxfordshire',
+ COBRAND_FEATURES => { open311_token => { oxfordshire => 'wrong-token' } },
+ }, sub {
+ $mech->post('/open311/v2/servicerequestupdates.xml');
+ is $mech->response->code, 400, 'Is bad request';
+ my $xml = _get_xml_object($mech->content);
+ is $xml->{error}[0]{description}, 'Bad request: api_key';
+ };
+};
+
+subtest 'With all data, an update is added' => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'oxfordshire',
+ COBRAND_FEATURES => { open311_token => { oxfordshire => 'receiving-token' } },
+ }, sub {
+ $mech->post_ok('/open311/v2/servicerequestupdates.xml', {
+ api_key => 'receiving-token',
+ service_request_id => $problem->external_id,
+ update_id => 'c123',
+ updated_datetime => $problem->confirmed->clone->add(hours => 2),
+ status => 'CLOSED',
+ description => 'This report has been fixed',
+ });
+ };
+
+ $problem->discard_changes;
+ is $problem->state, 'fixed - council', 'problem updated';
+ is $problem->comments->count, 1, 'One comment created';
+
+ my $comment = $problem->comments->first;
+ is $comment->text, 'This report has been fixed', 'correct text';
+ is $comment->user_id, $user->id, 'correct user';
+ is $comment->problem_state, 'fixed - council', 'correct state';
+ is $comment->external_id, 'c123', 'correct external id';
+
+ my $xml = _get_xml_object($mech->content);
+ my $response = $xml->{request_update};
+ is $response->[0]->{update_id}, $comment->id, 'correct id in response';
+};
+
+done_testing();
+
+sub _get_xml_object {
+ my ($xml) = @_;
+
+ # Of these, services/service_requests/service_request_updates are root
+ # elements, so GroupTags has no effect, but this is used in ForceArray too.
+ my $group_tags = {
+ services => 'service',
+ attributes => 'attribute',
+ values => 'value',
+ service_requests => 'request',
+ errors => 'error',
+ service_request_updates => 'request_update',
+ };
+ my $simple = XML::Simple->new(
+ ForceArray => [ values %$group_tags ],
+ KeyAttr => {},
+ GroupTags => $group_tags,
+ SuppressEmpty => undef,
+ );
+ my $obj = $simple->parse_string($xml);
+ return $obj;
+}
diff --git a/t/open311/getservicerequestupdates.t b/t/open311/getservicerequestupdates.t
index 32f1ec2ee..d58855122 100644
--- a/t/open311/getservicerequestupdates.t
+++ b/t/open311/getservicerequestupdates.t
@@ -510,8 +510,13 @@ for my $test (
$problemB->state( $test->{start_state} );
$problemB->update;
- my $update = Open311::GetServiceRequestUpdates->new( system_user => $user );
- $update->update_comments( $o, $bodies{2237} );
+ my $update = Open311::GetServiceRequestUpdates->new(
+ system_user => $user,
+ current_open311 => $o,
+ current_body => $bodies{2237},
+ );
+ $update->process_body;
+
is $problemB->comments->count, 1, 'comment count';
$problemB->discard_changes;
@@ -530,11 +535,16 @@ subtest 'Marking report as fixed closes it for updates (Bexley)' => sub {
$problemB->update( { bodies_str => $bodies{2494}->id } );
- my $update = Open311::GetServiceRequestUpdates->new( system_user => $user );
+ my $update = Open311::GetServiceRequestUpdates->new(
+ system_user => $user,
+ current_open311 => $o,
+ current_body => $bodies{2494},
+ current_cobrand => $bodies{2494}->get_cobrand_handler,
+ );
FixMyStreet::override_config {
ALLOWED_COBRANDS => 'bexley',
}, sub {
- $update->update_comments( $o, $bodies{2494} );
+ $update->process_body;
};
$problemB->discard_changes;
@@ -562,8 +572,12 @@ 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;
@@ -585,8 +599,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';
@@ -600,11 +618,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;
@@ -639,8 +661,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';
@@ -658,26 +684,30 @@ subtest 'using start and end date' => sub {
my $update = Open311::GetServiceRequestUpdates->new(
system_user => $user,
start_date => $start_dt,
+ current_open311 => $o,
);
- my $res = $update->update_comments( $o );
+ my $res = $update->process_body;
is $res, 0, 'returns 0 if start but no end date';
$update = Open311::GetServiceRequestUpdates->new(
system_user => $user,
end_date => $end_dt,
+ current_open311 => $o,
);
- $res = $update->update_comments( $o );
+ $res = $update->process_body;
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 . '';
@@ -735,19 +765,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';
};
@@ -826,9 +858,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';
@@ -871,9 +905,11 @@ 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';
@@ -925,9 +961,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';
@@ -990,9 +1028,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(
@@ -1052,12 +1092,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;
@@ -1106,9 +1148,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';
@@ -1141,10 +1185,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";