diff options
Diffstat (limited to 't/cobrand')
-rw-r--r-- | t/cobrand/bexley.t | 41 | ||||
-rw-r--r-- | t/cobrand/bristol.t | 8 | ||||
-rw-r--r-- | t/cobrand/bromley.t | 313 | ||||
-rw-r--r-- | t/cobrand/bucks.t | 40 | ||||
-rw-r--r-- | t/cobrand/form_extras.t | 2 | ||||
-rw-r--r-- | t/cobrand/get_body_sender.t | 18 | ||||
-rw-r--r-- | t/cobrand/hackney.t | 325 | ||||
-rw-r--r-- | t/cobrand/highwaysengland.t | 18 | ||||
-rw-r--r-- | t/cobrand/hounslow.t | 9 | ||||
-rw-r--r-- | t/cobrand/isleofwight.t | 15 | ||||
-rw-r--r-- | t/cobrand/northamptonshire.t | 182 | ||||
-rw-r--r-- | t/cobrand/oxfordshire.t | 107 | ||||
-rw-r--r-- | t/cobrand/peterborough.t | 81 | ||||
-rw-r--r-- | t/cobrand/tfl.t | 40 | ||||
-rw-r--r-- | t/cobrand/zurich.t | 73 |
15 files changed, 1210 insertions, 62 deletions
diff --git a/t/cobrand/bexley.t b/t/cobrand/bexley.t index 352e61389..46a25d923 100644 --- a/t/cobrand/bexley.t +++ b/t/cobrand/bexley.t @@ -50,14 +50,17 @@ FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'bexley' ], MAPIT_URL => 'http://mapit.uk/', STAGING_FLAGS => { send_reports => 1, skip_checks => 0 }, - COBRAND_FEATURES => { open311_email => { bexley => { - p1 => 'p1@bexley', - p1confirm => 'p1confirm@bexley', - lighting => 'thirdparty@notbexley.example.com,another@notbexley.example.com', - outofhours => 'outofhours@bexley,ooh2@bexley', - flooding => 'flooding@bexley', - eh => 'eh@bexley', - } } }, + COBRAND_FEATURES => { + open311_email => { bexley => { + p1 => 'p1@bexley', + p1confirm => 'p1confirm@bexley', + lighting => 'thirdparty@notbexley.example.com,another@notbexley.example.com', + outofhours => 'outofhours@bexley,ooh2@bexley', + flooding => 'flooding@bexley', + eh => 'eh@bexley', + } }, + category_groups => { bexley => 1 }, + }, }, sub { subtest 'cobrand displays council name' => sub { @@ -144,7 +147,7 @@ FixMyStreet::override_config { subtest 'resend is disabled in admin' => sub { my $user = $mech->log_in_ok('super@example.org'); - $user->update({ from_body => $body, is_superuser => 1 }); + $user->update({ from_body => $body, is_superuser => 1, name => 'Staff User' }); $mech->get_ok('/admin/report_edit/' . $report->id); $mech->content_contains('View report on site'); $mech->content_lacks('Resend report'); @@ -199,6 +202,16 @@ FixMyStreet::override_config { ], 'Request had multiple photos'; }; + subtest 'anonymous update message' => sub { + my $report = FixMyStreet::DB->resultset("Problem")->first; + my $staffuser = $mech->create_user_ok('super@example.org'); + $mech->create_comment_for_problem($report, $report->user, 'Commenter', 'Normal update', 't', 'confirmed', 'confirmed'); + $mech->create_comment_for_problem($report, $staffuser, 'Staff user', 'Staff update', 'f', 'confirmed', 'confirmed'); + $mech->get_ok('/report/' . $report->id); + $mech->content_contains('Posted by <strong>London Borough of Bexley</strong>'); + $mech->content_contains('Posted anonymously by a non-staff user'); + }; + }; subtest 'nearest road returns correct road' => sub { @@ -253,9 +266,10 @@ subtest 'geocoder' => sub { ] }; }; -my $bex = Test::MockModule->new('FixMyStreet::Cobrand::Bexley'); -$bex->mock('get', sub { - return <<EOF +subtest 'out of hours' => sub { + my $lwp = Test::MockModule->new('LWP::UserAgent'); + $lwp->mock('get', sub { + HTTP::Response->new(200, 'OK', [], <<EOF); { "england-and-wales": { "events": [ @@ -264,9 +278,8 @@ $bex->mock('get', sub { } } EOF -}); + }); -subtest 'out of hours' => sub { my $cobrand = FixMyStreet::Cobrand::Bexley->new; set_fixed_time('2019-10-16T12:00:00Z'); is $cobrand->_is_out_of_hours(), 0, 'not out of hours in the day'; diff --git a/t/cobrand/bristol.t b/t/cobrand/bristol.t index d4770b6ee..eacb65ce9 100644 --- a/t/cobrand/bristol.t +++ b/t/cobrand/bristol.t @@ -14,6 +14,12 @@ my $open311_contact = $mech->create_contact_ok( category => 'Street Lighting', email => 'LIGHT', ); +my $open311_edited_contact = $mech->create_contact_ok( + body_id => $body->id, + category => 'Flooding', + email => 'FLOOD', + send_method => '', +); my $email_contact = $mech->create_contact_ok( body_id => $body->id, category => 'Potholes', @@ -38,6 +44,7 @@ subtest 'Only Open311 categories are shown on Bristol cobrand', sub { }, sub { $mech->get_ok("/report/new/ajax?latitude=51.494885&longitude=-2.602237"); $mech->content_contains($open311_contact->category); + $mech->content_contains($open311_edited_contact->category); $mech->content_lacks($email_contact->category); }; }; @@ -49,6 +56,7 @@ subtest 'All categories are shown on FMS cobrand', sub { }, sub { $mech->get_ok("/report/new/ajax?latitude=51.494885&longitude=-2.602237"); $mech->content_contains($open311_contact->category); + $mech->content_contains($open311_edited_contact->category); $mech->content_contains($email_contact->category); }; }; diff --git a/t/cobrand/bromley.t b/t/cobrand/bromley.t index 71180cd3e..561b5b283 100644 --- a/t/cobrand/bromley.t +++ b/t/cobrand/bromley.t @@ -1,11 +1,19 @@ use CGI::Simple; +use Test::MockModule; +use Test::MockTime qw(:all); +use Test::Output; use FixMyStreet::TestMech; use FixMyStreet::Script::Reports; my $mech = FixMyStreet::TestMech->new; +# Mock fetching bank holidays +my $uk = Test::MockModule->new('FixMyStreet::Cobrand::UK'); +$uk->mock('_fetch_url', sub { '{}' }); + # Create test data my $user = $mech->create_user_ok( 'bromley@example.com', name => 'Bromley' ); -my $body = $mech->create_body_ok( 2482, 'Bromley Council'); +my $body = $mech->create_body_ok( 2482, 'Bromley Council', + { can_be_devolved => 1, send_extended_statuses => 1, comment_user => $user }); my $contact = $mech->create_contact_ok( body_id => $body->id, category => 'Other', @@ -26,6 +34,16 @@ $mech->create_contact_ok( email => 'tfl@example.org', ); +my $waste = $mech->create_contact_ok( + body => $body, + category => 'Report missed collection', + email => 'missed', + send_method => 'Open311', + endpoint => 'waste-endpoint', +); +$waste->set_extra_metadata(group => ['Waste']); +$waste->update; + my @reports = $mech->create_problems_for_body( 1, $body->id, 'Test', { latitude => 51.402096, longitude => 0.015784, @@ -123,7 +141,7 @@ for my $test ( cobrand => 'bromley', fields => { submit_update => 1, - username => 'unregistered@example.com', + username_register => 'unregistered@example.com', update => 'Update from an unregistered user', add_alert => undef, first_name => 'Unreg', @@ -136,7 +154,7 @@ for my $test ( cobrand => 'fixmystreet', fields => { submit_update => 1, - username => 'unregistered@example.com', + username_register => 'unregistered@example.com', update => 'Update from an unregistered user', add_alert => undef, name => 'Unreg User', @@ -177,7 +195,7 @@ for my $test ( }; } -subtest 'check display of TfL reports' => sub { +subtest 'check display of TfL and waste reports' => sub { $mech->create_problems_for_body( 1, $tfl->id, 'TfL Test', { latitude => 51.402096, longitude => 0.015784, @@ -193,6 +211,7 @@ subtest 'check display of TfL reports' => sub { }; $mech->content_like(qr{<a title="TfL Test[^>]*www.example.org[^>]*><img[^>]*grey}); $mech->content_like(qr{<a title="Test Test[^>]*href="/[^>]*><img[^>]*yellow}); + $mech->content_lacks('Report missed collection'); }; subtest 'check geolocation overrides' => sub { @@ -220,6 +239,7 @@ subtest 'check special subcategories in admin' => sub { ALLOWED_COBRANDS => 'bromley', MAPIT_URL => 'http://mapit.uk/', }, sub { + $mech->get_ok('/admin/templates/' . $body->id . '/new'); $mech->get_ok('/admin/users/' . $user->id); $mech->submit_form_ok({ with_fields => { 'contacts['.$contact->id.']' => 1, 'contacts[BLUE]' => 1 } }); }; @@ -241,4 +261,289 @@ subtest 'check heatmap page' => sub { }; }; +FixMyStreet::override_config { + ALLOWED_COBRANDS => 'bromley', + COBRAND_FEATURES => { + echo => { bromley => { sample_data => 1 } }, + waste => { bromley => 1 } + }, +}, sub { + subtest 'test open enquiries' => sub { + set_fixed_time('2020-05-19T12:00:00Z'); # After sample food waste collection + $mech->get_ok('/waste/12345'); + $mech->content_like(qr/Mixed Recycling.*?Next collection<\/dt>\s*<dd[^>]*>\s*Wednesday, 20th May\s+\(this collection has been adjusted/s); + $mech->follow_link_ok({ text => 'Report a problem with a food waste collection' }); + $mech->content_contains('Waste spillage'); + $mech->content_lacks('Gate not closed'); + restore_time(); + }; + + subtest 'test crew reported issue' => sub { + set_fixed_time('2020-05-21T12:00:00Z'); # After sample container mix + $mech->get_ok('/waste/12345'); + $mech->content_like(qr/Mixed Recycling.*?Last collection<\/dt>\s*<dd[^>]*>\s*Wednesday, 20th May\s+\(this collection has been adjusted/s); + $mech->content_contains('A missed collection cannot be reported, please see the last collection status above.'); + $mech->content_lacks('Report a mixed recycling '); + restore_time(); + }; + + subtest 'test reporting before/after completion' => sub { + set_fixed_time('2020-05-27T11:00:00Z'); + $mech->get_ok('/waste/12345'); + $mech->content_like(qr/Refuse collection.*?Last collection<\/dt>\s*<dd[^>]*>\s*Wednesday, 27th May\s+\(completed at 10:00am\)\s*<p>\s*Wrong Bin Out/s); + $mech->content_like(qr/Paper & Cardboard.*?Next collection<\/dt>\s*<dd[^>]*>\s*Wednesday, 27th May\s+\(in progress\)/s); + $mech->follow_link_ok({ text => 'Report a problem with a paper & cardboard collection' }); + $mech->content_lacks('Waste spillage'); + + set_fixed_time('2020-05-27T19:00:00Z'); + $mech->get_ok('/waste/12345'); + $mech->content_like(qr/Refuse collection.*?Last collection<\/dt>\s*<dd[^>]*>\s*Wednesday, 27th May\s+\(completed at 10:00am\)\s*<p>\s*Wrong Bin Out/s); + $mech->content_like(qr/Paper & Cardboard.*?Last collection<\/dt>\s*<dd[^>]*>\s*Wednesday, 27th May\s*<\/dd>/s); + $mech->follow_link_ok({ text => 'Report a problem with a paper & cardboard collection' }); + $mech->content_contains('Waste spillage'); + }; + + subtest 'test template creation' => sub { + $mech->log_in_ok('superuser@example.com'); + $mech->get_ok('/admin/templates/' . $body->id . '/new'); + $mech->submit_form_ok({ with_fields => { + title => 'Wrong bin', + text => 'We could not collect your waste as it was not correctly presented.', + resolution_code => 187, + task_type => 3216, + task_state => 'Completed', + } }); + $mech->log_out_ok; + }; + + subtest 'test reporting before/after completion' => sub { + $mech->get_ok('/waste/12345'); + $mech->content_contains('(completed at 10:00am)'); + $mech->content_contains('We could not collect your waste as it was not correctly presented.'); + $mech->content_lacks('Report a paper & cardboard collection'); + $mech->content_contains('Report a refuse collection'); + set_fixed_time('2020-05-28T12:00:00Z'); + $mech->get_ok('/waste/12345'); + $mech->content_contains('Report a refuse collection'); + set_fixed_time('2020-05-29T12:00:00Z'); + $mech->get_ok('/waste/12345'); + $mech->content_contains('Report a refuse collection'); + set_fixed_time('2020-05-30T12:00:00Z'); + $mech->get_ok('/waste/12345'); + $mech->content_lacks('Report a refuse collection'); + restore_time(); + }; +}; + +subtest 'test waste max-per-day' => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => 'bromley', + COBRAND_FEATURES => { + echo => { bromley => { max_per_day => 1, sample_data => 1 } }, + waste => { bromley => 1 } + }, + }, sub { + SKIP: { + skip( "No memcached", 2 ) unless Memcached::increment('bromley-test'); + Memcached::delete("bromley-test"); + $mech->get_ok('/waste/12345'); + $mech->get('/waste/12345'); + is $mech->res->code, 403, 'Now forbidden'; + } + }; + +}; + +package SOAP::Result; +sub result { return $_[0]->{result}; } +sub new { my $c = shift; bless { @_ }, $c; } + +package main; + +subtest 'updating of waste reports' => sub { + my $integ = Test::MockModule->new('SOAP::Lite'); + $integ->mock(call => sub { + my ($cls, @args) = @_; + my $method = $args[0]->name; + if ($method eq 'GetEvent') { + my ($key, $type, $value) = ${$args[3]->value}->value; + my $external_id = ${$value->value}->value->value; + my ($waste, $event_state_id, $resolution_code) = split /-/, $external_id; + return SOAP::Result->new(result => { + EventStateId => $event_state_id, + EventTypeId => '2104', + LastUpdatedDate => { OffsetMinutes => 60, DateTime => '2020-06-24T14:00:00Z' }, + ResolutionCodeId => $resolution_code, + }); + } elsif ($method eq 'GetEventType') { + return SOAP::Result->new(result => { + Workflow => { States => { State => [ + { CoreState => 'New', Name => 'New', Id => 15001 }, + { CoreState => 'Pending', Name => 'Unallocated', Id => 15002 }, + { CoreState => 'Pending', Name => 'Allocated to Crew', Id => 15003 }, + { CoreState => 'Closed', Name => 'Completed', Id => 15004, + ResolutionCodes => { StateResolutionCode => [ + { ResolutionCodeId => 201, Name => '' }, + { ResolutionCodeId => 202, Name => 'Spillage on Arrival' }, + ] } }, + { CoreState => 'Closed', Name => 'Not Completed', Id => 15005, + ResolutionCodes => { StateResolutionCode => [ + { ResolutionCodeId => 203, Name => 'Nothing Found' }, + { ResolutionCodeId => 204, Name => 'Too Heavy' }, + { ResolutionCodeId => 205, Name => 'Inclement Weather' }, + ] } }, + { CoreState => 'Closed', Name => 'Rejected', Id => 15006, + ResolutionCodes => { StateResolutionCode => [ + { ResolutionCodeId => 206, Name => 'Out of Time' }, + { ResolutionCodeId => 207, Name => 'Duplicate' }, + ] } }, + ] } }, + }); + } else { + is $method, 'UNKNOWN'; + } + }); + + FixMyStreet::override_config { + ALLOWED_COBRANDS => 'bromley', + COBRAND_FEATURES => { + echo => { bromley => { url => 'https://www.example.org/' } }, + waste => { bromley => 1 } + }, + }, sub { + @reports = $mech->create_problems_for_body(2, $body->id, 'Report missed collection', { + category => 'Report missed collection', + cobrand_data => 'waste', + }); + $reports[1]->update({ external_id => 'something-else' }); # To test loop + $report = $reports[0]; + my $cobrand = FixMyStreet::Cobrand::Bromley->new; + + $report->update({ external_id => 'waste-15001-' }); + stdout_like { + $cobrand->waste_fetch_events(1); + } qr/Fetching data for report/; + $report->discard_changes; + is $report->comments->count, 0, 'No new update'; + is $report->state, 'confirmed', 'No state change'; + + $report->update({ external_id => 'waste-15003-' }); + stdout_like { + $cobrand->waste_fetch_events(1); + } qr/Updating report to state action scheduled, Allocated to Crew/; + $report->discard_changes; + is $report->comments->count, 1, 'A new update'; + is $report->state, 'action scheduled', 'A state change'; + + $report->update({ external_id => 'waste-15003-' }); + stdout_like { + $cobrand->waste_fetch_events(1); + } qr/Latest update matches fetched state/; + $report->discard_changes; + is $report->comments->count, 1, 'No new update'; + is $report->state, 'action scheduled', 'State unchanged'; + + $report->update({ external_id => 'waste-15004-201' }); + stdout_like { + $cobrand->waste_fetch_events(1); + } qr/Updating report to state fixed - council, Completed/; + $report->discard_changes; + is $report->comments->count, 2, 'A new update'; + is $report->state, 'fixed - council', 'Changed to fixed'; + + $reports[1]->update({ state => 'fixed - council' }); + stdout_like { + $cobrand->waste_fetch_events(1); + } qr/^$/, 'No open reports'; + + $report->update({ external_id => 'waste-15005-205', state => 'confirmed' }); + stdout_like { + $cobrand->waste_fetch_events(1); + } qr/Updating report to state unable to fix, Inclement Weather/; + $report->discard_changes; + is $report->comments->count, 3, 'A new update'; + is $report->state, 'unable to fix', 'A state change'; + }; + + FixMyStreet::override_config { + ALLOWED_COBRANDS => 'bromley', + COBRAND_FEATURES => { + echo => { bromley => { + url => 'https://www.example.org/', + receive_action => 'action', + receive_username => 'un', + receive_password => 'password', + } }, + waste => { bromley => 1 } + }, + }, sub { + FixMyStreet::App->log->disable('info'); + + $mech->get('/waste/echo'); + is $mech->res->code, 405, 'Cannot GET'; + + $mech->post('/waste/echo', Content_Type => 'text/xml'); + is $mech->res->code, 400, 'No body'; + + my $in = '<Envelope><Header><Action>bad-action</Action></Header><Body></Body></Envelope>'; + $mech->post('/waste/echo', Content_Type => 'text/xml', Content => $in); + is $mech->res->code, 400, 'Bad action'; + + $in = '<Envelope><Header><Action>action</Action><Security><UsernameToken><Username></Username><Password></Password></UsernameToken></Security></Header><Body></Body></Envelope>'; + $mech->post('/waste/echo', Content_Type => 'text/xml', Content => $in); + is $mech->res->code, 400, 'Bad auth'; + + $in = <<EOF; +<?xml version="1.0" encoding="UTF-8"?> +<Envelope> + <Header> + <Action>action</Action> + <Security><UsernameToken><Username>un</Username><Password>password</Password></UsernameToken></Security> + </Header> + <Body> + <NotifyEventUpdated> + <event> + <Guid>waste-15005-XXX</Guid> + <EventTypeId>2104</EventTypeId> + <EventStateId>15006</EventStateId> + <ResolutionCodeId>207</ResolutionCodeId> + </event> + </NotifyEventUpdated> + </Body> +</Envelope> +EOF + + $mech->post('/waste/echo', Content_Type => 'text/xml', Content => $in); + is $mech->res->code, 200, 'OK response, even though event does not exist'; + is $report->comments->count, 3, 'No new update'; + + $in = <<EOF; +<?xml version="1.0" encoding="UTF-8"?> +<Envelope> + <Header> + <Action>action</Action> + <Security><UsernameToken><Username>un</Username><Password>password</Password></UsernameToken></Security> + </Header> + <Body> + <NotifyEventUpdated> + <event> + <Guid>waste-15005-205</Guid> + <EventTypeId>2104</EventTypeId> + <EventStateId>15006</EventStateId> + <ResolutionCodeId>207</ResolutionCodeId> + </event> + </NotifyEventUpdated> + </Body> +</Envelope> +EOF + $mech->post('/waste/echo', Content_Type => 'text/xml', Content => $in); + #$report->update({ external_id => 'waste-15005-205', state => 'confirmed' }); + is $report->comments->count, 4, 'A new update'; + $report->discard_changes; + is $report->state, 'closed', 'A state change'; + + FixMyStreet::App->log->enable('info'); + }; +}; + done_testing(); diff --git a/t/cobrand/bucks.t b/t/cobrand/bucks.t index 230a52f99..8d99178f5 100644 --- a/t/cobrand/bucks.t +++ b/t/cobrand/bucks.t @@ -112,7 +112,6 @@ subtest 'pothole on road not sent to extra email, only confirm sent' => sub { is $report->external_id, 248, 'Report has right external ID'; }; - # report made in Flytipping category off road should get moved to other category subtest 'Flytipping not on a road gets recategorised' => sub { $mech->log_in_ok($publicuser->email); @@ -129,13 +128,48 @@ subtest 'Flytipping not on a road gets recategorised' => sub { my $report = FixMyStreet::DB->resultset("Problem")->search(undef, { order_by => { -desc => 'id' } })->first; ok $report, "Found the report"; is $report->category, "Flytipping (off-road)", 'Report was recategorised correctly'; +}; + +subtest 'Flytipping not on a road on .com gets recategorised' => sub { + ok $mech->host("www.fixmystreet.com"), "change host to www"; + $mech->get_ok('/report/new?latitude=51.615559&longitude=-0.556903&category=Flytipping'); + $mech->submit_form_ok({ + with_fields => { + title => "Test Report", + detail => 'Test report details.', + category => 'Flytipping', + 'road-placement' => 'off-road', + } + }, "submit details"); + $mech->content_contains('on its way to the council right now'); + my $report = FixMyStreet::DB->resultset("Problem")->search(undef, { order_by => { -desc => 'id' } })->first; + ok $report, "Found the report"; + is $report->category, "Flytipping (off-road)", 'Report was recategorised correctly'; + ok $mech->host("buckinghamshire.fixmystreet.com"), "change host to bucks"; +}; + +subtest 'Flytipping not on a road going to HE does not get recategorised' => sub { + $mech->get_ok('/report/new?latitude=51.615559&longitude=-0.556903&category=Flytipping'); + $mech->submit_form_ok({ + with_fields => { + single_body_only => 'Highways England', + title => "Test Report", + detail => 'Test report details.', + category => 'Flytipping', + 'road-placement' => 'off-road', + } + }, "submit details"); + $mech->content_contains('We don’t handle this type of problem'); + my $report = FixMyStreet::DB->resultset("Problem")->search(undef, { order_by => { -desc => 'id' } })->first; + ok $report, "Found the report"; + is $report->category, "Flytipping", 'Report was not recategorised'; $mech->log_out_ok; }; subtest 'Ex-district reports are sent to correct emails' => sub { FixMyStreet::Script::Reports::send(); - $mech->email_count_is(2); # one for council, one confirmation for user + $mech->email_count_is(4); # (one for council, one confirmation for user) x 2 my @email = $mech->get_email; is $email[0]->header('To'), 'Buckinghamshire <flytipping@chiltern>'; }; @@ -229,7 +263,7 @@ subtest 'extra CSV columns are present' => sub { $mech->get_ok('/dashboard?export=1'); my @rows = $mech->content_as_csv; - is scalar @rows, 5, '1 (header) + 4 (reports) = 5 lines'; + is scalar @rows, 6, '1 (header) + 4 (reports) = 6 lines'; is scalar @{$rows[0]}, 21, '21 columns present'; is_deeply $rows[0], diff --git a/t/cobrand/form_extras.t b/t/cobrand/form_extras.t index 3807dd56a..72c725d75 100644 --- a/t/cobrand/form_extras.t +++ b/t/cobrand/form_extras.t @@ -41,7 +41,7 @@ FixMyStreet::override_config { detail => 'Test report details.', name => 'Joe Bloggs', may_show_name => '1', - username => 'test-1@example.com', + username_register => 'test-1@example.com', password_register => '', } }, 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 new file mode 100644 index 000000000..bdfcceef8 --- /dev/null +++ b/t/cobrand/hackney.t @@ -0,0 +1,325 @@ +use utf8; +use CGI::Simple; +use DateTime; +use Test::MockModule; +use FixMyStreet::TestMech; +use Open311; +use Open311::GetServiceRequests; +use Open311::GetServiceRequestUpdates; +use Open311::PostServiceRequestUpdates; +use FixMyStreet::Script::Alerts; +use FixMyStreet::Script::Reports; + +# disable info logs for this test run +FixMyStreet::App->log->disable('info'); +END { FixMyStreet::App->log->enable('info'); } + +ok( my $mech = FixMyStreet::TestMech->new, 'Created mech object' ); + +my $params = { + send_method => 'Open311', + send_comments => 1, + api_key => 'KEY', + endpoint => 'endpoint', + jurisdiction => 'home', + can_be_devolved => 1, +}; + +my $hackney = $mech->create_body_ok(2508, 'Hackney Council', $params); +my $contact = $mech->create_contact_ok( + body_id => $hackney->id, + category => 'Potholes & stuff', + email => 'pothole@example.org', +); +$contact->set_extra_fields( ( { + code => 'urgent', + datatype => 'string', + description => 'question', + variable => 'true', + required => 'false', + order => 1, + datatype_description => 'datatype', +} ) ); +$contact->update; + +my $user = $mech->create_user_ok('user@example.org', name => 'Test User'); +my $hackney_user = $mech->create_user_ok('hackney_user@example.org', name => 'Hackney User', from_body => $hackney); +$hackney_user->user_body_permissions->create({ + body => $hackney, + permission_type => 'moderate', +}); +$hackney_user->user_body_permissions->create({ + body => $hackney, + permission_type => 'category_edit', +}); + +my $contact2 = $mech->create_contact_ok( + body_id => $hackney->id, + category => 'Roads', + email => 'roads@example.org', + send_method => 'Email', +); + +my $admin_user = $mech->create_user_ok('admin-user@example.org', name => 'Admin User', from_body => $hackney); + +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', + latitude => 51.552267, + longitude => -0.063316, + user => $user, + external_id => 101202303 +}); + +subtest "check clicking all reports link" => sub { + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + ALLOWED_COBRANDS => ['hackney'], + }, sub { + $mech->get_ok('/'); + $mech->follow_link_ok({ text => 'All reports' }); + }; + + $mech->content_contains("A Hackney report", "Hackney report there"); + $mech->content_contains("Hackney Council", "is still on cobrand"); +}; + +subtest "check moderation label uses correct name" => sub { + my $REPORT_URL = '/report/' . $reports[0]->id; + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + ALLOWED_COBRANDS => ['hackney'], + COBRAND_FEATURES => { + do_not_reply_email => { + hackney => 'fms-hackney-DO-NOT-REPLY@hackney-example.com', + }, + verp_email_domain => { + hackney => 'hackney-example.com', + }, + }, + }, sub { + $mech->log_out_ok; + $mech->log_in_ok( $hackney_user->email ); + $mech->get_ok($REPORT_URL); + $mech->content_lacks('show-moderation'); + $mech->follow_link_ok({ text_regex => qr/^Moderate$/ }); + $mech->content_contains('show-moderation'); + $mech->submit_form_ok({ with_fields => { + problem_title => 'Good good', + problem_detail => 'Good good improved', + }}); + $mech->base_like( qr{\Q$REPORT_URL\E} ); + $mech->content_like(qr/Moderated by Hackney Council/); + }; +}; + +$_->delete for @reports; + +my $system_user = $mech->create_user_ok('system_user@example.org'); + +my ($p) = $mech->create_problems_for_body(1, $hackney->id, '', { cobrand => 'hackney' }); +my $alert = FixMyStreet::DB->resultset('Alert')->create( { + parameter => $p->id, + alert_type => 'new_updates', + user => $user, + cobrand => 'hackney', +} )->confirm; + +subtest "sends branded alert emails" => sub { + $mech->create_comment_for_problem($p, $system_user, 'Other User', 'This is some update text', 'f', 'confirmed', undef); + $mech->clear_emails_ok; + + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + ALLOWED_COBRANDS => ['hackney','fixmystreet'], + COBRAND_FEATURES => { + do_not_reply_email => { hackney => 'fms-hackney-DO-NOT-REPLY@hackney-example.com' }, + }, + }, sub { + FixMyStreet::Script::Alerts::send(); + }; + + my $email = $mech->get_email; + ok $email, "got an email"; + like $mech->get_text_body_from_email($email), qr/Hackney Council/, "emails are branded"; +}; + +$p->comments->delete; +$p->delete; + +subtest "sends branded confirmation emails" => sub { + $mech->log_out_ok; + $mech->clear_emails_ok; + $mech->get_ok('/?filter_category=Potholes+%26+stuff'); + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'hackney' ], + MAPIT_URL => 'http://mapit.uk/', + COBRAND_FEATURES => { + do_not_reply_email => { + hackney => 'fms-hackney-DO-NOT-REPLY@hackney-example.com', + }, + verp_email_domain => { + hackney => 'hackney-example.com', + }, + }, + }, sub { + $mech->submit_form_ok( { with_fields => { pc => 'E8 1DY', } }, + "submit location" ); + + # While we're here, check the category with an ampersand (regression test) + $mech->content_contains('<option value="Potholes & stuff" selected>'); + + # click through to the report page + $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, + "follow 'skip this step' link" ); + + $mech->submit_form_ok( + { + button => 'submit_register', + with_fields => { + title => 'Test Report', + detail => 'Test report details.', + photo1 => '', + name => 'Joe Bloggs', + username_register => 'test-1@example.com', + category => 'Roads', + } + }, + "submit good details" + ); + + my $email = $mech->get_email; + ok $email, "got an email"; + like $mech->get_text_body_from_email($email), qr/Hackney Council/, "emails are branded"; + + my $url = $mech->get_link_from_email($email); + $mech->get_ok($url); + $mech->clear_emails_ok; + }; +}; + +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 { + #STAGING_FLAGS => { send_reports => 1 }, + #MAPIT_URL => 'http://mapit.uk/', + #ALLOWED_COBRANDS => ['hackney','fixmystreet'], + #}, sub { + #FixMyStreet::Script::Reports::send(); + #}; + #my $email = $mech->get_email; + #ok $email, "got an email"; + #like $mech->get_text_body_from_email($email), qr/Hackney Council/, "emails are branded"; +#}; + +subtest "check category extra uses correct name" => sub { + my @extras = ( { + code => 'test', + datatype => 'string', + description => 'question', + variable => 'true', + required => 'false', + order => 1, + datatype_description => 'datatype', + } ); + $contact2->set_extra_fields( @extras ); + $contact2->update; + + my $extra_details; + + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + ALLOWED_COBRANDS => ['hackney','fixmystreet'], + }, sub { + $extra_details = $mech->get_ok_json('/report/new/category_extras?category=Roads&latitude=51.552267&longitude=-0.063316'); + }; + + like $extra_details->{category_extra}, qr/Hackney Council/, 'correct name in category extras'; +}; + +subtest "can edit special destination email addresses" => sub { + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + ALLOWED_COBRANDS => ['hackney'], + COBRAND_FEATURES => { anonymous_account => { hackney => 'anonymous' } }, + }, sub { + $contact2->update({ send_method => 'Email' }); + $mech->log_in_ok( $hackney_user->email ); + $mech->get_ok("/admin/body/" . $hackney->id . "/" . $contact2->category); + $mech->submit_form_ok( { with_fields => { email => 'park:parks@example.com;estate:estates@example;other:new@example.org' } }, + "submit valid new email address"); + $mech->content_lacks("Please enter a valid email"); + $contact2->discard_changes; + is $contact2->email, 'park:parks@example.com;estate:estates@example;other:new@example.org', "New email addresses saved"; + + $mech->get_ok("/admin/body/" . $hackney->id . "/" . $contact2->category); + $mech->submit_form_ok( { with_fields => { email => 'invalid' } }, + "submit invalid new email address"); + $mech->content_contains("Please enter a valid email"); + $contact2->discard_changes; + is $contact2->email, 'park:parks@example.com;estate:estates@example;other:new@example.org', "Invalid email addresses not saved"; + }; +}; + +done_testing(); diff --git a/t/cobrand/highwaysengland.t b/t/cobrand/highwaysengland.t index f6400ea7c..0b71c613f 100644 --- a/t/cobrand/highwaysengland.t +++ b/t/cobrand/highwaysengland.t @@ -29,12 +29,11 @@ my $highways = $mech->create_body_ok(2234, 'Highways England'); $mech->create_contact_ok(email => 'highways@example.com', body_id => $highways->id, category => 'Pothole'); -# Br1 3UH -subtest "check where heard from saved" => sub { - FixMyStreet::override_config { - ALLOWED_COBRANDS => 'highwaysengland', - MAPIT_URL => 'http://mapit.uk/', - }, sub { +FixMyStreet::override_config { + ALLOWED_COBRANDS => 'highwaysengland', + MAPIT_URL => 'http://mapit.uk/', +}, sub { + subtest "check where heard from saved" => sub { $mech->get_ok('/around'); $mech->submit_form_ok( { with_fields => { pc => 'M1, J16', } }, "submit location" ); $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, @@ -64,7 +63,12 @@ subtest "check where heard from saved" => sub { like $mech->get_text_body_from_email($email), qr/Heard from: Facebook/, 'where hear included in email' }; -}; + subtest "check anonymous display" => sub { + my ($problem) = $mech->create_problems_for_body(1, $highways->id, 'Title'); + $mech->get_ok('/report/' . $problem->id); + $mech->content_lacks('Reported by Test User at'); + }; +}; done_testing(); diff --git a/t/cobrand/hounslow.t b/t/cobrand/hounslow.t index 91c1cb455..e58309925 100644 --- a/t/cobrand/hounslow.t +++ b/t/cobrand/hounslow.t @@ -38,6 +38,15 @@ my ($report) = $mech->create_problems_for_body(1, $hounslow_id, 'A brand new pro cobrand => 'fixmystreet' }); +subtest "showing the front page" => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => 'hounslow', + }, sub { + $mech->get_ok('/'); + $mech->content_contains('completed in past month'); + }; +}; + subtest "it still shows old reports on fixmystreet.com" => sub { FixMyStreet::override_config { MAPIT_URL => 'http://mapit.uk/', diff --git a/t/cobrand/isleofwight.t b/t/cobrand/isleofwight.t index 3cac710da..ad9017e26 100644 --- a/t/cobrand/isleofwight.t +++ b/t/cobrand/isleofwight.t @@ -116,13 +116,24 @@ subtest "only original reporter can comment" => sub { }; }; +subtest "only original reporter can comment" => sub { + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + ALLOWED_COBRANDS => 'fixmystreet', + COBRAND_FEATURES => { updates_allowed => { fixmystreet => { 'Isle of Wight' => 'reporter' } } }, + }, sub { + $mech->log_out_ok; + $mech->get_ok('/report/' . $reports[0]->id); + $mech->content_contains('Only the original reporter may leave updates'); + }; +}; + subtest "check moderation label uses correct name" => sub { my $REPORT_URL = '/report/' . $reports[0]->id; FixMyStreet::override_config { MAPIT_URL => 'http://mapit.uk/', ALLOWED_COBRANDS => ['isleofwight'], }, sub { - $mech->log_out_ok; $mech->log_in_ok( $iow_user->email ); $mech->get_ok($REPORT_URL); $mech->content_lacks('show-moderation'); @@ -470,7 +481,7 @@ subtest "sends branded confirmation emails" => sub { detail => 'Test report details.', photo1 => '', name => 'Joe Bloggs', - username => 'test-1@example.com', + username_register => 'test-1@example.com', category => 'Roads', } }, diff --git a/t/cobrand/northamptonshire.t b/t/cobrand/northamptonshire.t index 57fe319a9..36a2c4638 100644 --- a/t/cobrand/northamptonshire.t +++ b/t/cobrand/northamptonshire.t @@ -52,7 +52,7 @@ $ncc->update( { comment_user_id => $counciluser->id } ); subtest 'Check district categories hidden on cobrand' => sub { FixMyStreet::override_config { - ALLOWED_COBRANDS => [ { northamptonshire => '.' } ], + ALLOWED_COBRANDS=> 'northamptonshire', MAPIT_URL => 'http://mapit.uk/', }, sub { $mech->get_ok( '/around' ); @@ -70,7 +70,7 @@ subtest 'Check district categories hidden on cobrand' => sub { subtest 'Check updates not sent for defects' => sub { FixMyStreet::override_config { - ALLOWED_COBRANDS => [ { northamptonshire => '.' } ], + ALLOWED_COBRANDS=> 'northamptonshire', MAPIT_URL => 'http://mapit.uk/', }, sub { my $updates = Open311::PostServiceRequestUpdates->new(); @@ -86,7 +86,7 @@ $report->update({ user => $user }); $comment->update({ extra => undef }); subtest 'check updates sent for non defects' => sub { FixMyStreet::override_config { - ALLOWED_COBRANDS => [ { northamptonshire => '.' } ], + ALLOWED_COBRANDS=> 'northamptonshire', MAPIT_URL => 'http://mapit.uk/', }, sub { my $updates = Open311::PostServiceRequestUpdates->new(); @@ -107,6 +107,182 @@ subtest 'check updates disallowed correctly' => sub { is $cobrand->updates_disallowed($report), 1; }; +subtest 'check further investigation state' => sub { + $comment->problem_state('investigating'); + $comment->update(); + + FixMyStreet::override_config { + ALLOWED_COBRANDS=> 'northamptonshire', + MAPIT_URL => 'http://mapit.uk/', + COBRAND_FEATURES => { + extra_state_mapping => { + northamptonshire => { + investigating => { + further => 'Under further investigation' + } + } + } + } + }, sub { + $mech->get_ok('/report/' . $comment->problem_id); + }; + + $mech->content_lacks('Under further investigation'); + + $comment->set_extra_metadata('external_status_code' => 'further'); + $comment->update; + + FixMyStreet::override_config { + ALLOWED_COBRANDS=> 'northamptonshire', + MAPIT_URL => 'http://mapit.uk/', + COBRAND_FEATURES => { + extra_state_mapping => { + northamptonshire => { + investigating => { + further => 'Under further investigation' + } + } + } + } + }, sub { + $mech->get_ok('/report/' . $comment->problem_id); + }; + + $mech->content_contains('Under further investigation'); + + FixMyStreet::override_config { + ALLOWED_COBRANDS=> 'northamptonshire', + MAPIT_URL => 'http://mapit.uk/', + COBRAND_FEATURES => { + extra_state_mapping => { + northamptonshire => { + fixed => { + further => 'Under further investigation' + } + }, + fixmystreet => { + 'Northamptonshire County Council' => { + fixed => { + further => 'Under further investigation' + } + } + } + } + } + }, sub { + $mech->get_ok('/report/' . $comment->problem_id); + }; + + $mech->content_contains('Investigating'); + $mech->content_lacks('Under further investigation'); + + FixMyStreet::override_config { + ALLOWED_COBRANDS=> 'northamptonshire', + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $mech->get_ok('/report/' . $comment->problem_id); + }; + + $mech->content_contains('Investigating'); + $mech->content_lacks('Under further investigation'); + + FixMyStreet::override_config { + ALLOWED_COBRANDS=> 'fixmystreet', + MAPIT_URL => 'http://mapit.uk/', + COBRAND_FEATURES => { + extra_state_mapping => { + northamptonshire => { + investigating => { + further => 'Under further investigation' + } + }, + fixmystreet => { + 'Northamptonshire County Council' => { + investigating => { + further => 'Under further investigation' + } + } + } + } + } + }, sub { + $mech->get_ok('/report/' . $comment->problem_id); + }; + + $mech->content_contains('Under further investigation'); + + FixMyStreet::override_config { + ALLOWED_COBRANDS=> 'fixmystreet', + MAPIT_URL => 'http://mapit.uk/', + COBRAND_FEATURES => { + extra_state_mapping => { + northamptonshire => { + fixed => { + further => 'Under further investigation' + } + }, + fixmystreet => { + 'Northamptonshire County Council' => { + fixed => { + further => 'Under further investigation' + } + } + } + } + } + }, sub { + $mech->get_ok('/report/' . $comment->problem_id); + }; + + $mech->content_contains('Investigating'); + $mech->content_lacks('Under further investigation'); + + FixMyStreet::override_config { + ALLOWED_COBRANDS=> 'fixmystreet', + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $mech->get_ok('/report/' . $comment->problem_id); + }; + + $mech->content_contains('Investigating'); + $mech->content_lacks('Under further investigation'); + + $comment->set_extra_metadata('external_status_code' => ''); + $comment->update; + my $comment2 = FixMyStreet::DB->resultset('Comment')->create( { + mark_fixed => 0, + user => $user, + problem => $report, + anonymous => 0, + text => 'this is a comment', + confirmed => DateTime->now, + state => 'confirmed', + problem_state => 'investigating', + cobrand => 'default', + } ); + $comment2->set_extra_metadata('external_status_code' => 'further'); + $comment2->update; + + FixMyStreet::override_config { + ALLOWED_COBRANDS=> 'northamptonshire', + MAPIT_URL => 'http://mapit.uk/', + COBRAND_FEATURES => { + extra_state_mapping => { + northamptonshire => { + investigating => { + further => 'Under further investigation' + } + } + } + } + }, sub { + $mech->get_ok('/report/' . $comment->problem_id); + }; + + $mech->content_contains('Investigating'); + $mech->content_contains('Under further investigation'); +}; + subtest 'check pin colour / reference shown' => sub { FixMyStreet::override_config { ALLOWED_COBRANDS => 'northamptonshire', diff --git a/t/cobrand/oxfordshire.t b/t/cobrand/oxfordshire.t index 65c6a3864..a1c842e2d 100644 --- a/t/cobrand/oxfordshire.t +++ b/t/cobrand/oxfordshire.t @@ -1,7 +1,10 @@ use Test::MockModule; +use CGI::Simple; use FixMyStreet::TestMech; use FixMyStreet::Script::Alerts; +use FixMyStreet::Script::Reports; +use Open311; my $mech = FixMyStreet::TestMech->new; my $oxon = $mech->create_body_ok(2237, 'Oxfordshire County Council'); @@ -50,6 +53,7 @@ subtest 'check /around?ajax defaults to open reports only' => sub { my @problems = FixMyStreet::DB->resultset('Problem')->search({}, { rows => 3, order_by => 'id' })->all; FixMyStreet::override_config { + STAGING_FLAGS => { send_reports => 1, skip_checks => 1 }, ALLOWED_COBRANDS => 'oxfordshire', MAPIT_URL => 'http://mapit.uk/', }, sub { @@ -63,10 +67,10 @@ FixMyStreet::override_config { is $mech->uri->path, '/report/' . $problem->id, 'redirects to report'; }; - subtest 'check unable to fix label' => sub { - my $user = $mech->create_user_ok( 'user@example.com', name => 'Test User' ); - my $user2 = $mech->create_user_ok( 'user2@example.com', name => 'Test User2' ); + my $user = $mech->create_user_ok( 'user@example.com', name => 'Test User' ); + my $user2 = $mech->create_user_ok( 'user2@example.com', name => 'Test User2' ); + subtest 'check unable to fix label' => sub { my $problem = $problems[0]; $problem->state( 'unable to fix' ); $problem->update; @@ -128,6 +132,103 @@ FixMyStreet::override_config { is $rows[2]->[20], '', 'Report without HIAMS ref has empty ref field'; is $rows[3]->[20], '123098123', 'Older Exor report has correct ref'; }; + + $oxon->update({ + send_method => 'Open311', + endpoint => 'endpoint', + api_key => 'key', + jurisdiction => 'home', + }); + my $contact = $mech->create_contact_ok( body_id => $oxon->id, category => 'Gullies and Catchpits', email => 'GC' ); + $contact->set_extra_fields( ( + { code => 'feature_id', datatype => 'hidden', variable => 'true' }, + { code => 'usrn', datatype => 'hidden', variable => 'true' }, + ) ); + $contact->update; + FixMyStreet::Script::Reports::send(); # Make sure no waiting reports + + for my $test ( + { + field => 'feature_id', + value => '12345', + text => 'Asset Id', + }, + ) { + subtest 'Check special Open311 request handling of ' . $test->{text}, sub { + my ($p) = $mech->create_problems_for_body( 1, $oxon->id, 'Test', { + cobrand => 'oxfordshire', + category => 'Gullies and Catchpits', + user => $user, + latitude => 51.754926, + longitude => -1.256179, + }); + $p->set_extra_fields({ name => $test->{field}, value => $test->{value}}); + $p->update; + + my $test_data = FixMyStreet::Script::Reports::send(); + + $p->discard_changes; + ok $p->whensent, 'Report marked as sent'; + is $p->send_method_used, 'Open311', 'Report sent via Open311'; + is $p->external_id, 248, 'Report has right external ID'; + unlike $p->detail, qr/$test->{text}:/, $test->{text} . ' not saved to report detail'; + + my $req = $test_data->{test_req_used}; + my $c = CGI::Simple->new($req->content); + like $c->param('description'), qr/$test->{text}: $test->{value}/, $test->{text} . ' included in body'; + }; + } + + subtest 'extra data sent with defect update' => sub { + my $comment = FixMyStreet::DB->resultset('Comment')->first; + $comment->set_extra_metadata(defect_raised => 1); + $comment->update; + $comment->problem->external_id('hey'); + $comment->problem->set_extra_metadata(defect_location_description => 'Location'); + $comment->problem->set_extra_metadata(defect_item_category => 'Kerbing'); + $comment->problem->set_extra_metadata(defect_item_type => 'Damaged'); + $comment->problem->set_extra_metadata(defect_item_detail => '1 kerb unit or 1 linear m'); + $comment->problem->set_extra_metadata(traffic_information => 'Signs and Cones'); + $comment->problem->set_extra_metadata(detailed_information => '100x100'); + $comment->problem->update; + + my $cbr = Test::MockModule->new('FixMyStreet::Cobrand::Oxfordshire'); + $cbr->mock('_fetch_features', sub { + my ($self, $cfg, $x, $y) = @_; + [ { + type => 'Feature', + geometry => { type => 'LineString', coordinates => [ [ 1, 2 ], [ 3, 4 ] ] }, + properties => { TYPE1_2_USRN => 13579 }, + } ]; + }); + my $test_res = HTTP::Response->new(); + $test_res->code(200); + $test_res->message('OK'); + $test_res->content('<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>'); + + my $o = Open311->new( + fixmystreet_body => $oxon, + test_mode => 1, + test_get_returns => { 'servicerequestupdates.xml' => $test_res }, + ); + + $o->post_service_request_update($comment); + my $cgi = CGI::Simple->new($o->test_req_used->content); + is $cgi->param('attribute[usrn]'), 13579, 'USRN sent with update'; + is $cgi->param('attribute[raise_defect]'), 1, 'Defect flag sent with update'; + is $cgi->param('attribute[defect_item_category]'), 'Kerbing'; + is $cgi->param('attribute[extra_details]'), $user2->email . ' TM1 Damaged 100x100'; + + # Now set a USRN on the problem (found at submission) + $comment->problem->push_extra_fields({ name => 'usrn', value => '12345' }); + $comment->problem->update; + + $o->post_service_request_update($comment); + $cgi = CGI::Simple->new($o->test_req_used->content); + is $cgi->param('attribute[usrn]'), 12345, 'USRN sent with update'; + is $cgi->param('attribute[raise_defect]'), 1, 'Defect flag sent with update'; + }; + }; done_testing(); diff --git a/t/cobrand/peterborough.t b/t/cobrand/peterborough.t index 5d07acb9f..f7e45f190 100644 --- a/t/cobrand/peterborough.t +++ b/t/cobrand/peterborough.t @@ -64,7 +64,7 @@ subtest "extra update params are sent to open311" => sub { test_get_returns => { 'servicerequestupdates.xml' => $test_res }, ); - my ($p) = $mech->create_problems_for_body(1, $peterborough->id, 'Title', { external_id => 1, category => 'Trees' }); + my ($p) = $mech->create_problems_for_body(1, $peterborough->id, 'Title', { external_id => 1, category => 'Trees', whensent => DateTime->now }); my $c = FixMyStreet::DB->resultset('Comment')->create({ problem => $p, user => $p->user, anonymous => 't', text => 'Update text', @@ -81,4 +81,83 @@ subtest "extra update params are sent to open311" => sub { }; }; +subtest "bartec report with no gecode handled correctly" => sub { + FixMyStreet::override_config { + STAGING_FLAGS => { send_reports => 1 }, + MAPIT_URL => 'http://mapit.uk/', + ALLOWED_COBRANDS => 'peterborough', + }, sub { + my $contact = $mech->create_contact_ok(body_id => $peterborough->id, category => 'Bins', email => 'Bartec-Bins'); + my ($p) = $mech->create_problems_for_body(1, $peterborough->id, 'Title', { category => 'Bins', latitude => 52.5608, longitude => 0.2405, cobrand => 'peterborough' }); + + my $test_data = FixMyStreet::Script::Reports::send(); + + $p->discard_changes; + ok $p->whensent, 'Report marked as sent'; + + my $req = $test_data->{test_req_used}; + my $cgi = CGI::Simple->new($req->content); + is $cgi->param('attribute[postcode]'), undef, 'postcode param not set'; + is $cgi->param('attribute[house_no]'), undef, 'house_no param not set'; + is $cgi->param('attribute[street]'), undef, 'street param not set'; + }; +}; + +subtest "extra bartec params are sent to open311" => sub { + FixMyStreet::override_config { + STAGING_FLAGS => { send_reports => 1 }, + MAPIT_URL => 'http://mapit.uk/', + ALLOWED_COBRANDS => 'peterborough', + }, sub { + my ($p) = $mech->create_problems_for_body(1, $peterborough->id, 'Title', { + category => 'Bins', + latitude => 52.5608, + longitude => 0.2405, + cobrand => 'peterborough', + geocode => { + resourceSets => [ { + resources => [ { + name => '12 A Street, XX1 1SZ', + address => { + addressLine => '12 A Street', + postalCode => 'XX1 1XZ' + } + } ] + } ] + }, + extra => { + _fields => [ + { name => 'site_code', value => '12345', }, + ], + }, + } ); + + my $test_data = FixMyStreet::Script::Reports::send(); + + $p->discard_changes; + ok $p->whensent, 'Report marked as sent'; + + my $req = $test_data->{test_req_used}; + my $cgi = CGI::Simple->new($req->content); + is $cgi->param('attribute[postcode]'), 'XX1 1XZ', 'postcode param sent'; + is $cgi->param('attribute[house_no]'), '12', 'house_no param sent'; + is $cgi->param('attribute[street]'), 'A Street', 'street param sent'; + }; +}; + +subtest 'Dashboard CSV extra columns' => sub { + my $staffuser = $mech->create_user_ok('counciluser@example.com', name => 'Council User', + from_body => $peterborough, password => 'password'); + $mech->log_in_ok( $staffuser->email ); + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + ALLOWED_COBRANDS => 'peterborough', + }, sub { + $mech->get_ok('/dashboard?export=1'); + }; + $mech->content_contains('"Reported As",USRN,"Nearest address"'); + $mech->content_contains('peterborough,,12345,"12 A Street, XX1 1SZ"'); +}; + + done_testing; diff --git a/t/cobrand/tfl.t b/t/cobrand/tfl.t index 8ddc3d671..142c7c14e 100644 --- a/t/cobrand/tfl.t +++ b/t/cobrand/tfl.t @@ -23,6 +23,10 @@ FixMyStreet::DB->resultset('BodyArea')->find_or_create({ area_id => 2457, # Epsom Ewell, outside London, for bus stop test body_id => $body->id, }); +FixMyStreet::DB->resultset('BodyArea')->find_or_create({ + area_id => 2508, # Hackney + body_id => $body->id, +}); my $superuser = $mech->create_user_ok('superuser@example.com', name => 'Super User', is_superuser => 1); my $staffuser = $mech->create_user_ok('counciluser@example.com', name => 'Council User', from_body => $body, password => 'password'); $staffuser->user_body_permissions->create({ @@ -58,6 +62,13 @@ my $bromley_flytipping = $mech->create_contact_ok( $bromley_flytipping->set_extra_metadata(group => [ 'Street cleaning' ]); $bromley_flytipping->update; +my $hackney = $mech->create_body_ok(2508, 'Hackney Council'); +$mech->create_contact_ok( + body_id => $hackney->id, + category => 'Abandoned Vehicle', + email => 'av-hackney@example.com', +); + my $contact1 = $mech->create_contact_ok( body_id => $body->id, category => 'Bus stops', @@ -188,6 +199,7 @@ FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'tfl', 'bromley', 'fixmystreet'], MAPIT_URL => 'http://mapit.uk/', COBRAND_FEATURES => { + category_groups => { tfl => 1 }, internal_ips => { tfl => [ '127.0.0.1' ] }, base_url => { tfl => 'https://street.tfl' @@ -413,6 +425,7 @@ subtest 'Dashboard CSV extra columns' => sub { $mech->get_ok('/dashboard?export=1&category=Bus+stops'); $mech->content_contains('Category,Subcategory'); $mech->content_contains('Query,Borough'); + $mech->content_contains(',Acknowledged,"Action scheduled",Fixed'); $mech->content_contains(',"Safety critical","Delivered to","Closure email at","Reassigned at","Reassigned by","Is the pole leaning?"'); $mech->content_contains('"Bus things","Bus stops"'); $mech->content_contains('"BR1 3UH",Bromley,'); @@ -430,10 +443,17 @@ subtest 'Dashboard CSV extra columns' => sub { admin_user => $staffuser->name, user => $staffuser, }); + FixMyStreet::DB->resultset('Comment')->create({ + problem => $report, user => $report->user, anonymous => 't', text => 'Update text', + problem_state => 'action scheduled', state => 'confirmed', mark_fixed => 0, + confirmed => $dt, + }); $mech->get_ok('/dashboard?export=1'); $mech->content_contains('Query,Borough'); + $mech->content_contains(',Acknowledged,"Action scheduled",Fixed'); $mech->content_contains(',"Safety critical","Delivered to","Closure email at","Reassigned at","Reassigned by"'); $mech->content_contains('(anonymous ' . $report->id . ')'); + $mech->content_contains($dt . ',,,confirmed,51.4021'); $mech->content_contains(',,,yes,busstops@example.com,,' . $dt . ',"Council User"'); }; @@ -442,7 +462,8 @@ subtest 'Inspect form state choices' => sub { my $id = $report->id; $mech->get_ok("/report/$id"); $mech->content_lacks('for triage'); - $mech->content_lacks('action scheduled'); + $mech->content_lacks('planned'); + $mech->content_lacks('investigating'); }; subtest "change category, report resent to new location" => sub { @@ -747,7 +768,7 @@ subtest 'Test no questionnaire sending' => sub { }; FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'tfl', 'bromley', 'fixmystreet' ], + ALLOWED_COBRANDS => [ 'tfl', 'bromley', 'fixmystreet', 'hackney' ], MAPIT_URL => 'http://mapit.uk/', COBRAND_FEATURES => { internal_ips => { tfl => [ '127.0.0.1' ] }, @@ -863,6 +884,21 @@ for my $test ( 'Trees' ], }, + { + host => 'hackney.fixmystreet.com', + name => "test no hackney categories on red route", + lat => 51.552287, + lon => -0.063326, + expected => [ + 'Bus stops', + 'Flooding', + 'Grit bins', + 'Pothole', + 'Timings', + 'Traffic lights', + 'Trees' + ], + }, ) { subtest $test->{name} . ' on ' . $test->{host} => sub { $mech->host($test->{host}); diff --git a/t/cobrand/zurich.t b/t/cobrand/zurich.t index 8c5acddca..c73bd01e1 100644 --- a/t/cobrand/zurich.t +++ b/t/cobrand/zurich.t @@ -14,6 +14,9 @@ use FixMyStreet::Script::Reports; use FixMyStreet::TestMech; my $mech = FixMyStreet::TestMech->new; +FixMyStreet::App->log->disable('info'); +END { FixMyStreet::App->log->enable('info'); } + # Check that you have the required locale installed - the following # should return a line with de_CH.utf8 in. If not install that locale. # @@ -98,7 +101,7 @@ my $superuser; subtest "set up superuser" => sub { $superuser = $mech->log_in_ok( 'super@example.org' ); # a user from body $zurich is a superuser, as $zurich has no parent id! - $superuser->update({ from_body => $zurich->id }); + $superuser->update({ name => 'Superuser', from_body => $zurich->id }); $EXISTING_REPORT_COUNT = get_export_rows_count($mech); $mech->log_out_ok; }; @@ -747,29 +750,74 @@ subtest "superuser and dm can see stats" => sub { $user = $mech->log_in_ok( 'dm1@example.org' ); $mech->get( '/admin/stats' ); is $mech->res->code, 200, "dm can now also see stats page"; - $mech->log_out_ok; }; subtest "only superuser can edit bodies" => sub { - $user = $mech->log_in_ok( 'dm1@example.org' ); $mech->get( '/admin/body/' . $zurich->id ); is $mech->res->code, 403, "only superuser should be able to edit bodies"; - $mech->log_out_ok; }; subtest "only superuser can see 'Add body' form" => sub { - $user = $mech->log_in_ok( 'dm1@example.org' ); $mech->get_ok( '/admin/bodies' ); $mech->content_contains('External Body'); $mech->content_lacks( '<form method="post" action="bodies"' ); - $mech->log_out_ok; }; subtest "phone number is mandatory" => sub { - $user = $mech->log_in_ok( 'dm1@example.org' ); $mech->get_ok( '/report/new?lat=47.381817&lon=8.529156' ); $mech->submit_form( with_fields => { phone => "" } ); $mech->content_contains( 'Diese Information wird benötigt' ); +}; + +my $internal; +subtest 'test flagged users make internal reports' => sub { + $user->update({ flagged => 1 }); + $mech->submit_form( with_fields => { phone => "01234", category => 'Cat1', detail => 'Details' } ); + $internal = FixMyStreet::DB->resultset('Problem')->search(undef, { order_by => { -desc => 'id' }, rows => 1 })->single; + is $internal->non_public, 1; + $mech->clear_emails_ok; +}; + +subtest 'internal report admin display' => sub { + $mech->get_ok('/admin/summary'); + $mech->content_lacks('href="report_edit/' . $internal->id); + $mech->get_ok('/admin/summary?internal=1'); + $mech->content_contains('href="report_edit/' . $internal->id); +}; + +subtest 'test no email sent if closed' => sub { + $internal->state('feedback pending'); + $internal->set_extra_metadata('email_confirmed' => 1); + $internal->update; + + $mech->get_ok( '/admin/report_edit/' . $internal->id ); + $mech->submit_form_ok( { + button => 'publish_response', + with_fields => { + status_update => 'Testing no email sent', + } }); + + $internal->discard_changes; + is $internal->state, 'fixed - council'; + $mech->email_count_is(0); +}; + +subtest 'SDM closing internal report' => sub { + $mech->log_in_ok('sdm1@example.org'); + $internal->update({ bodies_str => $subdivision->id, state => 'confirmed' }); + $mech->get_ok('/admin/report_edit/' . $internal->id); + $mech->submit_form_ok( { form_number => 2, button => 'no_more_updates' } ); + $internal->discard_changes; + is $internal->state, 'fixed - council', 'State updated'; +}; + +subtest 'remove internal flag' => sub { + $internal->update({ bodies_str => $subdivision->id, state => 'confirmed' }); + $mech->get_ok('/admin/report_edit/' . $internal->id); + $mech->submit_form_ok( { form_number => 2, button => 'stop_internal' } ); + $internal->discard_changes; + is $internal->non_public, 0; + $internal->delete; $mech->log_out_ok; }; @@ -859,7 +907,7 @@ subtest "photo must be supplied for categories that require it" => sub { $mech->get_ok('/report/new?lat=47.381817&lon=8.529156'); $mech->submit_form_ok({ with_fields => { detail => 'Problem-Bericht', - username => 'user@example.org', + username_register => 'user@example.org', category => 'Graffiti - photo required', }}); is $mech->res->code, 200, "missing photo shouldn't return anything but 200"; @@ -995,6 +1043,15 @@ $mech->log_out_ok; subtest 'users at the top level can be edited' => sub { $mech->log_in_ok( $superuser->email ); $mech->get_ok('/admin/users/' . $superuser->id ); + $mech->content_contains('name="flagged">'); + $mech->submit_form_ok({ with_fields => { flagged => 1 } }); + $superuser->discard_changes; + is $superuser->flagged, 1, 'Marked as flagged'; + $mech->get_ok('/admin/users/' . $superuser->id ); + $mech->content_contains('name="flagged" checked'); + $mech->submit_form_ok({ with_fields => { flagged => 0 } }); + $superuser->discard_changes; + is $superuser->flagged, 0, 'Unmarked'; }; subtest 'A visit to /reports is okay' => sub { |