diff --git a/conf/council-rutland_confirm.yml-example b/conf/council-rutland_confirm.yml-example new file mode 100644 index 000000000..8e26877b6 --- /dev/null +++ b/conf/council-rutland_confirm.yml-example @@ -0,0 +1,18 @@ +"logfile": "" +"min_log_level": "" + +"endpoint_url": "" +"username": "" +"password": "" +"tenant_id": "" + +"cutoff_enquiry_date": "" +"enquiry_method_code": "" +"point_of_contact_code": "" +"server_timezone": "" + +"service_whitelist": {} + +"forward_status_mapping": {} + +"reverse_status_mapping": {} diff --git a/conf/council-rutland.yml-example b/conf/council-rutland_salesforce.yml-example similarity index 100% rename from conf/council-rutland.yml-example rename to conf/council-rutland_salesforce.yml-example diff --git a/perllib/Integrations/Confirm.pm b/perllib/Integrations/Confirm.pm index 6e205d072..7e2692186 100644 --- a/perllib/Integrations/Confirm.pm +++ b/perllib/Integrations/Confirm.pm @@ -50,7 +50,7 @@ has ua => ( If the Confirm endpoint requires a particular EnquiryMethodCode for NewEnquiry requests, override this in the subclass. Valid values can be found by calling -the GetCustomerLookup method on the endpoint. +the GetCustomerLookups method on the endpoint. =cut @@ -64,7 +64,7 @@ has 'enquiry_method_code' => ( Similar to enquiry_method_code, if the Confirm endpoint requires a particular PointOfContactCode for NewEnquiry requests, override this in the subclass. -Valid values can be found by calling the GetCustomerLookup method on the endpoint. +Valid values can be found by calling the GetCustomerLookups method on the endpoint. =cut @@ -78,7 +78,7 @@ has 'point_of_contact_code' => ( Similar to enquiry_method_code/point_of_contact_code, if the Confirm endpoint requires a particular CustomerTypeCode for NewEnquiry requests, override this in the subclass. -Valid values can be found by calling the GetCustomerLookup method on the endpoint. +Valid values can be found by calling the GetCustomerLookups method on the endpoint. =cut @@ -874,6 +874,12 @@ sub GetEnquiries { return @enquiries; } +sub GetCustomerLookups { + my $self = shift; + my $lookups = $self->perform_request(\SOAP::Data->name('GetCustomerLookups')); + return $lookups; +} + sub GetEnquiryLookups { my $self = shift; diff --git a/perllib/Integrations/SalesForce/Rutland.pm b/perllib/Integrations/SalesForce/Rutland.pm index 71097ff2b..ef5070ce0 100644 --- a/perllib/Integrations/SalesForce/Rutland.pm +++ b/perllib/Integrations/SalesForce/Rutland.pm @@ -4,6 +4,7 @@ use Moo; extends 'Integrations::SalesForce::Base'; use JSON::MaybeXS; +use Try::Tiny; has 'requests_endpoint' => ( is => 'ro', @@ -118,7 +119,12 @@ sub get_services { $self->logger->debug("No memcached entry found for $key. Fetching services from Salesforce"); $services = []; - my $response = $self->get($self->services_endpoint . '?summary'); + my $response; + try { + $response = $self->get($self->services_endpoint . '?summary'); + } catch { + return (); + }; for my $service (@{ $response->{CategoryInformation} }) { push @$services, $service; } diff --git a/perllib/Open311/Endpoint.pm b/perllib/Open311/Endpoint.pm index f3141b5f2..9d7ac41e4 100644 --- a/perllib/Open311/Endpoint.pm +++ b/perllib/Open311/Endpoint.pm @@ -824,8 +824,13 @@ sub format_service_requests { ), ( map { - my $value = $request->$_->[0]; - $_ => $value || ''; + my $value; + if (scalar @{ $request->$_ } <= 1) { + $value = $request->$_->[0] || ''; + } else { + $value = $request->@{$_}; + } + $_ => $value; } qw/ media_url diff --git a/perllib/Open311/Endpoint/Integration/Confirm.pm b/perllib/Open311/Endpoint/Integration/Confirm.pm index fbc8dcb53..715e6122f 100644 --- a/perllib/Open311/Endpoint/Integration/Confirm.pm +++ b/perllib/Open311/Endpoint/Integration/Confirm.pm @@ -632,7 +632,7 @@ sub get_service_request_updates { my $job_photos = @{ $integ->enquiry_update_job_photo_statuses }; my $defect_photos = @{ $integ->enquiry_update_defect_photo_statuses }; - my $documents = 'documents { url documentName documentDate }'; + my $documents = 'documents { url documentName documentDate docTypeCode}'; my $job_documents = $job_photos ? $documents : ""; my $defect_documents = $defect_photos ? $documents : ""; @@ -1834,7 +1834,8 @@ sub _parse_graphql_docs { return map { { URL => $_->{url}, Name => $_->{documentName}, - Date => $self->date_parser->parse_datetime($_->{documentDate}) + Date => $self->date_parser->parse_datetime($_->{documentDate}), + ClassificationCode => $_->{docTypeCode} || '', } } @$docs; } diff --git a/perllib/Open311/Endpoint/Integration/Multi.pm b/perllib/Open311/Endpoint/Integration/Multi.pm index 04b23b24b..6bb7730a5 100644 --- a/perllib/Open311/Endpoint/Integration/Multi.pm +++ b/perllib/Open311/Endpoint/Integration/Multi.pm @@ -161,8 +161,6 @@ sub get_token { sub post_service_request_update { my ($self, $args) = @_; - # Cobrand needs to send the service_code through with updates - # (see Bexley's open311_munge_update_params in FMS for example) my ($integration, $service_code) = $self->_map_from_new_id($args->{service_code}, 'service'); my ($integration2, $service_request_id) = $self->_map_from_new_id($args->{service_request_id}, 'request'); die "$integration did not equal $integration2\n" if $integration ne $integration2; diff --git a/perllib/Open311/Endpoint/Integration/UK/Rutland.pm b/perllib/Open311/Endpoint/Integration/UK/Rutland.pm index 3f038cfa4..2181479ac 100644 --- a/perllib/Open311/Endpoint/Integration/UK/Rutland.pm +++ b/perllib/Open311/Endpoint/Integration/UK/Rutland.pm @@ -1,25 +1,32 @@ package Open311::Endpoint::Integration::UK::Rutland; -use parent 'Open311::Endpoint::Integration::SalesForce::Rutland'; use Moo; +extends 'Open311::Endpoint::Integration::Multi'; + +use Module::Pluggable + search_path => ['Open311::Endpoint::Integration::UK::Rutland'], + instantiate => 'new'; has jurisdiction_id => ( is => 'ro', default => 'rutland', ); -sub reverse_status_mapping { - my ($self, $status) = @_; +sub service_request_content { + '/open311/service_request_extended' +} - my %valid_status = map { my $no_spaces = $_; $no_spaces =~ s/\s+/_/g; $_ => $no_spaces; } ( - 'open', 'investigating', 'in progress', 'planned', 'action scheduled', - 'no further action', 'not councils responsibility', 'duplicate', 'internal referral', - 'fixed', 'closed', - ); +=pod - $valid_status{'not responsible'} = 'not_councils_responsibility'; +Rutland was previously only a Salesforce backend in open311-adapter, so we +maintain its categories/IDs without any backend prefix as any updates on pre-multi +reports will be looking for the id without the prefix - return $valid_status{lc($status)} || 'open'; -} +=cut + +has integration_without_prefix => ( + is => 'ro', + default => 'SalesForce', +); -1; +__PACKAGE__->run_if_script; diff --git a/perllib/Open311/Endpoint/Integration/UK/Rutland/Confirm.pm b/perllib/Open311/Endpoint/Integration/UK/Rutland/Confirm.pm new file mode 100644 index 000000000..a8ef7482e --- /dev/null +++ b/perllib/Open311/Endpoint/Integration/UK/Rutland/Confirm.pm @@ -0,0 +1,39 @@ +package Open311::Endpoint::Integration::UK::Rutland::Confirm; + +use Moo; +extends 'Open311::Endpoint::Integration::Confirm'; + +use Open311::Endpoint::Service::UKCouncil::Confirm; + +around BUILDARGS => sub { + my ($orig, $class, %args) = @_; + $args{jurisdiction_id} = 'rutland_confirm'; + $args{publish_service_update_text} = 1; + return $class->$orig(%args); +}; + +=head2 filter_photos_graphql + +Rutland want us to return photos with specific classification +tag. + +=cut + +around filter_photos_graphql => sub { + my ($orig, $self, @photos) = @_; + my @filtered = $self->$orig(@photos); + return grep { $_->{ClassificationCode} && $_->{ClassificationCode} eq 'DT20' } @filtered; +}; + +around _parse_enquiry_status_log => sub { + my ($orig, $self) = (shift, shift); + my $status_log = $_[0]; + + unless ($status_log->{EnquiryStatusCode} eq 'FMS') { + $status_log->{StatusLogNotes} = ''; + }; + + $self->$orig(@_); +}; + +1; diff --git a/perllib/Open311/Endpoint/Integration/SalesForce/Rutland.pm b/perllib/Open311/Endpoint/Integration/UK/Rutland/SalesForce.pm similarity index 84% rename from perllib/Open311/Endpoint/Integration/SalesForce/Rutland.pm rename to perllib/Open311/Endpoint/Integration/UK/Rutland/SalesForce.pm index 67563d34c..cf57d3ca2 100644 --- a/perllib/Open311/Endpoint/Integration/SalesForce/Rutland.pm +++ b/perllib/Open311/Endpoint/Integration/UK/Rutland/SalesForce.pm @@ -1,8 +1,4 @@ -package Open311::Endpoint::Integration::SalesForce::Rutland; - -use Moo; -extends 'Open311::Endpoint'; -with 'Open311::Endpoint::Role::mySociety'; +package Open311::Endpoint::Integration::UK::Rutland::SalesForce; use Open311::Endpoint::Service::UKCouncil::Rutland; use Open311::Endpoint::Service::Request::SalesForce; @@ -15,6 +11,34 @@ use Encode qw(encode_utf8); use Digest::MD5 qw(md5_hex); use DateTime::Format::Strptime; +use Moo; +extends 'Open311::Endpoint'; +with 'Open311::Endpoint::Role::mySociety'; + +has jurisdiction_id => ( + is => 'ro', + default => 'rutland_salesforce', +); + +has 'whitelist' => ( + is => 'ro', + is => 'lazy', + default => sub { shift->get_integration->config->{whitelist} || {} } +); + +sub reverse_status_mapping { + my ($self, $status) = @_; + + my %valid_status = map { my $no_spaces = $_; $no_spaces =~ s/\s+/_/g; $_ => $no_spaces; } ( + 'open', 'investigating', 'in progress', 'planned', 'action scheduled', + 'no further action', 'not councils responsibility', 'duplicate', 'internal referral', + 'fixed', 'closed', + ); + + $valid_status{'not responsible'} = 'not_councils_responsibility'; + return $valid_status{lc($status)} || 'open'; +} + sub service_request_content { '/open311/service_request_extended' } @@ -37,8 +61,6 @@ sub parse_datetime { return $strp->parse_datetime($time); } -sub reverse_status_mapping {} - has '+request_class' => ( is => 'ro', default => 'Open311::Endpoint::Service::Request::SalesForce', @@ -180,6 +202,7 @@ sub services { my ($self, $args) = @_; my @services = $self->get_integration->get_services($args); + @services = grep { $self->whitelist->{ $_->{name} } || $_->{hasChildren} eq 'true' } @services; my %service_lookup = map { $_->{serviceid} => $_ } @services; @@ -214,6 +237,7 @@ sub service { my $meta = $self->get_integration->get_service($id, $args); my @services = $self->get_integration->get_services($args); + @services = grep { $self->whitelist->{ $_->{name} } || $_->{hasChildren} eq 'true' } @services; my %service_lookup = map { $_->{serviceid} => $_ } @services; my $srv = $service_lookup{$id}; @@ -256,25 +280,24 @@ sub service { } my %options = ( + code => 'notice', required => 0, variable => 0, datatype => 'string', - automated => 'server_set', ); - push @{ $service->attributes }, Open311::Endpoint::Service::Attribute->new( - code => 'hint', - description => $hint, - %options, - ); - - push @{ $service->attributes }, Open311::Endpoint::Service::Attribute->new( - code => 'group_hint', - description => $group_hint, - %options, - ); + if ($hint || $group_hint) { + my $description = $group_hint ? '

' . $group_hint . '

' : ''; + $description .= $hint ? '

' . $hint . '

' : ''; + if ($description) { + push @{ $service->attributes }, Open311::Endpoint::Service::Attribute->new( + description => $description, + %options, + ); + }; + }; return $service; } -__PACKAGE__->run_if_script; +1; diff --git a/perllib/Open311/Endpoint/Role/Photos.pm b/perllib/Open311/Endpoint/Role/Photos.pm index aecec1154..48c630b09 100644 --- a/perllib/Open311/Endpoint/Role/Photos.pm +++ b/perllib/Open311/Endpoint/Role/Photos.pm @@ -25,11 +25,25 @@ around dispatch_request => sub { ); }; +# Handle being given a multi's jurisdiction_id directly sub get_photo { my ($self, $args) = @_; - $self->_call('get_photo', $args->{jurisdiction_id}, $args) - or [ 400, [ 'Content-type', 'text/plain' ], [ 'Bad request' ] ]; + my $jurisdiction_id = $args->{jurisdiction_id}; + + foreach ($self->plugins) { + if ($_->jurisdiction_id eq $jurisdiction_id) { + return $_->get_photo($args); + } + if ($_->isa('Open311::Endpoint::Integration::Multi')) { + foreach ($_->plugins) { + if ($_->jurisdiction_id eq $jurisdiction_id) { + return $_->get_photo($args); + } + } + } + } + + [ 400, [ 'Content-type', 'text/plain' ], [ 'Bad request' ] ]; } - 1; diff --git a/perllib/Open311/Endpoint/Role/mySociety.pm b/perllib/Open311/Endpoint/Role/mySociety.pm index 016628224..988697bd4 100644 --- a/perllib/Open311/Endpoint/Role/mySociety.pm +++ b/perllib/Open311/Endpoint/Role/mySociety.pm @@ -286,8 +286,13 @@ sub format_updates { ), ( map { - my $value = $update->$_->[0]; - $_ => $value || ''; + my $value; + if (scalar @{ $update->$_ } <= 1) { + $value = $update->$_->[0] || ''; + } else { + $value = $update->@{$_}; + } + $_ => $value; } qw/ media_url @@ -326,6 +331,7 @@ sub learn_additional_types { my ($self, $schema) = @_; $schema->learn_type( 'tag:wiki.open311.org,GeoReport_v2:rx/status_extended', Open311::Endpoint::Schema->enum('//str', + 'unchanged', 'open', 'closed', 'fixed', @@ -346,6 +352,7 @@ sub learn_additional_types { ); $schema->learn_type( 'tag:wiki.open311.org,GeoReport_v2:rx/status_extended_upper', Open311::Endpoint::Schema->enum('//str', + 'UNCHANGED', 'OPEN', 'CLOSED', 'FIXED', @@ -373,7 +380,7 @@ sub learn_additional_types { status => '/open311/status_extended', updated_datetime => '/open311/datetime', description => '//str', - media_url => '//str', + media_url => { type => '//any', of => [ { type => '//str' }, { type => '//arr', contents => '//str' } ] }, }, optional => { external_status_code => '//str', @@ -401,7 +408,7 @@ sub learn_additional_types { zipcode => '//str', lat => '//num', long => '//num', - media_url => '//str', + media_url => { type => '//any', of => [ { type => '//str' }, { type => '//arr', contents => '//str' } ] }, }, optional => { title => '//str', diff --git a/perllib/Open311/Endpoint/Service/Request/Update/mySociety.pm b/perllib/Open311/Endpoint/Service/Request/Update/mySociety.pm index 388c5b7a9..6fc64c65f 100644 --- a/perllib/Open311/Endpoint/Service/Request/Update/mySociety.pm +++ b/perllib/Open311/Endpoint/Service/Request/Update/mySociety.pm @@ -8,6 +8,7 @@ extends 'Open311::Endpoint::Service::Request::Update'; has status => ( is => 'ro', isa => Enum[ + 'unchanged', # For when the update has no state 'open', 'closed', 'fixed', diff --git a/t/open311/endpoint/confirm_photos.t b/t/open311/endpoint/confirm_photos.t index 85358e3b5..eafafc84a 100644 --- a/t/open311/endpoint/confirm_photos.t +++ b/t/open311/endpoint/confirm_photos.t @@ -96,7 +96,11 @@ subtest "fetching of job photos for enquiry update" => sub { GET => '/servicerequestupdates.xml?start_date=2025-01-01T00:00:00Z&end_date=2025-01-01T01:00:00Z', ); ok $res->is_success, 'valid request' or diag $res->content; - contains_string $res->content, 'http://example.com/photos?jurisdiction_id=confirm_dummy_photos&job=432&photo=1'; + contains_string $res->content, + ' + http://example.com/photos?jurisdiction_id=confirm_dummy_photos&job=432&photo=1 + http://example.com/photos?jurisdiction_id=confirm_dummy_photos&job=432&photo=2 + '; $lwp->mock(request => \&empty_json); $integration->mock(perform_request => \&empty_json); diff --git a/t/open311/endpoint/rutland_confirm.t b/t/open311/endpoint/rutland_confirm.t new file mode 100644 index 000000000..51ba7a79a --- /dev/null +++ b/t/open311/endpoint/rutland_confirm.t @@ -0,0 +1,79 @@ +package Integrations::Confirm::Rutland::Dummy; +use Path::Tiny; +use Moo; +extends 'Integrations::Confirm'; +sub _build_config_file { path(__FILE__)->sibling("rutland_confirm.yml")->stringify } + +package Open311::Endpoint::Integration::UK::Rutland::Confirm::Dummy; +use Path::Tiny; +use Moo; +extends 'Open311::Endpoint::Integration::UK::Rutland::Confirm'; +around BUILDARGS => sub { + my ($orig, $class, %args) = @_; + $args{jurisdiction_id} = 'rutland_confirm'; + $args{config_file} = path(__FILE__)->sibling("rutland_confirm.yml")->stringify; + return $class->$orig(%args); +}; +has integration_class => (is => 'ro', default => 'Integrations::Confirm::Rutland::Dummy'); + +package main; + +use strict; +use warnings; + +use Test::More; +use Test::LongString; +use Test::MockModule; + +BEGIN { $ENV{TEST_MODE} = 1; } + +my $open311 = Test::MockModule->new('Integrations::Confirm'); +$open311->mock(perform_request => sub { + return { OperationResponse => { GetEnquiryStatusChangesResponse => { UpdatedEnquiry => [ + { EnquiryNumber => 2020, EnquiryStatusLog => [ { EnquiryLogNumber => 5, StatusLogNotes => 'Private status log notes', LogEffectiveTime => '2026-01-23T12:00:00Z', LoggedTime => '2026-01-23T12:00:00Z', EnquiryStatusCode => 'AFMS' }, { EnquiryLogNumber => 6, StatusLogNotes => 'Private status log notes', LogEffectiveTime => '2026-01-23T12:00:00Z', LoggedTime => '2026-01-23T12:00:00Z', EnquiryStatusCode => 'FMSA' }, { EnquiryLogNumber => 7, StatusLogNotes => 'Public status log notes', LogEffectiveTime => '2026-01-23T12:00:00Z', LoggedTime => '2026-01-23T12:00:00Z', EnquiryStatusCode => 'FMS' } ] }, + ] } } }; +}); + +my $endpoint = Open311::Endpoint::Integration::UK::Rutland::Confirm::Dummy->new; + +subtest "Only uses the photo with the correct classification tag" => sub { + my @photos = ( + { + URL => '1', + Name => '1.jpg', + Date => DateTime->now->subtract(days => 1), + ClassificationCode => 'DT10', + }, + { + URL => '2', + Name => '2.jpg', + Date => DateTime->now->subtract(days => 2), + ClassificationCode => 'DT20', + }, + { + URL => '3', + Name => '3.jpg', + Date => DateTime->now->subtract(days => 3), + }, + ); + my @filtered = $endpoint->filter_photos_graphql(@photos); + + is @filtered, 1; + is $filtered[0]->{URL}, 2; +}; + +subtest 'Only pass on log notes for updates for "FMS" status' => sub { + my $res = $endpoint->run_test_request( + GET => '/servicerequestupdates.xml?start_date=2018-01-01T00:00:00Z&end_date=2018-02-01T00:00:00Z', + ); + ok $res->is_success, 'valid request' or diag $res->content; + contains_string $res->content, '2020_5'; + contains_string $res->content, '2020_6'; + contains_string $res->content, '2020_7'; + lacks_string $res->content, 'Private status log notes'; + contains_string $res->content, 'Public status log notes'; + contains_string $res->content, 'unchanged'; +}; + +done_testing; + diff --git a/t/open311/endpoint/rutland_confirm.yml b/t/open311/endpoint/rutland_confirm.yml new file mode 100644 index 000000000..c536fc71b --- /dev/null +++ b/t/open311/endpoint/rutland_confirm.yml @@ -0,0 +1,13 @@ +endpoint_url: "https://test.example.com/graphql" +web_url: "https://test.example.com/" +username: "test_user" +password: "test_pass" +tenant_id: "test_tenant" +server_timezone: "Europe/London" +service_whitelist: {} +ignored_attributes: [] +ignored_attribute_options: [] +forward_status_mapping: {} +reverse_status_mapping: { + FMS: unchanged + } diff --git a/t/open311/endpoint/rutland.t b/t/open311/endpoint/rutland_salesforce.t similarity index 93% rename from t/open311/endpoint/rutland.t rename to t/open311/endpoint/rutland_salesforce.t index aec3856d2..d8b2cf4f5 100644 --- a/t/open311/endpoint/rutland.t +++ b/t/open311/endpoint/rutland_salesforce.t @@ -30,6 +30,25 @@ has is_success => ( default => 1 ); +package Integrations::SalesForce::Rutland::Dummy; +use Path::Tiny; +use Moo; +extends 'Integrations::SalesForce::Rutland'; +sub _build_config_file { path(__FILE__)->sibling("rutland_salesforce.yml")->stringify } + +package Open311::Endpoint::Integration::UK::Rutland::SalesForce::Dummy; +use Path::Tiny; +use Moo; +extends 'Open311::Endpoint::Integration::UK::Rutland::SalesForce'; +around BUILDARGS => sub { + my ($orig, $class, %args) = @_; + $args{jurisdiction_id} = 'rutland_salesforce'; + $args{config_file} = path(__FILE__)->sibling("rutland_salesforce.yml")->stringify; + return $class->$orig(%args); +}; +has integration_class => (is => 'ro', default => 'Integrations::SalesForce::Rutland::Dummy'); + + package main; use strict; use warnings; @@ -44,12 +63,13 @@ use Test::MockTime ':all'; use Open311::Endpoint; use Data::Dumper; use JSON::MaybeXS; +use Path::Tiny; BEGIN { $ENV{TEST_MODE} = 1; } -use Open311::Endpoint::Integration::UK; -use Integrations::SalesForce::Rutland; +use Open311::Endpoint::Integration::UK::Rutland::SalesForce::Dummy; +use Integrations::SalesForce::Rutland::Dummy; -my $endpoint = Open311::Endpoint::Integration::UK->new; +my $endpoint = Open311::Endpoint::Integration::UK::Rutland::SalesForce::Dummy->new; my %responses = ( 'new_report' => '[{ "Id": "12345" }]', @@ -236,7 +256,7 @@ subtest "create basic problem" => sub { set_fixed_time('2014-01-01T12:00:00Z'); my $res = $endpoint->run_test_request( POST => '/requests.json', - jurisdiction_id => 'rutland', + jurisdiction_id => 'rutland_salesforce', api_key => 'test', service_code => 'POT', address_string => '22 Acacia Avenue', @@ -255,7 +275,6 @@ subtest "create basic problem" => sub { ok $res->is_success, 'valid request' or diag $res->content; - is_deeply decode_json($sent), [{ "detail__c" => "description", @@ -287,7 +306,7 @@ subtest "create problem with extra categories" => sub { set_fixed_time('2014-01-01T12:00:00Z'); my $res = $endpoint->run_test_request( POST => '/requests.json', - jurisdiction_id => 'rutland', + jurisdiction_id => 'rutland_salesforce', api_key => 'test', service_code => 'POT', address_string => '22 Acacia Avenue', @@ -340,7 +359,7 @@ subtest "create problem with extra list categories" => sub { set_fixed_time('2014-01-01T12:00:00Z'); my $res = $endpoint->run_test_request( POST => '/requests.json', - jurisdiction_id => 'rutland', + jurisdiction_id => 'rutland_salesforce', api_key => 'test', service_code => 'RC_08', address_string => '22 Acacia Avenue', @@ -393,7 +412,7 @@ subtest "create problem with multiple photos" => sub { set_fixed_time('2014-01-01T12:00:00Z'); my $res = $endpoint->run_test_request( POST => '/requests.json', - jurisdiction_id => 'rutland', + jurisdiction_id => 'rutland_salesforce', api_key => 'test', service_code => 'POT', address_string => '22 Acacia Avenue', @@ -447,7 +466,7 @@ subtest "create problem with unrecognised attribute" => sub { set_fixed_time('2014-01-01T12:00:00Z'); my $res = $endpoint->run_test_request( POST => '/requests.json', - jurisdiction_id => 'rutland', + jurisdiction_id => 'rutland_salesforce', api_key => 'test', service_code => 'POT', address_string => '22 Acacia Avenue', @@ -489,7 +508,7 @@ subtest "create problem with unrecognised attribute" => sub { subtest "check fetch problem" => sub { set_fixed_time('2014-01-01T12:00:00Z'); my $res = $endpoint->run_test_request( - GET => '/requests.json?jurisdiction_id=rutland&start_date=2018-01-10T00:00:00Z&end_date=2018-01-10T23:59:59Z', + GET => '/requests.json?jurisdiction_id=rutland_salesforce&start_date=2018-01-10T00:00:00Z&end_date=2018-01-10T23:59:59Z', ); my $sent = pop @sent; @@ -554,13 +573,12 @@ subtest "check fetch problem with not responsible status" => sub { }]', my $res = $endpoint->run_test_request( - GET => '/requests.json?jurisdiction_id=rutland&start_date=2018-01-10T00:00:00Z&end_date=2018-01-10T23:59:59Z', + GET => '/requests.json?jurisdiction_id=rutland_salesforce&start_date=2018-01-10T00:00:00Z&end_date=2018-01-10T23:59:59Z', ); my $sent = pop @sent; ok $res->is_success, 'valid request' or diag $res->content; - is_deeply decode_json($res->content), [ { address => '', @@ -619,7 +637,7 @@ subtest "check fetch problem ignores problems older than start date" => sub { }]', my $res = $endpoint->run_test_request( - GET => '/requests.json?jurisdiction_id=rutland&start_date=2018-01-10T00:00:00Z&end_date=2018-01-10T23:59:59Z', + GET => '/requests.json?jurisdiction_id=rutland_salesforce&start_date=2018-01-10T00:00:00Z&end_date=2018-01-10T23:59:59Z', ); my $sent = pop @sent; @@ -669,7 +687,7 @@ subtest "check fetch problem works with no start date" => sub { }]', my $res = $endpoint->run_test_request( - GET => '/requests.json?jurisdiction_id=rutland', + GET => '/requests.json?jurisdiction_id=rutland_salesforce', ); my $sent = pop @sent; @@ -699,7 +717,8 @@ subtest "create update" => sub { set_fixed_time('2014-01-01T12:00:00Z'); my $res = $endpoint->run_test_request( POST => '/servicerequestupdates.json', - jurisdiction_id => 'rutland', + jurisdiction_id => 'rutland_salesforce', + service_code => 'code', api_key => 'test', service_request_id => "a086E000001gcVRQAY", updated_datetime => "2014-01-01T12:00:00Z", @@ -732,8 +751,9 @@ subtest "create update with unicode" => sub { set_fixed_time('2014-01-01T12:00:00Z'); my $res = $endpoint->run_test_request( POST => '/servicerequestupdates.json', - jurisdiction_id => 'rutland', + jurisdiction_id => 'rutland_salesforce', api_key => 'test', + service_code => 'code', service_request_id => "a086E000001gcVRQAY", updated_datetime => "2014-01-01T12:00:00Z", update_id => 1234, @@ -764,7 +784,7 @@ subtest "create update with unicode" => sub { subtest "check fetch updates" => sub { set_fixed_time('2014-01-01T12:00:00Z'); my $res = $endpoint->run_test_request( - GET => '/servicerequestupdates.json?jurisdiction_id=rutland', + GET => '/servicerequestupdates.json?jurisdiction_id=rutland_salesforce', ); my $sent = pop @sent; @@ -792,7 +812,7 @@ subtest "check fetch update with no comment" => sub { }]'; my $res = $endpoint->run_test_request( - GET => '/servicerequestupdates.json?jurisdiction_id=rutland', + GET => '/servicerequestupdates.json?jurisdiction_id=rutland_salesforce', ); my $sent = pop @sent; @@ -820,7 +840,7 @@ subtest "check fetch update with unicode comment" => sub { }]'; my $res = $endpoint->run_test_request( - GET => '/servicerequestupdates.json?jurisdiction_id=rutland', + GET => '/servicerequestupdates.json?jurisdiction_id=rutland_salesforce', ); my $sent = pop @sent; @@ -848,7 +868,7 @@ subtest "check fetch update with not responsible status" => sub { }]'; my $res = $endpoint->run_test_request( - GET => '/servicerequestupdates.json?jurisdiction_id=rutland', + GET => '/servicerequestupdates.json?jurisdiction_id=rutland_salesforce', ); my $sent = pop @sent; @@ -868,7 +888,7 @@ subtest "check fetch update with not responsible status" => sub { subtest "check fetch service description" => sub { my $res = $endpoint->run_test_request( - GET => '/services.json?jurisdiction_id=rutland', + GET => '/services.json?jurisdiction_id=rutland_salesforce', ); my $sent = pop @sent; @@ -884,22 +904,13 @@ subtest "check fetch service description" => sub { type => "realtime", keywords => "", group => "Street Furniture" - }, - { - metadata => "true", - description => "Phasing/timing issues", - group => "Traffic Lights - Permanent", - service_code => "a012500000JJ0neAAD", - type => "realtime", - service_name => "Phasing/timing issues", - keywords => "" } ], 'correct json returned' or diag $res->content; }; subtest "check fetch failing request" => sub { my $res = $endpoint->run_test_request( - GET => '/services/RC_09.json?jurisdiction_id=rutland', + GET => '/services/RC_09.json?jurisdiction_id=rutland_salesforce', ); my $sent = pop @sent; @@ -917,7 +928,7 @@ subtest "check fetch failing request" => sub { subtest "check fetch service metadata" => sub { my $res = $endpoint->run_test_request( - GET => '/services/a096E000007pbxWQAQ.json?jurisdiction_id=rutland', + GET => '/services/a096E000007pbxWQAQ.json?jurisdiction_id=rutland_salesforce', ); my $sent = pop @sent; @@ -978,24 +989,13 @@ subtest "check fetch service metadata" => sub { description => "Additional Information", }, { - variable => 'false', - code => "hint", - datatype => "string", - required => 'false', - datatype_description => '', - order => 6, - description => "This is the category HTML hint", - automated => 'server_set', - }, - { - variable => 'false', - code => "group_hint", - datatype => "string", - required => 'false', - datatype_description => '', - order => 7, - description => "This is the group HTML hint", - automated => 'server_set', + "variable" => "false", + "required" => "false", + "order" => 6, + "code" => "notice", + "description" => "

This is the group HTML hint

This is the category HTML hint

", + "datatype" => "string", + "datatype_description" => "", } ] }, 'correct json returned'; diff --git a/t/open311/endpoint/rutland_salesforce.yml b/t/open311/endpoint/rutland_salesforce.yml new file mode 100644 index 000000000..084fce70c --- /dev/null +++ b/t/open311/endpoint/rutland_salesforce.yml @@ -0,0 +1,3 @@ +whitelist: + Fly Tipping: 1 + diff --git a/t/open311/endpoint/uk.t b/t/open311/endpoint/uk.t index 8cef9c3d5..b2583cd48 100644 --- a/t/open311/endpoint/uk.t +++ b/t/open311/endpoint/uk.t @@ -18,7 +18,6 @@ test_multi(0, 'Open311::Endpoint::Integration::UK', 'Open311::Endpoint::Integration::UK::Kingston' => 'kingston_echo', 'Open311::Endpoint::Integration::UK::Lincolnshire' => 'lincolnshire_confirm', 'Open311::Endpoint::Integration::UK::NorthumberlandAlloy' => 'northumberland_alloy', - 'Open311::Endpoint::Integration::UK::Rutland' => 'rutland', 'Open311::Endpoint::Integration::UK::Shropshire' => 'shropshire_confirm', 'Open311::Endpoint::Integration::UK::Southwark' => 'southwark_confirm', 'Open311::Endpoint::Integration::UK::Surrey' => 'surrey_boomi', @@ -92,6 +91,12 @@ test_multi(0, 'Open311::Endpoint::Integration::UK::BANES', #'Open311::Endpoint::Integration::UK::Bristol::Passthrough' => 'www.banes.gov.uk', ); +test_multi(1, 'Open311::Endpoint::Integration::UK::Rutland', + 'Open311::Endpoint::Integration::UK::Rutland::SalesForce' => 'rutland_salesforce', + 'Open311::Endpoint::Integration::UK::Rutland::Confirm' => 'rutland_confirm', +); + + done_testing; sub test_multi {