aboutsummaryrefslogtreecommitdiffstats
path: root/t/cobrand
diff options
context:
space:
mode:
Diffstat (limited to 't/cobrand')
-rw-r--r--t/cobrand/bathnes.t42
-rw-r--r--t/cobrand/bexley.t281
-rw-r--r--t/cobrand/bristol.t10
-rw-r--r--t/cobrand/bromley.t7
-rw-r--r--t/cobrand/bucks.t121
-rw-r--r--t/cobrand/cheshireeast.t129
-rw-r--r--t/cobrand/councils.t68
-rw-r--r--t/cobrand/eastsussex.t42
-rw-r--r--t/cobrand/features.t20
-rw-r--r--t/cobrand/fixmystreet.t31
-rw-r--r--t/cobrand/form_extras.t2
-rw-r--r--t/cobrand/greenwich.t25
-rw-r--r--t/cobrand/highwaysengland.t70
-rw-r--r--t/cobrand/hounslow.t101
-rw-r--r--t/cobrand/isleofwight.t628
-rw-r--r--t/cobrand/national_assets.t1
-rw-r--r--t/cobrand/northamptonshire.t126
-rw-r--r--t/cobrand/oxfordshire.t223
-rw-r--r--t/cobrand/peterborough.t84
-rw-r--r--t/cobrand/restriction.t5
-rw-r--r--t/cobrand/staging.t18
-rw-r--r--t/cobrand/tfl.t1089
-rw-r--r--t/cobrand/westminster.t259
-rw-r--r--t/cobrand/zurich.t1100
-rw-r--r--t/cobrand/zurich_attachments.txt4
25 files changed, 3668 insertions, 818 deletions
diff --git a/t/cobrand/bathnes.t b/t/cobrand/bathnes.t
index 6586dcb96..006dd757d 100644
--- a/t/cobrand/bathnes.t
+++ b/t/cobrand/bathnes.t
@@ -1,6 +1,10 @@
+use Test::MockModule;
use FixMyStreet::TestMech;
my $mech = FixMyStreet::TestMech->new;
+my $cobrand = Test::MockModule->new('FixMyStreet::Cobrand::BathNES');
+$cobrand->mock('area_types', sub { [ 'UTA' ] });
+
my $body = $mech->create_body_ok(2551, 'Bath and North East Somerset Council');
my @cats = ('Litter', 'Other', 'Potholes', 'Traffic lights');
for my $contact ( @cats ) {
@@ -11,7 +15,7 @@ my $counciluser = $mech->create_user_ok('counciluser@example.com', name => 'Coun
my $normaluser = $mech->create_user_ok('normaluser@example.com', name => 'Normal User');
$normaluser->update({ phone => "+447123456789" });
-$mech->create_problems_for_body(1, $body->id, 'Title', {
+my ($problem) = $mech->create_problems_for_body(1, $body->id, 'Title', {
areas => ",2651,", category => 'Potholes', cobrand => 'fixmystreet',
user => $normaluser, service => 'iOS', extra => {
_fields => [
@@ -59,6 +63,19 @@ subtest 'cobrand displays council name' => sub {
$mech->content_like( qr/Bath and North East Somerset\b/ );
};
+subtest 'check override contact display name' => sub {
+ $mech->log_in_ok( $superuser->email );
+ $mech->get_ok("/admin/body/" . $body->id . '/Litter');
+ $mech->content_contains('<h1>Litter</h1>');
+ $mech->content_contains('extra[display_name]');
+ $mech->submit_form_ok({ with_fields => {
+ 'extra[display_name]' => 'Wittering'
+ }});
+ $mech->get_ok('/reports/Bath+and+North+East+Somerset');
+ $mech->content_like(qr/Traffic lights<\/option>\s*<option value="Litter">\s*Wittering<\/option>/);
+ $mech->content_lacks('Litter</option>');
+};
+
subtest 'extra CSV columns are absent if permission not granted' => sub {
$mech->log_in_ok( $counciluser->email );
@@ -156,28 +173,28 @@ subtest 'extra CSV columns are present if permission granted' => sub {
is $rows[1]->[18], 'iOS', 'Site Used shows whether report made via app';
is $rows[1]->[19], '', 'Reported As is empty if not made on behalf of another user/body';
- is $rows[1]->[20], 'normaluser@example.com', 'User email is correct';
+ is $rows[1]->[20], $normaluser->email, 'User email is correct';
is $rows[1]->[21], '+447123456789', 'User phone number is correct';
is $rows[1]->[22], '', 'Staff User is empty if not made on behalf of another user';
is $rows[1]->[23], 'width = 10cm; depth = 25cm', 'Attribute Data is correct';
is $rows[2]->[18], 'bathnes', 'Site Used shows correct cobrand';
is $rows[2]->[19], 'body', 'Reported As is correct if made on behalf of body';
- is $rows[2]->[20], 'counciluser@example.com', 'User email is correct';
+ is $rows[2]->[20], $counciluser->email, 'User email is correct';
is $rows[2]->[21], '', 'User phone number is correct';
is $rows[2]->[22], '', 'Staff User is empty if not made on behalf of another user';
is $rows[2]->[23], '', 'Attribute Data is correct';
is $rows[3]->[18], 'bathnes', 'Site Used shows correct cobrand';
is $rows[3]->[19], 'another_user', 'Reported As is set if reported on behalf of another user';
- is $rows[3]->[20], 'normaluser@example.com', 'User email is correct';
+ is $rows[3]->[20], $normaluser->email, 'User email is correct';
is $rows[3]->[21], '+447123456789', 'User phone number is correct';
- is $rows[3]->[22], 'counciluser@example.com', 'Staff User is correct if made on behalf of another user';
+ is $rows[3]->[22], $counciluser->email, 'Staff User is correct if made on behalf of another user';
is $rows[3]->[23], '', 'Attribute Data is correct';
is $rows[4]->[18], 'bathnes', 'Site Used shows correct cobrand';
is $rows[4]->[19], 'anonymous_user', 'Reported As is set if reported on behalf of another user';
- is $rows[4]->[20], 'counciluser@example.com', 'User email is correct';
+ is $rows[4]->[20], $counciluser->email, 'User email is correct';
is $rows[4]->[21], '', 'User phone number is correct';
is $rows[4]->[22], '', 'Staff User is empty if not made on behalf of another user';
is $rows[4]->[23], '', 'Attribute Data is correct';
@@ -199,4 +216,17 @@ subtest 'extra CSV columns are present if permission granted' => sub {
};
+subtest 'check cobrand correctly reset on each request' => sub {
+ FixMyStreet::override_config {
+ 'ALLOWED_COBRANDS' => [ 'bathnes', 'fixmystreet' ],
+ }, sub {
+ $mech->log_in_ok( $superuser->email );
+ $mech->host('www.fixmystreet.com');
+ $mech->get_ok( '/contact?id=' . $problem->id );
+ $mech->host('bathnes.fixmystreet.com');
+ $mech->get_ok( '/contact?reject=1&id=' . $problem->id );
+ $mech->content_contains('Reject report');
+ }
+};
+
done_testing();
diff --git a/t/cobrand/bexley.t b/t/cobrand/bexley.t
new file mode 100644
index 000000000..352e61389
--- /dev/null
+++ b/t/cobrand/bexley.t
@@ -0,0 +1,281 @@
+use CGI::Simple;
+use Test::MockModule;
+use Test::MockTime qw(:all);
+use FixMyStreet::TestMech;
+use FixMyStreet::Script::Reports;
+use Catalyst::Test 'FixMyStreet::App';
+
+set_fixed_time('2019-10-16T17:00:00Z'); # Out of hours
+
+use_ok 'FixMyStreet::Cobrand::Bexley';
+use_ok 'FixMyStreet::Geocode::Bexley';
+
+my $ukc = Test::MockModule->new('FixMyStreet::Cobrand::UKCouncils');
+$ukc->mock('lookup_site_code', sub {
+ my ($self, $row, $buffer) = @_;
+ is $row->latitude, 51.408484, 'Correct latitude';
+ return "Road ID";
+});
+
+FixMyStreet::override_config {
+ COBRAND_FEATURES => {
+ contact_email => {
+ bexley => 'foo@bexley',
+ }
+ },
+}, sub {
+ my $cobrand = FixMyStreet::Cobrand::Bexley->new;
+ like $cobrand->contact_email, qr/bexley/;
+ is $cobrand->on_map_default_status, 'open';
+ is_deeply $cobrand->disambiguate_location->{bounds}, [ 51.408484, 0.074653, 51.515542, 0.2234676 ];
+};
+
+my $mech = FixMyStreet::TestMech->new;
+
+my $body = $mech->create_body_ok(2494, 'London Borough of Bexley', {
+ send_method => 'Open311', api_key => 'key', 'endpoint' => 'e', 'jurisdiction' => 'j' });
+$mech->create_contact_ok(body_id => $body->id, category => 'Abandoned and untaxed vehicles', email => "ConfirmABAN");
+$mech->create_contact_ok(body_id => $body->id, category => 'Lamp post', email => "StreetLightingLAMP");
+$mech->create_contact_ok(body_id => $body->id, category => 'Gulley covers', email => "GULL");
+$mech->create_contact_ok(body_id => $body->id, category => 'Damaged road', email => "ROAD");
+$mech->create_contact_ok(body_id => $body->id, category => 'Flooding in the road', email => "ConfirmFLOD");
+$mech->create_contact_ok(body_id => $body->id, category => 'Flytipping', email => "UniformFLY");
+$mech->create_contact_ok(body_id => $body->id, category => 'Dead animal', email => "ANIM");
+$mech->create_contact_ok(body_id => $body->id, category => 'Street cleaning and litter', email => "STREET");
+my $category = $mech->create_contact_ok(body_id => $body->id, category => 'Something dangerous', email => "DANG");
+$category->set_extra_metadata(group => 'Danger things');
+$category->update;
+
+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',
+ } } },
+}, sub {
+
+ subtest 'cobrand displays council name' => sub {
+ ok $mech->host("bexley.fixmystreet.com"), "change host to bexley";
+ $mech->get_ok('/');
+ $mech->content_contains('Bexley');
+ };
+
+ subtest 'cobrand displays council name' => sub {
+ $mech->get_ok('/reports/Bexley');
+ $mech->content_contains('Bexley');
+ };
+
+ my $report;
+ foreach my $test (
+ { category => 'Abandoned and untaxed vehicles', email => ['p1confirm'], code => 'ConfirmABAN',
+ extra => { 'name' => 'burnt', description => 'Was it burnt?', 'value' => 'Yes' } },
+ { category => 'Abandoned and untaxed vehicles', code => 'ConfirmABAN',
+ extra => { 'name' => 'burnt', description => 'Was it burnt?', 'value' => 'No' } },
+ { category => 'Dead animal', email => ['p1', 'outofhours', 'ooh2'], code => 'ANIM' },
+ { category => 'Something dangerous', email => ['p1', 'outofhours', 'ooh2'], code => 'DANG',
+ extra => { 'name' => 'dangerous', description => 'Was it dangerous?', 'value' => 'Yes' } },
+ { category => 'Something dangerous', code => 'DANG',
+ extra => { 'name' => 'dangerous', description => 'Was it dangerous?', 'value' => 'No' } },
+ { category => 'Street cleaning and litter', email => ['p1', 'outofhours', 'ooh2'], code => 'STREET',
+ extra => { 'name' => 'reportType', description => 'Type of report', 'value' => 'Oil spillage' } },
+ { category => 'Gulley covers', email => ['p1', 'outofhours', 'ooh2'], code => 'GULL',
+ extra => { 'name' => 'reportType', description => 'Type of report', 'value' => 'Cover missing' } },
+ { category => 'Gulley covers', code => 'GULL',
+ extra => { 'name' => 'reportType', description => 'Type of report', 'value' => 'Cover damaged' } },
+ { category => 'Gulley covers', email => ['p1', 'outofhours', 'ooh2'], code => 'GULL',
+ extra => { 'name' => 'dangerous', description => 'Was it dangerous?', 'value' => 'Yes' } },
+ { category => 'Damaged road', code => 'ROAD', email => ['p1', 'outofhours', 'ooh2'],
+ extra => { 'name' => 'dangerous', description => 'Was it dangerous?', 'value' => 'No' } },
+ { category => 'Damaged road', code => 'ROAD', email => ['p1', 'outofhours', 'ooh2'],
+ extra => { 'name' => 'dangerous', description => 'Was it dangerous?', 'value' => 'Yes' } },
+ { category => 'Lamp post', code => 'StreetLightingLAMP', email => ['thirdparty', 'another'],
+ extra => { 'name' => 'dangerous', description => 'Was it dangerous?', 'value' => 'No' } },
+ { category => 'Lamp post', code => 'StreetLightingLAMP', email => ['thirdparty', 'another'],
+ extra => { 'name' => 'dangerous', description => 'Was it dangerous?', 'value' => 'Yes' } },
+ { category => 'Flytipping', code => 'UniformFLY', email => ['eh'] },
+ { category => 'Flooding in the road', code => 'ConfirmFLOD', email => ['flooding'] },
+ ) {
+ ($report) = $mech->create_problems_for_body(1, $body->id, 'On Road', {
+ category => $test->{category}, cobrand => 'bexley',
+ latitude => 51.408484, longitude => 0.074653, areas => '2494',
+ });
+ if ($test->{extra}) {
+ $report->set_extra_fields(ref $test->{extra} eq 'ARRAY' ? @{$test->{extra}} : $test->{extra});
+ $report->update;
+ }
+
+ subtest 'NSGRef and correct email config' => sub {
+ 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'), $test->{code};
+ if ($test->{code} =~ /Confirm/) {
+ is $c->param('attribute[site_code]'), 'Road ID';
+ } elsif ($test->{code} =~ /Uniform/) {
+ is $c->param('attribute[uprn]'), 'Road ID';
+ } else {
+ is $c->param('attribute[NSGRef]'), 'Road ID';
+ }
+
+ if (my $t = $test->{email}) {
+ my $email = $mech->get_email;
+ $t = join('@[^@]*', @$t);
+ like $email->header('To'), qr/^[^@]*$t@[^@]*$/;
+ if ($test->{code} =~ /Confirm/) {
+ like $mech->get_text_body_from_email($email), qr/Site code: Road ID/;
+ } elsif ($test->{code} =~ /Uniform/) {
+ like $mech->get_text_body_from_email($email), qr/UPRN: Road ID/;
+ like $mech->get_text_body_from_email($email), qr/Uniform ID: 248/;
+ } else {
+ like $mech->get_text_body_from_email($email), qr/NSG Ref: Road ID/;
+ }
+ $mech->clear_emails_ok;
+ } else {
+ $mech->email_count_is(0);
+ }
+ };
+ }
+
+ subtest 'resend is disabled in admin' => sub {
+ my $user = $mech->log_in_ok('super@example.org');
+ $user->update({ from_body => $body, is_superuser => 1 });
+ $mech->get_ok('/admin/report_edit/' . $report->id);
+ $mech->content_contains('View report on site');
+ $mech->content_lacks('Resend report');
+ };
+
+ subtest "resending of reports by changing category" => sub {
+ $mech->get_ok('/admin/report_edit/' . $report->id);
+ $mech->submit_form_ok({ with_fields => { category => 'Damaged road' } });
+ 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'), 'ROAD', 'Report resent in new category';
+
+ $mech->submit_form_ok({ with_fields => { category => 'Gulley covers' } });
+ $test_data = FixMyStreet::Script::Reports::send();
+ is_deeply $test_data, {}, 'Report not resent';
+
+ $mech->submit_form_ok({ with_fields => { category => 'Lamp post' } });
+ $test_data = FixMyStreet::Script::Reports::send();
+ $req = $test_data->{test_req_used};
+ $c = CGI::Simple->new($req->content);
+ is $c->param('service_code'), 'StreetLightingLAMP', 'Report resent';
+ };
+
+ subtest 'extra CSV column present' => sub {
+ $mech->get_ok('/dashboard?export=1');
+ $mech->content_contains(',Category,Subcategory,');
+ $mech->content_contains('"Danger things","Something dangerous"');
+ };
+
+
+ subtest 'testing special Open311 behaviour', sub {
+ my @reports = $mech->create_problems_for_body( 1, $body->id, 'Test', {
+ category => 'Flooding in the road', cobrand => 'bexley',
+ latitude => 51.408484, longitude => 0.074653, areas => '2494',
+ photo => '74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg,74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg',
+ });
+ my $report = $reports[0];
+
+ my $test_data = FixMyStreet::Script::Reports::send();
+ $report->discard_changes;
+ ok $report->whensent, 'Report marked as sent';
+ is $report->send_method_used, 'Open311', 'Report sent via Open311';
+ is $report->external_id, 248, 'Report has right external ID';
+
+ my $req = $test_data->{test_req_used};
+ my $c = CGI::Simple->new($req->content);
+ is $c->param('attribute[title]'), 'Test Test 1 for ' . $body->id, 'Request had correct title';
+ is_deeply [ $c->param('media_url') ], [
+ 'http://bexley.example.org/photo/' . $report->id . '.0.full.jpeg?74e33622',
+ 'http://bexley.example.org/photo/' . $report->id . '.1.full.jpeg?74e33622',
+ ], 'Request had multiple photos';
+ };
+
+};
+
+subtest 'nearest road returns correct road' => sub {
+ my $cobrand = FixMyStreet::Cobrand::Bexley->new;
+ my $cfg = {
+ accept_feature => sub { 1 },
+ property => 'fid',
+ };
+ my $features = [
+ { geometry => { type => 'Polygon' } },
+ { geometry => { type => 'MultiLineString',
+ coordinates => [ [ [ 545499, 174361 ], [ 545420, 174359 ], [ 545321, 174352 ] ] ] },
+ properties => { fid => '20101226' } },
+ { geometry => { type => 'LineString',
+ coordinates => [ [ 545420, 174359 ], [ 545419, 174375 ], [ 545418, 174380 ], [ 545415, 174391 ] ] },
+ properties => { fid => '20100024' } },
+ ];
+ is $cobrand->_nearest_feature($cfg, 545451, 174380, $features), '20101226';
+};
+
+my $geo = Test::MockModule->new('FixMyStreet::Geocode');
+$geo->mock('cache', sub {
+ my $typ = shift;
+ return [] if $typ eq 'osm';
+ return {
+ features => [
+ {
+ properties => { ADDRESS => 'BRAMPTON ROAD', TOWN => 'BEXLEY' },
+ geometry => { type => 'LineString', coordinates => [ [ 1, 2 ], [ 3, 4] ] },
+ },
+ {
+ properties => { ADDRESS => 'FOOTPATH TO BRAMPTON ROAD', TOWN => 'BEXLEY' },
+ geometry => { type => 'MultiLineString', coordinates => [ [ [ 1, 2 ], [ 3, 4 ] ], [ [ 5, 6 ], [ 7, 8 ] ] ] },
+ },
+ ],
+ } if $typ eq 'bexley';
+});
+
+subtest 'geocoder' => sub {
+ my $c = ctx_request('/');
+ my $results = FixMyStreet::Geocode::Bexley->string("Brampton Road", $c);
+ is_deeply $results, { error => [
+ {
+ 'latitude' => '49.766844',
+ 'longitude' => '-7.557122',
+ 'address' => 'Brampton Road, Bexley'
+ }, {
+ 'address' => 'Footpath to Brampton Road, Bexley',
+ 'longitude' => '-7.557097',
+ 'latitude' => '49.766863'
+ }
+ ] };
+};
+
+my $bex = Test::MockModule->new('FixMyStreet::Cobrand::Bexley');
+$bex->mock('get', sub {
+ return <<EOF
+{
+ "england-and-wales": {
+ "events": [
+ { "date": "2019-12-25", "title": "Christmas Day", "notes": "", "bunting": true }
+ ]
+ }
+}
+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';
+ set_fixed_time('2019-10-16T04:00:00Z');
+ is $cobrand->_is_out_of_hours(), 1, 'out of hours early in the morning';
+ set_fixed_time('2019-10-13T12:00:00Z');
+ is $cobrand->_is_out_of_hours(), 1, 'out of hours at weekends';
+ set_fixed_time('2019-12-25T12:00:00Z');
+ is $cobrand->_is_out_of_hours(), 1, 'out of hours on bank holiday';
+};
+
+done_testing();
diff --git a/t/cobrand/bristol.t b/t/cobrand/bristol.t
index b2b8cff13..d4770b6ee 100644
--- a/t/cobrand/bristol.t
+++ b/t/cobrand/bristol.t
@@ -21,6 +21,16 @@ my $email_contact = $mech->create_contact_ok(
send_method => 'Email'
);
+subtest 'Reports page works with no reports', sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'bristol' ],
+ MAPIT_URL => 'http://mapit.uk/',
+ MAP_TYPE => 'Bristol',
+ }, sub {
+ $mech->get_ok("/reports");
+ };
+};
+
subtest 'Only Open311 categories are shown on Bristol cobrand', sub {
FixMyStreet::override_config {
ALLOWED_COBRANDS => [ 'bristol' ],
diff --git a/t/cobrand/bromley.t b/t/cobrand/bromley.t
index 6750d3183..71180cd3e 100644
--- a/t/cobrand/bromley.t
+++ b/t/cobrand/bromley.t
@@ -169,7 +169,7 @@ for my $test (
like $body, qr/This update will be sent to Bromley Council/i, "Email indicates problem will be sent to Bromley";
unlike $body, qr/Note that we do not send updates to/i, "Email does not say updates aren't sent to Bromley";
- my $unreg_user = FixMyStreet::App->model( 'DB::User' )->find( { email => 'unregistered@example.com' } );
+ my $unreg_user = FixMyStreet::DB->resultset('User')->find( { email => 'unregistered@example.com' } );
ok $unreg_user, 'found user';
@@ -233,10 +233,11 @@ subtest 'check heatmap page' => sub {
FixMyStreet::override_config {
ALLOWED_COBRANDS => 'bromley',
MAPIT_URL => 'http://mapit.uk/',
+ COBRAND_FEATURES => { category_groups => { bromley => 1 }, heatmap => { bromley => 1 } },
}, sub {
$mech->log_in_ok($user->email);
- $mech->get_ok('/about/heatmap?end_date=2018-12-31');
- $mech->get_ok('/about/heatmap?filter_category=RED&ajax=1');
+ $mech->get_ok('/dashboard/heatmap?end_date=2018-12-31');
+ $mech->get_ok('/dashboard/heatmap?filter_category=RED&ajax=1');
};
};
diff --git a/t/cobrand/bucks.t b/t/cobrand/bucks.t
index 965b90107..230a52f99 100644
--- a/t/cobrand/bucks.t
+++ b/t/cobrand/bucks.t
@@ -4,21 +4,38 @@ use FixMyStreet::Script::Reports;
my $mech = FixMyStreet::TestMech->new;
+# disable info logs for this test run
+FixMyStreet::App->log->disable('info');
+END { FixMyStreet::App->log->enable('info'); }
+
my $body = $mech->create_body_ok(2217, 'Buckinghamshire', {
- send_method => 'Open311', api_key => 'key', endpoint => 'endpoint', jurisdiction => 'fms' });
+ send_method => 'Open311', api_key => 'key', endpoint => 'endpoint', jurisdiction => 'fms', can_be_devolved => 1 });
my $counciluser = $mech->create_user_ok('counciluser@example.com', name => 'Council User', from_body => $body);
-
-$mech->create_contact_ok(body_id => $body->id, category => 'Flytipping', email => "FLY");
+my $publicuser = $mech->create_user_ok('fmsuser@example.org', name => 'Simon Neil');
+
+my $contact = $mech->create_contact_ok(body_id => $body->id, category => 'Flytipping', email => "FLY");
+$contact->set_extra_fields({
+ code => 'road-placement',
+ datatype => 'singlevaluelist',
+ description => 'Is the fly-tip located on',
+ order => 100,
+ required => 'true',
+ variable => 'true',
+ values => [
+ { key => 'road', name => 'The road' },
+ { key => 'off-road', name => 'Off the road/on a verge' },
+ ],
+});
+$contact->update;
$mech->create_contact_ok(body_id => $body->id, category => 'Potholes', email => "POT");
$mech->create_contact_ok(body_id => $body->id, category => 'Blocked drain', email => "DRA");
-
-my $district = $mech->create_body_ok(2257, 'Chiltern');
-$mech->create_contact_ok(body_id => $district->id, category => 'Flytipping', email => "flytipping\@chiltern");
-$mech->create_contact_ok(body_id => $district->id, category => 'Graffiti', email => "graffiti\@chiltern");
+$mech->create_contact_ok(body_id => $body->id, category => 'Car Parks', email => "car\@chiltern", send_method => 'Email');
+$mech->create_contact_ok(body_id => $body->id, category => 'Graffiti', email => "graffiti\@chiltern", send_method => 'Email');
+$mech->create_contact_ok(body_id => $body->id, category => 'Flytipping (off-road)', email => "districts_flytipping", send_method => 'Email');
my $cobrand = Test::MockModule->new('FixMyStreet::Cobrand::Buckinghamshire');
$cobrand->mock('lookup_site_code', sub {
- my ($self, $row, $buffer) = @_;
+ my ($self, $row) = @_;
return "Road ID" if $row->latitude == 51.812244;
});
@@ -26,6 +43,21 @@ FixMyStreet::override_config {
ALLOWED_COBRANDS => [ 'buckinghamshire', 'fixmystreet' ],
MAPIT_URL => 'http://mapit.uk/',
STAGING_FLAGS => { send_reports => 1, skip_checks => 0 },
+ COBRAND_FEATURES => {
+ open311_email => {
+ buckinghamshire => {
+ flytipping => 'flytipping@example.org',
+ flood => 'floods@example.org',
+ }
+ },
+ borough_email_addresses => {
+ buckinghamshire => {
+ districts_flytipping => [
+ { email => "flytipping\@chiltern", areas => [ 2257 ] },
+ ]
+ }
+ }
+ }
}, sub {
subtest 'cobrand displays council name' => sub {
@@ -36,24 +68,26 @@ subtest 'cobrand displays council name' => sub {
subtest 'cobrand displays correct categories' => sub {
my $json = $mech->get_ok_json('/report/new/ajax?latitude=51.615559&longitude=-0.556903');
- is @{$json->{bodies}}, 2, 'Both Chiltern and Bucks returned';
+ is @{$json->{bodies}}, 1, 'Bucks returned';
+ like $json->{category}, qr/Car Parks/, 'Car Parks displayed';
like $json->{category}, qr/Flytipping/, 'Flytipping displayed';
like $json->{category}, qr/Blocked drain/, 'Blocked drain displayed';
- unlike $json->{category}, qr/Graffiti/, 'Graffiti not displayed';
+ like $json->{category}, qr/Graffiti/, 'Graffiti displayed';
+ unlike $json->{category}, qr/Flytipping \(off-road\)/, 'Flytipping (off-road) not displayed';
$json = $mech->get_ok_json('/report/new/category_extras?latitude=51.615559&longitude=-0.556903');
- is @{$json->{bodies}}, 2, 'Still both Chiltern and Bucks returned';
+ is @{$json->{bodies}}, 1, 'Still Bucks returned';
};
my ($report) = $mech->create_problems_for_body(1, $body->id, 'On Road', {
category => 'Flytipping', cobrand => 'fixmystreet',
latitude => 51.812244, longitude => -0.827363,
+ dt => DateTime->now()->subtract(minutes => 10),
});
subtest 'flytipping on road sent to extra email' => sub {
FixMyStreet::Script::Reports::send();
my @email = $mech->get_email;
- my $tfb = join('', 'illegaldumpingcosts', '@', 'buckscc.gov.uk');
- is $email[0]->header('To'), '"TfB" <' . $tfb . '>';
+ is $email[0]->header('To'), 'TfB <flytipping@example.org>';
like $mech->get_text_body_from_email($email[1]), qr/report's reference number/;
$report->discard_changes;
is $report->external_id, 248, 'Report has right external ID';
@@ -66,6 +100,7 @@ subtest 'flytipping on road sent to extra email' => sub {
contributed_as => 'another_user',
contributed_by => $counciluser->id,
},
+ dt => DateTime->now()->subtract(minutes => 9),
});
subtest 'pothole on road not sent to extra email, only confirm sent' => sub {
@@ -77,58 +112,50 @@ subtest 'pothole on road not sent to extra email, only confirm sent' => sub {
is $report->external_id, 248, 'Report has right external ID';
};
-($report) = $mech->create_problems_for_body(1, $district->id, 'Off Road', {
- category => 'Flytipping', cobrand => 'buckinghamshire',
- latitude => 51.813173, longitude => -0.826741,
-});
-subtest 'flytipping off road sent to extra email' => sub {
+
+# 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);
+ $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('Your issue is on its way to the council.');
+ 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';
+
+ $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
my @email = $mech->get_email;
- is $email[0]->header('To'), '"Chiltern" <flytipping@chiltern>';
- like $mech->get_text_body_from_email($email[1]), qr/Please note that Buckinghamshire County Council is not responsible/;
- $report->discard_changes;
- is $report->external_id, undef, 'Report has right external ID';
+ is $email[0]->header('To'), 'Buckinghamshire <flytipping@chiltern>';
};
my ($report2) = $mech->create_problems_for_body(1, $body->id, 'Drainage problem', {
category => 'Blocked drain', cobrand => 'fixmystreet',
latitude => 51.812244, longitude => -0.827363,
+ dt => DateTime->now()->subtract(minutes => 8),
});
subtest 'blocked drain sent to extra email' => sub {
$mech->clear_emails_ok;
FixMyStreet::Script::Reports::send();
my @email = $mech->get_email;
- my $e = join('@', 'floodmanagement', 'buckscc.gov.uk');
- is $email[0]->header('To'), '"Flood Management" <' . $e . '>';
+ is $email[0]->header('To'), '"Flood Management" <floods@example.org>';
like $mech->get_text_body_from_email($email[1]), qr/report's reference number/;
};
$cobrand = FixMyStreet::Cobrand::Buckinghamshire->new();
-subtest 'Flytipping extra question used if necessary' => sub {
- my $errors = { 'road-placement' => 'This field is required' };
-
- $report->update({ bodies_str => $body->id });
- $cobrand->flytipping_body_fix($report, 'road', $errors);
- is $errors->{'road-placement'}, 'This field is required', 'Error stays if sent to county';
-
- $report->update({ bodies_str => $district->id });
- $report->discard_changes; # As e.g. ->bodies has been remembered.
- $cobrand->flytipping_body_fix($report, 'road', $errors);
- is $errors->{'road-placement'}, undef, 'Error removed if sent to district';
-
- $report->update({ bodies_str => $body->id . ',' . $district->id });
- $report->discard_changes; # As e.g. ->bodies has been remembered.
- $cobrand->flytipping_body_fix($report, 'road', $errors);
- is $report->bodies_str, $body->id, 'Sent to both becomes sent to county on-road';
-
- $report->update({ bodies_str => $district->id . ',' . $body->id });
- $report->discard_changes; # As e.g. ->bodies has been remembered.
- $cobrand->flytipping_body_fix($report, 'off-road', $errors);
- is $report->bodies_str, $district->id, 'Sent to both becomes sent to district off-road';
-};
-
for my $test (
{
desc => 'filters basic emails',
diff --git a/t/cobrand/cheshireeast.t b/t/cobrand/cheshireeast.t
new file mode 100644
index 000000000..4924a96ee
--- /dev/null
+++ b/t/cobrand/cheshireeast.t
@@ -0,0 +1,129 @@
+use CGI::Simple;
+use Test::MockModule;
+use FixMyStreet::TestMech;
+use FixMyStreet::Script::Alerts;
+use FixMyStreet::Script::Reports;
+
+FixMyStreet::App->log->disable('info');
+END { FixMyStreet::App->log->enable('info'); }
+
+my $mech = FixMyStreet::TestMech->new;
+
+my $body = $mech->create_body_ok( 21069, 'Cheshire East Council', {
+ send_method => 'Open311',
+ endpoint => 'endpoint',
+ api_key => 'key',
+ jurisdiction => 'cheshireeast_confirm',
+});
+
+my $contact = $mech->create_contact_ok(
+ body_id => $body->id,
+ category => 'Zebra Crossing',
+ email => 'ZEBRA',
+);
+
+my $cobrand = Test::MockModule->new('FixMyStreet::Cobrand::CheshireEast');
+$cobrand->mock('_fetch_features', sub {
+ return [];
+});
+
+use_ok 'FixMyStreet::Cobrand::CheshireEast';
+
+FixMyStreet::override_config {
+ COBRAND_FEATURES => {
+ contact_email => {
+ cheshireeast => 'foo@cheshireeast',
+ }
+ },
+}, sub {
+ my $cobrand = FixMyStreet::Cobrand::CheshireEast->new;
+ like $cobrand->contact_email, qr/cheshireeast/;
+ is_deeply $cobrand->disambiguate_location->{bounds}, [ 52.947150, -2.752929, 53.387445, -1.974789 ];
+};
+
+my @reports = $mech->create_problems_for_body( 1, $body->id, 'Test', {
+ category => 'Zebra Crossing',
+ photo => '74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg,74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg',
+});
+my $report = $reports[0];
+
+my $alert = FixMyStreet::DB->resultset("Alert")->create({
+ alert_type => 'new_updates',
+ cobrand => 'cheshireeast',
+ parameter => $report->id,
+ user => {
+ email => 'alert@example.com',
+ email_verified => 1,
+ },
+});
+$alert->confirm;
+
+$mech->create_comment_for_problem($report, $report->user, $report->name, 'blah', 0, 'confirmed', 'confirmed', {
+ confirmed => \'current_timestamp'
+});
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'cheshireeast',
+ MAPIT_URL => 'http://mapit.uk/',
+ STAGING_FLAGS => { skip_checks => 1, send_reports => 1 },
+}, sub {
+
+ subtest 'cobrand displays council name' => sub {
+ ok $mech->host("cheshireeast.fixmystreet.com"), "change host to cheshireeast";
+ $mech->get_ok('/');
+ $mech->content_contains('Cheshire East');
+ };
+
+ subtest 'testing special Open311 behaviour', sub {
+ my $test_data = FixMyStreet::Script::Reports::send();
+ $report->discard_changes;
+ ok $report->whensent, 'Report marked as sent';
+ is $report->send_method_used, 'Open311', 'Report sent via Open311';
+ is $report->external_id, 248, 'Report has right external ID';
+
+ my $req = $test_data->{test_req_used};
+ my $c = CGI::Simple->new($req->content);
+ is $c->param('attribute[title]'), 'Test Test 1 for ' . $body->id, 'Request had correct title';
+ is_deeply [ $c->param('media_url') ], [
+ 'http://www.example.org/photo/' . $report->id . '.0.full.jpeg?74e33622',
+ 'http://www.example.org/photo/' . $report->id . '.1.full.jpeg?74e33622',
+ ], 'Request had multiple photos';
+
+ };
+
+ subtest 'testing reference numbers shown' => sub {
+ $mech->get_ok('/report/' . $report->id);
+ $mech->content_contains('Council ref:&nbsp;' . $report->id);
+ FixMyStreet::Script::Alerts::send();
+ like $mech->get_text_body_from_email, qr/reference number is @{[$report->id]}/;
+ };
+
+ subtest 'contact page blocked', sub {
+ $mech->get('/contact');
+ is $mech->res->code, 404;
+ };
+
+ subtest 'check post-submission message', sub {
+ $mech->log_in_ok($report->user->email);
+ $mech->get_ok('/report/new?latitude=53.145324&longitude=-2.370437');
+ $mech->submit_form_ok({ with_fields => {
+ title => 'title',
+ detail => 'detail',
+ }});
+ my $report = FixMyStreet::DB->resultset('Problem')->search(undef, { order_by => { -desc => 'id' } })->first;
+ my $report_id = $report->id;
+ $mech->content_contains('0300 123 5020');
+ $mech->content_like(qr/quoting your reference number $report_id/);
+ };
+
+ subtest 'checking alert pages', sub {
+ $mech->get_ok('/alert');
+ $mech->content_contains('all reported problems');
+ $mech->submit_form_ok({ with_fields => { pc => 'CW11 1HZ' } });
+ $mech->content_contains('Reported problems within 10.0km');
+ $mech->content_contains('All reported problems');
+ $mech->content_contains('Reported problems within Sandbach Town');
+ };
+};
+
+done_testing();
diff --git a/t/cobrand/councils.t b/t/cobrand/councils.t
index c44605bd9..aac682b19 100644
--- a/t/cobrand/councils.t
+++ b/t/cobrand/councils.t
@@ -47,4 +47,72 @@ foreach my $test (
};
+subtest "Test update shown/not shown appropriately" => sub {
+ my $user = $mech->create_user_ok('test@example.com');
+ foreach my $cobrand ('oxfordshire', 'fixmystreet') {
+ foreach my $test (
+ # Three bools are logged out, reporter, staff user
+ { type => 'none', update => [0,0,0] },
+ { type => 'staff', update => [0,0,1] },
+ { type => 'reporter', update => [0,1,1] },
+ { type => 'reporter-open', state => 'closed', update => [0,0,0] },
+ { type => 'reporter-open', state => 'in progress', update => [0,1,1] },
+ { type => 'open', state => 'closed', update => [0,0,0] },
+ { type => 'open', state => 'in progress', update => [1,1,1] },
+ ) {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => $cobrand,
+ MAPIT_URL => 'http://mapit.uk/',
+ COBRAND_FEATURES => {
+ updates_allowed => {
+ oxfordshire => $test->{type},
+ fixmystreet => {
+ Oxfordshire => $test->{type},
+ }
+ }
+ },
+ }, sub {
+ subtest "$cobrand, $test->{type}" => sub {
+ $report->update({ state => $test->{state} || 'confirmed' });
+ $mech->log_out_ok;
+ $user->update({ from_body => undef });
+ $mech->get_ok("/report/$report_id");
+ $mech->contains_or_lacks($test->{update}[0], 'Provide an update');
+ $mech->log_in_ok('test@example.com');
+ $mech->get_ok("/report/$report_id");
+ $mech->contains_or_lacks($test->{update}[1], 'Provide an update');
+ $user->update({ from_body => $oxon->id });
+ $mech->get_ok("/report/$report_id");
+ $mech->contains_or_lacks($test->{update}[2], 'Provide an update');
+ };
+ };
+ }
+ }
+};
+
+subtest "CSP header from feature" => sub {
+ foreach my $cobrand (
+ { moniker => 'oxfordshire', test => 'oxon.analytics.example.org' },
+ { moniker =>'fixmystreet', test => '' },
+ { moniker => 'nonsecure', test => undef },
+ ) {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => $cobrand->{moniker},
+ COBRAND_FEATURES => {
+ content_security_policy => {
+ oxfordshire => 'oxon.analytics.example.org',
+ fixmystreet => 1,
+ }
+ },
+ }, sub {
+ $mech->get_ok("/");
+ if (defined $cobrand->{test}) {
+ like $mech->res->header('Content-Security-Policy'), qr/script-src 'self' 'unsafe-inline' 'nonce-[^']*' $cobrand->{test}/;
+ } else {
+ is $mech->res->header('Content-Security-Policy'), undef;
+ }
+ };
+ }
+};
+
done_testing();
diff --git a/t/cobrand/eastsussex.t b/t/cobrand/eastsussex.t
new file mode 100644
index 000000000..13383d44c
--- /dev/null
+++ b/t/cobrand/eastsussex.t
@@ -0,0 +1,42 @@
+use FixMyStreet::TestMech;
+use FixMyStreet::Script::Reports;
+use CGI::Simple;
+
+my $mech = FixMyStreet::TestMech->new;
+
+my $body = $mech->create_body_ok(2224, 'East Sussex Council',
+ { send_method => 'Open311', api_key => 'KEY', endpoint => 'endpoint', jurisdiction => 'eastsussex' });
+my $contact = $mech->create_contact_ok(body => $body, category => 'Pothole', email => 'POTHOLE');
+$contact->set_extra_fields(
+ { code => 'urgent', description => 'Is it urgent?', variable => 'true' },
+ { code => 'notice', description => 'This is a notice', variable => 'false' });
+$contact->update;
+my ($p) = $mech->create_problems_for_body(1, $body->id, 'East Sussex report', { category => 'Pothole' });
+$p->set_extra_fields({ name => 'urgent', value => 'no'});
+$p->update;
+
+subtest 'Check special Open311 request handling', sub {
+ my $orig_detail = $p->detail;
+ my $test_data;
+ FixMyStreet::override_config {
+ STAGING_FLAGS => { send_reports => 1 },
+ ALLOWED_COBRANDS => 'eastsussex',
+ BASE_URL => 'https://www.fixmystreet.com',
+ }, sub {
+ $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';
+ is $p->detail, $orig_detail, 'Detail in database not changed';
+
+ my $req = $test_data->{test_req_used};
+ my $c = CGI::Simple->new($req->content);
+ my $expected = join "\r\n", $p->title, '', $p->detail, '',
+ 'Is it urgent?', 'no', '', "https://www.fixmystreet.com" . $p->url, '';
+ is $c->param('description'), $expected, 'Correct description, with extra question and no notice text';
+};
+
+done_testing;
diff --git a/t/cobrand/features.t b/t/cobrand/features.t
new file mode 100644
index 000000000..45ea6336d
--- /dev/null
+++ b/t/cobrand/features.t
@@ -0,0 +1,20 @@
+use FixMyStreet::Test;
+use FixMyStreet::Cobrand;
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => ['bromley'],
+ COBRAND_FEATURES => {
+ foo => { tester => 1 },
+ bar => { default => 1 },
+ suggest_duplicates => { bromley => 1 },
+ }
+}, sub {
+ my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker('default')->new;
+ my $bromley = FixMyStreet::Cobrand->get_class_for_moniker('bromley')->new;
+
+ is $cobrand->feature('foo'), undef;
+ is $cobrand->feature('bar'), 1;
+ is $bromley->suggest_duplicates, 1;
+};
+
+done_testing();
diff --git a/t/cobrand/fixmystreet.t b/t/cobrand/fixmystreet.t
index b47269db4..a54e782f2 100644
--- a/t/cobrand/fixmystreet.t
+++ b/t/cobrand/fixmystreet.t
@@ -1,8 +1,13 @@
+use utf8;
use FixMyStreet::Script::UpdateAllReports;
+use Test::MockModule;
use FixMyStreet::TestMech;
my $mech = FixMyStreet::TestMech->new;
+my $resolver = Test::MockModule->new('Email::Valid');
+$resolver->mock('address', sub { $_[1] });
+
my $body = $mech->create_body_ok( 2514, 'Birmingham' );
my $contact = $mech->create_contact_ok(
@@ -53,7 +58,7 @@ FixMyStreet::override_config {
subtest 'check marketing dashboard csv' => sub {
$mech->log_in_ok('someone@birmingham.gov.uk');
- $mech->create_problems_for_body(105, $body->id, 'Title', {
+ $mech->create_problems_for_body(105, $body->id, 'Titlē', {
detail => "this report\nis split across\nseveral lines",
areas => ",2514,",
});
@@ -80,7 +85,7 @@ FixMyStreet::override_config {
'Column headers look correct';
my $body_id = $body->id;
- like $rows[1]->[1], qr/Title Test \d+ for $body_id/, 'problem title correct';
+ like $rows[1]->[1], qr/Titlē Test \d+ for $body_id/, 'problem title correct';
};
subtest 'check marketing dashboard contact listings' => sub {
@@ -106,6 +111,22 @@ FixMyStreet::override_config {
};
};
-END {
- done_testing();
-}
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'fixmystreet',
+}, sub {
+ subtest 'test enforced 2FA for superusers' => sub {
+ my $test_email = 'test@example.com';
+ my $user = FixMyStreet::DB->resultset('User')->find_or_create({ email => $test_email });
+ $user->password('password');
+ $user->is_superuser(1);
+ $user->update;
+
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok(
+ { with_fields => { username => $test_email, password_sign_in => 'password' } },
+ "sign in using form" );
+ $mech->content_contains('requires two-factor');
+ };
+};
+
+done_testing();
diff --git a/t/cobrand/form_extras.t b/t/cobrand/form_extras.t
index df76ccbe1..3807dd56a 100644
--- a/t/cobrand/form_extras.t
+++ b/t/cobrand/form_extras.t
@@ -84,7 +84,7 @@ FixMyStreet::override_config {
);
$mech->content_contains('Now check your email');
- my $problem = FixMyStreet::DB->resultset('Problem')->search({}, { order_by => '-id' })->first;
+ my $problem = FixMyStreet::DB->resultset('Problem')->search({}, { order_by => { -desc => 'id' } })->first;
is $problem->get_extra_metadata('address'), 'My address', 'Address is stored';
is $problem->get_extra_metadata('passport'), 'P123456', 'Passport number is stored';
};
diff --git a/t/cobrand/greenwich.t b/t/cobrand/greenwich.t
index e6aaca973..14ddba9be 100644
--- a/t/cobrand/greenwich.t
+++ b/t/cobrand/greenwich.t
@@ -5,7 +5,7 @@ use Open311::PopulateServiceList;
my $mech = FixMyStreet::TestMech->new;
-my $body = $mech->create_body_ok( 2493, 'Greenwich Council', {
+my $body = $mech->create_body_ok( 2493, 'Royal Borough of Greenwich', {
send_method => 'Open311',
endpoint => 'endpoint',
api_key => 'key',
@@ -110,5 +110,26 @@ subtest 'testing special Open311 behaviour', sub {
is $c->param('attribute[easting]'), 529025, 'Request had correct easting';
};
-done_testing();
+subtest 'RSS feed on .com' => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'fixmystreet',
+ MAPIT_TYPES => ['GRE'],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->get_ok('/rss/reports/Greenwich');
+ is $mech->uri->path, '/rss/reports/Greenwich';
+ };
+};
+subtest 'RSS feed on Greenwich' => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'greenwich',
+ MAPIT_TYPES => ['GRE'],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->get_ok('/rss/reports/Greenwich');
+ is $mech->uri->path, '/rss/reports/Greenwich';
+ };
+};
+
+done_testing();
diff --git a/t/cobrand/highwaysengland.t b/t/cobrand/highwaysengland.t
new file mode 100644
index 000000000..f6400ea7c
--- /dev/null
+++ b/t/cobrand/highwaysengland.t
@@ -0,0 +1,70 @@
+use FixMyStreet::TestMech;
+use FixMyStreet::App;
+use FixMyStreet::Script::Reports;
+use FixMyStreet::Cobrand::HighwaysEngland;
+use HighwaysEngland;
+use Test::MockModule;
+
+my $he_mock = Test::MockModule->new('HighwaysEngland');
+$he_mock->mock('database_file', sub { FixMyStreet->path_to('t/geocode/roads.sqlite'); });
+
+# disable info logs for this test run
+FixMyStreet::App->log->disable('info');
+END { FixMyStreet::App->log->enable('info'); }
+
+
+my $he_mock_cobrand = Test::MockModule->new('FixMyStreet::Cobrand::HighwaysEngland');
+$he_mock_cobrand->mock('anonymous_account', sub { { email => 'anoncategory@example.org', name => 'Anonymous Category' } });
+
+my $he = FixMyStreet::Cobrand::HighwaysEngland->new();
+
+my $r = $he->geocode_postcode('M1');
+ok $r->{error}, "searching for road only generates error";
+
+$r = $he->geocode_postcode('m1');
+ok $r->{error}, "searching for lowecase road only generates error";
+
+my $mech = FixMyStreet::TestMech->new;
+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 {
+ $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, },
+ "follow 'skip this step' link" );
+ $mech->submit_form_ok(
+ {
+ button => 'report_anonymously',
+ with_fields => {
+ title => "Test Report for HE",
+ detail => 'Test report details.',
+ category => 'Pothole',
+ where_hear => 'Facebook',
+ }
+ },
+ "submit good details"
+ );
+ $mech->content_contains('Thank you');
+
+ my $report = FixMyStreet::DB->resultset("Problem")->first;
+ ok $report, "Found the report";
+ is $report->get_extra_metadata('where_hear'), 'Facebook', 'saved where hear';
+
+ $mech->clear_emails_ok;
+ FixMyStreet::Script::Reports::send();
+ $mech->email_count_is(1);
+ my $email = $mech->get_email;
+ like $mech->get_text_body_from_email($email), qr/Heard from: Facebook/, 'where hear included in email'
+
+ };
+};
+
+
+done_testing();
diff --git a/t/cobrand/hounslow.t b/t/cobrand/hounslow.t
new file mode 100644
index 000000000..91c1cb455
--- /dev/null
+++ b/t/cobrand/hounslow.t
@@ -0,0 +1,101 @@
+use FixMyStreet::TestMech;
+
+ok( my $mech = FixMyStreet::TestMech->new, 'Created mech object' );
+
+my $hounslow_id = $mech->create_body_ok(2483, 'Hounslow Borough Council')->id;
+$mech->create_contact_ok(
+ body_id => $hounslow_id,
+ category => 'Potholes',
+ email => 'pothole@example.org',
+);
+
+my $user = $mech->create_user_ok('staff@example.org', from_body => $hounslow_id);
+$user->user_body_permissions->create({ body_id => $hounslow_id, permission_type => 'user_edit' });
+
+my $tfl = $mech->create_body_ok( 2483, 'TfL');
+$mech->create_contact_ok(
+ body_id => $tfl->id,
+ category => 'Traffic lights',
+ email => 'tfl@example.org',
+);
+
+$mech->create_problems_for_body(1, $hounslow_id, 'An old problem made before Hounslow FMS launched', {
+ confirmed => '2018-12-25 09:00',
+ lastupdate => '2018-12-25 09:00',
+ latitude => 51.482286,
+ longitude => -0.328163,
+
+});
+$mech->create_problems_for_body(1, $hounslow_id, 'A brand new problem made on the Hounslow site', {
+ latitude => 51.482286,
+ longitude => -0.328163,
+ cobrand => 'hounslow'
+});
+my ($report) = $mech->create_problems_for_body(1, $hounslow_id, 'A brand new problem made on fixmystreet.com', {
+ latitude => 51.482286,
+ longitude => -0.328163,
+ external_id => 'ABC123',
+ cobrand => 'fixmystreet'
+});
+
+subtest "it still shows old reports on fixmystreet.com" => sub {
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ ALLOWED_COBRANDS => 'fixmystreet',
+ }, sub {
+ $mech->get_ok('/reports/Hounslow');
+
+ $mech->content_contains('An old problem made before Hounslow FMS launched');
+ $mech->content_contains('A brand new problem made on the Hounslow site');
+ $mech->content_contains('A brand new problem made on fixmystreet.com');
+ };
+};
+
+subtest "it does not show old reports on Hounslow" => sub {
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ ALLOWED_COBRANDS => 'hounslow',
+ }, sub {
+ $mech->get_ok('/reports/Hounslow');
+ $mech->content_lacks('An old problem made before Hounslow FMS launched');
+ $mech->content_contains('A brand new problem made on the Hounslow site') or diag $mech->content;
+ $mech->content_contains('A brand new problem made on fixmystreet.com');
+ };
+};
+
+subtest "it shows the right things on an /around page" => sub {
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ ALLOWED_COBRANDS => 'hounslow',
+ }, sub {
+ $mech->get_ok('/around?pc=TW7+5JN');
+ $mech->content_lacks('An old problem made before Hounslow FMS launched');
+ $mech->content_contains('A brand new problem made on the Hounslow site') or diag $mech->content;
+ $mech->content_contains('A brand new problem made on fixmystreet.com');
+ };
+};
+
+subtest "Shows external ID on report page to staff users only" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'hounslow',
+ }, sub {
+ $mech->get_ok('/report/' . $report->id);
+ $mech->content_lacks('ABC123');
+ $mech->log_in_ok('staff@example.org');
+ $mech->get_ok('/report/' . $report->id);
+ $mech->content_contains('ABC123');
+ };
+};
+
+subtest "Admin searches right domains" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'hounslow',
+ }, sub {
+ foreach ('hounslowhighways.org', 'hounslow.gov.uk') {
+ $mech->get_ok('/admin/users?search=xyz@' . $_);
+ $mech->content_contains('xyz@' . $_);
+ }
+ };
+};
+
+done_testing();
diff --git a/t/cobrand/isleofwight.t b/t/cobrand/isleofwight.t
new file mode 100644
index 000000000..3cac710da
--- /dev/null
+++ b/t/cobrand/isleofwight.t
@@ -0,0 +1,628 @@
+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'); }
+
+my $cobrand = Test::MockModule->new('FixMyStreet::Cobrand::IsleOfWight');
+$cobrand->mock('lookup_site_code', sub {
+ my ($self, $row) = @_;
+ return "Road ID" if $row->latitude == 50.7108;
+});
+
+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 $isleofwight = $mech->create_body_ok(2636, 'Isle of Wight Council', $params);
+my $contact = $mech->create_contact_ok(
+ body_id => $isleofwight->id,
+ category => 'Potholes',
+ 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 $iow_user = $mech->create_user_ok('iow_user@example.org', name => 'IoW User', from_body => $isleofwight);
+$iow_user->user_body_permissions->create({
+ body => $isleofwight,
+ permission_type => 'moderate',
+});
+
+my $contact2 = $mech->create_contact_ok(
+ body_id => $isleofwight->id,
+ category => 'Roads',
+ email => 'roads@example.org',
+ send_method => 'Triage',
+);
+
+my $admin_user = $mech->create_user_ok('admin-user@example.org', name => 'Admin User', from_body => $isleofwight);
+
+$admin_user->user_body_permissions->create({
+ body => $isleofwight,
+ permission_type => 'triage'
+});
+
+my @reports = $mech->create_problems_for_body(1, $isleofwight->id, 'An Isle of wight report', {
+ confirmed => '2019-10-25 09:00',
+ lastupdate => '2019-10-25 09:00',
+ latitude => 50.7108,
+ longitude => -1.29573,
+ user => $user,
+ external_id => 101202303
+});
+
+subtest "check clicking all reports link" => sub {
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ ALLOWED_COBRANDS => 'isleofwight',
+ }, sub {
+ $mech->get_ok('/');
+ $mech->follow_link_ok({ text => 'All reports' });
+ };
+
+ $mech->content_contains("An Isle of wight report", "Isle of Wight report there");
+ $mech->content_contains("Island Roads", "is still on cobrand");
+};
+
+subtest "use external id for reference number" => sub {
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ ALLOWED_COBRANDS => 'isleofwight',
+ }, sub {
+ $mech->get_ok('/report/' . $reports[0]->id);
+ };
+
+ $mech->content_contains("101202303", "Display external id as reference number");
+};
+
+subtest "only original reporter can comment" => sub {
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ ALLOWED_COBRANDS => 'isleofwight',
+ COBRAND_FEATURES => { updates_allowed => { isleofwight => 'reporter' } },
+ }, sub {
+ $mech->get_ok('/report/' . $reports[0]->id);
+ $mech->content_contains('Only the original reporter may leave updates');
+
+ $mech->log_in_ok('user@example.org');
+ $mech->get_ok('/report/' . $reports[0]->id);
+ $mech->content_lacks('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');
+ $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 Island Roads/);
+ };
+};
+
+subtest "front page summary uses report category not title" => sub {
+ my $category = $reports[0]->category;
+ ok $category, "category is not blank";
+ my $title = $reports[0]->title;
+ ok $title, "title is not blank";
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ ALLOWED_COBRANDS => ['isleofwight'],
+ }, sub {
+ $mech->log_out_ok;
+ $mech->get_ok('/');
+ $mech->content_like( qr/item-list__heading">$category/ );
+ $mech->content_unlike( qr/item-list__heading">$title/ );
+ };
+};
+
+$_->delete for @reports;
+
+my $system_user = $mech->create_user_ok('system_user@example.org');
+
+for my $status ( qw/ CLOSED FIXED DUPLICATE NOT_COUNCILS_RESPONSIBILITY NO_FURTHER_ACTION / ) {
+ subtest "updates which mark report as $status close it to comments" => sub {
+ my $dt = DateTime->now(formatter => DateTime::Format::W3CDTF->new)->add( minutes => -5 );
+ my ($p) = $mech->create_problems_for_body(1, $isleofwight->id, '', { lastupdate => $dt });
+ $p->update({ external_id => $p->id });
+
+ my $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?>
+ <service_requests_updates>
+ <request_update>
+ <update_id>UPDATE_ID</update_id>
+ <service_request_id>SERVICE_ID</service_request_id>
+ <service_request_id_ext>ID_EXTERNAL</service_request_id_ext>
+ <status>STATUS</status>
+ <description>This is a note</description>
+ <updated_datetime>UPDATED_DATETIME</updated_datetime>
+ </request_update>
+ </service_requests_updates>
+ };
+
+ my $update_dt = DateTime->now(formatter => DateTime::Format::W3CDTF->new);
+
+ $requests_xml =~ s/STATUS/$status/;
+ $requests_xml =~ s/UPDATE_ID/@{[$p->id]}/;
+ $requests_xml =~ s/SERVICE_ID/@{[$p->id]}/;
+ $requests_xml =~ s/ID_EXTERNAL/@{[$p->id]}/;
+ $requests_xml =~ s/UPDATED_DATETIME/$update_dt/;
+
+ my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $requests_xml } );
+
+ my $update = Open311::GetServiceRequestUpdates->new(
+ system_user => $system_user,
+ current_open311 => $o,
+ current_body => $isleofwight,
+ );
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'isleofwight',
+ }, sub {
+ $update->process_body;
+ };
+
+ $mech->log_in_ok('user@example.org');
+ $mech->get_ok('/report/' . $p->id);
+ $mech->content_lacks('Provide an update', "No update form on report");
+
+ $p->discard_changes;
+ is $p->get_extra_metadata('closed_updates'), 1, "report closed to updates";
+ $p->comments->delete;
+ $p->delete;
+ };
+}
+
+subtest "fetched requests do not use the description text" => sub {
+ my $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?>
+ <service_requests>
+ <request>
+ <service_request_id>638344</service_request_id>
+ <status>open</status>
+ <status_notes>This is a note.</status_notes>
+ <service_name>Potholes</service_name>
+ <service_code>potholes\@example.org</service_code>
+ <description>This the description of a pothole problem</description>
+ <agency_responsible></agency_responsible>
+ <service_notice></service_notice>
+ <requested_datetime>DATETIME</requested_datetime>
+ <updated_datetime>DATETIME</updated_datetime>
+ <expected_datetime>DATETIME</expected_datetime>
+ <lat>50.71086</lat>
+ <long>-1.29573</long>
+ </request>
+ </service_requests>
+ };
+
+ my $dt = DateTime->now(formatter => DateTime::Format::W3CDTF->new)->add( minutes => -5 );
+ $requests_xml =~ s/DATETIME/$dt/gm;
+
+ my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'requests.xml' => $requests_xml } );
+
+ my $update = Open311::GetServiceRequests->new(
+ system_user => $iow_user,
+ );
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ ALLOWED_COBRANDS => 'isleofwight',
+ }, sub {
+ $update->create_problems( $o, $isleofwight );
+ };
+
+ my $p = FixMyStreet::DB->resultset('Problem')->search(
+ { external_id => 638344 }
+ )->first;
+
+ ok $p, 'Found problem';
+ is $p->title, 'Potholes problem', 'correct problem title';
+ is $p->detail, 'Potholes problem', 'correct problem description';
+ $p->delete;
+};
+
+subtest "fixing passes along the correct message" => sub {
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ ALLOWED_COBRANDS => 'isleofwight',
+ }, sub {
+ 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 => $isleofwight,
+ test_mode => 1,
+ test_get_returns => { 'servicerequestupdates.xml' => $test_res },
+ );
+
+ my ($p) = $mech->create_problems_for_body(1, $isleofwight->id, 'Title', { external_id => 1 });
+
+ my $c = FixMyStreet::DB->resultset('Comment')->create({
+ problem => $p, user => $p->user, anonymous => 't', text => 'Update text',
+ problem_state => 'fixed - council', state => 'confirmed', mark_fixed => 0,
+ confirmed => DateTime->now(),
+ });
+
+ my $id = $o->post_service_request_update($c);
+ is $id, 248, 'correct update ID returned';
+ my $cgi = CGI::Simple->new($o->test_req_used->content);
+ like $cgi->param('description'), qr/^FMS-Update:/, 'FMS update prefix included';
+ unlike $cgi->param('description'), qr/The customer indicated that this issue had been fixed/, 'No fixed message included';
+
+ $c = $mech->create_comment_for_problem($p, $p->user, 'Name', 'Update text', 'f', 'confirmed', 'fixed - user');
+ $c->discard_changes; # Otherwise cannot set_nanosecond
+
+ $id = $o->post_service_request_update($c);
+ is $id, 248, 'correct update ID returned';
+ $cgi = CGI::Simple->new($o->test_req_used->content);
+ like $cgi->param('description'), qr/^FMS-Update: \[The customer indicated that this issue had been fixed/, 'Fixed message included';
+ $p->comments->delete;
+ $p->delete;
+ };
+};
+
+subtest 'Check special Open311 request handling', sub {
+ $mech->clear_emails_ok;
+ my ($p) = $mech->create_problems_for_body(1, $isleofwight->id, 'Title', { category => 'Potholes', latitude => 50.7108, longitude => -1.29573, cobrand => 'isleofwight' });
+ $p->set_extra_fields({ name => 'urgent', value => 'no'});
+ $p->update;
+
+ my $test_data;
+ FixMyStreet::override_config {
+ STAGING_FLAGS => { send_reports => 1 },
+ ALLOWED_COBRANDS => ['isleofwight' ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $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';
+
+ my $req = $test_data->{test_req_used};
+ my $c = CGI::Simple->new($req->content);
+ is $c->param('attribute[urgent]'), undef, 'no urgent param sent';
+ is $c->param('attribute[site_code]'), 'Road ID', 'road ID set';
+
+ $mech->email_count_is(1);
+ my $email = $mech->get_email;
+ ok $email, "got an email";
+ like $mech->get_text_body_from_email($email),
+ qr/your enquiry has been received by Island Roads/, "correct report send email text";
+};
+
+subtest "comment recording triage details is not sent" => sub {
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ ALLOWED_COBRANDS => [ 'isleofwight' ],
+ }, sub {
+ 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></service_request_updates>');
+
+ my $o = Open311->new(
+ fixmystreet_body => $isleofwight,
+ test_mode => 1,
+ test_get_returns => { 'servicerequestupdates.xml' => $test_res },
+ );
+
+ my ($p) = $mech->create_problems_for_body(
+ 1, $isleofwight->id, 'Title',
+ {
+ category => 'Roads',
+ areas => 2636,
+ latitude => 50.71086,
+ longitude => -1.29573,
+ whensent => DateTime->now->add( minutes => -5 ),
+ send_method_used => 'Triage',
+ state => 'for triage',
+ external_id => 1,
+ });
+
+ $mech->log_out_ok;
+ $mech->log_in_ok($admin_user->email);
+ my $report_url = '/report/' . $p->id;
+ $mech->get_ok($report_url);
+ $mech->submit_form_ok( {
+ with_fields => {
+ category => 'Potholes',
+ include_update => 0,
+ }
+ },
+ 'triage form submitted'
+ );
+
+ ok $p->comments->first, 'comment created for problem';
+
+ $p->update({
+ send_method_used => 'Open311',
+ whensent => DateTime->now->add( minutes => -5 ),
+ });
+
+ my $updates = Open311::PostServiceRequestUpdates->new(
+ current_open311 => $o,
+ );
+ my $id = $updates->process_body($isleofwight);
+ ok !$o->test_req_used, 'no open311 update sent';
+
+ $p->comments->delete;
+ $p->delete;
+ };
+};
+
+my ($p) = $mech->create_problems_for_body(1, $isleofwight->id, '', { cobrand => 'isleofwight' });
+my $alert = FixMyStreet::DB->resultset('Alert')->create( {
+ parameter => $p->id,
+ alert_type => 'new_updates',
+ user => $user,
+ cobrand => 'isleofwight',
+} )->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 => ['isleofwight','fixmystreet'],
+ }, 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/Island Roads/, "emails are branded";
+};
+
+$p->comments->delete;
+$p->delete;
+
+subtest "check not responsible as correct text" => sub {
+ my ($p) = $mech->create_problems_for_body(
+ 1, $isleofwight->id, 'Title',
+ {
+ category => 'Roads',
+ areas => 2636,
+ latitude => 50.71086,
+ longitude => -1.29573,
+ whensent => DateTime->now->add( minutes => -5 ),
+ send_method_used => 'Open311',
+ state => 'not responsible',
+ external_id => 1,
+ });
+
+ my $c = FixMyStreet::DB->resultset('Comment')->create({
+ problem => $p, user => $p->user, anonymous => 't', text => 'Update text',
+ problem_state => 'not responsible', state => 'confirmed', mark_fixed => 0,
+ confirmed => DateTime->now(),
+ });
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ ALLOWED_COBRANDS => ['isleofwight'],
+ }, sub {
+ $mech->get_ok('/report/' . $p->id);
+ };
+
+ $mech->content_contains("not Island Roads’ responsibility", "not reponsible message contains correct text");
+ $p->comments->delete;
+ $p->delete;
+};
+
+subtest "sends branded confirmation emails" => sub {
+ $mech->log_out_ok;
+ $mech->clear_emails_ok;
+ $mech->get_ok('/around');
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'isleofwight' ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => 'PO30 5XJ', } },
+ "submit location" );
+
+ # 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 => 'test-1@example.com',
+ category => 'Roads',
+ }
+ },
+ "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/Island Roads/, "emails are branded";
+
+ my $url = $mech->get_link_from_email($email);
+ $mech->get_ok($url);
+ $mech->clear_emails_ok;
+ };
+};
+
+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 => ['isleofwight','fixmystreet'],
+ }, 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/Island Roads/, "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 => ['isleofwight','fixmystreet'],
+ }, sub {
+ $extra_details = $mech->get_ok_json('/report/new/category_extras?category=Roads&latitude=50.71086&longitude=-1.29573');
+ };
+
+ like $extra_details->{category_extra}, qr/Island Roads/, 'correct name in category extras';
+};
+
+subtest "reports are marked for triage upon submission" => sub {
+ $mech->log_out_ok;
+ $mech->clear_emails_ok;
+ $mech->log_in_ok($user->email);
+ $mech->get_ok('/around');
+ FixMyStreet::override_config {
+ STAGING_FLAGS => { send_reports => 1, skip_checks => 0 },
+ ALLOWED_COBRANDS => [ 'isleofwight' ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => 'PO30 5XJ', } },
+ "submit location" );
+
+ # 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 => '',
+ category => 'Roads',
+ }
+ },
+ "submit good details"
+ );
+
+ my $report = $user->problems->first;
+ ok $report, "Found the report";
+ is $report->state, 'confirmed', 'report confirmed';
+
+ $mech->clear_emails_ok;
+
+ FixMyStreet::Script::Reports::send();
+ $report->discard_changes;
+ is $report->state, 'for triage', 'report marked as for triage';
+ ok $report->whensent, 'report marked as sent';
+
+ $mech->email_count_is(1);
+ my $email = $mech->get_email;
+ like $mech->get_text_body_from_email($email),
+ qr/submitted to Island Roads for review/, 'correct text for email sent for Triage';
+ };
+};
+
+for my $cobrand ( 'fixmystreet', 'isleofwight' ) {
+ subtest "only categories for Triage are displayed on " . $cobrand => sub {
+ $mech->log_out_ok;
+ $mech->get_ok('/around');
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ $cobrand ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => 'PO30 5XJ', } },
+ "submit location" );
+
+ # click through to the report page
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, },
+ "follow 'skip this step' link" );
+
+ my $f = $mech->form_name('mapSkippedForm');
+ ok $f, 'found form';
+ my $cats = $f->find_input('category');
+ ok $cats, 'found category element';
+ my @values = $cats->possible_values;
+ is_deeply \@values, [ '-- Pick a category --', 'Roads' ], 'correct category list';
+ };
+ };
+
+ subtest "staff user can see non Triage categories on " . $cobrand => sub {
+ $mech->log_out_ok;
+ $mech->log_in_ok($admin_user->email);
+ $mech->get_ok('/around');
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ $cobrand ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => 'PO30 5XJ', } },
+ "submit location" );
+
+ # click through to the report page
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, },
+ "follow 'skip this step' link" );
+
+ my $f = $mech->form_name('mapSkippedForm');
+ ok $f, 'found form';
+ my $cats = $f->find_input('category');
+ ok $cats, 'found category element';
+ my @values = $cats->possible_values;
+ is_deeply \@values, [ '-- Pick a category --', 'Potholes' ], 'correct category list';
+ };
+ };
+}
+
+done_testing();
diff --git a/t/cobrand/national_assets.t b/t/cobrand/national_assets.t
index 378425193..32e27079b 100644
--- a/t/cobrand/national_assets.t
+++ b/t/cobrand/national_assets.t
@@ -20,6 +20,7 @@ subtest 'cobrand assets includes not applied on cobrand sites', sub {
ALLOWED_COBRANDS => [ 'bathnes' ],
MAPIT_URL => 'http://mapit.uk/',
MAP_TYPE => 'FMS,OSM,BathNES,Buckinghamshire',
+ STAGING_FLAGS => { skip_checks => 1 },
}, sub {
$mech->get_ok("/report/new?latitude=51.494885&longitude=-2.602237");
$mech->content_lacks('buckinghamshire/assets.js');
diff --git a/t/cobrand/northamptonshire.t b/t/cobrand/northamptonshire.t
new file mode 100644
index 000000000..57fe319a9
--- /dev/null
+++ b/t/cobrand/northamptonshire.t
@@ -0,0 +1,126 @@
+use Test::MockModule;
+
+use FixMyStreet::TestMech;
+use Open311::PostServiceRequestUpdates;
+
+use_ok 'FixMyStreet::Cobrand::Northamptonshire';
+
+my $mech = FixMyStreet::TestMech->new;
+
+use open ':std', ':encoding(UTF-8)';
+
+my $ncc = $mech->create_body_ok(2234, 'Northamptonshire County Council', {
+ send_method => 'Open311', api_key => 'key', 'endpoint' => 'e', 'jurisdiction' => 'j', send_comments => 1 });
+my $nbc = $mech->create_body_ok(2397, 'Northampton Borough Council');
+
+my $counciluser = $mech->create_user_ok('counciluser@example.com', name => 'Council User', from_body => $ncc);
+my $user = $mech->create_user_ok('user@example.com', name => 'User');
+
+my $ncc_contact = $mech->create_contact_ok(
+ body_id => $ncc->id,
+ category => 'Trees',
+ email => 'trees-2234@example.com',
+);
+
+my $nbc_contact = $mech->create_contact_ok(
+ body_id => $nbc->id,
+ category => 'Flytipping',
+ email => 'flytipping-2397@example.com',
+);
+
+my ($report) = $mech->create_problems_for_body(1, $ncc->id, 'Defect Problem', {
+ whensent => DateTime->now()->subtract( minutes => 5 ),
+ external_id => 1,
+ send_method_used => 'Open311',
+ user => $counciluser
+});
+
+my $comment = 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 => 'confirmed',
+ cobrand => 'default',
+} );
+
+$ncc->update( { comment_user_id => $counciluser->id } );
+
+
+subtest 'Check district categories hidden on cobrand' => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { northamptonshire => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->get_ok( '/around' );
+ $mech->submit_form_ok( { with_fields => { pc => 'NN1 1NS' } },
+ "submit location" );
+ is_deeply $mech->page_errors, [], "no errors for pc";
+
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, },
+ "follow 'skip this step' link" );
+
+ $mech->content_contains('Trees');
+ $mech->content_lacks('Flytipping');
+ };
+};
+
+subtest 'Check updates not sent for defects' => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { northamptonshire => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ my $updates = Open311::PostServiceRequestUpdates->new();
+ $updates->send;
+ };
+
+ $comment->discard_changes;
+ is $comment->send_fail_count, 0, "comment sending not attempted";
+ is $comment->get_extra_metadata('cobrand_skipped_sending'), 1, "skipped sending comment";
+};
+
+$report->update({ user => $user });
+$comment->update({ extra => undef });
+subtest 'check updates sent for non defects' => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { northamptonshire => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ my $updates = Open311::PostServiceRequestUpdates->new();
+ $updates->send;
+ };
+
+ $comment->discard_changes;
+ is $comment->send_fail_count, 1, "comment sending attempted";
+};
+
+my $cobrand = FixMyStreet::Cobrand::Northamptonshire->new;
+
+subtest 'check updates disallowed correctly' => sub {
+ is $cobrand->updates_disallowed($report), 0;
+ $report->update({ state => 'closed' });
+ is $cobrand->updates_disallowed($report), 1;
+ $report->update({ state => 'confirmed', user => $counciluser });
+ is $cobrand->updates_disallowed($report), 1;
+};
+
+subtest 'check pin colour / reference shown' => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'northamptonshire',
+ #MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ is $cobrand->pin_colour($report, 'around'), 'blue';
+ $mech->get_ok('/report/' . $report->id);
+ $mech->content_lacks('ref:&nbsp;' . $report->id);
+ $report->update({ user => $user });
+ is $cobrand->pin_colour($report, 'around'), 'yellow';
+ is $cobrand->pin_colour($report, 'my'), 'red';
+ $mech->get_ok('/report/' . $report->id);
+ $mech->content_contains('ref:&nbsp;' . $report->id);
+ };
+};
+
+done_testing();
diff --git a/t/cobrand/oxfordshire.t b/t/cobrand/oxfordshire.t
index 2625aa0d5..65c6a3864 100644
--- a/t/cobrand/oxfordshire.t
+++ b/t/cobrand/oxfordshire.t
@@ -1,11 +1,11 @@
-
use Test::MockModule;
-use FixMyStreet::Integrations::ExorRDI;
use FixMyStreet::TestMech;
+use FixMyStreet::Script::Alerts;
my $mech = FixMyStreet::TestMech->new;
my $oxon = $mech->create_body_ok(2237, 'Oxfordshire County Council');
+my $counciluser = $mech->create_user_ok('counciluser@example.com', name => 'Council User', from_body => $oxon);
subtest 'check /around?ajax defaults to open reports only' => sub {
my $categories = [ 'Bridges', 'Fences', 'Manhole' ];
@@ -31,7 +31,7 @@ subtest 'check /around?ajax defaults to open reports only' => sub {
}
FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ { 'oxfordshire' => '.' } ],
+ ALLOWED_COBRANDS => 'oxfordshire',
}, sub {
my $json = $mech->get_ok_json( '/around?ajax=1&status=all&bbox=' . $bbox );
my $pins = $json->{pins};
@@ -47,160 +47,87 @@ subtest 'check /around?ajax defaults to open reports only' => sub {
}
};
-my $superuser = $mech->create_user_ok('superuser@example.com', name => 'Super User', is_superuser => 1);
-my $inspector = $mech->create_user_ok('inspector@example.com', name => 'Inspector');
-$inspector->user_body_permissions->create({ body => $oxon, permission_type => 'report_inspect' });
+my @problems = FixMyStreet::DB->resultset('Problem')->search({}, { rows => 3, order_by => 'id' })->all;
-my @problems = FixMyStreet::DB->resultset('Problem')->search({}, { rows => 3 })->all;
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'oxfordshire',
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
-subtest 'Exor RDI download appears on Oxfordshire cobrand admin' => sub {
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ { 'oxfordshire' => '.' } ],
- }, sub {
- $mech->log_in_ok( $superuser->email );
- $mech->get_ok('/admin');
- $mech->content_contains("Download Exor RDI");
- }
-};
+ subtest 'can use customer reference to search for reports' => sub {
+ my $problem = $problems[0];
+ $problem->set_extra_metadata( customer_reference => 'ENQ12456' );
+ $problem->update;
-subtest "Exor RDI download doesn't appear outside of Oxfordshire cobrand admin" => sub {
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ],
- }, sub {
- $mech->log_in_ok( $superuser->email );
- $mech->get_ok('/admin');
- $mech->content_lacks("Download Exor RDI");
- }
-};
+ $mech->get_ok('/around?pc=ENQ12456');
+ is $mech->uri->path, '/report/' . $problem->id, 'redirects to report';
+ };
-subtest 'Exor file looks okay' => sub {
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'oxfordshire' ],
- MAPIT_URL => 'http://mapit.uk/',
- }, sub {
- $mech->log_in_ok( $superuser->email );
- $mech->get_ok('/admin/exordefects');
- $mech->submit_form_ok( { with_fields => {
- start_date => '2017-05-05',
- end_date => '2017-05-05',
- user_id => $inspector->id,
- } }, 'submit download');
- $mech->content_contains("No inspections by that inspector in the selected date range");
-
- my $dt = FixMyStreet::DB->resultset('DefectType')->create({
- body => $oxon,
- name => 'Footpath',
- description => 'Footpath stuff',
- });
- $dt->set_extra_metadata(activity_code => 'FC');
- $dt->set_extra_metadata(defect_code => 'SFP1');
- $dt->update;
- my $dt2 = FixMyStreet::DB->resultset('DefectType')->create({
- body => $oxon,
- name => 'Accidental sign damage',
- description => 'Accidental sign damage',
- });
- $dt2->set_extra_metadata(activity_code => 'S');
- $dt2->set_extra_metadata(defect_code => 'ACC2');
- $dt2->update;
- my $i = 123;
- foreach my $problem (@problems) {
- $problem->update({ state => 'action scheduled', external_id => $i });
- $problem->update({ defect_type => $dt }) if $i == 123;
- $problem->set_extra_metadata(traffic_information => 'Signs and Cones') if $i == 124;
- $problem->update({ defect_type => $dt2 }) if $i == 124;
- FixMyStreet::DB->resultset('AdminLog')->create({
- admin_user => $inspector->name,
- user => $inspector,
- object_type => 'problem',
- action => 'inspected',
- object_id => $problem->id,
- whenedited => DateTime->new(year => 2017, month => 5, day => 5, hour => 12),
- });
- $i++;
- }
- $mech->submit_form_ok( { with_fields => {
- start_date => '2017-05-05',
- end_date => '2017-05-05',
- user_id => $inspector->id,
- } }, 'submit download');
- (my $rdi = $mech->content) =~ s/\r\n/\n/g;
- $rdi =~ s/(I,[FMS]C?,,)\d+/$1XXX/g; # Remove unique ID figures, unknown order
- is $rdi, <<EOF, "RDI file matches expected";
-"1,1.8,1.0.0.0,ENHN,"
-"G,1989169,,,XX,170505,1600,D,INS,N,,,,"
-"H,FC"
-"I,FC,,XXX,"434970E 209683N Nearest postcode: OX28 4DS.",1200,,,,,,,,"TM none","123 XX TM0 ""
-"J,SFP1,2,,,434970,209683,,,,,"
-"M,resolve,,,/CFC,,"
-"P,0,999999"
-"G,1989169,,,XX,170505,1600,D,INS,N,,,,"
-"H,MC"
-"I,MC,,XXX,"434970E 209683N Nearest postcode: OX28 4DS.",1200,,,,,,,,"TM none","125 XX TM0 ""
-"J,SFP2,2,,,434970,209683,,,,,"
-"M,resolve,,,/CMC,,"
-"P,0,999999"
-"G,1989169,,,XX,170505,1600,D,INS,N,,,,"
-"H,S"
-"I,S,,XXX,"434970E 209683N Nearest postcode: OX28 4DS.",1200,,,,,,,,"TM Signs and Cones","124 XX TM1 ""
-"J,ACC2,2,,,434970,209683,,,,,"
-"M,resolve,,,/CSI,,"
-"P,0,999999"
-"X,3,3,3,3,0,0,0,3,0,3,0,0,0"
-EOF
- foreach my $problem (@problems) {
- $problem->discard_changes;
- is $problem->get_extra_metadata('rdi_processed'), undef, "Problem was not logged as sent in RDI";
- }
+ 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 $problem = $problems[0];
+ $problem->state( 'unable to fix' );
+ $problem->update;
-subtest 'Reports are marked as inspected correctly' => sub {
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'oxfordshire' ],
- MAPIT_URL => 'http://mapit.uk/',
- }, sub {
- my $date = DateTime->new(year => 2017, month => 5, day => 5, hour => 12);
-
- my $now = DateTime->now(
- time_zone => FixMyStreet->time_zone || FixMyStreet->local_time_zone
- );
- my $datetime = Test::MockModule->new('DateTime');
- $datetime->mock('now', sub { $now });
-
- my $params = {
- start_date => $date,
- end_date => $date,
- inspection_date => $date,
- user => $inspector,
- mark_as_processed => 1,
- };
- my $rdi = FixMyStreet::Integrations::ExorRDI->new($params);
- $rdi->construct;
-
- foreach my $problem (@problems) {
- $problem->discard_changes;
- is $problem->get_extra_metadata('rdi_processed'), $now->strftime( '%Y-%m-%d %H:%M' ), "Problem was logged as sent in RDI";
- }
+ my $alert = FixMyStreet::DB->resultset('Alert')->create( {
+ parameter => $problem->id,
+ alert_type => 'new_updates',
+ cobrand => 'oxfordshire',
+ user => $user,
+ } )->confirm;
+
+ FixMyStreet::DB->resultset('Comment')->create( {
+ problem_state => 'unable to fix',
+ problem_id => $problem->id,
+ user_id => $user2->id,
+ name => 'User',
+ mark_fixed => 'f',
+ text => "this is an update",
+ state => 'confirmed',
+ confirmed => 'now()',
+ anonymous => 'f',
+ } );
+
+
+ $mech->get_ok('/report/' . $problem->id);
+ $mech->content_contains('Investigation complete');
+
+ FixMyStreet::Script::Alerts::send();
+ $mech->email_count_is(1);
+ my $email = $mech->get_email;
+ my $body = $mech->get_text_body_from_email($email);
+ like $body, qr/Investigation complete/, 'state correct in email';
};
-};
-subtest 'can use customer reference to search for reports' => sub {
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'oxfordshire' ],
- MAPIT_URL => 'http://mapit.uk/',
- }, sub {
- my $problem = $problems[0];
- $problem->set_extra_metadata( customer_reference => 'ENQ12456' );
- $problem->update;
+ subtest 'extra CSV columns are present' => sub {
- $mech->log_out_ok;
- $mech->get_ok('/around?pc=ENQ12456');
- is $mech->uri->path, '/report/' . $problem->id, 'redirects to report';
+ $problems[1]->update({ external_id => $problems[1]->id });
+ $problems[2]->update({ external_id => "123098123" });
+
+ $mech->log_in_ok( $counciluser->email );
+
+ $mech->get_ok('/dashboard?export=1');
+
+ my @rows = $mech->content_as_csv;
+ is scalar @rows, 7, '1 (header) + 6 (reports) = 7 lines';
+ is scalar @{$rows[0]}, 21, '21 columns present';
+
+ is_deeply $rows[0],
+ [
+ 'Report ID', 'Title', 'Detail', 'User Name', 'Category',
+ 'Created', 'Confirmed', 'Acknowledged', 'Fixed', 'Closed',
+ 'Status', 'Latitude', 'Longitude', 'Query', 'Ward',
+ 'Easting', 'Northing', 'Report URL', 'Site Used',
+ 'Reported As', 'HIAMS/Exor Ref',
+ ],
+ 'Column headers look correct';
+
+ is $rows[1]->[20], 'ENQ12456', 'HIAMS reference included in row';
+ is $rows[2]->[20], '', 'Report without HIAMS ref has empty ref field';
+ is $rows[3]->[20], '123098123', 'Older Exor report has correct ref';
};
};
-END {
- done_testing();
-}
+done_testing();
diff --git a/t/cobrand/peterborough.t b/t/cobrand/peterborough.t
new file mode 100644
index 000000000..5d07acb9f
--- /dev/null
+++ b/t/cobrand/peterborough.t
@@ -0,0 +1,84 @@
+use FixMyStreet::TestMech;
+use FixMyStreet::Script::Reports;
+use CGI::Simple;
+
+my $mech = FixMyStreet::TestMech->new;
+
+my $params = {
+ send_method => 'Open311',
+ send_comments => 1,
+ api_key => 'KEY',
+ endpoint => 'endpoint',
+ jurisdiction => 'home',
+ can_be_devolved => 1,
+};
+my $peterborough = $mech->create_body_ok(2566, 'Peterborough City Council', $params);
+
+subtest 'open311 request handling', sub {
+ FixMyStreet::override_config {
+ STAGING_FLAGS => { send_reports => 1 },
+ ALLOWED_COBRANDS => ['peterborough' ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ my $contact = $mech->create_contact_ok(body_id => $peterborough->id, category => 'Trees', email => 'TREES');
+ my ($p) = $mech->create_problems_for_body(1, $peterborough->id, 'Title', { category => 'Trees', latitude => 52.5608, longitude => 0.2405, cobrand => 'peterborough' });
+ $p->push_extra_fields({ name => 'emergency', value => 'no'});
+ $p->push_extra_fields({ name => 'private_land', value => 'no'});
+ $p->push_extra_fields({ name => 'PCC-light', value => 'whatever'});
+ $p->push_extra_fields({ name => 'PCC-skanska-csc-ref', value => '1234'});
+ $p->push_extra_fields({ name => 'tree_code', value => 'tree-42'});
+ $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 correct external ID';
+ is $p->get_extra_field_value('emergency'), 'no';
+
+ my $req = $test_data->{test_req_used};
+ my $c = CGI::Simple->new($req->content);
+ is $c->param('attribute[description]'), "Title Test 1 for " . $peterborough->id . " Detail\r\n\r\nSkanska CSC ref: 1234", 'Ref added to description';
+ is $c->param('attribute[emergency]'), undef, 'no emergency param sent';
+ is $c->param('attribute[private_land]'), undef, 'no private_land param sent';
+ is $c->param('attribute[PCC-light]'), undef, 'no pcc- param sent';
+ is $c->param('attribute[tree_code]'), 'tree-42', 'tree_code param sent';
+ };
+};
+
+subtest "extra update params are sent to open311" => sub {
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ ALLOWED_COBRANDS => 'peterborough',
+ }, sub {
+ my $contact = $mech->create_contact_ok(body_id => $peterborough->id, category => 'Trees', email => 'TREES');
+ 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>ezytreev-248</update_id></request_update></service_request_updates>');
+
+ my $o = Open311->new(
+ fixmystreet_body => $peterborough,
+ test_mode => 1,
+ test_get_returns => { 'servicerequestupdates.xml' => $test_res },
+ );
+
+ my ($p) = $mech->create_problems_for_body(1, $peterborough->id, 'Title', { external_id => 1, category => 'Trees' });
+
+ my $c = FixMyStreet::DB->resultset('Comment')->create({
+ problem => $p, user => $p->user, anonymous => 't', text => 'Update text',
+ problem_state => 'fixed - council', state => 'confirmed', mark_fixed => 0,
+ confirmed => DateTime->now(),
+ });
+
+ my $id = $o->post_service_request_update($c);
+ is $id, "ezytreev-248", 'correct update ID returned';
+ my $cgi = CGI::Simple->new($o->test_req_used->content);
+ is $cgi->param('description'), '[Customer FMS update] Update text', 'FMS update prefix included';
+ is $cgi->param('service_request_id_ext'), $p->id, 'Service request ID included';
+ is $cgi->param('service_code'), $contact->email, 'Service code included';
+ };
+};
+
+done_testing;
diff --git a/t/cobrand/restriction.t b/t/cobrand/restriction.t
index 63fe326b1..185f365c8 100644
--- a/t/cobrand/restriction.t
+++ b/t/cobrand/restriction.t
@@ -19,7 +19,10 @@ package main;
use FixMyStreet::TestMech;
-my $c = FixMyStreet::App->new;
+use Catalyst::Test 'FixMyStreet::App';
+
+my ($res, $c) = ctx_request('/');
+
my $cobrand = FixMyStreet::Cobrand::Tester->new({c => $c});
$c->stash->{cobrand} = $cobrand;
diff --git a/t/cobrand/staging.t b/t/cobrand/staging.t
new file mode 100644
index 000000000..5d79daa4b
--- /dev/null
+++ b/t/cobrand/staging.t
@@ -0,0 +1,18 @@
+use FixMyStreet::TestMech;
+my $mech = FixMyStreet::TestMech->new;
+
+subtest 'staging banner is visible by default on staging sites' => sub {
+ $mech->get_ok('/');
+ $mech->content_contains('<div class="dev-site-notice">');
+};
+
+FixMyStreet::override_config {
+ STAGING_FLAGS => { hide_staging_banner => 1 },
+}, sub {
+ subtest 'staging banner can be hidden through STAGING_FLAGS config' => sub {
+ $mech->get_ok('/');
+ $mech->content_lacks('<div class="dev-site-notice">');
+ };
+};
+
+done_testing();
diff --git a/t/cobrand/tfl.t b/t/cobrand/tfl.t
new file mode 100644
index 000000000..8ddc3d671
--- /dev/null
+++ b/t/cobrand/tfl.t
@@ -0,0 +1,1089 @@
+use FixMyStreet::TestMech;
+use FixMyStreet::App;
+use FixMyStreet::Script::Reports;
+use FixMyStreet::Script::Questionnaires;
+
+# disable info logs for this test run
+FixMyStreet::App->log->disable('info');
+END { FixMyStreet::App->log->enable('info'); }
+
+my $mech = FixMyStreet::TestMech->new;
+
+use t::Mock::Tilma;
+my $tilma = t::Mock::Tilma->new;
+LWP::Protocol::PSGI->register($tilma->to_psgi_app, host => 'tilma.mysociety.org');
+
+
+my $body = $mech->create_body_ok(2482, 'TfL');
+FixMyStreet::DB->resultset('BodyArea')->find_or_create({
+ area_id => 2483, # Hounslow
+ body_id => $body->id,
+});
+FixMyStreet::DB->resultset('BodyArea')->find_or_create({
+ area_id => 2457, # Epsom Ewell, outside London, for bus stop test
+ 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({
+ body => $body,
+ permission_type => 'contribute_as_body',
+});
+$staffuser->user_body_permissions->create({
+ body => $body,
+ permission_type => 'default_to_body',
+});
+my $user = $mech->create_user_ok('londonresident@example.com');
+
+my $bromley = $mech->create_body_ok(2482, 'Bromley');
+my $bromleyuser = $mech->create_user_ok('bromleyuser@bromley.example.com', name => 'Bromley Staff', from_body => $bromley);
+$mech->create_contact_ok(
+ body_id => $bromley->id,
+ category => 'Accumulated Litter',
+ email => 'litter-bromley@example.com',
+);
+my $bromley_flooding = $mech->create_contact_ok(
+ body_id => $bromley->id,
+ category => 'Flooding (Bromley)',
+ email => 'litter-bromley@example.com',
+);
+$bromley_flooding->set_extra_metadata(display_name => 'Flooding');
+$bromley_flooding->update;
+
+my $bromley_flytipping = $mech->create_contact_ok(
+ body_id => $bromley->id,
+ category => 'Flytipping (Bromley)',
+ email => 'flytipping-bromley@example.com',
+);
+$bromley_flytipping->set_extra_metadata(group => [ 'Street cleaning' ]);
+$bromley_flytipping->update;
+
+my $contact1 = $mech->create_contact_ok(
+ body_id => $body->id,
+ category => 'Bus stops',
+ email => 'busstops@example.com',
+);
+$contact1->set_extra_metadata(group => [ 'Bus things' ]);
+$contact1->set_extra_fields(
+ {
+ code => 'leaning',
+ description => 'Is the pole leaning?',
+ datatype => 'string',
+ },
+ {
+ code => 'stop_code',
+ description => 'Stop number',
+ datatype => 'string',
+ automated => 'hidden_field',
+ }
+);
+$contact1->update;
+my $contact2 = $mech->create_contact_ok(
+ body_id => $body->id,
+ category => 'Traffic lights',
+ email => 'trafficlights@example.com',
+);
+$contact2->set_extra_fields({
+ code => "safety_critical",
+ description => "Safety critical",
+ automated => "hidden_field",
+ order => 1,
+ datatype => "singlevaluelist",
+ values => [
+ {
+ name => "Yes",
+ key => "yes"
+ },
+ {
+ name => "No",
+ key => "no"
+ }
+ ]
+});
+$contact2->update;
+my $contact2b = $mech->create_contact_ok(
+ body_id => $body->id,
+ category => 'Timings',
+ email => 'trafficlighttimings@example.com',
+);
+
+my $contact3 = $mech->create_contact_ok(
+ body_id => $body->id,
+ category => 'Pothole',
+ email => 'pothole@example.com',
+);
+$contact3->set_extra_fields({
+ code => "safety_critical",
+ description => "Safety critical",
+ automated => "hidden_field",
+ order => 1,
+ datatype => "singlevaluelist",
+ values => [
+ {
+ name => "Yes",
+ key => "yes"
+ },
+ {
+ name => "No",
+ key => "no"
+ }
+ ]
+});
+$contact3->update;
+my $contact4 = $mech->create_contact_ok(
+ body_id => $body->id,
+ category => 'Flooding',
+ email => 'flooding@example.com',
+);
+$contact4->set_extra_fields(
+ {
+ code => "safety_critical",
+ description => "Safety critical",
+ automated => "hidden_field",
+ order => 1,
+ datatype => "singlevaluelist",
+ values => [
+ {
+ name => "Yes",
+ key => "yes"
+ },
+ {
+ name => "No",
+ key => "no"
+ }
+ ]
+ },
+ {
+ code => "location",
+ description => "Where is the flooding?",
+ variable => "true",
+ order => 1,
+ required => "true",
+ datatype => "singlevaluelist",
+ values => [
+ {
+ name => "Carriageway",
+ key => "carriageway"
+ },
+ {
+ name => "Footway",
+ key => "footway"
+ }
+ ]
+ }
+);
+$contact4->update;
+my $contact5 = $mech->create_contact_ok(
+ body_id => $body->id,
+ category => 'Trees',
+ email => 'AOAT',
+);
+my $contact6 = $mech->create_contact_ok(
+ body_id => $body->id,
+ category => 'Grit bins',
+ email => 'AOAT,gritbins@example.com',
+);
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'tfl', 'bromley', 'fixmystreet'],
+ MAPIT_URL => 'http://mapit.uk/',
+ COBRAND_FEATURES => {
+ internal_ips => { tfl => [ '127.0.0.1' ] },
+ base_url => {
+ tfl => 'https://street.tfl'
+ },
+ borough_email_addresses => { tfl => {
+ AOAT => [
+ {
+ email => 'hounslow@example.com',
+ areas => [ 2483 ],
+ },
+ {
+ email => 'bromley@example.com',
+ areas => [ 2482 ],
+ },
+ ],
+ } },
+ anonymous_account => {
+ tfl => 'anonymous'
+ },
+ contact_name => {
+ tfl => 'TfL Street Care',
+ },
+ do_not_reply_email => {
+ tfl => 'fms-tfl-DO-NOT-REPLY@example.com',
+ },
+ send_questionnaire => {
+ fixmystreet => {
+ TfL => 0,
+ }
+ },
+ },
+}, sub {
+
+$mech->host("tfl.fixmystreet.com");
+
+subtest "test report creation anonymously by button" => sub {
+ $mech->get_ok('/around');
+ $mech->submit_form_ok( { with_fields => { pc => 'BR1 3UH', } }, "submit location" );
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" );
+ $mech->submit_form_ok(
+ {
+ button => 'report_anonymously',
+ with_fields => {
+ title => 'Anonymous Test Report 1',
+ detail => 'Test report details.',
+ category => 'Bus stops',
+ }
+ },
+ "submit report anonymously"
+ );
+ my $report = FixMyStreet::DB->resultset("Problem")->find({ title => 'Anonymous Test Report 1'});
+ ok $report, "Found the report";
+
+ $mech->content_contains('Your issue is on its way to Transport for London');
+ $mech->content_contains('Your reference for this report is FMS' . $report->id) or diag $mech->content;
+
+ is_deeply $mech->page_errors, [], "check there were no errors";
+
+ is $report->state, 'confirmed', "report confirmed";
+ $mech->get_ok( '/report/' . $report->id );
+
+ is $report->bodies_str, $body->id;
+ is $report->name, 'Anonymous user';
+ is $report->user->email, 'anonymous@tfl.gov.uk';
+ is $report->anonymous, 1; # Doesn't change behaviour here, but uses anon account's name always
+ is $report->get_extra_metadata('contributed_as'), 'anonymous_user';
+
+ my $alert = FixMyStreet::App->model('DB::Alert')->find( {
+ user => $report->user,
+ alert_type => 'new_updates',
+ parameter => $report->id,
+ } );
+ is $alert, undef, "no alert created";
+
+ $mech->not_logged_in_ok;
+};
+
+subtest "test report creation anonymously by staff user" => sub {
+ $mech->clear_emails_ok;
+ $mech->log_in_ok( $staffuser->email );
+ $mech->get_ok('/around');
+ $mech->submit_form_ok( { with_fields => { pc => 'BR1 3UH', } }, "submit location" );
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" );
+ $mech->submit_form_ok(
+ {
+ button => 'report_anonymously',
+ with_fields => {
+ title => 'Anonymous Test Report 2',
+ detail => 'Test report details.',
+ category => 'Bus stops',
+ }
+ },
+ "submit report"
+ );
+ is_deeply $mech->page_errors, [], "check there were no errors";
+
+ my $report = FixMyStreet::DB->resultset("Problem")->find({ title => 'Anonymous Test Report 2'});
+ ok $report, "Found the report";
+
+ $mech->content_contains('Your issue is on its way to Transport for London');
+ $mech->content_contains('Your reference for this report is FMS' . $report->id) or diag $mech->content;
+
+ is $report->state, 'confirmed', "report confirmed";
+ $mech->get_ok( '/report/' . $report->id );
+
+ $report->update({ state => 'fixed - council' });
+ my $json = $mech->get_ok_json('/around/nearby?latitude=' . $report->latitude . '&longitude=' . $report->longitude);
+ is @{$json->{pins}}, 2, 'right number of pins';
+
+ is $report->bodies_str, $body->id;
+ is $report->name, 'Anonymous user';
+ is $report->user->email, 'anonymous@tfl.gov.uk';
+ is $report->anonymous, 1;
+ is $report->get_extra_metadata('contributed_as'), 'anonymous_user';
+
+ my $alerts = FixMyStreet::App->model('DB::Alert')->search( {
+ alert_type => 'new_updates',
+ parameter => $report->id,
+ } );
+ is $alerts->count, 0, "no alerts created";
+ ok $mech->email_count_is(0), "no emails sent";
+
+ $mech->log_out_ok;
+};
+
+FixMyStreet::DB->resultset("Problem")->delete_all;
+
+subtest "test report creation and reference number" => sub {
+ $mech->log_in_ok( $user->email );
+ $mech->get_ok('/around');
+ $mech->submit_form_ok( { with_fields => { pc => 'BR1 3UH', } }, "submit location" );
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" );
+ $mech->submit_form_ok(
+ {
+ with_fields => {
+ title => 'Test Report 1',
+ detail => 'Test report details.',
+ name => 'Joe Bloggs',
+ may_show_name => '1',
+ category => 'Bus stops',
+ }
+ },
+ "submit good details"
+ );
+
+ my $report = FixMyStreet::DB->resultset("Problem")->find({ title => 'Test Report 1'});
+ ok $report, "Found the report";
+
+ $mech->content_contains('Your issue is on its way to Transport for London');
+ $mech->content_contains('Your reference for this report is FMS' . $report->id) or diag $mech->content;
+
+ is_deeply $mech->page_errors, [], "check there were no errors";
+
+ is $report->state, 'confirmed', "report confirmed";
+
+ is $report->bodies_str, $body->id;
+ is $report->name, 'Joe Bloggs';
+};
+
+subtest "test bus report creation outside London, .com" => sub {
+ $mech->host('www.fixmystreet.com');
+ $mech->get_ok('/report/new?latitude=51.345714&longitude=-0.227959');
+ $mech->content_lacks('Bus things');
+ $mech->host('tfl.fixmystreet.com');
+};
+
+subtest "test bus report creation outside London" => sub {
+ $mech->get_ok('/report/new?latitude=51.345714&longitude=-0.227959');
+ $mech->submit_form_ok(
+ {
+ with_fields => {
+ # A bus stop in East Ewell
+ latitude => 51.345714,
+ longitude => -0.227959,
+ title => 'Test outwith London',
+ detail => 'Test report details.',
+ name => 'Joe Bloggs',
+ may_show_name => '1',
+ category => 'Bus stops',
+ }
+ },
+ "submit good details"
+ );
+ $mech->content_contains('Your issue is on its way to Transport for London');
+ is_deeply $mech->page_errors, [], "check there were no errors";
+
+ my $report = FixMyStreet::DB->resultset("Problem")->find({ title => 'Test outwith London'});
+ ok $report, "Found the report";
+ is $report->state, 'confirmed', "report confirmed";
+ is $report->bodies_str, $body->id;
+ $report->delete;
+
+ $mech->log_out_ok;
+};
+
+subtest "extra information included in email" => sub {
+ my $report = FixMyStreet::DB->resultset("Problem")->find({ title => 'Test Report 1'});
+ $report->set_extra_fields({ name => 'stop_code', value => '12345678' });
+ $report->update;
+ my $id = $report->id;
+
+ $mech->clear_emails_ok;
+ FixMyStreet::Script::Reports::send();
+ my @email = $mech->get_email;
+ is $email[0]->header('To'), 'TfL <busstops@example.com>';
+ like $mech->get_text_body_from_email($email[0]), qr/Report reference: FMS$id/, "FMS-prefixed ID in TfL email";
+ like $mech->get_text_body_from_email($email[0]), qr/Stop number: 12345678/, "Bus stop code in TfL email";
+ is $email[1]->header('To'), $report->user->email;
+ is $email[1]->header('From'), '"TfL Street Care" <fms-tfl-DO-NOT-REPLY@example.com>';
+ like $mech->get_text_body_from_email($email[1]), qr/report's reference number is FMS$id/, "FMS-prefixed ID in reporter email";
+ $mech->clear_emails_ok;
+
+ $mech->get_ok( '/report/' . $report->id );
+ $mech->content_contains('FMS' . $report->id) or diag $mech->content;
+};
+
+subtest 'Dashboard CSV extra columns' => sub {
+ my $report = FixMyStreet::DB->resultset("Problem")->find({ title => 'Test Report 1'});
+ $report->set_extra_fields({ name => 'leaning', value => 'Yes' });
+ $report->update;
+
+ $mech->log_in_ok( $staffuser->email );
+ $mech->get_ok('/dashboard?export=1&category=Bus+stops');
+ $mech->content_contains('Category,Subcategory');
+ $mech->content_contains('Query,Borough');
+ $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,');
+ $mech->content_contains(',,,no,busstops@example.com,,,,Yes');
+
+ $report->set_extra_fields({ name => 'safety_critical', value => 'yes' });
+ $report->anonymous(1);
+ $report->update;
+ my $dt = DateTime->now();
+ FixMyStreet::DB->resultset("AdminLog")->create({
+ action => 'category_change',
+ whenedited => $dt,
+ object_id => $report->id,
+ object_type => 'problem',
+ admin_user => $staffuser->name,
+ user => $staffuser,
+ });
+ $mech->get_ok('/dashboard?export=1');
+ $mech->content_contains('Query,Borough');
+ $mech->content_contains(',"Safety critical","Delivered to","Closure email at","Reassigned at","Reassigned by"');
+ $mech->content_contains('(anonymous ' . $report->id . ')');
+ $mech->content_contains(',,,yes,busstops@example.com,,' . $dt . ',"Council User"');
+};
+
+subtest 'Inspect form state choices' => sub {
+ my $report = FixMyStreet::DB->resultset("Problem")->find({ title => 'Test Report 1'});
+ my $id = $report->id;
+ $mech->get_ok("/report/$id");
+ $mech->content_lacks('for triage');
+ $mech->content_lacks('action scheduled');
+};
+
+subtest "change category, report resent to new location" => sub {
+ my $report = FixMyStreet::DB->resultset("Problem")->find({ title => 'Test Report 1'});
+ my $id = $report->id;
+
+ $mech->log_in_ok( $superuser->email );
+ $mech->get_ok("/admin/report_edit/$id");
+ $mech->content_lacks('Timings');
+ $mech->submit_form_ok({ with_fields => { category => 'Traffic lights' } });
+
+ FixMyStreet::Script::Reports::send();
+ my @email = $mech->get_email;
+ is $email[0]->header('To'), 'TfL <trafficlights@example.com>';
+ $mech->clear_emails_ok;
+
+ $mech->log_out_ok;
+};
+
+for my $test (
+ [ 'BR1 3UH', 'tfl.fixmystreet.com', 'Trees', 'TfL <bromley@example.com>', 'Bromley borough team', 'reference number is FMS' ],
+ [ 'BR1 3UH', 'www.fixmystreet.com', 'Trees', 'TfL <bromley@example.com>', 'Bromley borough team', 'reference number is' ],
+ [ 'BR1 3UH', 'bromley.fixmystreet.com', 'Trees', 'TfL <bromley@example.com>', 'Bromley borough team', '' ],
+ [ 'TW7 5JN', 'tfl.fixmystreet.com', 'Trees', 'TfL <hounslow@example.com>', 'Hounslow borough team', 'reference number is FMS' ],
+ [ 'TW7 5JN', 'www.fixmystreet.com', 'Trees', 'TfL <hounslow@example.com>', 'Hounslow borough team', 'reference number is' ],
+ [ 'TW7 5JN', 'tfl.fixmystreet.com', 'Grit bins', 'TfL <hounslow@example.com>, TfL <gritbins@example.com>', 'Hounslow borough team and additional address', 'reference number is FMS' ],
+ [ 'TW7 5JN', 'www.fixmystreet.com', 'Grit bins', 'TfL <hounslow@example.com>, TfL <gritbins@example.com>', 'Hounslow borough team and additional address', 'reference number is' ],
+) {
+ my ($postcode, $host, $category, $to, $name, $ref ) = @$test;
+ subtest "test report is sent to $name on $host" => sub {
+ $mech->host($host);
+ $mech->log_in_ok( $user->email );
+ $mech->get_ok('/around');
+ $mech->submit_form_ok( { with_fields => { pc => $postcode, } }, "submit location" );
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" );
+ $mech->submit_form_ok(
+ {
+ with_fields => {
+ title => 'Test Report for borough team',
+ detail => 'Test report details.',
+ may_show_name => '1',
+ category => $category,
+ $host eq 'bromley.fixmystreet.com' ? (
+ fms_extra_title => 'DR',
+ first_name => "Joe",
+ last_name => "Bloggs",
+ ) : (
+ name => 'Joe Bloggs',
+ ),
+ }
+ },
+ "submit good details"
+ );
+
+ $mech->clear_emails_ok;
+ FixMyStreet::Script::Reports::send();
+ my @email = $mech->get_email;
+ is $email[0]->header('To'), $to, 'Sent to correct address';
+ like $email[0]->as_string, qr/iEYI87gX6Upb\+tKYzrSmN83pTnv606AOtahHTepSm/, 'Right logo';
+ like $mech->get_text_body_from_email($email[0]), qr/https:\/\/street.tfl/, 'Correct link';
+ like $mech->get_text_body_from_email($email[1]), qr/$ref/, "Correct reference number in reporter email" if $ref;
+ $mech->clear_emails_ok;
+ FixMyStreet::DB->resultset("Problem")->find({ title => 'Test Report for borough team'})->delete;
+ };
+}
+
+$mech->host("tfl.fixmystreet.com");
+
+subtest 'check lookup by reference' => sub {
+ my $id = FixMyStreet::DB->resultset("Problem")->first->id;
+
+ $mech->get_ok('/');
+ $mech->submit_form_ok( { with_fields => { pc => 'FMS12345' } }, 'bad ref');
+ $mech->content_contains('Searching found no reports');
+
+ $mech->get_ok('/');
+ $mech->submit_form_ok( { with_fields => { pc => "FMS$id" } }, 'good FMS-prefixed ref');
+ is $mech->uri->path, "/report/$id", "redirected to report page when using FMS-prefixed ref";
+
+ $mech->get_ok('/');
+ $mech->submit_form_ok( { with_fields => { pc => "fms $id" } }, 'good FMS-prefixed with a space ref');
+ is $mech->uri->path, "/report/$id", "redirected to report page when using FMS-prefixed ref";
+
+ $mech->get_ok('/');
+ $mech->submit_form_ok( { with_fields => { pc => "$id" } }, 'good ref');
+ is $mech->uri->path, "/report/$id", "redirected to report page when using non-prefixed ref";
+};
+
+for my $test (
+ {
+ states => [ 'confirmed' ],
+ colour => 'red'
+ },
+ {
+ states => ['action scheduled', 'in progress', 'investigating', 'planned'],
+ colour => 'orange'
+ },
+ {
+ states => [ FixMyStreet::DB::Result::Problem->fixed_states, FixMyStreet::DB::Result::Problem->closed_states ],
+ colour => 'green'
+ },
+) {
+ subtest 'check ' . $test->{colour} . ' pin states' => sub {
+ my $report = FixMyStreet::DB->resultset("Problem")->find({ title => 'Test Report 1'});
+ my $url = '/around?ajax=1&bbox=' . ($report->longitude - 0.01) . ',' . ($report->latitude - 0.01)
+ . ',' . ($report->longitude + 0.01) . ',' . ($report->latitude + 0.01);
+
+ for my $state ( @{ $test->{states} } ) {
+ $report->update({ state => $state });
+ my $json = $mech->get_ok_json( $url );
+ my $colour = $json->{pins}[0][2];
+ is $colour, $test->{colour}, 'correct ' . $test->{colour} . ' pin for state ' . $state;
+ }
+ };
+}
+
+subtest 'check correct base URL & title in AJAX pins' => sub {
+ my $report = FixMyStreet::DB->resultset("Problem")->find({ title => 'Test Report 1'});
+ my $url = '/around?ajax=1&bbox=' . ($report->longitude - 0.01) . ',' . ($report->latitude - 0.01)
+ . ',' . ($report->longitude + 0.01) . ',' . ($report->latitude + 0.01);
+
+ $report->update({ state => 'confirmed' });
+ $report->discard_changes;
+ is $report->cobrand, 'tfl', 'Report made on TfL cobrand';
+
+ $mech->host("fixmystreet.com");
+ my $json = $mech->get_ok_json( $url );
+ is $json->{pins}[0][4], $report->category . " problem", "category is used for title" or diag $mech->content;
+ is $json->{pins}[0][7], "https://street.tfl", "base_url is included and correct" or diag $mech->content;
+
+ $mech->host("tfl.fixmystreet.com");
+ $json = $mech->get_ok_json( $url );
+ is $json->{pins}[0][4], $report->title, "title is shown on TfL cobrand" or diag $mech->content;
+ is $json->{pins}[0][7], undef, "base_url is not present on TfL cobrand response";
+
+ $mech->host("fixmystreet.com");
+ $report->update({cobrand => 'fixmystreet'});
+ $json = $mech->get_ok_json( $url );
+ is $json->{pins}[0][4], $report->title, "title is shown if report made on fixmystreet cobrand" or diag $mech->content;
+ is $json->{pins}[0][7], undef, "base_url is not present if report made on fixmystreet cobrand";
+
+ $report->update({cobrand => 'tfl'});
+ $mech->host("tfl.fixmystreet.com");
+};
+
+subtest 'check report age on /around' => sub {
+ $mech->log_in_ok($staffuser->email);
+ my $report = FixMyStreet::DB->resultset("Problem")->find({ title => 'Test Report 1'});
+ $report->update({ state => 'confirmed' });
+
+ $mech->get_ok( '/around?lat=' . $report->latitude . '&lon=' . $report->longitude );
+ $mech->content_contains($report->title);
+ $mech->content_contains('item-list__item__borough">Bromley');
+
+ $report->update({
+ confirmed => \"current_timestamp-'7 weeks'::interval",
+ whensent => \"current_timestamp-'7 weeks'::interval",
+ lastupdate => \"current_timestamp-'7 weeks'::interval",
+ });
+
+ $mech->get_ok( '/around?lat=' . $report->latitude . '&lon=' . $report->longitude );
+ $mech->content_lacks($report->title);
+
+ $report->update({
+ confirmed => \"current_timestamp",
+ whensent => \"current_timestamp",
+ lastupdate => \"current_timestamp",
+ });
+};
+
+subtest 'check report age in general' => sub {
+ my $report = FixMyStreet::DB->resultset("Problem")->find({ title => 'Test Report 1'});
+ $report->update({ state => 'confirmed' });
+ $mech->get_ok('/report/' . $report->id);
+ $report->update({ lastupdate => \"current_timestamp-'4 years'::interval" });
+ $mech->get('/report/' . $report->id);
+ is $mech->res->code, 404;
+ $report->update({ lastupdate => \"current_timestamp" });
+};
+
+subtest 'TfL admin allows inspectors to be assigned to borough areas' => sub {
+ $mech->log_in_ok($superuser->email);
+
+ $mech->get_ok("/admin/users/" . $staffuser->id) or diag $mech->content;
+
+ $mech->submit_form_ok( { with_fields => {
+ area_ids => [2482],
+ } } );
+
+ $staffuser->discard_changes;
+ is_deeply $staffuser->area_ids, [2482], "User assigned to Bromley LBO area";
+
+ $staffuser->update({ area_ids => undef}); # so login below doesn't break
+};
+
+my $report = FixMyStreet::DB->resultset("Problem")->find({ title => 'Test Report 1'});
+$report->update({ cobrand => 'fixmystreet' });
+$staffuser->add_to_planned_reports($report);
+
+for my $host ( 'www.fixmystreet.com', 'tfl.fixmystreet.com' ) {
+ subtest "Leave an update on a shortlisted report on $host, get an email" => sub {
+ $mech->host($host);
+ $mech->log_in_ok( $user->email );
+ $mech->get_ok('/report/' . $report->id);
+ $mech->submit_form_ok({ with_fields => { update => 'This is an update' }});
+ my $email = $mech->get_email;
+ my $text = $mech->get_text_body_from_email;
+ like $text, qr/This is an update/, 'Right email';
+ like $text, qr/street.tfl/, 'Right url';
+ like $text, qr/Street Care/, 'Right name';
+ like $email->as_string, qr/iEYI87gX6Upb\+tKYzrSmN83pTnv606AOtahHTepSm/, 'Right logo';
+ };
+}
+
+subtest 'TfL staff can access TfL admin' => sub {
+ $mech->log_in_ok( $staffuser->email );
+ $mech->get_ok('/admin');
+ $mech->content_contains( 'This is the administration interface for' );
+ $mech->log_out_ok;
+};
+
+subtest 'Bromley staff cannot access TfL admin' => sub {
+ $mech->log_in_ok( $bromleyuser->email );
+ ok $mech->get('/admin');
+ is $mech->res->code, 403, "got 403";
+ $mech->log_out_ok;
+};
+
+subtest 'Test passwords work appropriately' => sub {
+ $mech->host('www.fixmystreet.com');
+ $mech->get_ok('/auth');
+ $user->password('dotcom');
+ $user->update;
+ $mech->submit_form_ok(
+ { with_fields => { username => $user->email, password_sign_in => 'dotcom' } },
+ "sign in using form" );
+ $mech->content_contains('Your account');
+ $mech->host('tfl.fixmystreet.com');
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok(
+ { with_fields => { username => $user->email, password_sign_in => 'dotcom' } },
+ "sign in using form" );
+ $mech->content_lacks('Your account');
+
+ $user->password('tfl');
+ $user->update;
+ $mech->submit_form_ok(
+ { with_fields => { username => $user->email, password_sign_in => 'tfl' } },
+ "sign in using form" );
+ $mech->content_contains('Your account');
+ $mech->host('www.fixmystreet.com');
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok(
+ { with_fields => { username => $user->email, password_sign_in => 'tfl' } },
+ "sign in using form" );
+ $mech->content_lacks('Your account');
+};
+
+my $tfl_report;
+subtest 'Test user reports are visible on cobrands appropriately' => sub {
+ ($tfl_report) = $mech->create_problems_for_body(1, $body->id, 'Test TfL report made on TfL', { cobrand => 'tfl' });
+ $mech->create_problems_for_body(1, $body->id, 'Test TfL report made on .com', { cobrand => 'fixmystreet' });
+ $mech->create_problems_for_body(1, $bromley->id, 'Test Bromley report made on .com', { cobrand => 'fixmystreet' });
+
+ $mech->log_in_ok('test@example.com');
+ $mech->get_ok('/my');
+ $mech->content_contains('1 to 2 of 2');
+ $mech->content_contains('Test TfL report made on .com');
+ $mech->content_lacks('Test TfL report made on TfL');
+ $mech->content_contains('Test Bromley report');
+
+ $mech->host('tfl.fixmystreet.com');
+ $mech->log_in_ok('test@example.com');
+ $mech->get_ok('/my');
+ $mech->content_contains('1 to 2 of 2');
+ $mech->content_contains('Test TfL report made on .com');
+ $mech->content_contains('Test TfL report made on TfL');
+ $mech->content_lacks('Test Bromley report');
+};
+
+subtest 'Test public reports are visible on cobrands appropriately' => sub {
+ $mech->get_ok('/around?pc=SW1A+1AA');
+ $mech->content_contains('Test TfL report made on .com');
+ $mech->content_contains('Test TfL report made on TfL');
+ $mech->content_lacks('Test Bromley report');
+
+ $mech->host('www.fixmystreet.com');
+ $mech->get_ok('/around?pc=SW1A+1AA');
+ $mech->content_contains('Test TfL report made on .com');
+ $mech->content_lacks('Test TfL report made on TfL');
+ $mech->content_contains('Test Bromley report');
+ $mech->content_contains('https://street.tfl/report/' . $tfl_report->id);
+ $mech->content_contains('Other problem');
+};
+
+subtest 'Test no questionnaire sending' => sub {
+ $report->update({ send_questionnaire => 1, whensent => \"current_timestamp-'7 weeks'::interval" });
+ FixMyStreet::Script::Questionnaires::send();
+ $mech->email_count_is(0);
+};
+
+};
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'tfl', 'bromley', 'fixmystreet' ],
+ MAPIT_URL => 'http://mapit.uk/',
+ COBRAND_FEATURES => {
+ internal_ips => { tfl => [ '127.0.0.1' ] },
+ safety_critical_categories => { tfl => {
+ Pothole => 1,
+ Flooding => {
+ location => [ "carriageway" ],
+ },
+ } },
+ anonymous_account => {
+ tfl => 'anonymous'
+ },
+ do_not_reply_email => {
+ tfl => 'fms-tfl-DO-NOT-REPLY@example.com',
+ },
+ },
+}, sub {
+
+for my $test (
+ {
+ host => 'www.fixmystreet.com',
+ name => "test red route categories",
+ lat => 51.4039,
+ lon => 0.018697,
+ expected => [
+ 'Accumulated Litter', # Tests TfL->_cleaning_categories
+ 'Bus stops',
+ 'Flooding',
+ 'Flytipping (Bromley)', # In the 'Street cleaning' group
+ 'Grit bins',
+ 'Pothole',
+ 'Timings',
+ 'Traffic lights',
+ 'Trees'
+ ],
+ },
+ {
+ host => 'www.fixmystreet.com',
+ name => "test non-red route categories",
+ lat => 51.4021,
+ lon => 0.01578,
+ expected => [
+ 'Accumulated Litter', # Tests TfL->_cleaning_categories
+ 'Bus stops',
+ 'Flooding (Bromley)',
+ 'Flytipping (Bromley)', # In the 'Street cleaning' group
+ 'Grit bins',
+ 'Timings',
+ 'Traffic lights',
+ 'Trees'
+ ],
+ },
+ {
+ host => 'tfl.fixmystreet.com',
+ name => "test red route categories",
+ lat => 51.4039,
+ lon => 0.018697,
+ expected => [
+ 'Bus stops',
+ 'Flooding',
+ 'Grit bins',
+ 'Pothole',
+ 'Timings',
+ 'Traffic lights',
+ 'Trees'
+ ],
+ },
+ {
+ host => 'tfl.fixmystreet.com',
+ name => "test non-red route categories",
+ lat => 51.4021,
+ lon => 0.01578,
+ expected => [
+ 'Bus stops',
+ 'Flooding',
+ 'Grit bins',
+ 'Pothole',
+ 'Timings',
+ 'Traffic lights',
+ 'Trees'
+ ],
+ },
+ {
+ host => 'bromley.fixmystreet.com',
+ name => "test red route categories",
+ lat => 51.4039,
+ lon => 0.018697,
+ expected => [
+ 'Accumulated Litter',
+ 'Bus stops',
+ 'Flooding',
+ 'Flytipping (Bromley)',
+ 'Grit bins',
+ 'Pothole',
+ 'Timings',
+ 'Traffic lights',
+ 'Trees'
+ ],
+ },
+ {
+ host => 'bromley.fixmystreet.com',
+ name => "test non-red route categories",
+ lat => 51.4021,
+ lon => 0.01578,
+ expected => [
+ 'Accumulated Litter',
+ 'Bus stops',
+ 'Flooding (Bromley)',
+ 'Flytipping (Bromley)',
+ 'Grit bins',
+ 'Timings',
+ 'Traffic lights',
+ 'Trees'
+ ],
+ },
+) {
+ subtest $test->{name} . ' on ' . $test->{host} => sub {
+ $mech->host($test->{host});
+ my $resp = $mech->get_ok_json( '/report/new/ajax?latitude=' . $test->{lat} . '&longitude=' . $test->{lon} );
+ my @actual = sort keys %{ $resp->{by_category} };
+ is_deeply \@actual, $test->{expected};
+ };
+}
+
+for my $host ( 'tfl.fixmystreet.com', 'www.fixmystreet.com', 'bromley.fixmystreet.com' ) {
+ for my $test (
+ {
+ name => "test non-safety critical category",
+ safety_critical => 'no',
+ category => "Traffic lights",
+ subject => "Problem Report: Test Report",
+ },
+ {
+ name => "test safety critical category",
+ safety_critical => 'yes',
+ category => "Pothole",
+ subject => "Dangerous Pothole Report: Test Report",
+ pc => "BR1 3EF", # this is on a red route (according to Mock::MapIt and Mock::Tilma anyway)
+ },
+ {
+ name => "test category extra field - safety critical",
+ safety_critical => 'yes',
+ category => "Flooding",
+ extra_fields => {
+ location => "carriageway",
+ },
+ subject => "Dangerous Flooding Report: Test Report",
+ pc => "BR1 3EF", # this is on a red route (according to Mock::MapIt and Mock::Tilma anyway)
+ },
+ {
+ name => "test category extra field - non-safety critical",
+ safety_critical => 'no',
+ category => "Flooding",
+ extra_fields => {
+ location => "footway",
+ },
+ subject => "Problem Report: Test Report",
+ pc => "BR1 3EF", # this is on a red route (according to Mock::MapIt and Mock::Tilma anyway)
+ },
+ ) {
+ subtest $test->{name} . ' on ' . $host => sub {
+ $mech->log_in_ok( $user->email );
+ $mech->host($host);
+ $mech->get_ok('/around');
+ my $pc = $test->{pc} || 'BR1 3UH';
+ $mech->submit_form_ok( { with_fields => { pc => $pc, } }, "submit location ($pc)" );
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" );
+ $mech->submit_form_ok(
+ {
+ with_fields => {
+ category => $test->{category}
+ },
+ button => 'submit_category_part_only',
+ }
+ );
+ $mech->submit_form_ok(
+ {
+ with_fields => {
+ title => 'Test Report',
+ detail => 'Test report details.',
+ may_show_name => '1',
+ category => $test->{category},
+ %{ $test->{extra_fields} || {} },
+ $host eq 'bromley.fixmystreet.com' ? (
+ fms_extra_title => 'DR',
+ first_name => "Joe",
+ last_name => "Bloggs",
+ ) : (
+ name => 'Joe Bloggs',
+ ),
+ }
+ },
+ "submit report form"
+ );
+
+ my $report = FixMyStreet::App->model('DB::Problem')->to_body( $body->id )->search(undef, {
+ order_by => { -desc => 'id' },
+ })->first;
+ ok $report, "Found the report";
+
+ is $report->get_extra_field_value('safety_critical'), $test->{safety_critical}, "safety critical flag set to " . $test->{safety_critical};
+
+ $mech->clear_emails_ok;
+ FixMyStreet::Script::Reports::send();
+ my @email = $mech->get_email;
+ is $email[0]->header('Subject'), $test->{subject};
+ if ($test->{safety_critical} eq 'yes') {
+ like $mech->get_text_body_from_email($email[0]), qr/This report is marked as safety critical./, "Safety critical message included in email body";
+ }
+ $mech->clear_emails_ok;
+
+
+ $mech->log_out_ok;
+ };
+ }
+}
+};
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'tfl',
+ MAPIT_URL => 'http://mapit.uk/',
+ COBRAND_FEATURES => { internal_ips => { tfl => [ '127.0.0.1' ] } },
+}, sub {
+ subtest 'On internal network, user not asked to sign up for 2FA' => sub {
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok(
+ { with_fields => { username => $staffuser->email, password_sign_in => 'password' } },
+ "sign in using form" );
+ $mech->content_contains('Your account');
+ };
+ subtest 'On internal network, user with 2FA not asked to enter it' => sub {
+ use Auth::GoogleAuth;
+ my $auth = Auth::GoogleAuth->new;
+ my $code = $auth->code;
+
+ $staffuser->set_extra_metadata('2fa_secret', $auth->secret32);
+ $staffuser->update;
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok(
+ { with_fields => { username => $staffuser->email, password_sign_in => 'password' } },
+ "sign in using form" );
+ $mech->content_lacks('generate a two-factor code');
+ $mech->content_contains('Your account');
+ };
+ subtest 'On internal network, cannot disable 2FA' => sub {
+ $mech->get_ok('/auth/generate_token');
+ $mech->content_contains('Change two-factor');
+ $mech->content_lacks('Deactivate two-factor');
+ $staffuser->unset_extra_metadata('2fa_secret');
+ $staffuser->update;
+ };
+};
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'tfl',
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
+ subtest 'On external network, user asked to sign up for 2FA' => sub {
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok(
+ { with_fields => { username => $staffuser->email, password_sign_in => 'password' } },
+ "sign in using form" );
+ $mech->content_contains('requires two-factor authentication');
+ };
+ subtest 'On external network, user with 2FA asked to enter it' => sub {
+ use Auth::GoogleAuth;
+ my $auth = Auth::GoogleAuth->new;
+ my $code = $auth->code;
+
+ $staffuser->set_extra_metadata('2fa_secret', $auth->secret32);
+ $staffuser->update;
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok(
+ { with_fields => { username => $staffuser->email, password_sign_in => 'password' } },
+ "sign in using form" );
+ $mech->content_contains('Please generate a two-factor code');
+ $mech->submit_form_ok({ with_fields => { '2fa_code' => $code } }, "provide correct 2FA code" );
+ };
+ subtest 'On external network, cannot disable 2FA' => sub {
+ $mech->get_ok('/auth/generate_token');
+ $mech->content_contains('Change two-factor');
+ $mech->content_lacks('Deactivate two-factor');
+ $staffuser->unset_extra_metadata('2fa_secret');
+ $staffuser->update;
+ };
+
+ subtest 'RSS feed has correct name' => sub {
+ $mech->get_ok('/rss/xsl');
+ $mech->content_contains('RSS feed from the Street Care website');
+ $mech->content_lacks('FixMyStreet');
+ $mech->get_ok('/rss/problems');
+ $mech->content_contains('New problems on Street Care');
+ $mech->content_lacks('FixMyStreet');
+ };
+};
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'fixmystreet', 'tfl' ],
+ MAPIT_URL => 'http://mapit.uk/'
+}, sub {
+ foreach (qw(tfl.fixmystreet.com fixmystreet.com)) {
+ $mech->host($_);
+ my ($p) = $mech->create_problems_for_body(1, $body->id, 'NotResp');
+ my $c = FixMyStreet::DB->resultset('Comment')->create({
+ problem => $p, user => $p->user, anonymous => 't', text => 'Update text',
+ problem_state => 'not responsible', state => 'confirmed', mark_fixed => 0,
+ confirmed => DateTime->now(),
+ });
+ subtest "check not responsible as correct text on $_" => sub {
+ $mech->get_ok('/report/' . $p->id);
+ $mech->content_contains("not TfL’s responsibility", "not reponsible message contains correct text");
+ };
+ $p->comments->delete;
+ $p->delete;
+ }
+};
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'bromley',
+ MAPIT_URL => 'http://mapit.uk/'
+}, sub {
+
+subtest 'Bromley staff can access Bromley admin' => sub {
+ $mech->log_in_ok( $bromleyuser->email );
+ $mech->get_ok('/admin');
+ $mech->content_contains( 'This is the administration interface for' );
+ $mech->log_out_ok;
+};
+
+subtest 'TfL staff cannot access Bromley admin' => sub {
+ $mech->log_in_ok( $staffuser->email );
+ ok $mech->get('/admin');
+ is $mech->res->code, 403, "got 403";
+ $mech->log_out_ok;
+};
+
+};
+
+done_testing();
diff --git a/t/cobrand/westminster.t b/t/cobrand/westminster.t
new file mode 100644
index 000000000..54de5a160
--- /dev/null
+++ b/t/cobrand/westminster.t
@@ -0,0 +1,259 @@
+use CGI::Simple;
+use Test::MockModule;
+use FixMyStreet::TestMech;
+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 $cobrand = Test::MockModule->new('FixMyStreet::Cobrand::Westminster');
+$cobrand->mock('lookup_site_code', sub {
+ my ($self, $row) = @_;
+ return "My USRN" if $row->latitude == 51.501009;
+});
+
+my $body = $mech->create_body_ok(2504, 'Westminster City Council', {
+ send_method => 'Open311', api_key => 'key', 'endpoint' => 'e', 'jurisdiction' => 'j' });
+my $superuser = $mech->create_user_ok(
+ 'superuser@example.com',
+ name => 'Test Superuser',
+ is_superuser => 1
+);
+my $staff_user = $mech->create_user_ok(
+ 'westminster@example.com',
+ name => 'Test User',
+ from_body => $body
+);
+my $normal_user = $mech->create_user_ok(
+ 'westminster-resident@example.com',
+ name => 'Public User'
+);
+my ($report) = $mech->create_problems_for_body(1, $body->id, 'Title');
+my $comment1 = $mech->create_comment_for_problem($report, $normal_user, 'User', 'this update was left on the Westminster cobrand', 0, 'confirmed', 'confirmed', { cobrand => 'westminster' });
+my $comment2 = $mech->create_comment_for_problem($report, $normal_user, 'User', 'this update was left on the fixmystreet.com cobrand', 0, 'confirmed', 'confirmed', { cobrand => 'fixmystreet' });
+my $comment3 = $mech->create_comment_for_problem($report, $normal_user, 'User', 'this update was imported via Open311', 0, 'confirmed', 'confirmed', { cobrand => '' });
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'westminster',
+ MAPIT_URL => 'http://mapit.uk/',
+ COBRAND_FEATURES => {
+ updates_allowed => {
+ westminster => 'staff',
+ },
+ oidc_login => {
+ westminster => {
+ client_id => 'example_client_id',
+ secret => 'example_secret_key',
+ auth_uri => 'http://oidc.example.org/oauth2/v2.0/authorize',
+ token_uri => 'http://oidc.example.org/oauth2/v2.0/token',
+ display_name => 'MyWestminster'
+ }
+ }
+ }
+}, sub {
+ subtest 'Cobrand allows social auth' => sub {
+ my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker('westminster')->new();
+ ok $cobrand->social_auth_enabled;
+ };
+
+ subtest 'Login button displayed correctly' => sub {
+ $mech->get_ok("/auth");
+ $mech->content_contains("Sign in with MyWestminster");
+ };
+
+ subtest 'Reports do not have update form' => sub {
+ $mech->get_ok('/report/' . $report->id);
+ $mech->content_lacks('Provide an update');
+ };
+
+ subtest 'Reports show updates from Westminster cobrand' => sub {
+ $mech->get_ok('/report/' . $report->id);
+ $mech->content_contains($comment1->text);
+ };
+
+ subtest 'Reports show updates from Open311' => sub {
+ $mech->get_ok('/report/' . $report->id);
+ $mech->content_contains($comment3->text);
+ };
+
+ subtest "Reports don't show updates from fixmystreet.com cobrand" => sub {
+ $mech->get_ok('/report/' . $report->id);
+ $mech->content_lacks($comment2->text);
+ };
+};
+
+subtest 'Reports have an update form for superusers' => sub {
+ # Westminster cobrand disables email signin, so we have to
+ # login and *then* set the cobrand.
+ $mech->log_in_ok( $superuser->email );
+
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'westminster',
+ MAPIT_URL => 'http://mapit.uk/',
+ COBRAND_FEATURES => {
+ updates_allowed => {
+ westminster => 'staff',
+ },
+ },
+ }, sub {
+ $mech->get_ok('/report/' . $report->id);
+ $mech->content_contains('Provide an update');
+ };
+
+ $mech->log_out_ok();
+};
+
+subtest 'Reports have an update form for staff users' => sub {
+ $mech->log_in_ok( $staff_user->email );
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'westminster',
+ MAPIT_URL => 'http://mapit.uk/',
+ COBRAND_FEATURES => {
+ updates_allowed => {
+ westminster => 'staff',
+ },
+ },
+ }, sub {
+ $mech->get_ok('/report/' . $report->id);
+ $mech->content_contains('Provide an update');
+ };
+ $mech->log_out_ok();
+};
+
+for (
+ {
+ ALLOWED_COBRANDS => 'westminster',
+ MAPIT_URL => 'http://mapit.uk/',
+ COBRAND_FEATURES => {
+ oidc_login => {
+ westminster => 0
+ }
+ }
+ },
+ {
+ ALLOWED_COBRANDS => 'westminster',
+ MAPIT_URL => 'http://mapit.uk/',
+ COBRAND_FEATURES => {
+ oidc_login => {
+ hounslow => {
+ client_id => 'example_client_id',
+ secret => 'example_secret_key',
+ auth_uri => 'http://oidc.example.org/oauth2/v2.0/authorize',
+ token_uri => 'http://oidc.example.org/oauth2/v2.0/token',
+ display_name => 'MyHounslow'
+ }
+ }
+ }
+ },
+ {
+ ALLOWED_COBRANDS => 'westminster',
+ MAPIT_URL => 'http://mapit.uk/',
+ }
+) {
+ FixMyStreet::override_config $_, sub {
+ subtest 'Cobrand disallows social auth' => sub {
+ my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker('westminster')->new();
+ ok !$cobrand->social_auth_enabled;
+ };
+
+ subtest 'Login button not displayed' => sub {
+ $mech->get_ok("/auth");
+ $mech->content_lacks("Login with MyWestminster");
+ };
+ };
+}
+
+$mech->delete_problems_for_body($body->id);
+$mech->create_contact_ok(body_id => $body->id, category => 'Abandoned bike', email => "BIKE");
+($report) = $mech->create_problems_for_body(1, $body->id, 'Bike', {
+ category => "Abandoned bike", cobrand => 'westminster',
+ latitude => 51.501009, longitude => -0.141588, areas => '2504',
+});
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'westminster' ],
+ MAPIT_URL => 'http://mapit.uk/',
+ STAGING_FLAGS => { send_reports => 1, skip_checks => 0 },
+ COBRAND_FEATURES => { anonymous_account => { westminster => 'anon' } },
+}, sub {
+ subtest 'USRN set correctly' => sub {
+ 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'), 'BIKE';
+ is $c->param('attribute[USRN]'), 'My USRN';
+ };
+};
+
+for my $cobrand (qw(westminster fixmystreet)) {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => $cobrand,
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ subtest "No reporter alert created in $cobrand" => sub {
+ my $user = $mech->log_in_ok('test@example.org');
+ $mech->get_ok('/');
+ $mech->submit_form_ok( { with_fields => { pc => 'SW1A1AA' } }, "submit location" );
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" );
+ $mech->submit_form_ok( { with_fields => {
+ title => 'Title', detail => 'Detail', category => 'Abandoned bike', name => 'Test Example',
+ } }, 'submitted okay' );
+ is $user->alerts->count, 0;
+ };
+ };
+}
+
+my $westminster = FixMyStreet::Cobrand::Westminster->new;
+subtest 'correct config returned for USRN/UPRN lookup' => sub {
+ my $actual = $westminster->lookup_site_code_config('USRN');
+ delete $actual->{accept_feature}; # is_deeply doesn't like code
+ is_deeply $actual, {
+ buffer => 1000,
+ proxy_url => "https://tilma.mysociety.org/resource-proxy/proxy.php",
+ url => "https://westminster.assets/40/query",
+ property => 'USRN',
+ };
+ $actual = $westminster->lookup_site_code_config('UPRN');
+ delete $actual->{accept_feature}; # is_deeply doesn't like code
+ is_deeply $actual, {
+ buffer => 1000,
+ proxy_url => "https://tilma.mysociety.org/resource-proxy/proxy.php",
+ url => "https://westminster.assets/25/query",
+ property => 'UPRN',
+ accept_types => {
+ Point => 1
+ },
+ };
+};
+
+subtest 'nearest UPRN returns correct point' => sub {
+ my $cfg = {
+ accept_feature => sub { 1 },
+ property => 'UPRN',
+ accept_types => {
+ Point => 1,
+ },
+ };
+ my $features = [
+ # A couple of incorrect geometry types to check they're ignored...
+ { geometry => { type => 'Polygon' } },
+ { geometry => { type => 'LineString',
+ coordinates => [ [ 527735, 181004 ], [ 527755, 181004 ] ] },
+ properties => { fid => '20100024' } },
+ # And two points which are further away than the above linestring,
+ # the second of which is the closest to our testing point.
+ { geometry => { type => 'Point',
+ coordinates => [ 527795, 181024 ] },
+ properties => { UPRN => '10012387122' } },
+ { geometry => { type => 'Point',
+ coordinates => [ 527739, 181009 ] },
+ properties => { UPRN => '10012387123' } },
+ ];
+ is $westminster->_nearest_feature($cfg, 527745, 180994, $features), '10012387123';
+};
+
+
+done_testing();
diff --git a/t/cobrand/zurich.t b/t/cobrand/zurich.t
index ee2724a07..8c5acddca 100644
--- a/t/cobrand/zurich.t
+++ b/t/cobrand/zurich.t
@@ -1,11 +1,13 @@
# TODO
# Overdue alerts
+use utf8;
use DateTime;
use Email::MIME;
use File::Temp;
use LWP::Protocol::PSGI;
use Test::LongString;
+use Test::MockModule;
use Path::Tiny;
use t::Mock::MapItZurich;
use FixMyStreet::Script::Reports;
@@ -28,18 +30,8 @@ $cobrand->db_state_migration;
my $sample_file = path(__FILE__)->parent->parent->child("app/controller/sample.jpg");
ok $sample_file->exists, "sample file $sample_file exists";
-# This is a helper method that will send the reports but with the config
-# correctly set - notably STAGING_FLAGS send_reports needs to be true, and
-# zurich must be allowed cobrand if we want to be able to call cobrand
-# methods on it.
sub send_reports_for_zurich {
- FixMyStreet::override_config {
- STAGING_FLAGS => { send_reports => 1 },
- ALLOWED_COBRANDS => ['zurich']
- }, sub {
- # Actually send the report
- FixMyStreet::Script::Reports::send('zurich');
- };
+ FixMyStreet::Script::Reports::send();
}
sub reset_report_state {
my ($report, $created) = @_;
@@ -51,45 +43,47 @@ sub reset_report_state {
$report->whensent(undef);
$report->state('submitted');
$report->created($created) if $created;
+ $report->category('Other');
$report->update;
}
-# Front page test
-ok $mech->host("zurich.example.com"), "change host to Zurich";
+my $UPLOAD_DIR = File::Temp->newdir();
FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
+ STAGING_FLAGS => { send_reports => 1 },
+ BASE_URL => 'https://www.zurich',
+ ALLOWED_COBRANDS => 'zurich',
+ MAPIT_URL => 'http://mapit.zurich/',
+ MAPIT_TYPES => [ 'O08' ],
+ MAPIT_ID_WHITELIST => [ 423017 ],
+ MAP_TYPE => 'Zurich,OSM',
+ PHOTO_STORAGE_BACKEND => 'FileSystem',
+ PHOTO_STORAGE_OPTIONS => {
+ UPLOAD_DIR => $UPLOAD_DIR,
+ },
}, sub {
- $mech->get_ok('/');
-};
+
+# Front page test
+ok $mech->host("zurich.example.com"), "change host to Zurich";
+$mech->get_ok('/');
$mech->content_like( qr/zurich/i );
# Set up bodies
my $zurich = $mech->create_body_ok( 1, 'Zurich' );
-$zurich->parent( undef );
-$zurich->update;
-my $division = $mech->create_body_ok( 2, 'Division 1' );
-$division->parent( $zurich->id );
-$division->send_method( 'Zurich' );
-$division->endpoint( 'division@example.org' );
-$division->update;
-$division->body_areas->find_or_create({ area_id => 423017 });
-my $subdivision = $mech->create_body_ok( 3, 'Subdivision A' );
-$subdivision->parent( $division->id );
-$subdivision->send_method( 'Zurich' );
-$subdivision->endpoint( 'subdivision@example.org' );
-$subdivision->update;
-my $external_body = $mech->create_body_ok( 4, 'External Body' );
-$external_body->send_method( 'Zurich' );
-$external_body->endpoint( 'external_body@example.net' );
-$external_body->update;
+my $division = $mech->create_body_ok( 423017, 'Division 1', {
+ parent => $zurich->id, send_method => 'Zurich', endpoint => 'division@example.org' } );
+my $division2 = $mech->create_body_ok( 423017, 'Division 2', {
+ parent => $zurich->id, send_method => 'Zurich', endpoint => 'division2@example.org' } );
+my $subdivision = $mech->create_body_ok( 3, 'Subdivision A',
+ { parent => $division->id, send_method => 'Zurich', endpoint => 'subdivision@example.org' } );
+my $external_body = $mech->create_body_ok( 4, 'External Body',
+ { send_method => 'Zurich', endpoint => 'external_body@example.net' } );
+my $external_body2 = $mech->create_body_ok( 4, 'Another Body External',
+ { send_method => 'Zurich', endpoint => 'external_body2@example.net' } );
sub get_export_rows_count {
my $mech = shift;
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- }, sub {
- $mech->get_ok( '/admin/stats?export=1' );
- };
+ my $extra = shift || '';
+ $mech->get_ok( '/admin/stats?export=1' . $extra);
is $mech->res->code, 200, 'csv retrieved ok';
is $mech->content_type, 'text/csv', 'content_type correct' and do {
my @lines = split /\n/, $mech->content;
@@ -117,29 +111,24 @@ my @reports = $mech->create_problems_for_body( 1, $division->id, 'Test', {
});
my $report = $reports[0];
-FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAP_TYPE => 'Zurich,OSM',
-}, sub {
- $mech->get_ok( '/report/' . $report->id );
-};
-$mech->content_contains('&Uuml;berpr&uuml;fung ausstehend')
+$mech->get_ok( '/report/' . $report->id );
+$mech->content_contains('Überprüfung ausstehend')
or die $mech->content;
-FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAP_TYPE => 'Zurich,OSM',
-}, sub {
- my $json = $mech->get_ok_json( '/report/ajax/' . $report->id );
- is $json->{report}->{title}, "&Uuml;berpr&uuml;fung ausstehend", "correct title";
- is $json->{report}->{state}, "submitted", "correct state";
-};
+my $json = $mech->get_ok_json( '/report/ajax/' . $report->id );
+is $json->{report}->{title}, "Überprüfung ausstehend", "correct title";
+is $json->{report}->{state}, "submitted", "correct state";
+
+$report->state('fixed - council');
+$report->set_extra_metadata(public_response => 'Freundliche Grüsse');
+$report->update;
+$json = $mech->get_ok_json( '/report/ajax/' . $report->id );
+is $json->{report}->{state}, "closed", "correct state";
+is $json->{updates}->{details}, "Freundliche Grüsse", "correct public response";
+
+$report->update({ state => 'submitted' });
subtest "Banners are displayed correctly" => sub {
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAP_TYPE => 'Zurich,OSM',
- }, sub {
for my $test (
{
description => 'new report',
@@ -162,8 +151,8 @@ subtest "Banners are displayed correctly" => sub {
{
description => 'closed report',
state => 'external',
- banner_id => 'closed',
- banner_text => 'Extern',
+ banner_id => 'fixed',
+ banner_text => 'Beantwortet',
},
{
description => 'in progress report',
@@ -211,17 +200,14 @@ subtest "Banners are displayed correctly" => sub {
};
}
$report->update({ state => 'submitted' });
- };
};
-# Check logging in to deal with this report
-FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
-}, sub {
+my $user;
+subtest 'check logging in to deal with this report' => sub {
$mech->get_ok( '/admin' );
is $mech->uri->path, '/auth', "got sent to the sign in page";
- my $user = $mech->log_in_ok( 'dm1@example.org') ;
+ $user = $mech->log_in_ok( 'dm1@example.org') ;
$user->from_body( undef );
$user->update;
ok $mech->get( '/admin' );
@@ -230,12 +216,12 @@ FixMyStreet::override_config {
$user->update;
$mech->get_ok( '/admin' );
-};
-is $mech->uri->path, '/admin', "am logged in";
+ is $mech->uri->path, '/admin', "am logged in";
-$mech->content_contains( 'report_edit/' . $report->id );
-$mech->content_contains( DateTime->now->strftime("%d.%m.%Y") );
-$mech->content_contains( 'Erfasst' );
+ $mech->content_contains( 'report_edit/' . $report->id );
+ $mech->content_contains( DateTime->now->strftime("%d.%m.%Y") );
+ $mech->content_contains( 'Erfasst' );
+};
subtest "changing of categories" => sub {
# create a few categories (which are actually contacts)
@@ -260,13 +246,8 @@ subtest "changing of categories" => sub {
ok ( !$comments_rs->first, "There are no comments yet" );
# change the category via the web interface
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAP_TYPE => 'Zurich,OSM',
- }, sub {
- $mech->get_ok( '/admin/report_edit/' . $report->id );
- $mech->submit_form_ok( { with_fields => { category => 'Cat2' } } );
- };
+ $mech->get_ok( '/admin/report_edit/' . $report->id );
+ $mech->submit_form_ok( { with_fields => { category => 'Cat2' } } );
# check changes correctly saved
$report->discard_changes();
@@ -280,6 +261,38 @@ subtest "changing of categories" => sub {
$report->update({category => $original_category });
};
+subtest "private categories" => sub {
+ $mech->log_in_ok( 'super@example.org' );
+ $mech->get_ok('/admin/bodies');
+ $mech->follow_link_ok({ text => 'Division 1' });
+ $mech->submit_form_ok({ with_fields => {
+ category => 'Allgemein',
+ state => 'inactive',
+ email => 'allgemein@example.org',
+ 'extra[admin_label]' => 'StadtPeople',
+ 'extra[abbreviation]' => 'STA',
+ note => 'New',
+ }});
+ $mech->follow_link_ok({ text => 'Allgemein' });
+ $mech->content_contains('<option value="inactive" selected>');
+ $mech->content_like(qr/admin_label.*?StadtPeople/);
+
+ $mech->get_ok( '/around?lat=47.381817&lon=8.529156' );
+ $mech->content_lacks('StadtPeople');
+ $mech->content_contains('Allgemein');
+ $mech->get_ok( '/report/new?lat=47.381817&lon=8.529156' );
+ $mech->content_lacks('StadtPeople');
+ $mech->content_lacks('Allgemein');
+
+ $report->update({ category => 'Allgemein' });
+ $mech->get_ok('/report/' . $report->id);
+ $mech->content_lacks('StadtPeople');
+ $mech->content_contains('Allgemein');
+
+ $mech->get_ok('/admin/report_edit/' . $report->id);
+ $mech->content_contains('<option value="Allgemein">StadtPeople (STA)</option>');
+};
+
sub get_moderated_count {
# my %date_params = ( );
# my $moderated = FixMyStreet::DB->resultset('Problem')->search({
@@ -288,17 +301,12 @@ sub get_moderated_count {
# use a separate mech to avoid stomping on test state
my $mech = FixMyStreet::TestMech->new;
- my $user = $mech->log_in_ok( 'super@example.org' );
+ $mech->log_in_ok( 'super@example.org' );
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- }, sub {
- $mech->get( '/admin/stats' );
- };
+ $mech->get( '/admin/stats' );
if ($mech->content =~/Innerhalb eines Arbeitstages moderiert: (\d+)/) {
return $1;
- }
- else {
+ } else {
fail sprintf "Could not get moderation results (%d)", $mech->status;
return undef;
}
@@ -306,127 +314,112 @@ sub get_moderated_count {
subtest "report_edit" => sub {
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAP_TYPE => 'Zurich,OSM',
- }, sub {
+ reset_report_state($report);
+ ok ( ! $report->get_extra_metadata('moderated_overdue'), 'Report currently unmoderated' );
+ is get_moderated_count(), 0;
- reset_report_state($report);
- ok ( ! $report->get_extra_metadata('moderated_overdue'), 'Report currently unmoderated' );
- is get_moderated_count(), 0;
-
- $mech->get_ok( '/admin/report_edit/' . $report->id );
- $mech->content_contains( 'Unbest&auml;tigt' ); # Unconfirmed email
- $mech->submit_form_ok( { with_fields => { state => 'confirmed' } } );
- $mech->get_ok( '/report/' . $report->id );
+ $mech->log_in_ok( 'dm1@example.org') ;
+ $mech->get_ok( '/admin/report_edit/' . $report->id );
+ $mech->content_contains( 'Unbestätigt' ); # Unconfirmed email
+ $mech->submit_form_ok( { with_fields => { state => 'confirmed' } } );
+ $mech->get_ok( '/report/' . $report->id );
- $report->discard_changes();
+ $report->discard_changes();
- $mech->content_contains('Aufgenommen');
- $mech->content_contains('Test Test');
- $mech->content_lacks('photo/' . $report->id . '.0.jpeg');
- $mech->email_count_is(0);
+ $mech->content_contains('Aufgenommen');
+ $mech->content_contains('Test Test');
+ $mech->content_lacks('photo/' . $report->id . '.0.jpeg');
+ $mech->email_count_is(0);
- $report->discard_changes;
+ $report->discard_changes;
- is ( $report->get_extra_metadata('moderated_overdue'), 0, 'Report now marked moderated' );
- is get_moderated_count(), 1;
+ is ( $report->get_extra_metadata('moderated_overdue'), 0, 'Report now marked moderated' );
+ is get_moderated_count(), 1;
- # Set state back to 10 days ago so that report is overdue
- my $created = $report->created;
- reset_report_state($report, $created->clone->subtract(days => 10));
+ # Set state back to 10 days ago so that report is overdue
+ my $created = $report->created;
+ reset_report_state($report, $created->clone->subtract(days => 10));
- is get_moderated_count(), 0;
+ is get_moderated_count(), 0;
- $mech->get_ok( '/admin/report_edit/' . $report->id );
- $mech->submit_form_ok( { with_fields => { state => 'confirmed' } } );
- $mech->get_ok( '/report/' . $report->id );
+ $mech->get_ok( '/admin/report_edit/' . $report->id );
+ $mech->submit_form_ok( { with_fields => { state => 'confirmed' } } );
+ $mech->get_ok( '/report/' . $report->id );
- $report->discard_changes;
- is ( $report->get_extra_metadata('moderated_overdue'), 1, 'moderated_overdue set correctly when overdue' );
- is get_moderated_count(), 0, 'Moderated count not increased when overdue';
+ $report->discard_changes;
+ is ( $report->get_extra_metadata('moderated_overdue'), 1, 'moderated_overdue set correctly when overdue' );
+ is get_moderated_count(), 0, 'Moderated count not increased when overdue';
- reset_report_state($report, $created);
+ reset_report_state($report, $created);
- $mech->get_ok( '/admin/report_edit/' . $report->id );
- $mech->submit_form_ok( { with_fields => { state => 'confirmed' } } );
- $mech->get_ok( '/report/' . $report->id );
- $report->discard_changes;
- is ( $report->get_extra_metadata('moderated_overdue'), 0, 'Marking confirmed sets moderated_overdue' );
- is ( $report->get_extra_metadata('closed_overdue'), undef, 'Marking confirmed does NOT set closed_overdue' );
- is get_moderated_count(), 1;
+ $mech->get_ok( '/admin/report_edit/' . $report->id );
+ $mech->submit_form_ok( { with_fields => { state => 'confirmed' } } );
+ $mech->get_ok( '/report/' . $report->id );
+ $report->discard_changes;
+ is ( $report->get_extra_metadata('moderated_overdue'), 0, 'Marking confirmed sets moderated_overdue' );
+ is ( $report->get_extra_metadata('closed_overdue'), undef, 'Marking confirmed does NOT set closed_overdue' );
+ is get_moderated_count(), 1;
- $mech->get_ok( '/admin/report_edit/' . $report->id );
- $mech->submit_form_ok( { with_fields => { state => 'hidden' } } );
- $mech->get_ok( '/report/' . $report->id, 'still visible as response not published yet' );
+ $mech->get_ok( '/admin/report_edit/' . $report->id );
+ $mech->submit_form_ok( { with_fields => { state => 'hidden' } } );
+ $mech->get_ok( '/report/' . $report->id, 'still visible as response not published yet' );
- $report->discard_changes;
- is ( $report->get_extra_metadata('moderated_overdue'), 0, 'Still marked moderated_overdue' );
- is ( $report->get_extra_metadata('closed_overdue'), undef, "Marking hidden doesn't set closed_overdue..." );
- is ( $report->state, 'feedback pending', 'Marking hidden actually sets state to feedback pending');
- is ( $report->get_extra_metadata('closure_status'), 'hidden', 'Marking hidden sets closure_status to hidden');
- is get_moderated_count(), 1, 'Check still counted moderated'
- or diag $report->get_column('extra');
-
- # publishing actually sets hidden
- $mech->get_ok( '/admin/report_edit/' . $report->id );
- $mech->form_with_fields( 'status_update' );
- $mech->submit_form_ok( { button => 'publish_response' } );
- $mech->get_ok( '/admin/report_edit/' . $report->id );
- $report->discard_changes;
+ $report->discard_changes;
+ is ( $report->get_extra_metadata('moderated_overdue'), 0, 'Still marked moderated_overdue' );
+ is ( $report->get_extra_metadata('closed_overdue'), undef, "Marking hidden doesn't set closed_overdue..." );
+ is ( $report->state, 'feedback pending', 'Marking hidden actually sets state to feedback pending');
+ is ( $report->get_extra_metadata('closure_status'), 'hidden', 'Marking hidden sets closure_status to hidden');
+ is get_moderated_count(), 1, 'Check still counted moderated'
+ or diag $report->get_column('extra');
+
+ # publishing actually sets hidden
+ $mech->get_ok( '/admin/report_edit/' . $report->id );
+ $mech->form_with_fields( 'status_update' );
+ $mech->submit_form_ok( { button => 'publish_response' } );
+ $mech->get_ok( '/admin/report_edit/' . $report->id );
+ $report->discard_changes;
- is ( $report->get_extra_metadata('closed_overdue'), 0, "Closing as hidden sets closed_overdue..." );
- is ( $report->state, 'hidden', 'Closing as hidden sets state to hidden');
- is ( $report->get_extra_metadata('closure_status'), undef, 'Closing as hidden unsets closure_status');
+ is ( $report->get_extra_metadata('closed_overdue'), 0, "Closing as hidden sets closed_overdue..." );
+ is ( $report->state, 'hidden', 'Closing as hidden sets state to hidden');
+ is ( $report->get_extra_metadata('closure_status'), undef, 'Closing as hidden unsets closure_status');
- $mech->submit_form_ok( { with_fields => { new_internal_note => 'Initial internal note.' } } );
- $report->discard_changes;
- is ( $report->state, 'hidden', 'Another internal note does not reopen');
+ $mech->submit_form_ok( { with_fields => { new_internal_note => 'Initial internal note.' } } );
+ $report->discard_changes;
+ is ( $report->state, 'hidden', 'Another internal note does not reopen');
- $mech->get( '/report/' . $report->id);
- is $mech->res->code, 410;
+ $mech->get( '/report/' . $report->id);
+ is $mech->res->code, 410;
- reset_report_state($report);
- is ( $report->get_extra_metadata('moderated_overdue'), undef, 'Sanity check' );
- is get_moderated_count(), 0;
+ reset_report_state($report);
+ is ( $report->get_extra_metadata('moderated_overdue'), undef, 'Sanity check' );
+ is get_moderated_count(), 0;
- # Check that setting to 'hidden' also triggers moderation
- $mech->get_ok( '/admin/report_edit/' . $report->id );
- $mech->submit_form_ok( { with_fields => { state => 'hidden' } } );
- $mech->get_ok( '/admin/report_edit/' . $report->id );
- $mech->form_with_fields( 'status_update' );
- $mech->submit_form_ok( { button => 'publish_response' } );
+ # Check that setting to 'hidden' also triggers moderation
+ $mech->get_ok( '/admin/report_edit/' . $report->id );
+ $mech->submit_form_ok( { with_fields => { state => 'hidden' } } );
+ $mech->get_ok( '/admin/report_edit/' . $report->id );
+ $mech->form_with_fields( 'status_update' );
+ $mech->submit_form_ok( { button => 'publish_response' } );
- $report->discard_changes;
- is ( $report->get_extra_metadata('moderated_overdue'), 0, 'Marking hidden from scratch sets moderated_overdue' );
- is ( $report->get_extra_metadata('closed_overdue'), 0, 'Marking hidden from scratch also set closed_overdue' );
- is get_moderated_count(), 1;
+ $report->discard_changes;
+ is ( $report->get_extra_metadata('moderated_overdue'), 0, 'Marking hidden from scratch sets moderated_overdue' );
+ is ( $report->get_extra_metadata('closed_overdue'), 0, 'Marking hidden from scratch also set closed_overdue' );
+ is get_moderated_count(), 1;
- is ($cobrand->get_or_check_overdue($report), 0, 'sanity check');
- $report->update({ created => $created->clone->subtract(days => 10) });
- is ($cobrand->get_or_check_overdue($report), 0, 'overdue call not increased');
+ is ($cobrand->get_or_check_overdue($report), 0, 'sanity check');
+ $report->update({ created => $created->clone->subtract(days => 10) });
+ is ($cobrand->get_or_check_overdue($report), 0, 'overdue call not increased');
- reset_report_state($report, $created);
- }
+ reset_report_state($report, $created);
};
# Give the report three photos
-my $UPLOAD_DIR = File::Temp->newdir();
my @files = map { $_ x 40 . ".jpeg" } (1..3);
$sample_file->copy(path($UPLOAD_DIR, $_)) for @files;
$report->photo(join(',', @files));
$report->update;
-FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAPIT_URL => 'http://mapit.zurich/',
- MAP_TYPE => 'Zurich,OSM',
- PHOTO_STORAGE_BACKEND => 'FileSystem',
- PHOTO_STORAGE_OPTIONS => {
- UPLOAD_DIR => $UPLOAD_DIR,
- },
-}, sub {
- # Photo publishing
+subtest 'Photo publishing' => sub {
$mech->get_ok( '/admin/report_edit/' . $report->id );
$mech->submit_form_ok( { with_fields => { state => 'confirmed', publish_photo_1 => 1 } } );
$mech->get_ok( '/around?lat=' . $report->latitude . ';lon=' . $report->longitude);
@@ -469,50 +462,37 @@ $mech->log_out_ok;
subtest 'SDM' => sub {
my $user = $mech->log_in_ok( 'sdm1@example.org') ;
$user->update({ from_body => undef });
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- }, sub {
- ok $mech->get( '/admin' );
- };
+ ok $mech->get( '/admin' );
is $mech->res->code, 403, 'Got 403';
$user->from_body( $subdivision->id );
$user->update;
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- }, sub {
- $mech->get_ok( '/admin' );
- };
+ $mech->get_ok( '/admin' );
is $mech->uri->path, '/admin', "am logged in";
$mech->content_contains( 'report_edit/' . $report->id );
$mech->content_contains( DateTime->now->strftime("%d.%m.%Y") );
$mech->content_contains( 'In Bearbeitung' );
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAP_TYPE => 'Zurich,OSM',
- }, sub {
- $mech->get_ok( '/admin/report_edit/' . $report->id );
- $mech->content_contains( 'Initial internal note' );
+ $mech->get_ok( '/admin/report_edit/' . $report->id );
+ $mech->content_contains( 'Initial internal note' );
- $mech->submit_form_ok( { with_fields => { status_update => 'This is an update.' } } );
- is $mech->uri->path, '/admin/report_edit/' . $report->id, "still on edit page";
- $mech->content_contains('This is an update');
- ok $mech->form_with_fields( 'status_update' );
- $mech->submit_form_ok( { button => 'no_more_updates' } );
- is $mech->uri->path, '/admin/summary', "redirected now finished with report.";
+ $mech->submit_form_ok( { with_fields => { status_update => 'This is an update.' } } );
+ is $mech->uri->path, '/admin/report_edit/' . $report->id, "still on edit page";
+ $mech->content_contains('This is an update');
+ ok $mech->form_with_fields( 'status_update' );
+ $mech->submit_form_ok( { button => 'no_more_updates' } );
+ is $mech->uri->path, '/admin/summary', "redirected now finished with report.";
- # Can still view the edit page but can't change anything
- $mech->get_ok( '/admin/report_edit/' . $report->id );
- $mech->content_contains('<input disabled');
- $mech->submit_form_ok( { with_fields => { status_update => 'This is a disallowed update.' } } );
- $mech->content_lacks('This is a disallowed update');
+ # Can still view the edit page but can't change anything
+ $mech->get_ok( '/admin/report_edit/' . $report->id );
+ $mech->content_contains('<input disabled');
+ $mech->submit_form_ok( { with_fields => { status_update => 'This is a disallowed update.' } } );
+ $mech->content_lacks('This is a disallowed update');
- $mech->get_ok( '/report/' . $report->id );
- $mech->content_contains('In Bearbeitung');
- $mech->content_contains('Test Test');
- };
+ $mech->get_ok( '/report/' . $report->id );
+ $mech->content_contains('In Bearbeitung');
+ $mech->content_contains('Test Test');
send_reports_for_zurich();
$email = $mech->get_email;
@@ -524,119 +504,99 @@ subtest 'SDM' => sub {
is $report->state, 'feedback pending', 'Report now in feedback pending state';
subtest 'send_back' => sub {
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAP_TYPE => 'Zurich,OSM',
- }, sub {
- $report->update({ bodies_str => $subdivision->id, state => 'in progress' });
- $mech->get_ok( '/admin/report_edit/' . $report->id );
- $mech->submit_form_ok( { form_number => 2, button => 'send_back' } );
- $report->discard_changes;
- is $report->state, 'confirmed', 'Report sent back to confirmed state';
- is $report->bodies_str, $division->id, 'Report sent back to division';
- };
+ $report->update({ bodies_str => $subdivision->id, state => 'in progress' });
+ $mech->get_ok( '/admin/report_edit/' . $report->id );
+ $mech->submit_form_ok( { form_number => 2, button => 'send_back' } );
+ $report->discard_changes;
+ is $report->state, 'confirmed', 'Report sent back to confirmed state';
+ is $report->bodies_str, $division->id, 'Report sent back to division';
};
subtest 'not contactable' => sub {
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAP_TYPE => 'Zurich,OSM',
- }, sub {
- $report->update({ bodies_str => $subdivision->id, state => 'in progress' });
- $mech->get_ok( '/admin/report_edit/' . $report->id );
- $mech->submit_form_ok( { button => 'not_contactable', form_number => 2 } );
- $report->discard_changes;
- is $report->state, 'feedback pending', 'Report sent back to Rueckmeldung ausstehend state';
- is $report->get_extra_metadata('closure_status'), 'not contactable', 'Report sent back to not_contactable state';
- is $report->bodies_str, $division->id, 'Report sent back to division';
- };
+ $report->update({ bodies_str => $subdivision->id, state => 'in progress' });
+ $mech->get_ok( '/admin/report_edit/' . $report->id );
+ $mech->submit_form_ok( { button => 'not_contactable', form_number => 2 } );
+ $report->discard_changes;
+ is $report->state, 'feedback pending', 'Report sent back to Rueckmeldung ausstehend state';
+ is $report->get_extra_metadata('closure_status'), 'not contactable', 'Report sent back to not_contactable state';
+ is $report->bodies_str, $division->id, 'Report sent back to division';
};
$mech->log_out_ok;
};
-my $user = $mech->log_in_ok( 'dm1@example.org') ;
-FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
-}, sub {
+subtest 'Test publishing of final update by DM' => sub {
+ $user = $mech->log_in_ok( 'dm1@example.org');
$mech->get_ok( '/admin' );
-};
-reset_report_state($report);
-$report->update({ state => 'feedback pending' });
+ reset_report_state($report);
+ $report->update({ state => 'feedback pending' });
-$mech->content_contains( 'report_edit/' . $report->id );
-$mech->content_contains( DateTime->now->strftime("%d.%m.%Y") );
+ $mech->content_contains( 'report_edit/' . $report->id );
+ $mech->content_contains( DateTime->now->strftime("%d.%m.%Y") );
-# User confirms their email address
-$report->set_extra_metadata(email_confirmed => 1);
-$report->confirmed(DateTime->now);
-$report->update;
+ # User confirms their email address
+ $report->set_extra_metadata(email_confirmed => 1);
+ $report->confirmed(DateTime->now);
+ $report->update;
-FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAP_TYPE => 'Zurich,OSM',
-}, sub {
# Quick RSS check here, while we have a report
$mech->get_ok('/rss/problems');
+ my $module = Test::MockModule->new('FixMyStreet::Geocode::Zurich');
+ $module->mock(admin_district => sub { 'Admin district' });
+
$mech->get_ok( '/admin/report_edit/' . $report->id );
- $mech->content_lacks( 'Unbest&auml;tigt' ); # Confirmed email
+
+ $mech->content_contains('Admin district');
+
+ $mech->content_lacks( 'Unbestätigt' ); # Confirmed email
$mech->submit_form_ok( { with_fields => { status_update => 'FINAL UPDATE' } } );
$mech->form_with_fields( 'status_update' );
$mech->submit_form_ok( { button => 'publish_response' } );
$mech->get_ok( '/report/' . $report->id );
+ $mech->content_contains('Beantwortet');
+ $mech->content_contains('Test Test');
+ $mech->content_contains('FINAL UPDATE');
+
+ $email = $mech->get_email;
+ like $email->header('To'), qr/test\@example.com/, 'to line looks correct';
+ like $email->header('From'), qr/do-not-reply\@example.org/, 'from line looks correct';
+ like $email->body, qr/FINAL UPDATE/, 'body looks correct';
+ $mech->clear_emails_ok;
};
-$mech->content_contains('Beantwortet');
-$mech->content_contains('Test Test');
-$mech->content_contains('FINAL UPDATE');
-
-$email = $mech->get_email;
-like $email->header('To'), qr/test\@example.com/, 'to line looks correct';
-like $email->header('From'), qr/do-not-reply\@example.org/, 'from line looks correct';
-like $email->body, qr/FINAL UPDATE/, 'body looks correct';
-$mech->clear_emails_ok;
-# Assign feedback pending (via confirmed), don't confirm email
-@reports = $mech->create_problems_for_body( 1, $division->id, 'Second', {
- state => 'submitted',
- confirmed => undef,
- cobrand => 'zurich',
- areas => ',423017,',
-});
-$report = $reports[0];
+subtest "Assign feedback pending (via confirmed), don't confirm email, no email sent" => sub {
+ @reports = $mech->create_problems_for_body( 1, $division->id, 'Second', {
+ state => 'submitted',
+ confirmed => undef,
+ cobrand => 'zurich',
+ areas => ',423017,',
+ });
+ $report = $reports[0];
-FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAP_TYPE => 'Zurich,OSM',
-}, sub {
$mech->get_ok( '/admin/report_edit/' . $report->id );
$mech->submit_form_ok( { with_fields => { state => 'confirmed' } } );
$mech->get_ok( '/admin/report_edit/' . $report->id );
$mech->submit_form_ok( { with_fields => { state => 'feedback pending' } } );
$mech->get_ok( '/report/' . $report->id );
-};
-$mech->content_contains('In Bearbeitung');
-$mech->content_contains('Second Test');
+ $mech->content_contains('In Bearbeitung');
+ $mech->content_contains('Second Test');
-FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAP_TYPE => 'Zurich,OSM',
-}, sub {
$mech->get_ok( '/admin/report_edit/' . $report->id );
- $mech->content_contains( 'Unbest&auml;tigt' );
+ $mech->content_contains( 'Unbestätigt' );
$report->discard_changes;
$mech->form_with_fields( 'status_update' );
$mech->submit_form_ok( { button => 'publish_response', with_fields => { status_update => 'FINAL UPDATE' } } );
$mech->get_ok( '/report/' . $report->id );
-};
-$mech->content_contains('Beantwortet');
-$mech->content_contains('Second Test');
-$mech->content_contains('FINAL UPDATE');
+ $mech->content_contains('Beantwortet');
+ $mech->content_contains('Second Test');
+ $mech->content_contains('FINAL UPDATE');
-$mech->email_count_is(0);
+ $mech->email_count_is(0);
+};
# Report assigned to third party
@@ -650,31 +610,27 @@ $report = $reports[0];
subtest "external report triggers email" => sub {
my $EXTERNAL_MESSAGE = 'Look Ma, no hands!';
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAP_TYPE => 'Zurich,OSM',
- }, sub {
- # required to see body_external field
- $report->state('feedback pending');
- $report->set_extra_metadata('closure_status' => 'external');
- # Set the public_response manually here because the default one will have line breaks that get escaped as HTML, causing the comparison to fail.
- $report->set_extra_metadata('public_response' => 'Freundliche Gruesse Ihre Stadt Zuerich');
- $report->update;
+ # required to see body_external field
+ $report->state('feedback pending');
+ $report->set_extra_metadata('closure_status' => 'external');
+ # Set the public_response manually here because the default one will have line breaks that get escaped as HTML, causing the comparison to fail.
+ $report->set_extra_metadata('public_response' => 'Freundliche Gruesse Ihre Stadt Zuerich');
+ $report->update;
+
+ $mech->get_ok( '/admin/report_edit/' . $report->id );
+ $mech->form_with_fields( 'publish_response' );
+ $mech->submit_form_ok( {
+ button => 'publish_response',
+ with_fields => {
+ body_external => $external_body->id,
+ external_message => $EXTERNAL_MESSAGE,
+ } });
+ $report->discard_changes;
+ $mech->get_ok( '/report/' . $report->id );
- $mech->get_ok( '/admin/report_edit/' . $report->id );
- $mech->form_with_fields( 'publish_response' );
- $mech->submit_form_ok( {
- button => 'publish_response',
- with_fields => {
- body_external => $external_body->id,
- external_message => $EXTERNAL_MESSAGE,
- } });
- $report->discard_changes;
- $mech->get_ok( '/report/' . $report->id );
- };
is ($report->state, 'external', 'Report was closed correctly');
- $mech->content_contains('Extern')
+ $mech->content_contains('Beantwortet')
or die $mech->content;
$mech->content_contains('Third Test');
$mech->content_contains($report->get_extra_metadata('public_response')) or die $mech->content;
@@ -688,30 +644,25 @@ subtest "external report triggers email" => sub {
$mech->clear_emails_ok;
subtest "Test third_personal boolean setting" => sub {
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAP_TYPE => 'Zurich,OSM',
- }, sub {
- $mech->get_ok( '/admin' );
- # required to see body_external field
- $report->state('feedback pending');
- $report->set_extra_metadata('closure_status' => 'external');
- $report->set_extra_metadata('public_response' => 'Freundliche Gruesse Ihre Stadt Zuerich');
- $report->update;
+ $mech->get_ok( '/admin' );
+ # required to see body_external field
+ $report->state('feedback pending');
+ $report->set_extra_metadata('closure_status' => 'external');
+ $report->set_extra_metadata('public_response' => 'Freundliche Gruesse Ihre Stadt Zuerich');
+ $report->update;
- is $mech->uri->path, '/admin', "am logged in";
- $mech->content_contains( 'report_edit/' . $report->id );
- $mech->get_ok( '/admin/report_edit/' . $report->id );
- $mech->form_with_fields( 'publish_response' );
- $mech->submit_form_ok( {
- button => 'publish_response',
- with_fields => {
- body_external => $external_body->id,
- third_personal => 1,
- } });
- $mech->get_ok( '/report/' . $report->id );
- };
- $mech->content_contains('Extern');
+ is $mech->uri->path, '/admin', "am logged in";
+ $mech->content_contains( 'report_edit/' . $report->id );
+ $mech->get_ok( '/admin/report_edit/' . $report->id );
+ $mech->form_with_fields( 'publish_response' );
+ $mech->submit_form_ok( {
+ button => 'publish_response',
+ with_fields => {
+ body_external => $external_body->id,
+ third_personal => 1,
+ } });
+ $mech->get_ok( '/report/' . $report->id );
+ $mech->content_contains('Beantwortet');
$mech->content_contains('Third Test');
$mech->content_contains($report->get_extra_metadata('public_response'));
send_reports_for_zurich();
@@ -724,30 +675,25 @@ subtest "external report triggers email" => sub {
};
subtest "Test external wish sending" => sub {
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAP_TYPE => 'Zurich,OSM',
- }, sub {
- # set as wish
- $report->discard_changes;
- $report->state('feedback pending');
- $report->set_extra_metadata('closure_status' => 'wish');
- $report->update;
- is ($report->state, 'feedback pending', 'Sanity check') or die;
-
- $mech->get_ok( '/admin/report_edit/' . $report->id );
-
- $mech->form_with_fields( 'publish_response' );
- $mech->submit_form_ok( {
- button => 'publish_response',
- with_fields => {
- body_external => $external_body->id,
- external_message => $EXTERNAL_MESSAGE,
- } });
- # Wishes publicly viewable
- $mech->get_ok( '/report/' . $report->id );
- $mech->content_contains('Freundliche Gruesse Ihre Stadt Zuerich');
- };
+ # set as wish
+ $report->discard_changes;
+ $report->state('feedback pending');
+ $report->set_extra_metadata('closure_status' => 'wish');
+ $report->update;
+ is ($report->state, 'feedback pending', 'Sanity check') or die;
+
+ $mech->get_ok( '/admin/report_edit/' . $report->id );
+
+ $mech->form_with_fields( 'publish_response' );
+ $mech->submit_form_ok( {
+ button => 'publish_response',
+ with_fields => {
+ body_external => $external_body->id,
+ external_message => $EXTERNAL_MESSAGE,
+ } });
+ # Wishes publicly viewable
+ $mech->get_ok( '/report/' . $report->id );
+ $mech->content_contains('Freundliche Gruesse Ihre Stadt Zuerich');
send_reports_for_zurich();
$email = $mech->get_email;
like $email->header('Subject'), qr/Weitergeleitete Meldung/, 'subject looks okay';
@@ -760,30 +706,26 @@ subtest "external report triggers email" => sub {
subtest "Closure email includes public response" => sub {
my $PUBLIC_RESPONSE = "This is the public response to your report. Freundliche Gruesse.";
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAP_TYPE => 'Zurich,OSM',
- }, sub {
- # set as extern
- reset_report_state($report);
- $report->state('feedback pending');
- $report->set_extra_metadata('closure_status' => 'external');
- $report->set_extra_metadata('email_confirmed' => 1);
- $report->unset_extra_metadata('public_response');
- $report->update;
- is ($report->state, 'feedback pending', 'Sanity check') or die;
-
- $mech->get_ok( '/admin/report_edit/' . $report->id );
-
- $mech->form_with_fields( 'publish_response' );
- $mech->submit_form_ok( {
- button => 'publish_response',
- with_fields => {
- body_external => $external_body->id,
- external_message => $EXTERNAL_MESSAGE,
- status_update => $PUBLIC_RESPONSE,
- } });
- };
+ # set as extern
+ reset_report_state($report);
+ $report->state('feedback pending');
+ $report->set_extra_metadata('closure_status' => 'external');
+ $report->set_extra_metadata('email_confirmed' => 1);
+ $report->unset_extra_metadata('public_response');
+ $report->update;
+ is ($report->state, 'feedback pending', 'Sanity check') or die;
+
+ $mech->get_ok( '/admin/report_edit/' . $report->id );
+
+ $mech->form_with_fields( 'publish_response' );
+ $mech->submit_form_ok( {
+ button => 'publish_response',
+ with_fields => {
+ body_external => $external_body->id,
+ external_message => $EXTERNAL_MESSAGE,
+ status_update => $PUBLIC_RESPONSE,
+ } });
+
$email = $mech->get_email;
my $report_id = $report->id;
like Encode::decode('MIME-Header', $email->header('Subject')), qr/Meldung #$report_id/, 'subject looks okay';
@@ -798,91 +740,89 @@ subtest "superuser and dm can see stats" => sub {
$mech->log_out_ok;
$user = $mech->log_in_ok( 'super@example.org' );
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- }, sub {
- $mech->get( '/admin/stats' );
- };
+ $mech->get( '/admin/stats' );
is $mech->res->code, 200, "superuser should be able to see stats page";
$mech->log_out_ok;
$user = $mech->log_in_ok( 'dm1@example.org' );
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- }, sub {
- $mech->get( '/admin/stats' );
- };
+ $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' );
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAPIT_URL => 'http://mapit.zurich/',
- }, sub {
- $mech->get( '/admin/body/' . $zurich->id );
- };
+ $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' );
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAPIT_URL => 'http://mapit.zurich/',
- MAPIT_TYPES => [ 'O08' ],
- MAPIT_ID_WHITELIST => [ 423017 ],
- }, sub {
- $mech->get_ok( '/admin/bodies' );
- };
+ $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 {
- FixMyStreet::override_config {
- MAPIT_TYPES => [ 'O08' ],
- MAPIT_URL => 'http://mapit.zurich/',
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAPIT_ID_WHITELIST => [ 423017 ],
- MAP_TYPE => 'Zurich,OSM',
- }, 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&ouml;tigt' );
- $mech->log_out_ok;
- };
+ $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' );
+ $mech->log_out_ok;
};
subtest "phone number is not mandatory for reports from mobile apps" => sub {
- FixMyStreet::override_config {
- MAPIT_TYPES => [ 'O08' ],
- MAPIT_URL => 'http://mapit.zurich/',
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAPIT_ID_WHITELIST => [ 423017 ],
- MAP_TYPE => 'Zurich,OSM',
- }, sub {
- $mech->post_ok( '/report/new/mobile?lat=47.381817&lon=8.529156' , {
- service => 'iPhone',
- detail => 'Problem-Bericht',
- lat => 47.381817,
- lon => 8.529156,
- email => 'user@example.org',
- pc => '',
- name => '',
- category => 'bad category',
- });
- my $res = $mech->response;
- ok $res->header('Content-Type') =~ m{^application/json\b}, 'response should be json';
- unlike $res->content, qr/Diese Information wird ben&ouml;tigt/, 'response should not contain phone error';
- # Clear out the mailq
- $mech->clear_emails_ok;
- };
+ $mech->post_ok( '/report/new/mobile?lat=47.381817&lon=8.529156' , {
+ service => 'iPhone',
+ detail => 'Problem-Bericht',
+ lat => 47.381817,
+ lon => 8.529156,
+ email => 'user@example.org',
+ pc => '',
+ name => '',
+ category => 'bad category',
+ });
+ my $res = $mech->response;
+ ok $res->header('Content-Type') =~ m{^application/json\b}, 'response should be json';
+ unlike $res->content, qr/Diese Information wird benötigt/, 'response should not contain phone error';
+ # Clear out the mailq
+ $mech->clear_emails_ok;
+};
+
+subtest "link external body to category" => sub {
+ $mech->log_in_ok( 'super@example.org' );
+ $mech->get_ok( '/admin/body/' . $zurich->id );
+ $mech->content_lacks('extra[category]');
+ $mech->get_ok( '/admin/body/' . $division->id );
+ $mech->content_lacks('extra[category]');
+ $mech->get_ok( '/admin/body/' . $subdivision->id );
+ $mech->content_lacks('extra[category]');
+ $mech->get_ok( '/admin/body/' . $external_body->id );
+ $mech->content_contains('extra[category]');
+ $mech->submit_form_ok({ with_fields => { 'extra[category]' => 'Cat1' } });
+ $mech->content_contains('<option value="Cat1" selected>');
+ $external_body->discard_changes;
+ is $external_body->get_extra_metadata('category'), 'Cat1';
+};
+
+subtest "shows correct external bodies" => sub {
+ $report->discard_changes;
+ $report->state('feedback pending');
+ $report->set_extra_metadata('closure_status' => 'external');
+ $report->update;
+ $user = $mech->log_in_ok( 'dm1@example.org' );
+ $mech->get_ok( '/admin/report_edit/' . $report->id );
+ $mech->content_like(qr/<option[^>]*>External Body<\/option>\s*<option[^>]*>Another Body External<\/option>/); # Test order
+
+ $user = $mech->log_in_ok( 'dm2@example.org' );
+ $user->update({ from_body => $division2->id });
+ $report->update({ bodies_str => $division2->id });
+ $mech->get_ok( '/admin/report_edit/' . $report->id );
+ $mech->content_contains('Another Body External');
+ $mech->content_lacks('External Body');
+ $report->update({ bodies_str => $division->id });
};
subtest "problems can't be assigned to deleted bodies" => sub {
@@ -891,30 +831,22 @@ subtest "problems can't be assigned to deleted bodies" => sub {
$user->update;
$report->state( 'confirmed' );
$report->update;
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAPIT_URL => 'http://mapit.zurich/',
- MAPIT_TYPES => [ 'O08' ],
- MAPIT_ID_WHITELIST => [ 423017 ],
- MAP_TYPE => 'Zurich,OSM',
- }, sub {
- $mech->get_ok( '/admin/body/' . $external_body->id );
- $mech->submit_form_ok( { with_fields => { deleted => 1 } } );
- $mech->get_ok( '/admin/report_edit/' . $report->id );
- $mech->content_lacks( $external_body->name )
- or do {
- diag $mech->content;
- diag $external_body->name;
- die;
- };
- };
+ $mech->get_ok( '/admin/body/' . $external_body->id );
+ $mech->submit_form_ok( { with_fields => { deleted => 1 } } );
+ $mech->get_ok( '/admin/report_edit/' . $report->id );
+ $mech->content_lacks( $external_body->name )
+ or do {
+ diag $mech->content;
+ diag $external_body->name;
+ die;
+ };
$user->from_body( $division->id );
$user->update;
$mech->log_out_ok;
};
subtest "photo must be supplied for categories that require it" => sub {
- FixMyStreet::App->model('DB::Contact')->find_or_create({
+ FixMyStreet::DB->resultset('Contact')->find_or_create({
body => $division,
category => "Graffiti - photo required",
email => "graffiti\@example.org",
@@ -924,44 +856,34 @@ subtest "photo must be supplied for categories that require it" => sub {
note => "note for graffiti",
extra => { photo_required => 1 }
});
- FixMyStreet::override_config {
- MAPIT_TYPES => [ 'O08' ],
- MAPIT_URL => 'http://mapit.zurich/',
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAPIT_ID_WHITELIST => [ 423017 ],
- MAP_TYPE => 'Zurich,OSM',
- }, 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',
- category => 'Graffiti - photo required',
- }});
- is $mech->res->code, 200, "missing photo shouldn't return anything but 200";
- $mech->content_contains(_("Photo is required."), 'response should contain photo error message');
- };
+ $mech->get_ok('/report/new?lat=47.381817&lon=8.529156');
+ $mech->submit_form_ok({ with_fields => {
+ detail => 'Problem-Bericht',
+ username => 'user@example.org',
+ category => 'Graffiti - photo required',
+ }});
+ is $mech->res->code, 200, "missing photo shouldn't return anything but 200";
+ $mech->content_contains(_("Photo is required."), 'response should contain photo error message');
};
subtest "test stats" => sub {
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- }, sub {
- $user = $mech->log_in_ok( 'super@example.org' );
-
- $mech->get_ok( '/admin/stats' );
- is $mech->res->code, 200, "superuser should be able to see stats page";
-
- $mech->content_contains('Innerhalb eines Arbeitstages moderiert: 3');
- $mech->content_contains('Innerhalb von f&uuml;nf Arbeitstagen abgeschlossen: 3');
- # my @data = $mech->content =~ /(?:moderiert|abgeschlossen): \d+/g;
- # diag Dumper(\@data); use Data::Dumper;
-
- my $export_count = get_export_rows_count($mech);
- if (defined $export_count) {
- is $export_count - $EXISTING_REPORT_COUNT, 3, 'Correct number of reports';
- $mech->content_contains('fixed - council');
- }
- };
+ $user = $mech->log_in_ok( 'super@example.org' );
+
+ $mech->get_ok( '/admin/stats' );
+ is $mech->res->code, 200, "superuser should be able to see stats page";
+
+ $mech->content_contains('Innerhalb eines Arbeitstages moderiert: 3');
+ $mech->content_contains('Innerhalb von fünf Arbeitstagen abgeschlossen: 3');
+ # my @data = $mech->content =~ /(?:moderiert|abgeschlossen): \d+/g;
+ # diag Dumper(\@data); use Data::Dumper;
+
+ my $export_count = get_export_rows_count($mech);
+ if (defined $export_count) {
+ is $export_count - $EXISTING_REPORT_COUNT, 3, 'Correct number of reports';
+ $mech->content_contains('fixed - council');
+ }
+ $export_count = get_export_rows_count($mech, '&ym=' . DateTime->now->strftime("%m.%Y"));
+ is $export_count - $EXISTING_REPORT_COUNT, 3, 'Correct number of reports when filtering by month';
};
subtest "test admin_log" => sub {
@@ -977,136 +899,108 @@ subtest "test admin_log" => sub {
};
subtest 'email images to external partners' => sub {
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAP_TYPE => 'Zurich,OSM',
- }, sub {
- reset_report_state($report);
+ reset_report_state($report);
- my $photo = path(__FILE__)->parent->child('zurich-logo_portal.x.jpg')->slurp_raw;
- my $photoset = FixMyStreet::App::Model::PhotoSet->new({
- data_items => [ $photo ],
- });
- my $fileid = $photoset->data;
-
- $report->set_extra_metadata('publish_photo' => { 0 => 1 });
- # The below email comparison must not have an external message.
- $report->unset_extra_metadata('external_message');
- $report->update({
- state => 'external',
- photo => $fileid,
- external_body => $external_body->id,
- });
+ my $photo = path(__FILE__)->parent->child('zurich-logo_portal.x.jpg')->slurp_raw;
+ my $photoset = FixMyStreet::App::Model::PhotoSet->new({
+ data_items => [ $photo ],
+ });
+ my $fileid = $photoset->data;
+
+ $report->set_extra_metadata('publish_photo' => { 0 => 1 });
+ # The below email comparison must not have an external message.
+ $report->unset_extra_metadata('external_message');
+ $report->update({
+ state => 'external',
+ photo => $fileid,
+ external_body => $external_body->id,
+ });
- $mech->clear_emails_ok;
- send_reports_for_zurich();
+ $mech->clear_emails_ok;
+ send_reports_for_zurich();
- my @emails = $mech->get_email;
- my $email_as_string = $mech->get_first_email(@emails);
- my ($boundary) = $email_as_string =~ /boundary="([A-Za-z0-9.]*)"/ms;
- my $email = Email::MIME->new($email_as_string);
-
- my $expected_email_content = path(__FILE__)->parent->child('zurich_attachments.txt')->slurp;
-
- my $REPORT_ID = $report->id;
- $expected_email_content =~ s{Subject: (.*?)\r?\n}{
- my $subj = Encode::decode('MIME-Header', $1);
- $subj =~ s{REPORT_ID}{$REPORT_ID}g;
- 'Subject: ' . Email::MIME::Encode::mime_encode($subj, "utf-8") . "\n";
- }eg;
- $expected_email_content =~ s{REPORT_ID}{$REPORT_ID}g;
- $expected_email_content =~ s{BOUNDARY}{$boundary}g;
- my $expected_email = Email::MIME->new($expected_email_content);
-
- my @email_parts;
- $email->walk_parts(sub {
- my ($part) = @_;
- push @email_parts, [ { $part->header_pairs }, $part->body ];
- });
- my @expected_email_parts;
- $expected_email->walk_parts(sub {
- my ($part) = @_;
- push @expected_email_parts, [ { $part->header_pairs }, $part->body ];
- });
- is_deeply \@email_parts, \@expected_email_parts, 'MIME email text ok'
- or do {
- (my $test_name = $0) =~ s{/}{_}g;
- my $path = path("test-output-$test_name.tmp");
- $path->spew($email_as_string);
- diag "Saved output in $path";
- };
+ my @emails = $mech->get_email;
+ my $email_as_string = $mech->get_first_email(@emails);
+ my ($boundary) = $email_as_string =~ /boundary="([A-Za-z0-9.]*)"/ms;
+ my $email = Email::MIME->new($email_as_string);
+
+ my $expected_email_content = path(__FILE__)->parent->child('zurich_attachments.txt')->slurp;
+
+ my $REPORT_ID = $report->id;
+ $expected_email_content =~ s{Subject: (.*?)\r?\n}{
+ my $subj = Encode::decode('MIME-Header', $1);
+ $subj =~ s{REPORT_ID}{$REPORT_ID}g;
+ 'Subject: ' . Email::MIME::Encode::mime_encode($subj, "utf-8", 9) . "\n";
+ }eg;
+ $expected_email_content =~ s{REPORT_ID}{$REPORT_ID}g;
+ $expected_email_content =~ s{BOUNDARY}{$boundary}g;
+ my $expected_email = Email::MIME->new($expected_email_content);
+
+ my @email_parts;
+ $email->walk_parts(sub {
+ my ($part) = @_;
+ push @email_parts, [ { $part->header_pairs }, $part->body ];
+ });
+ my @expected_email_parts;
+ $expected_email->walk_parts(sub {
+ my ($part) = @_;
+ push @expected_email_parts, [ { $part->header_pairs }, $part->body ];
+ });
+ is_deeply \@email_parts, \@expected_email_parts, 'MIME email text ok'
+ or do {
+ (my $test_name = $0) =~ s{/}{_}g;
+ my $path = path("test-output-$test_name.tmp");
+ $path->spew($email_as_string);
+ diag "Saved output in $path";
};
};
subtest 'Status update shown as appropriate' => sub {
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAP_TYPE => 'Zurich,OSM',
- }, sub {
- # ALL closed states must hide the public_response edit, and public ones
- # must show the answer in blue.
- for (['feedback pending', 1, 0, 0],
- ['fixed - council', 0, 1, 0],
- ['external', 0, 1, 0],
- ['hidden', 0, 0, 1])
- {
- my ($state, $update, $public, $user_response) = @$_;
- $report->update({ state => $state });
- $mech->get_ok( '/admin/report_edit/' . $report->id );
- $mech->contains_or_lacks($update, "name='status_update'");
- $mech->contains_or_lacks($public || $user_response, '<div class="admin-official-answer">');
-
- if ($public) {
- $mech->get_ok( '/report/' . $report->id );
- $mech->content_contains('Antwort</h4>');
- }
- }
- };
+ # ALL closed states must hide the public_response edit, and public ones
+ # must show the answer in blue.
+ for (['feedback pending', 1, 0, 0],
+ ['fixed - council', 0, 1, 0],
+ ['external', 0, 1, 0],
+ ['hidden', 0, 0, 1])
+ {
+ my ($state, $update, $public, $user_response) = @$_;
+ $report->update({ state => $state });
+ $mech->get_ok( '/admin/report_edit/' . $report->id );
+ $mech->contains_or_lacks($update, "name='status_update'");
+ $mech->contains_or_lacks($public || $user_response, '<div class="admin-official-answer">');
+
+ if ($public) {
+ $mech->get_ok( '/report/' . $report->id );
+ $mech->content_contains('Antwort</h4>');
+ }
+ }
};
subtest 'time_spent' => sub {
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAP_TYPE => 'Zurich,OSM',
- }, sub {
- my $report = $reports[0];
-
- is $report->get_time_spent, 0, '0 minutes spent';
- $report->update({ state => 'in progress' });
- $mech->get_ok( '/admin/report_edit/' . $report->id );
- $mech->form_with_fields( 'time_spent' );
- $mech->submit_form_ok( {
- with_fields => {
- time_spent => 10,
- } });
- is $report->get_time_spent, 10, '10 minutes spent';
- };
+ my $report = $reports[0];
+
+ is $report->get_time_spent, 0, '0 minutes spent';
+ $report->update({ state => 'in progress' });
+ $mech->get_ok( '/admin/report_edit/' . $report->id );
+ $mech->form_with_fields( 'time_spent' );
+ $mech->submit_form_ok( {
+ with_fields => {
+ time_spent => 10,
+ } });
+ is $report->get_time_spent, 10, '10 minutes spent';
};
$mech->log_out_ok;
-FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAPIT_URL => 'http://mapit.zurich/',
- MAPIT_TYPES => [ 'ZZZ' ],
-}, sub {
- subtest 'users at the top level can be edited' => sub {
- $mech->log_in_ok( $superuser->email );
- $mech->get_ok('/admin/users/' . $superuser->id );
- };
+subtest 'users at the top level can be edited' => sub {
+ $mech->log_in_ok( $superuser->email );
+ $mech->get_ok('/admin/users/' . $superuser->id );
};
-FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
-}, sub {
- subtest 'A visit to /reports is okay' => sub {
- $mech->get_ok('/reports');
- };
+subtest 'A visit to /reports is okay' => sub {
+ $mech->get_ok('/reports');
};
-END {
- ok $mech->host("www.fixmystreet.com"), "change host back";
- done_testing();
-}
+};
-1;
+done_testing();
diff --git a/t/cobrand/zurich_attachments.txt b/t/cobrand/zurich_attachments.txt
index 25a1bacf0..e9b717618 100644
--- a/t/cobrand/zurich_attachments.txt
+++ b/t/cobrand/zurich_attachments.txt
@@ -3,7 +3,7 @@ Subject: =?iso-8859-1?Q?Z=FCri?= wie neu: Weitergeleitete Meldung #REPORT_ID
Content-Type: multipart/mixed; boundary="BOUNDARY"
To: "External Body" <external_body@example.net>
Content-Transfer-Encoding: 7bit
-From: "FixMyStreet" <division@example.org>
+From: FixMyStreet <division@example.org>
--BOUNDARY
@@ -12,7 +12,7 @@ Content-Transfer-Encoding: quoted-printable
Gr=C3=BCezi External Body,
-=C3=96ffentliche URL: http://www.example.org/report/REPORT_ID
+=C3=96ffentliche URL: https://www.zurich/report/REPORT_ID
Bei Fragen zu "Z=C3=BCri wie neu" wenden Sie sich bitte an =
gis-zentrum@zuerich.ch.=