diff options
author | Matthew Somerville <matthew@mysociety.org> | 2020-05-11 12:43:02 +0100 |
---|---|---|
committer | Dave Arter <davea@mysociety.org> | 2020-07-02 14:38:29 +0100 |
commit | 53b9f82cbb7fe81484b8bbf434f0b0acd925b454 (patch) | |
tree | 7f3b53b88e1a8a5dc70aa425a1997be068b05e31 | |
parent | c3b4b23b378f6d14881675556571e912d1a52ee0 (diff) |
[Hackney] Special destination handling.
-rw-r--r-- | perllib/FixMyStreet/Cobrand/Default.pm | 3 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/Hackney.pm | 62 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/UKCouncils.pm | 2 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/Zurich.pm | 2 | ||||
-rw-r--r-- | perllib/FixMyStreet/Queue/Item/Report.pm | 2 | ||||
-rwxr-xr-x | perllib/Open311/PostServiceRequestUpdates.pm | 2 | ||||
-rw-r--r-- | t/cobrand/get_body_sender.t | 18 | ||||
-rw-r--r-- | t/cobrand/hackney.t | 71 |
8 files changed, 133 insertions, 29 deletions
diff --git a/perllib/FixMyStreet/Cobrand/Default.pm b/perllib/FixMyStreet/Cobrand/Default.pm index 73340338b..bd8b7e4b4 100644 --- a/perllib/FixMyStreet/Cobrand/Default.pm +++ b/perllib/FixMyStreet/Cobrand/Default.pm @@ -957,9 +957,10 @@ Get stats to display on the council reports page sub get_report_stats { return 0; } sub get_body_sender { - my ( $self, $body, $category ) = @_; + my ( $self, $body, $problem ) = @_; # look up via category + my $category = $problem->category; my $contact = $body->contacts->search( { category => $category } )->first; if ( $body->can_be_devolved && $contact && $contact->send_method ) { return { method => $contact->send_method, config => $contact, contact => $contact }; diff --git a/perllib/FixMyStreet/Cobrand/Hackney.pm b/perllib/FixMyStreet/Cobrand/Hackney.pm index f08cd0dd9..dbf070628 100644 --- a/perllib/FixMyStreet/Cobrand/Hackney.pm +++ b/perllib/FixMyStreet/Cobrand/Hackney.pm @@ -3,6 +3,7 @@ use parent 'FixMyStreet::Cobrand::Whitelabel'; use strict; use warnings; +use mySociety::EmailUtil qw(is_valid_email); sub council_area_id { return 2508; } sub council_area { return 'Hackney'; } @@ -33,7 +34,7 @@ sub open311_config { } sub open311_extra_data { - my ($self, $row, $h, $extra) = @_; + my ($self, $row, $h, $extra, $contact) = @_; my $open311_only = [ { name => 'report_url', @@ -46,6 +47,13 @@ sub open311_extra_data { value => $row->category }, ]; + # Make sure contact 'email' set correctly for Open311 + if (my $sent_to = $row->get_extra_metadata('sent_to')) { + $row->unset_extra_metadata('sent_to'); + my $code = $sent_to->{$contact->email}; + $contact->email($code) if $code; + } + return $open311_only; } @@ -80,4 +88,56 @@ sub open311_filter_contacts_for_deletion { }); } +sub lookup_site_code_config { + my ($self, $type) = @_; + my $property_map = { + park => "greenspaces:hackney_park", + estate => "housing:lbh_estate", + }; + { + buffer => 3, # metres + url => "https://map.hackney.gov.uk/geoserver/wfs", + srsname => "urn:ogc:def:crs:EPSG::27700", + typename => $property_map->{$type}, + property => ( $type eq "park" ? "park_id" : "id" ), + accept_feature => sub { 1 }, + accept_types => { Polygon => 1 }, + outputformat => "json", + } +} + +sub get_body_sender { + my ( $self, $body, $problem ) = @_; + + my $contact = $body->contacts->search( { category => $problem->category } )->first; + + my $parts = join '\s*', qw(^ park : (.*?) ; estate : (.*?) ; other : (.*?) $); + my $regex = qr/$parts/i; + if (my ($park, $estate, $other) = $contact->email =~ $regex) { + my $to = $other; + if (my $park_id = $self->lookup_site_code($problem, 'park')) { + $to = $park; + } elsif (my $estate_id = $self->lookup_site_code($problem, 'estate')) { + $to = $estate; + } + $problem->set_extra_metadata(sent_to => { $contact->email => $to }); + if (is_valid_email($to)) { + return { method => 'Email', contact => $contact }; + } + } + return $self->SUPER::get_body_sender($body, $problem); +} + +# Translate email address to actual delivery address +sub munge_sendreport_params { + my ($self, $row, $h, $params) = @_; + + my $sent_to = $row->get_extra_metadata('sent_to') or return; + $row->unset_extra_metadata('sent_to'); + for my $recip (@{$params->{To}}) { + my ($email, $name) = @$recip; + $recip->[0] = $sent_to->{$email} if $sent_to->{$email}; + } +} + 1; diff --git a/perllib/FixMyStreet/Cobrand/UKCouncils.pm b/perllib/FixMyStreet/Cobrand/UKCouncils.pm index 21dd2d455..7456d9ddf 100644 --- a/perllib/FixMyStreet/Cobrand/UKCouncils.pm +++ b/perllib/FixMyStreet/Cobrand/UKCouncils.pm @@ -392,7 +392,7 @@ sub _fetch_features_url { SRSNAME => $cfg->{srsname}, TYPENAME => $cfg->{typename}, VERSION => "1.1.0", - outputformat => "geojson", + outputformat => $cfg->{outputformat} || "geojson", $cfg->{filter} ? ( Filter => $cfg->{filter} ) : ( BBOX => $cfg->{bbox} ), ); diff --git a/perllib/FixMyStreet/Cobrand/Zurich.pm b/perllib/FixMyStreet/Cobrand/Zurich.pm index 3cf678f9c..42932ec41 100644 --- a/perllib/FixMyStreet/Cobrand/Zurich.pm +++ b/perllib/FixMyStreet/Cobrand/Zurich.pm @@ -217,7 +217,7 @@ sub allow_photo_display { } sub get_body_sender { - my ( $self, $body, $category ) = @_; + my ( $self, $body, $problem ) = @_; return { method => 'Zurich' }; } diff --git a/perllib/FixMyStreet/Queue/Item/Report.pm b/perllib/FixMyStreet/Queue/Item/Report.pm index e38987838..60e9ad3dc 100644 --- a/perllib/FixMyStreet/Queue/Item/Report.pm +++ b/perllib/FixMyStreet/Queue/Item/Report.pm @@ -172,7 +172,7 @@ sub _create_reporters { my @dear; my %reporters = (); while (my $body = $bodies->next) { - my $sender_info = $self->cobrand->get_body_sender( $body, $row->category ); + my $sender_info = $self->cobrand_handler->get_body_sender( $body, $row ); my $sender = "FixMyStreet::SendReport::" . $sender_info->{method}; if ( ! exists $self->senders->{ $sender } ) { diff --git a/perllib/Open311/PostServiceRequestUpdates.pm b/perllib/Open311/PostServiceRequestUpdates.pm index d7345ea4d..a31bca8f7 100755 --- a/perllib/Open311/PostServiceRequestUpdates.pm +++ b/perllib/Open311/PostServiceRequestUpdates.pm @@ -50,7 +50,7 @@ sub open311_params { my $conf = $body; if ($comment) { my $cobrand_logged = $comment->get_cobrand_logged; - my $sender = $cobrand_logged->get_body_sender($body, $comment->problem->category); + my $sender = $cobrand_logged->get_body_sender($body, $comment->problem); $conf = $sender->{config}; } diff --git a/t/cobrand/get_body_sender.t b/t/cobrand/get_body_sender.t index 06ffb42a5..a1e8f2320 100644 --- a/t/cobrand/get_body_sender.t +++ b/t/cobrand/get_body_sender.t @@ -6,31 +6,21 @@ use_ok 'FixMyStreet::Cobrand'; my $c = FixMyStreet::Cobrand::FixMyStreet->new(); -FixMyStreet::DB->resultset('BodyArea')->search( { body_id => 1000 } )->delete; -FixMyStreet::DB->resultset('Body')->search( { name => 'Body of a Thousand' } )->delete; - my $body = FixMyStreet::DB->resultset('Body')->find_or_create({ id => 1000, name => 'Body of a Thousand', }); -my $body_area = $body->body_areas->find_or_create({ area_id => 1000 }); + +my $problem = FixMyStreet::DB->resultset('Problem')->new({}); FixMyStreet::override_config { MAPIT_TYPES => [ 'LBO' ], MAPIT_URL => 'http://mapit.uk/', # Not actually used as no special casing at present }, sub { - is_deeply $c->get_body_sender( $body ), { method => 'Email', contact => undef }, 'defaults to email'; - $body_area->update({ area_id => 2481 }); # Croydon LBO - is_deeply $c->get_body_sender( $body ), { method => 'Email', contact => undef }, 'still email if London borough'; + is_deeply $c->get_body_sender( $body, $problem ), { method => 'Email', contact => undef }, 'defaults to email'; }; $body->send_method( 'TestMethod' ); -is $c->get_body_sender( $body )->{ method }, 'TestMethod', 'uses send_method in preference to London'; - -$body_area->update({ area_id => 1000 }); # Nothing -is $c->get_body_sender( $body )->{ method }, 'TestMethod', 'uses send_method in preference to Email'; - -$body_area->delete; -$body->delete; +is $c->get_body_sender( $body, $problem )->{ method }, 'TestMethod', 'uses send_method in preference to Email'; done_testing(); diff --git a/t/cobrand/hackney.t b/t/cobrand/hackney.t index 519b1b3b8..82fefc15b 100644 --- a/t/cobrand/hackney.t +++ b/t/cobrand/hackney.t @@ -53,16 +53,11 @@ my $contact2 = $mech->create_contact_ok( body_id => $hackney->id, category => 'Roads', email => 'roads@example.org', - send_method => 'Triage', + send_method => 'Email', ); my $admin_user = $mech->create_user_ok('admin-user@example.org', name => 'Admin User', from_body => $hackney); -$admin_user->user_body_permissions->create({ - body => $hackney, - permission_type => 'triage' -}); - my @reports = $mech->create_problems_for_body(1, $hackney->id, 'A Hackney report', { confirmed => '2019-10-25 09:00', lastupdate => '2019-10-25 09:00', @@ -129,7 +124,6 @@ subtest "sends branded alert emails" => sub { FixMyStreet::Script::Alerts::send(); }; - $mech->email_count_is(1); my $email = $mech->get_email; ok $email, "got an email"; like $mech->get_text_body_from_email($email), qr/Hackney Council/, "emails are branded"; @@ -168,7 +162,6 @@ subtest "sends branded confirmation emails" => sub { "submit good details" ); - $mech->email_count_is(1); my $email = $mech->get_email; ok $email, "got an email"; like $mech->get_text_body_from_email($email), qr/Hackney Council/, "emails are branded"; @@ -179,6 +172,67 @@ subtest "sends branded confirmation emails" => sub { }; }; +FixMyStreet::override_config { + STAGING_FLAGS => { send_reports => 1 }, + MAPIT_URL => 'http://mapit.uk/', + ALLOWED_COBRANDS => ['hackney', 'fixmystreet'], +}, sub { + subtest "special send handling" => sub { + my $cbr = Test::MockModule->new('FixMyStreet::Cobrand::Hackney'); + my $p = FixMyStreet::DB->resultset("Problem")->search(undef, { order_by => { -desc => 'id' } })->first; + $contact2->update({ email => 'park:parks@example;estate:estates@example;other:OTHER', send_method => '' }); + + subtest 'in a park' => sub { + $cbr->mock('_fetch_features', sub { + my ($self, $cfg, $x, $y) = @_; + return [{ + properties => { park_id => 'park' }, + geometry => { + type => 'Polygon', + coordinates => [ [ [ $x-1, $y-1 ], [ $x+1, $y+1 ] ] ], + } + }] if $cfg->{typename} eq 'greenspaces:hackney_park'; + }); + FixMyStreet::Script::Reports::send(); + my $email = $mech->get_email; + is $email->header('To'), '"Hackney Council" <parks@example>'; + $mech->clear_emails_ok; + $p->discard_changes; + $p->update({ whensent => undef }); + }; + + subtest 'in an estate' => sub { + $cbr->mock('_fetch_features', sub { + my ($self, $cfg, $x, $y) = @_; + return [{ + properties => { id => 'estate' }, + geometry => { + type => 'Polygon', + coordinates => [ [ [ $x-1, $y-1 ], [ $x+1, $y+1 ] ] ], + } + }] if $cfg->{typename} eq 'housing:lbh_estate'; + }); + FixMyStreet::Script::Reports::send(); + my $email = $mech->get_email; + is $email->header('To'), '"Hackney Council" <estates@example>'; + $mech->clear_emails_ok; + $p->discard_changes; + $p->update({ whensent => undef }); + }; + + subtest 'elsewhere' => sub { + $cbr->mock('_fetch_features', sub { + my ($self, $cfg, $x, $y) = @_; + return []; # Not in park or estate + }); + my $test_data = FixMyStreet::Script::Reports::send(); + my $req = $test_data->{test_req_used}; + my $c = CGI::Simple->new($req->content); + is $c->param('service_code'), 'OTHER'; + }; + }; +}; + #subtest "sends branded report sent emails" => sub { #$mech->clear_emails_ok; #FixMyStreet::override_config { @@ -188,7 +242,6 @@ subtest "sends branded confirmation emails" => sub { #}, sub { #FixMyStreet::Script::Reports::send(); #}; - #$mech->email_count_is(1); #my $email = $mech->get_email; #ok $email, "got an email"; #like $mech->get_text_body_from_email($email), qr/Hackney Council/, "emails are branded"; |