diff --git a/perllib/Open311/Endpoint.pm b/perllib/Open311/Endpoint.pm
index 1fec84f3..6376d5da 100644
--- a/perllib/Open311/Endpoint.pm
+++ b/perllib/Open311/Endpoint.pm
@@ -326,8 +326,9 @@ sub dispatch_request {
$self->call_api( POST_Service_Request => $args, );
},
- sub (GET + /tokens/*) {
- return Open311::Endpoint::Result->error( 400, 'not implemented' );
+ sub (GET + /tokens/* + ?*) {
+ my ($self, $token, $args) = @_;
+ $self->call_api( GET_Token => $token, $args );
},
sub (GET + /requests + ?*) {
@@ -589,6 +590,55 @@ sub POST_Service_Request {
};
}
+sub GET_Token_input_schema {
+ my $self = shift;
+ return {
+ type => '//seq',
+ contents => [
+ '//str',
+ $self->get_jurisdiction_id_validation,
+ ],
+ };
+}
+
+sub GET_Token_output_schema {
+ my ($self, $args) = @_;
+ return {
+ type => '//rec',
+ required => {
+ service_requests => {
+ type => '//arr',
+ contents => {
+ type => '//rec',
+ required => {
+ service_request_id => $self->get_identifier_type('service_request_id'),
+ },
+ optional => {
+ token => '//str',
+ },
+ },
+ },
+ },
+ };
+}
+
+sub GET_Token {
+ my ($self, $token, $args) = @_;
+
+ my @service_requests = $self->get_token( $token, $args );
+
+ return {
+ service_requests => [
+ map {
+ +{
+ $_->service_request_id ? (service_request_id => $_->service_request_id) : (),
+ $_->token ? (token => $_->token) : (),
+ }
+ } @service_requests,
+ ],
+ };
+}
+
sub GET_Service_Requests_input_schema {
my $self = shift;
return {
diff --git a/perllib/Open311/Endpoint/Integration/Multi.pm b/perllib/Open311/Endpoint/Integration/Multi.pm
index 2a1fcf5c..04b23b24 100644
--- a/perllib/Open311/Endpoint/Integration/Multi.pm
+++ b/perllib/Open311/Endpoint/Integration/Multi.pm
@@ -141,6 +141,19 @@ sub post_service_request {
my $integration_service = (ref $service)->new(%$service, service_code => $service_code);
my $result = $self->_call('post_service_request', $integration, $integration_service, $integration_args);
+ if ($result->token) {
+ ($result) = $self->_map_with_new_id(token => [$integration, $result]);
+ } else {
+ ($result) = $self->_map_with_new_id(service_request_id => [$integration, $result]);
+ }
+ return $result;
+}
+
+sub get_token {
+ my ($self, $token, $args) = @_;
+
+ my ($integration, $int_token) = $self->_map_from_new_id($token, 'token');
+ my $result = $self->_call('get_token', $integration, $int_token);
($result) = $self->_map_with_new_id(service_request_id => [$integration, $result]);
return $result;
}
diff --git a/perllib/Open311/Endpoint/Integration/Passthrough.pm b/perllib/Open311/Endpoint/Integration/Passthrough.pm
index 23b29e16..7c96b7d2 100644
--- a/perllib/Open311/Endpoint/Integration/Passthrough.pm
+++ b/perllib/Open311/Endpoint/Integration/Passthrough.pm
@@ -42,6 +42,8 @@ has jurisdiction_id => ( is => 'ro' );
has endpoint => ( is => 'ro' );
has api_key => ( is => 'ro' );
+has batch_service => ( is => 'ro' );
+
=head2 ignore_services
Provide a list of service codes that should be ignored and not passed back from
@@ -154,7 +156,10 @@ sub service {
my $data = $self->memcache->get("service/$service_id");
return $data if $data;
my $xml = $self->_request(GET => "services/$service_id.xml");
- my $service = Open311::Endpoint::Service->new( service_code => $service_id );
+ my $service = Open311::Endpoint::Service->new(
+ service_code => $service_id,
+ type => $self->batch_service ? 'batch' : 'realtime',
+ );
foreach (@{$xml->{attributes}}) {
$_->{required} = $_->{required} eq 'true' ? 1 : 0;
$_->{variable} = $_->{variable} eq 'true' ? 1 : 0;
@@ -181,11 +186,23 @@ sub post_service_request {
_strip_args($args);
my $xml = $self->_request(POST => "requests.xml", $args);
+ if (my $token = $xml->{request}[0]{token}) {
+ my $result = Open311::Endpoint::Service::Request->new(token => $token);
+ return $result;
+ }
my $id = $xml->{request}[0]{service_request_id};
my $result = Open311::Endpoint::Service::Request->new(service_request_id => $id);
return $result;
}
+sub get_token {
+ my ($self, $token, $args) = @_;
+
+ my $xml = $self->_request(GET => "tokens/$token.xml");
+ my $result = Open311::Endpoint::Service::Request->new(%{$xml->{request}[0]});
+ return $result;
+}
+
=head2 post_service_request_update
Resets the attributes to be in the format they were received, then passes
diff --git a/perllib/Open311/Endpoint/Integration/UK.pm b/perllib/Open311/Endpoint/Integration/UK.pm
index 9d96a587..c2897b7d 100644
--- a/perllib/Open311/Endpoint/Integration/UK.pm
+++ b/perllib/Open311/Endpoint/Integration/UK.pm
@@ -64,6 +64,12 @@ sub post_service_request {
$service, $args);
}
+sub get_token {
+ my ($self, $token, $args) = @_;
+ return $self->_call('get_token', $args->{jurisdiction_id},
+ $token, $args);
+}
+
sub service_request_content {
my ($self, $args) = @_;
return $self->_call('service_request_content', $args->{jurisdiction_id});
diff --git a/perllib/Open311/Endpoint/Integration/UK/Merton.pm b/perllib/Open311/Endpoint/Integration/UK/Merton.pm
index e087b207..5cffa691 100644
--- a/perllib/Open311/Endpoint/Integration/UK/Merton.pm
+++ b/perllib/Open311/Endpoint/Integration/UK/Merton.pm
@@ -60,6 +60,9 @@ sub _map_from_new_id {
} else {
$integration = 'Passthrough';
}
+ } elsif ($type eq 'token') {
+ # Echo does not use tokens
+ $integration = 'Passthrough';
}
return ($integration, $code);
}
diff --git a/perllib/Open311/Endpoint/Integration/UK/Merton/Passthrough.pm b/perllib/Open311/Endpoint/Integration/UK/Merton/Passthrough.pm
index 35c53655..dbc72d4b 100644
--- a/perllib/Open311/Endpoint/Integration/UK/Merton/Passthrough.pm
+++ b/perllib/Open311/Endpoint/Integration/UK/Merton/Passthrough.pm
@@ -17,6 +17,7 @@ extends 'Open311::Endpoint::Integration::Passthrough';
around BUILDARGS => sub {
my ($orig, $class, %args) = @_;
$args{jurisdiction_id} = 'www.merton.gov.uk';
+ $args{batch_service} = 1;
return $class->$orig(%args);
};
diff --git a/t/open311/endpoint/merton.t b/t/open311/endpoint/merton.t
index 85f28800..4515640b 100644
--- a/t/open311/endpoint/merton.t
+++ b/t/open311/endpoint/merton.t
@@ -32,9 +32,15 @@ $ua->mock(get => sub {
$file = 'xml/merton/services.xml';
} elsif ($_[1] eq 'services/TEST.xml') {
$file = 'xml/merton/service.xml';
+ } elsif ($_[1] eq 'tokens/TOKEN.xml') {
+ $file = 'xml/merton/token.xml';
}
return HTTP::Response->new(200, 'OK', [], path(__FILE__)->sibling($file)->slurp);
});
+$ua->mock(post => sub {
+ my $file = 'xml/merton/requestpost.xml';
+ return HTTP::Response->new(200, 'OK', [], path(__FILE__)->sibling($file)->slurp);
+});
use_ok 'Open311::Endpoint::Integration::UK::Merton';
@@ -116,4 +122,24 @@ subtest "Get service definition with a group" => sub {
}, 'correct json returned';
};
+subtest "Post a report, get a token" => sub {
+ my $res = $endpoint->run_test_request(
+ POST => '/requests.json',
+ api_key => 'test',
+ service_code => 'TEST',
+ address_string => 'address',
+ 'attribute[service]' => 1234,
+ 'attribute[usrn]' => 1234,
+ 'attribute[fixmystreet_id]' => 1001,
+ );
+ ok $res->is_success, 'valid request' or diag $res->content;
+ is_deeply decode_json($res->content), [ { "token" => 'TOKEN' } ];
+};
+
+subtest "Convert a token to an ID" => sub {
+ my $res = $endpoint->run_test_request( GET => "/tokens/TOKEN.json" );
+ ok $res->is_success, 'valid request' or diag $res->content;
+ is_deeply decode_json($res->content), [ { "service_request_id" => 'ServiceID' } ];
+};
+
done_testing;
diff --git a/t/open311/endpoint/xml/merton/requestpost.xml b/t/open311/endpoint/xml/merton/requestpost.xml
new file mode 100644
index 00000000..135daac0
--- /dev/null
+++ b/t/open311/endpoint/xml/merton/requestpost.xml
@@ -0,0 +1,7 @@
+
+
+
+ TOKEN
+
+
+
diff --git a/t/open311/endpoint/xml/merton/token.xml b/t/open311/endpoint/xml/merton/token.xml
new file mode 100644
index 00000000..f19dd234
--- /dev/null
+++ b/t/open311/endpoint/xml/merton/token.xml
@@ -0,0 +1,7 @@
+
+
+
+ ServiceID
+
+
+