aboutsummaryrefslogtreecommitdiffstats
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/Mock/MapIt.pm2
-rw-r--r--t/app/controller/admin/bodies.t39
-rw-r--r--t/app/controller/admin/report_edit.t125
-rw-r--r--t/app/controller/admin/stats.t26
-rw-r--r--t/app/controller/admin/templates.t51
-rw-r--r--t/app/controller/alert_new.t5
-rw-r--r--t/app/controller/around.t10
-rw-r--r--t/app/controller/contact.t66
-rw-r--r--t/app/controller/develop.t33
-rw-r--r--t/app/controller/fakemapit.t13
-rw-r--r--t/app/controller/open311.t13
-rw-r--r--t/app/controller/photo.t36
-rw-r--r--t/app/controller/questionnaire.t21
-rw-r--r--t/app/controller/report_as_other.t31
-rw-r--r--t/app/controller/report_display.t106
-rw-r--r--t/app/controller/report_inspect.t59
-rw-r--r--t/app/controller/report_new.t162
-rw-r--r--t/app/controller/report_new_open311.t138
-rw-r--r--t/app/controller/report_updates.t55
-rw-r--r--t/app/controller/reports.t3
-rw-r--r--t/app/model/defecttype.t21
-rw-r--r--t/app/model/problem.t4
-rw-r--r--t/app/model/responsepriority.t18
-rw-r--r--t/app/model/responsetemplate.t28
-rw-r--r--t/app/model/session.t14
-rw-r--r--t/app/script/archive_old_enquiries.t51
l---------t/browser1
-rw-r--r--t/cobrand/bathnes.t197
-rw-r--r--t/cobrand/bromley.t83
-rw-r--r--t/cobrand/closest.t16
-rw-r--r--t/cobrand/fixmystreet.t6
-rw-r--r--t/cobrand/form_extras.t35
-rw-r--r--t/cobrand/oxfordshire.t60
-rw-r--r--t/cobrand/rutland.t61
-rw-r--r--t/cobrand/zurich.t156
-rw-r--r--t/map/tests.t2
-rw-r--r--t/open311.t63
-rw-r--r--t/open311/getservicerequests.t427
-rw-r--r--t/open311/getservicerequestupdates.t153
-rw-r--r--t/open311/populate-service-list.t72
-rw-r--r--t/script/inactive.t71
-rw-r--r--t/sendreport/open311.t84
42 files changed, 2247 insertions, 370 deletions
diff --git a/t/Mock/MapIt.pm b/t/Mock/MapIt.pm
index 8dd10c53d..c57f7e0ed 100644
--- a/t/Mock/MapIt.pm
+++ b/t/Mock/MapIt.pm
@@ -23,6 +23,7 @@ sub output {
}
my @PLACES = (
+ [ '?', 53.387402, -2.943997, 2527, 'Liverpool City Council', 'MTD' ],
[ 'EH1 1BB', 55.952055, -3.189579, 2651, 'Edinburgh City Council', 'UTA', 20728, 'City Centre', 'UTE' ],
[ 'BS10 5EE', 51.494885, -2.602237, 2561, 'Bristol City Council', 'UTA', 148646, 'Bedminster', 'UTW' ],
[ 'SW1A 1AA', 51.501009, -0.141588, 2504, 'Westminster City Council', 'LBO' ],
@@ -30,6 +31,7 @@ my @PLACES = (
[ '?', 51.754926, -1.256179, 2237, 'Oxfordshire County Council', 'CTY', 2421, 'Oxford City Council', 'DIS' ],
[ 'OX20 1SZ', 51.754926, -1.256179, 2237, 'Oxfordshire County Council', 'CTY', 2421, 'Oxford City Council', 'DIS' ],
[ 'BR1 3UH', 51.4021, 0.01578, 2482, 'Bromley Council', 'LBO' ],
+ [ 'BR1 3UH', 51.402096, 0.015784, 2482, 'Bromley Council', 'LBO' ],
[ '?', 50.78301, -0.646929 ],
[ 'GU51 4AE', 51.279456, -0.846216, 2333, 'Hart District Council', 'DIS', 2227, 'Hampshire County Council', 'CTY' ],
[ 'WS1 4NH', 52.563074, -1.991032, 2535, 'Sandwell Borough Council', 'MTD' ],
diff --git a/t/app/controller/admin/bodies.t b/t/app/controller/admin/bodies.t
index 9bdf8fb9a..a485d286d 100644
--- a/t/app/controller/admin/bodies.t
+++ b/t/app/controller/admin/bodies.t
@@ -150,6 +150,45 @@ subtest 'check open311 configuring' => sub {
is $conf->endpoint, 'http://example.org/open311', 'endpoint updated';
is $conf->api_key, 'new api key', 'api key updated';
is $conf->jurisdiction, 'open311', 'jurisdiction configures';
+ ok !$conf->get_extra_metadata('fetch_all_problems'), 'fetch all problems unset';
+
+ $mech->form_number(3);
+ $mech->submit_form_ok(
+ {
+ with_fields => {
+ api_key => 'new api key',
+ endpoint => 'http://example.org/open311',
+ jurisdiction => 'open311',
+ send_comments => 0,
+ send_method => 'Open311',
+ fetch_all_problems => 1,
+ }
+ }
+ );
+
+ $mech->content_contains('Values updated');
+
+ $conf = FixMyStreet::App->model('DB::Body')->find( $body->id );
+ ok $conf->get_extra_metadata('fetch_all_problems'), 'fetch all problems set';
+
+ $mech->form_number(3);
+ $mech->submit_form_ok(
+ {
+ with_fields => {
+ api_key => 'new api key',
+ endpoint => 'http://example.org/open311',
+ jurisdiction => 'open311',
+ send_comments => 0,
+ send_method => 'Open311',
+ fetch_all_problems => 0,
+ }
+ }
+ );
+
+ $mech->content_contains('Values updated');
+
+ $conf = FixMyStreet::App->model('DB::Body')->find( $body->id );
+ ok !$conf->get_extra_metadata('fetch_all_problems'), 'fetch all problems unset';
};
subtest 'check text output' => sub {
diff --git a/t/app/controller/admin/report_edit.t b/t/app/controller/admin/report_edit.t
index a8a0bd143..5e3e6c315 100644
--- a/t/app/controller/admin/report_edit.t
+++ b/t/app/controller/admin/report_edit.t
@@ -79,6 +79,7 @@ foreach my $test (
anonymous => 0,
flagged => undef,
non_public => undef,
+ closed_updates => undef,
},
changes => { title => 'Edited Report', },
log_entries => [qw/edit/],
@@ -95,6 +96,7 @@ foreach my $test (
anonymous => 0,
flagged => undef,
non_public => undef,
+ closed_updates => undef,
},
changes => { detail => 'Edited Detail', },
log_entries => [qw/edit edit/],
@@ -111,6 +113,7 @@ foreach my $test (
anonymous => 0,
flagged => undef,
non_public => undef,
+ closed_updates => undef,
},
changes => { name => 'Edited User', },
log_entries => [qw/edit edit edit/],
@@ -128,6 +131,7 @@ foreach my $test (
anonymous => 0,
flagged => undef,
non_public => undef,
+ closed_updates => undef,
},
changes => {
flagged => 'on',
@@ -147,6 +151,7 @@ foreach my $test (
anonymous => 0,
flagged => 'on',
non_public => undef,
+ closed_updates => undef,
},
changes => { username => $user2->email, },
log_entries => [qw/edit edit edit edit edit/],
@@ -164,6 +169,7 @@ foreach my $test (
anonymous => 0,
flagged => 'on',
non_public => undef,
+ closed_updates => undef,
},
expect_comment => 1,
changes => { state => 'unconfirmed' },
@@ -181,6 +187,7 @@ foreach my $test (
anonymous => 0,
flagged => 'on',
non_public => undef,
+ closed_updates => undef,
},
expect_comment => 1,
changes => { state => 'confirmed' },
@@ -198,6 +205,7 @@ foreach my $test (
anonymous => 0,
flagged => 'on',
non_public => undef,
+ closed_updates => undef,
},
expect_comment => 1,
changes => { state => 'fixed' },
@@ -216,6 +224,7 @@ foreach my $test (
anonymous => 0,
flagged => 'on',
non_public => undef,
+ closed_updates => undef,
},
expect_comment => 1,
changes => { state => 'hidden' },
@@ -235,6 +244,7 @@ foreach my $test (
anonymous => 0,
flagged => 'on',
non_public => undef,
+ closed_updates => undef,
},
expect_comment => 1,
changes => {
@@ -257,6 +267,7 @@ foreach my $test (
anonymous => 1,
flagged => 'on',
non_public => undef,
+ closed_updates => undef,
},
changes => {},
log_entries => [
@@ -275,6 +286,7 @@ foreach my $test (
anonymous => 1,
flagged => 'on',
non_public => undef,
+ closed_updates => undef,
},
changes => {
non_public => 'on',
@@ -285,6 +297,24 @@ foreach my $test (
resend => 0,
},
{
+ description => 'close to updates',
+ fields => {
+ title => 'Edited Report',
+ detail => 'Edited Detail',
+ state => 'confirmed',
+ name => 'Edited User',
+ username => $user2->email,
+ anonymous => 1,
+ flagged => 'on',
+ non_public => 'on',
+ closed_updates => undef,
+ },
+ changes => { closed_updates => 'on' },
+ log_entries => [
+ qw/edit edit resend edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/
+ ],
+ },
+ {
description => 'change state to investigating as body superuser',
fields => {
title => 'Edited Report',
@@ -295,12 +325,13 @@ foreach my $test (
anonymous => 1,
flagged => 'on',
non_public => 'on',
+ closed_updates => undef,
},
expect_comment => 1,
user_body => $oxfordshire,
changes => { state => 'investigating' },
log_entries => [
- qw/edit state_change edit resend edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/
+ qw/edit state_change edit edit resend edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/
],
resend => 0,
},
@@ -315,13 +346,14 @@ foreach my $test (
anonymous => 1,
flagged => 'on',
non_public => 'on',
+ closed_updates => undef,
},
expect_comment => 1,
expected_text => '*Category changed from ‘Other’ to ‘Potholes’*',
user_body => $oxfordshire,
changes => { state => 'in progress', category => 'Potholes' },
log_entries => [
- qw/edit state_change edit state_change edit resend edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/
+ qw/edit state_change edit state_change edit edit resend edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/
],
resend => 0,
},
@@ -364,9 +396,22 @@ foreach my $test (
$mech->content_lacks( 'type="submit" name="resend"', 'no resend button' );
}
+ if ($report->state eq 'fixed') {
+ $mech->content_contains('pin-green');
+ }
+
$test->{changes}->{flagged} = 1 if $test->{changes}->{flagged};
$test->{changes}->{non_public} = 1 if $test->{changes}->{non_public};
+ if ($test->{changes}->{closed_updates}) {
+ is $report->get_extra_metadata('closed_updates'), 1, "closed_updates updated";
+ $mech->get_ok("/report/$report_id");
+ $mech->content_lacks('Provide an update');
+ $report->unset_extra_metadata('closed_updates');
+ $report->update;
+ delete $test->{changes}->{closed_updates};
+ }
+
is $report->$_, $test->{changes}->{$_}, "$_ updated" for grep { $_ ne 'username' } keys %{ $test->{changes} };
if ( $test->{user} ) {
@@ -447,6 +492,7 @@ subtest 'change email to new user' => sub {
anonymous => 1,
flagged => 'on',
non_public => 'on',
+ closed_updates => undef,
external_id => '13',
external_body => '',
external_team => '',
@@ -553,4 +599,79 @@ subtest "Test setting a report from unconfirmed to something else doesn't cause
$mech->get_ok("/report/$report_id");
};
+subtest "Test display of report extra data" => sub {
+ $mech->get_ok("/admin/report_edit/$report_id");
+ $mech->content_contains('Extra data: No');
+ $report->set_extra_metadata('extra_field', 'this is extra data');
+ $report->update;
+ $mech->get_ok("/admin/report_edit/$report_id");
+ $mech->content_contains('extra_field</strong>: this is extra data');
+};
+
+my $report2 = FixMyStreet::App->model('DB::Problem')->find_or_create(
+ {
+ postcode => 'SW1A 1AA',
+ bodies_str => '2504',
+ areas => ',105255,11806,11828,2247,2504,',
+ category => 'Other',
+ title => 'Report to Duplicate Edit',
+ detail => 'Detail for Duplicate Report to Edit',
+ used_map => 't',
+ name => 'Test User',
+ anonymous => 'f',
+ external_id => '13',
+ state => 'confirmed',
+ confirmed => $dt->ymd . ' ' . $dt->hms,
+ lang => 'en-gb',
+ service => '',
+ cobrand => '',
+ cobrand_data => '',
+ send_questionnaire => 't',
+ latitude => '51.5016605453401',
+ longitude => '-0.142497580865087',
+ user_id => $user->id,
+ whensent => $dt->ymd . ' ' . $dt->hms,
+ }
+);
+
+subtest "Test display of report duplicates extra data" => sub {
+ $report->update( { extra => undef } );
+ $mech->get_ok("/admin/report_edit/$report_id");
+ $mech->content_contains('Extra data: No');
+
+ $report2->set_duplicate_of($report_id);
+ $report2->update;
+
+ $mech->get_ok("/admin/report_edit/$report_id");
+ $mech->content_contains('Duplicates</strong>: ' . $report2->id);
+};
+
+subtest "Test display of fields extra data" => sub {
+ $report->unset_extra_metadata( 'duplicates' );
+ $report->update;
+ $mech->get_ok("/admin/report_edit/$report_id");
+ $mech->content_contains('Extra data: No');
+
+ $report->push_extra_fields( {
+ name => 'report_url',
+ value => 'http://example.com',
+ });
+ $report->update;
+
+ $report->discard_changes;
+
+ $mech->get_ok("/admin/report_edit/$report_id");
+ $mech->content_contains('report_url</strong>: http://example.com');
+
+ $report->set_extra_fields( {
+ description => 'Report URL',
+ name => 'report_url',
+ value => 'http://example.com',
+ });
+ $report->update;
+
+ $mech->get_ok("/admin/report_edit/$report_id");
+ $mech->content_contains('Report URL (report_url)</strong>: http://example.com');
+};
+
done_testing();
diff --git a/t/app/controller/admin/stats.t b/t/app/controller/admin/stats.t
index dae51d31f..ce6f8466c 100644
--- a/t/app/controller/admin/stats.t
+++ b/t/app/controller/admin/stats.t
@@ -9,4 +9,30 @@ subtest "smoke view some stats pages" => sub {
$mech->get_ok('/admin/stats/questionnaire');
};
+subtest "test refused stats page works" => sub {
+ my $body1 = $mech->create_body_ok(2651, 'Edinburgh Council');
+ my $body2 = $mech->create_body_ok(2237, 'Oxfordshire Council', { send_method => 'Refused' });
+ my $body3 = $mech->create_body_ok(2243, 'Warwickshire Council', { can_be_devolved => 1 });
+ $mech->create_contact_ok(body_id => $body1->id, category => 'Street lighting', email => 'REFUSED');
+ $mech->create_contact_ok(body_id => $body1->id, category => 'Potholes', email => 'potholes@example.org');
+ $mech->create_contact_ok(body_id => $body2->id, category => 'Potholes', email => 'potholes@example.org');
+ $mech->create_contact_ok(body_id => $body3->id, category => 'Street lighting', email => 'lights@example.org');
+ $mech->create_contact_ok(body_id => $body3->id, category => 'Potholes', email => 'potholes@example.org', send_method => 'Refused');
+
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ }, sub {
+ $mech->get_ok('/admin/stats/refused');
+ };
+ $mech->content =~ /class="content"(.*)class="nav-wrapper/s;
+ my @lines = split /<li>/, $1;
+ is @lines, 7;
+ like $lines[1], qr/Edinburgh/;
+ like $lines[2], qr/Street lighting/;
+ like $lines[3], qr/Oxfordshire/;
+ like $lines[4], qr/ALL/;
+ like $lines[5], qr/Warwickshire/;
+ like $lines[6], qr/Potholes/;
+};
+
done_testing();
diff --git a/t/app/controller/admin/templates.t b/t/app/controller/admin/templates.t
index 179a1afcb..0d4430cad 100644
--- a/t/app/controller/admin/templates.t
+++ b/t/app/controller/admin/templates.t
@@ -180,4 +180,55 @@ subtest "all-category auto-response templates that duplicate a single category c
is $oxfordshire->response_templates->count, 1, "Duplicate response template wasn't added";
};
+subtest "auto-response templates that duplicate external_status_code can't be added" => sub {
+ $mech->delete_response_template($_) for $oxfordshire->response_templates;
+ my $template = $oxfordshire->response_templates->create({
+ title => "Report fixed - potholes",
+ text => "Thank you for your report. This problem has been fixed.",
+ auto_response => 1,
+ external_status_code => '100',
+ });
+ $template->contact_response_templates->find_or_create({
+ contact_id => $oxfordshirecontact->id,
+ });
+ is $oxfordshire->response_templates->count, 1, "Initial response template was created";
+
+
+ $mech->log_in_ok( $superuser->email );
+ $mech->get_ok( "/admin/templates/" . $oxfordshire->id . "/new" );
+
+ my $fields = {
+ title => "Report marked fixed - all cats",
+ text => "Thank you for your report. This problem has been fixed.",
+ auto_response => 'on',
+ external_status_code => '100',
+ };
+ $mech->submit_form_ok( { with_fields => $fields } );
+ is $mech->uri->path, '/admin/templates/' . $oxfordshire->id . '/new', 'not redirected';
+ $mech->content_contains( 'Please correct the errors below' );
+ $mech->content_contains( 'There is already an auto-response template for this category/state.' );
+
+ is $oxfordshire->response_templates->count, 1, "Duplicate response template wasn't added";
+};
+
+subtest "templates that set state and external_status_code can't be added" => sub {
+ $mech->delete_response_template($_) for $oxfordshire->response_templates;
+ $mech->log_in_ok( $superuser->email );
+ $mech->get_ok( "/admin/templates/" . $oxfordshire->id . "/new" );
+
+ my $fields = {
+ title => "Report marked fixed - all cats",
+ text => "Thank you for your report. This problem has been fixed.",
+ auto_response => 'on',
+ state => 'fixed - council',
+ external_status_code => '100',
+ };
+ $mech->submit_form_ok( { with_fields => $fields } );
+ is $mech->uri->path, '/admin/templates/' . $oxfordshire->id . '/new', 'not redirected';
+ $mech->content_contains( 'Please correct the errors below' );
+ $mech->content_contains( 'State and external status code cannot be used simultaneously.' );
+
+ is $oxfordshire->response_templates->count, 0, "Invalid response template wasn't added";
+};
+
done_testing();
diff --git a/t/app/controller/alert_new.t b/t/app/controller/alert_new.t
index 4e8fd1b29..27371e4a9 100644
--- a/t/app/controller/alert_new.t
+++ b/t/app/controller/alert_new.t
@@ -451,9 +451,8 @@ subtest "Test normal alert signups and that alerts are sent" => sub {
is $count, 5, 'Three emails, with five matching lines in them';
my $email = $emails[0];
- my $body = $mech->get_text_body_from_email($email);
- like $body, qr/Other User/, 'Update name given';
- unlike $body, qr/Anonymous User/, 'Update name not given';
+ is +(my $c = () = $email->as_string =~ /Other User/g), 2, 'Update name given, twice';
+ unlike $email->as_string, qr/Anonymous User/, 'Update name not given';
# The update alert was to the problem reporter, so has a special update URL
$mech->log_out_ok;
diff --git a/t/app/controller/around.t b/t/app/controller/around.t
index 618998513..8eaba6450 100644
--- a/t/app/controller/around.t
+++ b/t/app/controller/around.t
@@ -137,7 +137,7 @@ subtest 'check non public reports are not displayed on around page' => sub {
};
-subtest 'check category and status filtering works on /around' => sub {
+subtest 'check category, status and extra filtering works on /around' => sub {
my $body = $mech->create_body_ok(2237, "Oxfordshire");
my $categories = [ 'Pothole', 'Vegetation', 'Flytipping' ];
@@ -157,6 +157,7 @@ subtest 'check category and status filtering works on /around' => sub {
%$params,
category => $category,
state => $state,
+ external_body => "$category-$state",
);
$mech->create_problems_for_body( 1, $body->id, 'Around page', \%report_params );
}
@@ -185,6 +186,13 @@ subtest 'check category and status filtering works on /around' => sub {
$json = $mech->get_ok_json( '/around?ajax=1&status=fixed&filter_category=Vegetation&bbox=' . $bbox );
$pins = $json->{pins};
is scalar @$pins, 1, 'correct number of fixed Vegetation reports';
+
+ my $cobrand = Test::MockModule->new('FixMyStreet::Cobrand::Default');
+ $cobrand->mock('display_location_extra_params', sub { { external_body => "Pothole-fixed" } });
+
+ $json = $mech->get_ok_json( '/around?ajax=1&bbox=' . $bbox );
+ $pins = $json->{pins};
+ is scalar @$pins, 1, 'correct number of external_body reports';
};
subtest 'check skip_around skips around page' => sub {
diff --git a/t/app/controller/contact.t b/t/app/controller/contact.t
index c1039d15b..4f255f058 100644
--- a/t/app/controller/contact.t
+++ b/t/app/controller/contact.t
@@ -37,6 +37,17 @@ for my $test (
detail => 'More detail on the different problem',
postcode => 'EH99 1SP',
confirmed => '2011-05-03 13:24:28.145168',
+ anonymous => 0,
+ hidden => 1,
+ meta => 'Reported anonymously at 13:24, Tue 3 May 2011',
+ },
+ {
+ name => 'A User',
+ email => 'problem_report_test@example.com',
+ title => 'A different problem',
+ detail => 'More detail on the different problem',
+ postcode => 'EH99 1SP',
+ confirmed => '2011-05-03 13:24:28.145168',
anonymous => 1,
meta => 'Reported anonymously at 13:24, Tue 3 May 2011',
update => {
@@ -45,6 +56,38 @@ for my $test (
text => 'This is an update',
},
},
+ {
+ name => 'A User',
+ email => 'problem_report_test@example.com',
+ title => 'A different problem',
+ detail => 'More detail on the different problem',
+ postcode => 'EH99 1SP',
+ confirmed => '2011-05-03 13:24:28.145168',
+ anonymous => 1,
+ meta => 'Reported anonymously at 13:24, Tue 3 May 2011',
+ update => {
+ other_problem => 1,
+ name => 'Different User',
+ email => 'commenter@example.com',
+ text => 'This is an update',
+ },
+ },
+ {
+ name => 'A User',
+ email => 'problem_report_test@example.com',
+ title => 'A different problem',
+ detail => 'More detail on the different problem',
+ postcode => 'EH99 1SP',
+ confirmed => '2011-05-03 13:24:28.145168',
+ anonymous => 1,
+ meta => 'Reported anonymously at 13:24, Tue 3 May 2011',
+ update => {
+ hidden => 1,
+ name => 'Different User',
+ email => 'commenter@example.com',
+ text => 'This is an update',
+ },
+ },
)
{
subtest 'check reporting a problem displays correctly' => sub {
@@ -58,7 +101,7 @@ for my $test (
confirmed => $test->{confirmed},
name => $test->{name},
anonymous => $test->{anonymous},
- state => 'confirmed',
+ state => $test->{hidden} ? 'hidden' : 'confirmed',
user => $user,
latitude => 0,
longitude => 0,
@@ -76,9 +119,9 @@ for my $test (
$update = FixMyStreet::App->model('DB::Comment')->create(
{
- problem_id => $problem->id,
+ problem_id => $update_info->{other_problem} ? $problem_main->id : $problem->id,
user => $update_user,
- state => 'confirmed',
+ state => $update_info->{hidden} ? 'hidden' : 'confirmed',
text => $update_info->{text},
confirmed => \'current_timestamp',
mark_fixed => 'f',
@@ -90,9 +133,20 @@ for my $test (
ok $problem, 'succesfully create a problem';
if ( $update ) {
- $mech->get_ok( '/contact?id=' . $problem->id . '&update_id=' . $update->id );
- $mech->content_contains('reporting the following update');
- $mech->content_contains( $test->{update}->{text} );
+ if ( $test->{update}->{hidden} ) {
+ $mech->get( '/contact?id=' . $problem->id . '&update_id=' . $update->id );
+ is $mech->res->code, 404, 'cannot report a hidden update';
+ } elsif ( $test->{update}->{other_problem} ) {
+ $mech->get( '/contact?id=' . $problem->id . '&update_id=' . $update->id );
+ is $mech->res->code, 404, 'cannot view an update for another problem';
+ } else {
+ $mech->get_ok( '/contact?id=' . $problem->id . '&update_id=' . $update->id );
+ $mech->content_contains('reporting the following update');
+ $mech->content_contains( $test->{update}->{text} );
+ }
+ } elsif ( $test->{hidden} ) {
+ $mech->get( '/contact?id=' . $problem->id );
+ is $mech->res->code, 410, 'cannot report a hidden problem';
} else {
$mech->get_ok( '/contact?id=' . $problem->id );
$mech->content_contains('reporting the following problem');
diff --git a/t/app/controller/develop.t b/t/app/controller/develop.t
new file mode 100644
index 000000000..92aa86721
--- /dev/null
+++ b/t/app/controller/develop.t
@@ -0,0 +1,33 @@
+use FixMyStreet::TestMech;
+
+ok( my $mech = FixMyStreet::TestMech->new, 'Created mech object' );
+
+my ($problem) = $mech->create_problems_for_body(1, 2504, 'title');
+my $update = $mech->create_comment_for_problem($problem, $problem->user, 'Name', 'Text', 'f', 'confirmed', 'confirmed');
+
+subtest 'not visible on live site' => sub {
+ FixMyStreet::override_config {
+ STAGING_SITE => 0
+ }, sub {
+ $mech->get('/_dev/email/');
+ is $mech->res->code, 404;
+ $mech->get('/_dev/email/login');
+ is $mech->res->code, 404;
+ };
+};
+
+subtest 'dev email index page' => sub {
+ $mech->get_ok('/_dev/email/');
+ $mech->content_contains('login">login</a></li>');
+ $mech->content_contains('questionnaire?problem=' . $problem->id . '">questionnaire</a></li>');
+ $mech->content_contains('update-confirm?update=' . $update->id . '">update-confirm</a></li>');
+};
+
+subtest 'individual email previews' => sub {
+ $mech->get_ok('/_dev/email/alert-problem-area');
+ $mech->get_ok('/_dev/email/alert-update?problem=' . $problem->id);
+ $mech->get_ok('/_dev/email/questionnaire?problem=' . $problem->id);
+ $mech->get_ok('/_dev/email/update-confirm?update=' . $update->id);
+};
+
+done_testing();
diff --git a/t/app/controller/fakemapit.t b/t/app/controller/fakemapit.t
new file mode 100644
index 000000000..c89aac600
--- /dev/null
+++ b/t/app/controller/fakemapit.t
@@ -0,0 +1,13 @@
+use JSON::MaybeXS;
+use FixMyStreet::TestMech;
+
+my $mech = FixMyStreet::TestMech->new;
+
+FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
+ $mech->get_ok('/mapit/areas/Birmingham');
+ is_deeply decode_json($mech->content), {2514 => {parent_area => undef, id => 2514, name => "Birmingham City Council", type => "MTD"}};
+};
+
+done_testing;
diff --git a/t/app/controller/open311.t b/t/app/controller/open311.t
index 29cd38129..9f4f594fe 100644
--- a/t/app/controller/open311.t
+++ b/t/app/controller/open311.t
@@ -1,3 +1,4 @@
+use JSON::MaybeXS;
use FixMyStreet::TestMech;
my $mech = FixMyStreet::TestMech->new;
@@ -5,4 +6,16 @@ my $mech = FixMyStreet::TestMech->new;
$mech->get_ok('/open311.cgi/v2/requests.rss?jurisdiction_id=fiksgatami.no&status=open&agency_responsible=1854');
like $mech->uri, qr[/open311/v2/requests\.rss\?.{65}]; # Don't know order parameters will be in now
+$mech->create_problems_for_body(2, 2237, 'Around page');
+$mech->get_ok('/open311/v2/requests.xml?jurisdiction_id=foo&status=open&agency_responsible=2237');
+$mech->content_contains('<description>Around page Test 2 for 2237: Around page Test 2 for 2237 Detail</description>');
+$mech->content_contains('<interface_used>Web interface</interface_used>');
+$mech->content_contains('<status>open</status>');
+
+$mech->get_ok('/open311/v2/requests.json?jurisdiction_id=foo&status=open&agency_responsible=2237');
+my $json = decode_json($mech->content);
+my $problems = $json->{requests}[0]{request};
+is @$problems, 2;
+like $problems->[0]{description}, qr/Around page Test/;
+
done_testing();
diff --git a/t/app/controller/photo.t b/t/app/controller/photo.t
index dbbc697d7..e9183836b 100644
--- a/t/app/controller/photo.t
+++ b/t/app/controller/photo.t
@@ -66,7 +66,43 @@ subtest "Check multiple upload worked" => sub {
'Returned upload_fileid contains expected hash, 3 times');
my $image_file = path($UPLOAD_DIR, '74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg');
ok $image_file->exists, 'File uploaded to temp';
+
+ $mech->submit_form_ok({ with_fields => { name => 'Bob Jones' } });
+ ok $mech->success, 'Made request with multiple photo upload';
};
};
+subtest "Check photo uploading URL works" => sub {
+ my $UPLOAD_DIR = tempdir( CLEANUP => 1 );
+
+ # submit initial pc form
+ FixMyStreet::override_config {
+ UPLOAD_DIR => $UPLOAD_DIR,
+ }, sub {
+ $mech->post( '/photo/upload',
+ Content_Type => 'form-data',
+ Content => {
+ photo1 => [ $sample_file, undef, Content_Type => 'application/octet-stream' ],
+ },
+ );
+ ok $mech->success, 'Made request with multiple photo upload';
+ is $mech->content, '{"id":"74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg"}';
+ my $image_file = path($UPLOAD_DIR, '74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg');
+ ok $image_file->exists, 'File uploaded to temp';
+ };
+};
+
+subtest "Check photo URL endpoints work" => sub {
+ my $p = FixMyStreet::DB->resultset("Problem")->first;
+
+ $mech->get_ok('/photo/temp.74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg');
+ my $image_file = FixMyStreet->path_to('web/photo/temp.74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg');
+ ok -e $image_file, 'File uploaded to temp';
+ $mech->get_ok('/photo/' . $p->id . '.jpeg');
+ $image_file = FixMyStreet->path_to('web/photo/' . $p->id . '.jpeg');
+ ok -e $image_file, 'File uploaded to temp';
+ my $res = $mech->get('/photo/0.jpeg');
+ is $res->code, 404, "got 404";
+};
+
done_testing();
diff --git a/t/app/controller/questionnaire.t b/t/app/controller/questionnaire.t
index c6d112df7..75542d759 100644
--- a/t/app/controller/questionnaire.t
+++ b/t/app/controller/questionnaire.t
@@ -52,7 +52,7 @@ like $plain->body, qr/fill in our short questionnaire/i, "got questionnaire emai
like $plain->body_str, qr/Testing \x{2013} Detail/, 'email contains encoded character';
is $plain->header('Content-Type'), 'text/plain; charset="utf-8"', 'in the right character set';
-my $url = $mech->get_link_from_email($email);
+my $url = $mech->get_link_from_email($email, 0, 1);
my ($token) = $url =~ m{/Q/(\S+)};
ok $token, "extracted questionnaire token '$token'";
$mech->clear_emails_ok;
@@ -108,6 +108,23 @@ foreach my $test (
};
}
+subtest "If been_fixed is provided in the URL" => sub {
+ $mech->get_ok("/Q/" . $token->token . "?been_fixed=Yes");
+ $mech->content_contains('id="been_fixed_yes" value="Yes" checked');
+ $report->discard_changes;
+ is $report->state, 'fixed - user';
+ $questionnaire->discard_changes;
+ is $questionnaire->old_state, 'confirmed';
+ is $questionnaire->new_state, 'fixed - user';
+ $mech->submit_form_ok({ with_fields => { been_fixed => 'Unknown', reported => 'Yes', another => 'No' } });
+ $report->discard_changes;
+ is $report->state, 'confirmed';
+ $questionnaire->discard_changes;
+ is $questionnaire->old_state, 'confirmed';
+ is $questionnaire->new_state, 'unknown';
+ $questionnaire->update({ whenanswered => undef, ever_reported => undef, old_state => undef, new_state => undef });
+};
+
$mech->get_ok("/Q/" . $token->token);
$mech->title_like( qr/Questionnaire/ );
$mech->submit_form_ok( );
@@ -399,7 +416,7 @@ FixMyStreet::override_config {
$mech->clear_emails_ok;
$body =~ s/\s+/ /g;
like $body, qr/fill in our short questionnaire/i, "got questionnaire email";
- my $url = $mech->get_link_from_email($email);
+ my $url = $mech->get_link_from_email($email, 0, 1);
($token) = $url =~ m{/Q/(\S+)};
ok $token, "extracted questionnaire token '$token'";
diff --git a/t/app/controller/report_as_other.t b/t/app/controller/report_as_other.t
index e8f65eb7b..367d9a1d4 100644
--- a/t/app/controller/report_as_other.t
+++ b/t/app/controller/report_as_other.t
@@ -1,5 +1,6 @@
use FixMyStreet::TestMech;
use FixMyStreet::App;
+use FixMyStreet::Script::Reports;
# disable info logs for this test run
FixMyStreet::App->log->disable('info');
@@ -15,7 +16,7 @@ my $test_email = 'body-user@example.net';
my $user = $mech->log_in_ok($test_email);
$user->update({ from_body => $body->id, name => 'Body User' });
-my ($report_to_update) = $mech->create_problems_for_body(1, $body->id, 'Title');
+my ($report_to_update) = $mech->create_problems_for_body(1, $body->id, 'Title', { category => 'Potholes' });
subtest "Body user, no permissions, no special reporting tools shown" => sub {
start_report();
@@ -100,6 +101,9 @@ subtest "Body user, has permission to add report as another user with landline n
};
subtest "Body user, has permission to add report as another (existing) user with email" => sub {
+ FixMyStreet::Script::Reports::send();
+ $mech->clear_emails_ok;
+
$mech->create_user_ok('existing@example.net', name => 'Existing User');
my $report = add_report(
'contribute_as_another_user',
@@ -116,6 +120,15 @@ subtest "Body user, has permission to add report as another (existing) user with
isnt $report->user->id, $user->id, 'user does not match';
like $mech->get_text_body_from_email, qr/Your report to Oxfordshire County Council has been logged/;
push @users, $report->user;
+
+ my $send_confirmation_mail_override = Sub::Override->new(
+ "FixMyStreet::Cobrand::Default::report_sent_confirmation_email",
+ sub { return 1; }
+ );
+ FixMyStreet::Script::Reports::send();
+ $mech->email_count_is(2);
+ $mech->clear_emails_ok;
+ $send_confirmation_mail_override->restore();
};
subtest "Body user, has permission to add report as another (existing) user with phone" => sub {
@@ -138,6 +151,9 @@ subtest "Body user, has permission to add report as another (existing) user with
};
subtest "Body user, has permission to add report as anonymous user" => sub {
+ FixMyStreet::Script::Reports::send();
+ $mech->clear_emails_ok;
+
my $report = add_report(
'contribute_as_anonymous_user',
form_as => 'anonymous_user',
@@ -149,6 +165,19 @@ subtest "Body user, has permission to add report as anonymous user" => sub {
is $report->user->name, 'Body User', 'user name unchanged';
is $report->user->id, $user->id, 'user matches';
is $report->anonymous, 1, 'report anonymous';
+
+ my $send_confirmation_mail_override = Sub::Override->new(
+ "FixMyStreet::Cobrand::Default::report_sent_confirmation_email",
+ sub { return 1; }
+ );
+
+ FixMyStreet::Script::Reports::send();
+ # No report sent email is sent
+ $mech->email_count_is(1);
+ my $email = $mech->get_email;
+ like $email->header('Subject'), qr/Problem Report: Test Report/, 'report email title correct';
+ $mech->clear_emails_ok;
+ $send_confirmation_mail_override->restore();
};
subtest "Body user, has permission to add update as council" => sub {
diff --git a/t/app/controller/report_display.t b/t/app/controller/report_display.t
index f0913fbd2..17b9180c1 100644
--- a/t/app/controller/report_display.t
+++ b/t/app/controller/report_display.t
@@ -115,6 +115,12 @@ subtest "duplicate reports are signposted correctly" => sub {
$report2->update;
};
+subtest "test /report/ajax" => sub {
+ my $json = $mech->get_ok_json( "/report/ajax/$report_id" );
+ is $json->{report}->{title}, "Test 2", "correct title";
+ is $json->{report}->{state}, "confirmed", "correct state";
+};
+
subtest "test a good report" => sub {
$mech->get_ok("/report/$report_id");
is $mech->uri->path, "/report/$report_id", "at /report/$report_id";
@@ -419,106 +425,6 @@ for my $test (
};
}
-subtest "Zurich unconfirmeds are 200" => sub {
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAP_TYPE => 'Zurich,OSM',
- }, sub {
- $mech->host( 'zurich.example.com' );
- ok $report->update( { state => 'unconfirmed' } ), 'unconfirm report';
- $mech->get_ok("/report/$report_id");
- $mech->content_contains( '&Uuml;berpr&uuml;fung ausstehend' );
- ok $report->update( { state => 'confirmed' } ), 'confirm report again';
- $mech->host( 'www.fixmystreet.com' );
- };
-};
-
-subtest "Zurich banners are displayed correctly" => sub {
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'zurich' ],
- MAP_TYPE => 'Zurich,OSM',
- }, sub {
- $mech->host( 'zurich.example.com' );
-
- for my $test (
- {
- description => 'new report',
- state => 'unconfirmed',
- banner_id => 'closed',
- banner_text => 'Erfasst'
- },
- {
- description => 'confirmed report',
- state => 'confirmed',
- banner_id => 'closed',
- banner_text => 'Aufgenommen',
- },
- {
- description => 'fixed report',
- state => 'fixed - council',
- banner_id => 'fixed',
- banner_text => 'Beantwortet',
- },
- {
- description => 'closed report',
- state => 'closed',
- banner_id => 'closed',
- banner_text => _('Extern'),
- },
- {
- description => 'in progress report',
- state => 'in progress',
- banner_id => 'progress',
- banner_text => 'In Bearbeitung',
- },
- {
- description => 'planned report',
- state => 'planned',
- banner_id => 'progress',
- banner_text => 'In Bearbeitung',
- },
- {
- description => 'planned report',
- state => 'planned',
- banner_id => 'progress',
- banner_text => 'In Bearbeitung',
- },
- {
- description => 'jurisdiction unknown',
- state => 'unable to fix',
- banner_id => 'fixed',
- # We can't use _('Jurisdiction Unknown') here because
- # TestMech::extract_problem_banner decodes the HTML entities before
- # the string is passed back.
- banner_text => 'Zust\x{e4}ndigkeit unbekannt',
- },
- ) {
- subtest "banner for $test->{description}" => sub {
- $report->state( $test->{state} );
- $report->update;
-
- $mech->get_ok("/report/$report_id");
- is $mech->uri->path, "/report/$report_id", "at /report/$report_id";
- my $banner = $mech->extract_problem_banner;
- if ( $banner->{text} ) {
- $banner->{text} =~ s/^ //g;
- $banner->{text} =~ s/ $//g;
- }
-
- is $banner->{id}, $test->{banner_id}, 'banner id';
- if ($test->{banner_text}) {
- like_string( $banner->{text}, qr/$test->{banner_text}/i, 'banner text is ' . $test->{banner_text} );
- } else {
- is $banner->{text}, $test->{banner_text}, 'banner text';
- }
-
- };
- }
-
- $mech->host( 'www.fixmystreet.com' );
- };
-};
-
my $oxfordshire = $mech->create_body_ok(2237, 'Oxfordshire County Council');
my $oxfordshireuser = $mech->create_user_ok('counciluser@example.com', name => 'Council User', from_body => $oxfordshire);
diff --git a/t/app/controller/report_inspect.t b/t/app/controller/report_inspect.t
index 239cc408b..6a001225d 100644
--- a/t/app/controller/report_inspect.t
+++ b/t/app/controller/report_inspect.t
@@ -36,8 +36,8 @@ my $report_id = $report->id;
my $report2_id = $report2->id;
my $report3_id = $report3->id;
-
-my $user = $mech->log_in_ok('test@example.com');
+$mech->create_user_ok('body@example.com', name => 'Body User');
+my $user = $mech->log_in_ok('body@example.com');
$user->set_extra_metadata('categories', [ $contact->id ]);
$user->update( { from_body => $oxon } );
@@ -50,18 +50,36 @@ FixMyStreet::override_config {
$mech->content_lacks('Save changes');
$mech->content_lacks('Priority');
$mech->content_lacks('Traffic management');
+ $mech->content_lacks('/admin/report_edit/'.$report_id.'">admin</a>)');
$user->user_body_permissions->create({ body => $oxon, permission_type => 'report_edit_priority' });
$mech->get_ok("/report/$report_id");
$mech->content_contains('Save changes');
$mech->content_contains('Priority');
$mech->content_lacks('Traffic management');
+ $mech->content_lacks('/admin/report_edit/'.$report_id.'">admin</a>)');
$user->user_body_permissions->create({ body => $oxon, permission_type => 'report_inspect' });
$mech->get_ok("/report/$report_id");
$mech->content_contains('Save changes');
$mech->content_contains('Priority');
$mech->content_contains('Traffic management');
+ $mech->content_lacks('/admin/report_edit/'.$report_id.'">admin</a>)');
+ };
+
+ subtest "council staff can't see admin report edit link on FMS.com" => sub {
+ my $report_edit_permission = $user->user_body_permissions->create({
+ body => $oxon, permission_type => 'report_edit' });
+ $mech->get_ok("/report/$report_id");
+ $mech->content_lacks('/admin/report_edit/'.$report_id.'">admin</a>)');
+ $report_edit_permission->delete;
+ };
+
+ subtest "superusers can see admin report edit link on FMS.com" => sub {
+ $user->update({is_superuser => 1});
+ $mech->get_ok("/report/$report_id");
+ $mech->content_contains('/admin/report_edit/'.$report_id.'">admin</a>)');
+ $user->update({is_superuser => 0});
};
subtest "test basic inspect submission" => sub {
@@ -539,6 +557,13 @@ FixMyStreet::override_config {
is $report->get_extra_metadata('traffic_information'), 'Signs and Cones', 'report data changed';
};
+ subtest "admin link present on inspect page on cobrand" => sub {
+ my $report_edit_permission = $user->user_body_permissions->create({
+ body => $oxon, permission_type => 'report_edit' });
+ $mech->get_ok("/report/$report_id");
+ $mech->content_contains('/admin/report_edit/'.$report_id.'">admin</a>)');
+ $report_edit_permission->delete;
+ };
};
FixMyStreet::override_config {
@@ -559,6 +584,7 @@ FixMyStreet::override_config {
my $expected_fields = {
state => 'action scheduled',
category => 'Cows',
+ non_public => undef,
public_update => '',
priority => $rp->id,
include_update => '1',
@@ -594,6 +620,35 @@ FixMyStreet::override_config {
is $report->comments->count, 1, "Only leaves one update";
like $report->comments->first->text, qr/Category changed.*Badgers/, 'update text included category change';
};
+
+ subtest "test non-public changing" => sub {
+ $report->comments->delete;
+ is $report->non_public, 0, 'Not set to non-public';
+ $mech->get_ok("/report/$report_id");
+ $mech->submit_form(button => 'save', with_fields => { include_update => 0, non_public => 1 });
+ is $report->comments->count, 0, "No updates left";
+ $report->discard_changes;
+ is $report->non_public, 1, 'Now set to non-public';
+ $mech->submit_form(button => 'save', with_fields => { include_update => 0, non_public => 0 });
+ is $report->comments->count, 0, "No updates left";
+ $report->discard_changes;
+ is $report->non_public, 0, 'Not set to non-public';
+ };
+
+ subtest "test saved-at setting" => sub {
+ $report->comments->delete;
+ $mech->get_ok("/report/$report_id");
+ # set the timezone on this so the date comparison below doesn't fail due to mismatched
+ # timezones
+ my $now = DateTime->now(
+ time_zone => FixMyStreet->time_zone || FixMyStreet->local_time_zone
+ )->subtract(days => 1);
+ $mech->submit_form(button => 'save', form_id => 'report_inspect_form',
+ fields => { include_update => 1, public_update => 'An update', saved_at => $now->epoch });
+ $report->discard_changes;
+ is $report->comments->count, 1, "One update";
+ is $report->comments->first->confirmed, $now;
+ };
};
FixMyStreet::override_config {
diff --git a/t/app/controller/report_new.t b/t/app/controller/report_new.t
index 3c120b0b0..dff04176b 100644
--- a/t/app/controller/report_new.t
+++ b/t/app/controller/report_new.t
@@ -1,3 +1,4 @@
+use Test::MockModule;
use FixMyStreet::TestMech;
use FixMyStreet::App;
use Web::Scraper;
@@ -86,6 +87,16 @@ my $contact8 = $mech->create_contact_ok(
category => 'Street lighting',
email => 'highways@example.com'
);
+my $contact9 = $mech->create_contact_ok(
+ body_id => $body_ids{2226}, # Gloucestershire
+ category => 'Street lighting',
+ email => 'streetlights-2226@example.com',
+);
+my $contact10 = $mech->create_contact_ok(
+ body_id => $body_ids{2326}, # Cheltenham
+ category => 'Street lighting',
+ email => 'streetlights-2326@example.com',
+);
# test that the various bit of form get filled in and errors correctly
# generated.
@@ -932,6 +943,125 @@ foreach my $test (
}
+# XXX add test for category with multiple bodies
+foreach my $test (
+ {
+ desc => "test report creation for multiple bodies",
+ category => 'Street lighting',
+ councils => [ 2226, 2326 ],
+ extra_fields => {},
+ email_count => 2,
+ },
+ {
+ desc => "test single_body_only means only one report body",
+ category => 'Street lighting',
+ councils => [ 2326 ],
+ extra_fields => { single_body_only => 'Cheltenham Borough Council' },
+ email_count => 1,
+ },
+ {
+ desc => "test invalid single_body_only means multiple report bodies",
+ category => 'Street lighting',
+ councils => [ 2226, 2326 ],
+ extra_fields => { single_body_only => 'Invalid council' },
+ email_count => 1,
+ },
+) {
+ subtest $test->{desc} => sub {
+
+ # check that the user does not exist
+ my $test_email = 'test-2@example.com';
+
+ $mech->clear_emails_ok;
+ my $user = $mech->log_in_ok($test_email);
+
+ # setup the user.
+ ok $user->update(
+ {
+ name => 'Test User',
+ phone => '01234 567 890',
+ }
+ ),
+ "set users details";
+
+ # submit initial pc form
+ $mech->get_ok('/around');
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => 'GL50 2PR', } },
+ "submit location" );
+
+ # click through to the report page
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, },
+ "follow 'skip this step' link" );
+
+ # check that the fields are correctly prefilled
+ is_deeply(
+ $mech->visible_form_values,
+ {
+ title => '',
+ detail => '',
+ may_show_name => '1',
+ name => 'Test User',
+ phone => '01234 567 890',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ category => '-- Pick a category --',
+ },
+ "user's details prefilled"
+ );
+
+ $mech->submit_form_ok(
+ {
+ with_fields => {
+ title => "Test Report at café",
+ detail => 'Test report details.',
+ photo1 => '',
+ name => 'Joe Bloggs',
+ may_show_name => '1',
+ phone => '07903 123 456',
+ category => $test->{category},
+ %{$test->{extra_fields}}
+ }
+ },
+ "submit good details"
+ );
+ };
+
+ # find the report
+ my $report = $user->problems->first;
+ ok $report, "Found the report";
+
+ # Check the report has been assigned appropriately
+ is $report->bodies_str, join(',', @body_ids{@{$test->{councils}}});
+
+ $mech->content_contains('Thank you for reporting this issue');
+
+ # check that no emails have been sent
+ $mech->email_count_is(0);
+
+ # check report is confirmed and available
+ is $report->state, 'confirmed', "report is now confirmed";
+ $mech->get_ok( '/report/' . $report->id );
+
+ # Test that AJAX pages return the right data
+ $mech->get_ok(
+ '/around?ajax=1&bbox=' . ($report->longitude - 0.01) . ',' . ($report->latitude - 0.01)
+ . ',' . ($report->longitude + 0.01) . ',' . ($report->latitude + 0.01)
+ );
+ $mech->content_contains( "Test Report at caf\xc3\xa9" );
+ $saved_lat = $report->latitude;
+ $saved_lon = $report->longitude;
+
+ # cleanup
+ $mech->delete_user($user);
+ };
+
+}
+
subtest "Test inactive categories" => sub {
FixMyStreet::override_config {
ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
@@ -958,6 +1088,21 @@ subtest "Test inactive categories" => sub {
};
};
+subtest "category groups" => sub {
+ my $cobrand = Test::MockModule->new('FixMyStreet::Cobrand::FixMyStreet');
+ $cobrand->mock('enable_category_groups', sub { 1 });
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'fixmystreet',
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $contact2->update( { extra => { group => 'Roads' } } );
+ $contact9->update( { extra => { group => 'Roads' } } );
+ $contact10->update( { extra => { group => 'Roads' } } );
+ $mech->get_ok("/report/new?lat=$saved_lat&lon=$saved_lon");
+ $mech->content_like(qr{<optgroup label="Roads">\s*<option value='Potholes'>Potholes</option>\s*<option value='Street lighting'>Street lighting</option></optgroup>});
+ };
+};
+
subtest "test report creation for a category that is non public" => sub {
$mech->log_out_ok;
$mech->clear_emails_ok;
@@ -1040,6 +1185,7 @@ FixMyStreet::override_config {
$extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=' . $saved_lat . '&longitude=' . $saved_lon );
};
$mech->content_contains( "Pothol\xc3\xa9s" );
+like $extra_details->{councils_text}, qr/<strong>Cheltenham/;
ok !$extra_details->{titles_list}, 'Non Bromley does not send back list of titles';
FixMyStreet::override_config {
@@ -1733,7 +1879,11 @@ subtest "extra google analytics code displayed on email confirmation problem cre
};
};
-subtest "inspectors get redirected directly to the report page" => sub {
+foreach my $test (
+ { non_public => 0 },
+ { non_public => 1 },
+) {
+ subtest "inspectors get redirected directly to the report page, non_public=$test->{non_public}" => sub {
FixMyStreet::override_config {
ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
BASE_URL => 'https://www.fixmystreet.com',
@@ -1746,10 +1896,14 @@ subtest "inspectors get redirected directly to the report page" => sub {
body => $bodies[0],
permission_type => 'planned_reports',
});
+ $user->user_body_permissions->find_or_create({
+ body => $bodies[0],
+ permission_type => 'report_inspect',
+ });
$mech->log_in_ok('inspector@example.org');
$mech->get_ok('/');
- $mech->submit_form_ok( { with_fields => { pc => 'GL50 2PR' } },
+ $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB' } },
"submit location" );
$mech->follow_link_ok(
{ text_regex => qr/skip this step/i, },
@@ -1766,6 +1920,7 @@ subtest "inspectors get redirected directly to the report page" => sub {
may_show_name => '1',
phone => '07903 123 456',
category => 'Trees',
+ non_public => $test->{non_public},
}
},
"submit good details"
@@ -1773,6 +1928,7 @@ subtest "inspectors get redirected directly to the report page" => sub {
like $mech->uri->path, qr/\/report\/[0-9]+/, 'Redirects directly to report';
}
-};
+ };
+}
done_testing();
diff --git a/t/app/controller/report_new_open311.t b/t/app/controller/report_new_open311.t
index 0224e7e47..17b489447 100644
--- a/t/app/controller/report_new_open311.t
+++ b/t/app/controller/report_new_open311.t
@@ -1,5 +1,6 @@
use FixMyStreet::TestMech;
use FixMyStreet::App;
+use Test::LongString;
use Web::Scraper;
# disable info logs for this test run
@@ -39,32 +40,57 @@ my $contact2 = $mech->create_contact_ok(
category => 'Graffiti Removal',
email => '101',
);
+$mech->create_contact_ok(
+ body_id => $body->id, # Edinburgh
+ category => 'Ball lighting',
+ email => '102',
+ extra => { _fields => [
+ { description => 'Size', code => 'size', required => 'True', automated => '' },
+ { description => 'Speed', code => 'speed', required => 'True', automated => 'server_set' },
+ { description => 'Colour', code => 'colour', required => 'True', automated => 'hidden_field' },
+ ] },
+);
+
+my $body2 = $mech->create_body_ok(2651, 'Edinburgh Council');
+my $contact4 = $mech->create_contact_ok(
+ body_id => $body2->id, # Edinburgh
+ category => 'Pothole',
+ email => '103',
+ extra => { _fields => [
+ { description => 'USRN', code => 'usrn', required => 'true', automated => 'hidden_field', variable => 'true', order => '1' },
+ { description => 'Asset ID', code => 'central_asset_id', required => 'true', automated => 'hidden_field', variable => 'true', order => '2' },
+ ] },
+);
# test that the various bit of form get filled in and errors correctly
# generated.
+my $empty_form = {
+ title => '',
+ detail => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ name => '',
+ may_show_name => '1',
+ username => '',
+ email => '',
+ phone => '',
+ category => '',
+ password_sign_in => '',
+ password_register => '',
+ remember_me => undef,
+};
foreach my $test (
{
msg => 'all fields empty',
pc => 'EH99 1SP',
fields => {
- title => '',
- detail => '',
- photo1 => '',
- photo2 => '',
- photo3 => '',
- name => '',
- may_show_name => '1',
- username => '',
- email => '',
- phone => '',
- category => 'Street lighting',
- password_sign_in => '',
- password_register => '',
- remember_me => undef,
+ %$empty_form,
+ category => 'Street lighting',
},
changes => {
number => '',
- type => 'old',
+ type => '',
},
errors => [
'This information is required',
@@ -80,6 +106,7 @@ foreach my $test (
username => 'testopen311@example.com',
category => 'Street lighting',
number => 27,
+ type => 'old',
},
extra => [
{
@@ -94,6 +121,45 @@ foreach my $test (
}
]
},
+ {
+ msg => 'automated things',
+ pc => 'EH99 1SP',
+ fields => {
+ %$empty_form,
+ category => 'Ball lighting',
+ },
+ changes => {
+ size => '',
+ },
+ hidden => [ 'colour' ],
+ errors => [
+ 'This information is required',
+ 'Please enter a subject',
+ 'Please enter some details',
+ 'Please enter your email',
+ 'Please enter your name',
+ ],
+ submit_with => {
+ title => 'test',
+ detail => 'test detail',
+ name => 'Test User',
+ username => 'testopen311@example.com',
+ size => 'big',
+ colour => 'red',
+ },
+ extra => [
+ {
+ name => 'size',
+ value => 'big',
+ description => 'Size',
+ },
+ {
+ name => 'colour',
+ value => 'red',
+ description => 'Colour',
+ }
+ ]
+ },
)
{
subtest "check form errors where $test->{msg}" => sub {
@@ -139,6 +205,12 @@ foreach my $test (
};
is_deeply $mech->visible_form_values, $new_values,
"values correctly changed";
+ if ($test->{hidden}) {
+ my %hidden_fields = map { $_->name => 1 } grep { $_->type eq 'hidden' } ($mech->forms)[0]->inputs;
+ foreach (@{$test->{hidden}}) {
+ is $hidden_fields{$_}, 1;
+ }
+ }
if ( $test->{fields}->{category} eq 'Street lighting' ) {
my $result = scraper {
@@ -146,7 +218,7 @@ foreach my $test (
}
->scrape( $mech->response );
- is_deeply $result->{option}, [ qw/old modern/], 'displayed streetlight type select';
+ is_deeply $result->{option}, [ "", qw/old modern/], 'displayed streetlight type select';
}
$new_values = {
@@ -172,4 +244,38 @@ foreach my $test (
};
}
+subtest "Category extras omits description label when all fields are hidden" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ my $json = $mech->get_ok_json('/report/new/category_extras?category=Pothole&latitude=55.952055&longitude=-3.189579');
+ my $category_extra = $json->{category_extra};
+ contains_string($category_extra, "usrn");
+ contains_string($category_extra, "central_asset_id");
+ lacks_string($category_extra, "USRN", "Lacks 'USRN' label");
+ lacks_string($category_extra, "Asset ID", "Lacks 'Asset ID' label");
+ lacks_string($category_extra, "resolve your problem quicker, by providing some extra detail", "Lacks description text");
+ };
+};
+
+subtest "Category extras includes description label for user" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $contact4->push_extra_fields({ description => 'Size?', code => 'size', required => 'true', automated => '', variable => 'true', order => '3' });
+ $contact4->update;
+
+ my $json = $mech->get_ok_json('/report/new/category_extras?category=Pothole&latitude=55.952055&longitude=-3.189579');
+ my $category_extra = $json->{category_extra};
+ contains_string($category_extra, "usrn");
+ contains_string($category_extra, "central_asset_id");
+ lacks_string($category_extra, "USRN", "Lacks 'USRN' label");
+ lacks_string($category_extra, "Asset ID", "Lacks 'Asset ID' label");
+ contains_string($category_extra, "Size?");
+ contains_string($category_extra, "resolve your problem quicker, by providing some extra detail", "Contains description text");
+ };
+};
+
done_testing();
diff --git a/t/app/controller/report_updates.t b/t/app/controller/report_updates.t
index aefe77e47..aba7340b0 100644
--- a/t/app/controller/report_updates.t
+++ b/t/app/controller/report_updates.t
@@ -146,6 +146,42 @@ subtest "unconfirmed updates not displayed" => sub {
};
subtest "several updates shown in correct order" => sub {
+ my @qs;
+ for my $fields ( { # One with an associated update below
+ problem_id => $report_id,
+ whensent => '2011-03-10 12:23:16',
+ whenanswered => '2011-03-10 12:23:16',
+ old_state => 'confirmed',
+ new_state => 'confirmed',
+ },
+ { # One with no associated update
+ problem_id => $report_id,
+ whensent => '2011-03-11 12:23:16',
+ whenanswered => '2011-03-11 12:23:16',
+ old_state => 'confirmed',
+ new_state => 'confirmed',
+ },
+ { # One with no associated update, different state (doesn't match problem state, never mind)
+ problem_id => $report_id,
+ whensent => '2011-03-12 12:23:16',
+ whenanswered => '2011-03-12 12:23:16',
+ old_state => 'investigating',
+ new_state => 'investigating',
+ },
+ { # One for the fixed update
+ problem_id => $report_id,
+ whensent => '2011-03-15 08:12:36',
+ whenanswered => '2011-03-15 08:12:36',
+ old_state => 'confirmed',
+ new_state => 'fixed - user',
+ },
+ ) {
+ my $q = FixMyStreet::App->model('DB::Questionnaire')->find_or_create(
+ $fields
+ );
+ push @qs, $q;
+ }
+
for my $fields ( {
problem_id => $report_id,
user_id => $user2->id,
@@ -180,16 +216,27 @@ subtest "several updates shown in correct order" => sub {
my $comment = FixMyStreet::App->model('DB::Comment')->find_or_create(
$fields
);
+ if ($fields->{text} eq 'Second update') {
+ $comment->set_extra_metadata(questionnaire_id => $qs[0]->id);
+ $comment->update;
+ }
+ if ($fields->{text} eq 'Third update') {
+ $comment->set_extra_metadata(questionnaire_id => $qs[3]->id);
+ $comment->update;
+ }
}
$mech->get_ok("/report/$report_id");
my $meta = $mech->extract_update_metas;
- is scalar @$meta, 4, 'number of updates';
+ is scalar @$meta, 6, 'number of updates';
is $meta->[0], 'Posted by Other User at 12:23, Thu 10 March 2011', 'first update';
- is $meta->[1], 'Posted by Main User at 12:23, Thu 10 March 2011', 'second update';
- is $meta->[2], 'State changed to: Fixed', 'third update, part 1';
- is $meta->[3], 'Posted anonymously at 08:12, Tue 15 March 2011', 'third update, part 2';
+ is $meta->[1], 'Posted by Main User at 12:23, Thu 10 March 2011 Still open, via questionnaire', 'second update';
+ is $meta->[2], 'Still open, via questionnaire, 12:23, Fri 11 March 2011', 'questionnaire';
+ is $meta->[3], 'Still open, via questionnaire, 12:23, Sat 12 March 2011', 'questionnaire';
+ is $meta->[4], 'State changed to: Fixed', 'third update, part 1';
+ is $meta->[5], 'Posted anonymously at 08:12, Tue 15 March 2011', 'third update, part 2';
+ $report->questionnaires->delete;
};
for my $test (
diff --git a/t/app/controller/reports.t b/t/app/controller/reports.t
index 76c920562..8cdfddd1b 100644
--- a/t/app/controller/reports.t
+++ b/t/app/controller/reports.t
@@ -95,6 +95,9 @@ $fife_problems[10]->update( {
state => 'hidden',
});
+# Run the cron script old-data (for the table no longer used by default)
+FixMyStreet::Script::UpdateAllReports::generate(1);
+
# Run the cron script that makes the data for /reports so we don't get an error.
my $data = FixMyStreet::Script::UpdateAllReports::generate_dashboard();
diff --git a/t/app/model/defecttype.t b/t/app/model/defecttype.t
index 4f380db59..e924129e2 100644
--- a/t/app/model/defecttype.t
+++ b/t/app/model/defecttype.t
@@ -99,27 +99,6 @@ subtest 'by_categories returns defect types for an area with multiple bodies' =>
is scalar @$pavements, 3, 'Pavements have 3 defect types';
};
-subtest 'by_categories encodes HTML entities' => sub {
- my $apostrophe_defect_type = FixMyStreet::App->model('DB::DefectType')->find_or_create(
- {
- body_id => $oxfordshire->id,
- name => 'This defect type\'s name has an apostrophe',
- description => 'This defect type is for all categories'
- }
- );
- $apostrophe_defect_type->set_extra_metadata('defect_code' => 'Here\'s an apostrophe');
- $apostrophe_defect_type->update();
-
- my @contacts = FixMyStreet::DB->resultset('Contact')->not_deleted->search( { body_id => [ $oxfordshire->id ] } )->all;
- my $defect_types = FixMyStreet::App->model('DB::DefectType')->by_categories($area_id, @contacts);
- my $traffic_lights = decode_json($defect_types->{'Traffic lights'});
- my $defect_type = @$traffic_lights[2];
- is $defect_type->{name}, 'This defect type&#39;s name has an apostrophe';
- is $defect_type->{extra}->{defect_code}, 'Here&#39;s an apostrophe';
-
-};
-
-
END {
done_testing();
}
diff --git a/t/app/model/problem.t b/t/app/model/problem.t
index 27f6aed66..b9bbe4682 100644
--- a/t/app/model/problem.t
+++ b/t/app/model/problem.t
@@ -514,6 +514,7 @@ foreach my $test ( {
subtest $test->{ desc } => sub {
my $override = {
ALLOWED_COBRANDS => [ 'fixmystreet' ],
+ MAPIT_URL => 'http://mapit.uk/',
BASE_URL => 'http://www.fixmystreet.com',
};
if ( $test->{cobrand} && $test->{cobrand} =~ /hart/ ) {
@@ -587,9 +588,10 @@ foreach my $test ( {
};
}
-subtest 'check can set mutiple emails as a single contact' => sub {
+subtest 'check can set multiple emails as a single contact' => sub {
my $override = {
ALLOWED_COBRANDS => [ 'fixmystreet' ],
+ MAPIT_URL => 'http://mapit.uk/',
};
my $contact = {
diff --git a/t/app/model/responsepriority.t b/t/app/model/responsepriority.t
index 03c5bccae..4e624bf07 100644
--- a/t/app/model/responsepriority.t
+++ b/t/app/model/responsepriority.t
@@ -78,24 +78,6 @@ subtest 'by_categories returns all response priorities for an area with multiple
is scalar @$traffic_lights, 2, 'Traffic lights have 2 defect types';
};
-subtest 'by_categories encodes HTML entities' => sub {
- FixMyStreet::App->model('DB::ResponsePriority')->find_or_create(
- {
- body_id => $other_body->id,
- name => 'This priority\'s name has an apostrophe',
- description => 'This priority is for all categories'
- }
- );
-
- my @contacts = FixMyStreet::DB->resultset('Contact')->not_deleted->search( { body_id => [ $oxfordshire->id ] } )->all;
- my $priorities = FixMyStreet::App->model('DB::ResponsePriority')->by_categories($area_id, @contacts);
-
- my $traffic_lights = decode_json($priorities->{'Traffic lights'});
- use Data::Dumper;
- my $priority = @$traffic_lights[2];
- is $priority->{name}, 'This priority&#39;s name has an apostrophe';
-};
-
END {
$mech->delete_body( $other_body );
$mech->delete_body( $oxfordshire );
diff --git a/t/app/model/responsetemplate.t b/t/app/model/responsetemplate.t
new file mode 100644
index 000000000..fbabc1c12
--- /dev/null
+++ b/t/app/model/responsetemplate.t
@@ -0,0 +1,28 @@
+use FixMyStreet::TestMech;
+use JSON::MaybeXS;
+
+my $mech = FixMyStreet::TestMech->new;
+my $area_id = 2651;
+
+my $body = $mech->create_body_ok($area_id, 'Edinburgh Council');
+my $c1 = $mech->create_contact_ok(category => 'Potholes', body_id => $body->id, email => 'p');
+my $c2 = $mech->create_contact_ok(category => 'Graffiti', body_id => $body->id, email => 'g');
+my $t1 = FixMyStreet::DB->resultset('ResponseTemplate')->create({ body_id => $body->id, title => "Title 1", text => "Text 1" });
+my $t2 = FixMyStreet::DB->resultset('ResponseTemplate')->create({ body_id => $body->id, title => "Title 2", text => "Text 2", state => 'investigating' });
+my $t3 = FixMyStreet::DB->resultset('ResponseTemplate')->create({ body_id => $body->id, title => "Title 3", text => "Text 3" });
+$t1->add_to_contacts($c1);
+$t2->add_to_contacts($c2);
+
+my @contacts = FixMyStreet::DB->resultset('Contact')->not_deleted->search( { body_id => [ $body->id ] } )->all;
+
+subtest 'by_categories returns allresponse templates grouped by category' => sub {
+ my $templates = FixMyStreet::App->model('DB::ResponseTemplate')->by_categories($area_id, @contacts);
+ my $potholes = decode_json($templates->{Potholes});
+ my $graffiti = decode_json($templates->{Graffiti});
+
+ is scalar @$potholes, 2, 'Potholes have 2 templates';
+ is scalar @$graffiti, 2, 'Graffiti has 2 templates';
+ is $graffiti->[0]->{state}, 'investigating', 'Graffiti first template has right state';
+};
+
+done_testing;
diff --git a/t/app/model/session.t b/t/app/model/session.t
new file mode 100644
index 000000000..f76533727
--- /dev/null
+++ b/t/app/model/session.t
@@ -0,0 +1,14 @@
+use FixMyStreet::TestMech;
+
+my $mech = FixMyStreet::TestMech->new;
+
+$mech->log_in_ok('test@example.com');
+
+my $session = FixMyStreet::DB->resultset("Session")->first;
+
+my $id = $session->id;
+$id =~ s/\s+$//;
+is $id, "session:" . $session->id_code;
+is $session->user->email, 'test@example.com';
+
+done_testing;
diff --git a/t/app/script/archive_old_enquiries.t b/t/app/script/archive_old_enquiries.t
index e1adeec85..9774d3fc3 100644
--- a/t/app/script/archive_old_enquiries.t
+++ b/t/app/script/archive_old_enquiries.t
@@ -5,15 +5,18 @@ my $mech = FixMyStreet::TestMech->new();
$mech->clear_emails_ok;
-my $opts = {
- commit => 1,
-};
-
my $user = $mech->create_user_ok('test@example.com', name => 'Test User');
my $oxfordshire = $mech->create_body_ok(2237, 'Oxfordshire County Council');
my $west_oxon = $mech->create_body_ok(2420, 'West Oxfordshire District Council');
-$opts->{body} = $oxfordshire->id;
+my $opts = {
+ commit => 1,
+ body => $oxfordshire->id,
+ cobrand => 'oxfordshire',
+ closure_cutoff => "2015-01-01 00:00:00",
+ email_cutoff => "2016-01-01 00:00:00",
+ user => $user->id,
+};
subtest 'sets reports to the correct status' => sub {
FixMyStreet::override_config {
@@ -65,10 +68,48 @@ subtest 'sets reports to the correct status' => sub {
is $report4->state, 'closed', 'Report 4 has been set to closed';
is $report5->state, 'closed', 'Report 5 has been set to closed';
+ my $comment = $report1->comments->first;
+ is $comment->problem_state, 'closed';
+
is $report->state, 'confirmed', 'Recent report has been left alone';
};
};
+subtest 'marks alerts as sent' => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'oxfordshire' ],
+ }, sub {
+ my ($report) = $mech->create_problems_for_body(1, $oxfordshire->id, 'Test', {
+ areas => ',2237,',
+ lastupdate => '2015-12-01 07:00:00',
+ user_id => $user->id,
+ });
+ my $alert = FixMyStreet::DB->resultset('Alert')->find_or_create(
+ {
+ user => $user,
+ parameter => $report->id,
+ alert_type => 'new_updates',
+ whensubscribed => '2015-12-01 07:00:00',
+ confirmed => 1,
+ cobrand => 'default',
+ }
+ );
+ is $alert->alerts_sent->count, 0, 'Nothing has been sent for this alert';
+
+ FixMyStreet::Script::ArchiveOldEnquiries::archive($opts);
+
+ $report->discard_changes;
+
+ is $report->state, 'closed', 'Report has been set to closed';
+
+ is $alert->alerts_sent->count, 1, 'Alert marked as sent for this report';
+
+ my $alert_sent = $alert->alerts_sent->first;
+ my $comment = $report->comments->first;
+ is $alert_sent->parameter, $comment->id, 'AlertSent created for new comment';
+ };
+};
+
subtest 'sends emails to a user' => sub {
FixMyStreet::override_config {
ALLOWED_COBRANDS => [ 'oxfordshire' ],
diff --git a/t/browser b/t/browser
new file mode 120000
index 000000000..78da5bd3f
--- /dev/null
+++ b/t/browser
@@ -0,0 +1 @@
+../.cypress/cypress/integration \ No newline at end of file
diff --git a/t/cobrand/bathnes.t b/t/cobrand/bathnes.t
new file mode 100644
index 000000000..e0ad07c16
--- /dev/null
+++ b/t/cobrand/bathnes.t
@@ -0,0 +1,197 @@
+use FixMyStreet::TestMech;
+my $mech = FixMyStreet::TestMech->new;
+
+my $body = $mech->create_body_ok(2551, 'Bath and North East Somerset Council');
+my @cats = ('Litter', 'Other', 'Potholes', 'Traffic lights');
+for my $contact ( @cats ) {
+ $mech->create_contact_ok(body_id => $body->id, category => $contact, email => "$contact\@example.org");
+}
+my $superuser = $mech->create_user_ok('superuser@example.com', name => 'Super User', is_superuser => 1);
+my $counciluser = $mech->create_user_ok('counciluser@example.com', name => 'Council User', from_body => $body);
+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', {
+ areas => ",2651,", category => 'Potholes', cobrand => 'fixmystreet',
+ user => $normaluser, service => 'iOS', extra => {
+ _fields => [
+ {
+ description => 'Width of pothole?',
+ name => "width",
+ value => "10cm"
+ },
+ {
+ description => 'Depth of pothole?',
+ name => "depth",
+ value => "25cm"
+ },
+ ]
+ }
+});
+$mech->create_problems_for_body(1, $body->id, 'Title', {
+ areas => ",2651,", category => 'Traffic lights', cobrand => 'bathnes',
+ user => $counciluser, extra => {
+ contributed_as => 'body',
+ }
+});
+$mech->create_problems_for_body(1, $body->id, 'Title', {
+ areas => ",2651,", category => 'Litter', cobrand => 'bathnes',
+ user => $normaluser, extra => {
+ contributed_as => 'another_user',
+ contributed_by => $counciluser->id,
+ }
+});
+$mech->create_problems_for_body(1, $body->id, 'Title', {
+ areas => ",2651,", category => 'Other', cobrand => 'bathnes',
+ user => $counciluser, extra => {
+ contributed_as => 'anonymous_user',
+ }
+});
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'bathnes' ],
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
+
+subtest 'cobrand displays council name' => sub {
+ ok $mech->host("bathnes.fixmystreet.com"), "change host to bathnes";
+ $mech->get_ok('/');
+ $mech->content_like( qr/Bath and North East Somerset\b/ );
+};
+
+subtest 'extra CSV columns are absent if permission not granted' => sub {
+ $mech->log_in_ok( $counciluser->email );
+
+ $mech->get_ok('/dashboard?export=1');
+
+ open my $data_handle, '<', \$mech->content;
+ my $csv = Text::CSV->new( { binary => 1 } );
+ my @rows;
+ while ( my $row = $csv->getline( $data_handle ) ) {
+ push @rows, $row;
+ }
+ is scalar @rows, 5, '1 (header) + 4 (reports) = 5 lines';
+
+ is scalar @{$rows[0]}, 18, '18 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',
+ ],
+ 'Column headers look correct';
+};
+
+subtest "Custom CSV fields permission can be granted" => sub {
+ $mech->log_in_ok( $superuser->email );
+
+ is $counciluser->user_body_permissions->count, 0, 'counciluser has no permissions';
+
+ $mech->get_ok("/admin/user_edit/" . $counciluser->id);
+ $mech->content_contains('Extra columns in CSV export');
+
+ $mech->submit_form_ok( { with_fields => {
+ name => $counciluser->name,
+ email => $counciluser->email,
+ body => $counciluser->from_body->id,
+ phone => '',
+ flagged => undef,
+ "permissions[export_extra_columns]" => 'on',
+ } } );
+
+ ok $counciluser->has_body_permission_to("export_extra_columns"), "counciluser has been granted CSV extra fields permission";
+};
+
+subtest 'extra CSV columns are present if permission granted' => sub {
+ $mech->log_in_ok( $counciluser->email );
+
+ $mech->get_ok('/dashboard?export=1');
+
+ open my $data_handle, '<', \$mech->content;
+ my $csv = Text::CSV->new( { binary => 1 } );
+ my @rows;
+ while ( my $row = $csv->getline( $data_handle ) ) {
+ push @rows, $row;
+ }
+ is scalar @rows, 5, '1 (header) + 4 (reports) = 5 lines';
+
+ is scalar @{$rows[0]}, 24, '24 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',
+ 'User Email',
+ 'User Phone',
+ 'Reported As',
+ 'Staff User',
+ 'Attribute Data',
+ 'Site Used',
+ ],
+ 'Column headers look correct';
+
+ is $rows[1]->[18], 'normaluser@example.com', 'User email is correct';
+ is $rows[1]->[19], '+447123456789', 'User phone number is correct';
+ is $rows[1]->[20], '', 'Reported As is empty if not made on behalf of another user/body';
+ is $rows[1]->[21], '', 'Staff User is empty if not made on behalf of another user';
+ is $rows[1]->[22], 'width = 10cm; depth = 25cm', 'Attribute Data is correct';
+ is $rows[1]->[23], 'iOS', 'Site Used shows whether report made via app';
+
+ is $rows[2]->[18], 'counciluser@example.com', 'User email is correct';
+ is $rows[2]->[19], '', 'User phone number is correct';
+ is $rows[2]->[20], 'body', 'Reported As is correct if made on behalf of body';
+ is $rows[2]->[21], '', 'Staff User is empty if not made on behalf of another user';
+ is $rows[2]->[22], '', 'Attribute Data is correct';
+ is $rows[2]->[23], 'bathnes', 'Site Used shows correct cobrand';
+
+ is $rows[3]->[18], 'normaluser@example.com', 'User email is correct';
+ is $rows[3]->[19], '+447123456789', 'User phone number is correct';
+ is $rows[3]->[20], 'another_user', 'Reported As is set if reported on behalf of another user';
+ is $rows[3]->[21], 'counciluser@example.com', 'Staff User is correct if made on behalf of another user';
+ is $rows[3]->[22], '', 'Attribute Data is correct';
+ is $rows[3]->[23], 'bathnes', 'Site Used shows correct cobrand';
+
+ is $rows[4]->[18], 'counciluser@example.com', 'User email is correct';
+ is $rows[4]->[19], '', 'User phone number is correct';
+ is $rows[4]->[20], 'anonymous_user', 'Reported As is set if reported on behalf of another user';
+ is $rows[4]->[21], '', 'Staff User is empty if not made on behalf of another user';
+ is $rows[4]->[22], '', 'Attribute Data is correct';
+ is $rows[4]->[23], 'bathnes', 'Site Used shows correct cobrand';
+};
+
+
+};
+
+done_testing();
diff --git a/t/cobrand/bromley.t b/t/cobrand/bromley.t
index 41e351dea..b3fb3564b 100644
--- a/t/cobrand/bromley.t
+++ b/t/cobrand/bromley.t
@@ -46,29 +46,68 @@ $mech->content_contains( 'State changed to: In progress' );
$mech->content_contains( 'marks it as unable to fix' );
$mech->content_contains( 'State changed to: No further action' );
-subtest 'testing special Open311 behaviour', sub {
- $report->set_extra_fields();
- $report->update;
- $body->update( { send_method => 'Open311', endpoint => 'http://bromley.endpoint.example.com', jurisdiction => 'FMS', api_key => 'test', send_comments => 1 } );
- my $test_data;
- FixMyStreet::override_config {
- STAGING_FLAGS => { send_reports => 1 },
- ALLOWED_COBRANDS => [ 'fixmystreet', 'bromley' ],
- }, sub {
- $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';
+for my $test (
+ {
+ desc => 'testing special Open311 behaviour',
+ updates => {},
+ expected => {
+ 'attribute[easting]' => 529025,
+ 'attribute[northing]' => 179716,
+ 'attribute[service_request_id_ext]' => $report->id,
+ 'attribute[report_title]' => 'Test Test 1 for ' . $body->id,
+ 'jurisdiction_id' => 'FMS',
+ address_id => undef,
+ },
+ },
+ {
+ desc => 'testing Open311 behaviour with no map click or postcode',
+ updates => {
+ used_map => 0,
+ postcode => ''
+ },
+ expected => {
+ 'attribute[easting]' => 529025,
+ 'attribute[northing]' => 179716,
+ 'attribute[service_request_id_ext]' => $report->id,
+ 'jurisdiction_id' => 'FMS',
+ 'address_id' => '#NOTPINPOINTED#',
+ },
+ },
+ {
+ desc => 'asset ID',
+ feature_id => '1234',
+ expected => {
+ 'attribute[service_request_id_ext]' => $report->id,
+ 'attribute[report_title]' => 'Test Test 1 for ' . $body->id . ' | ID: 1234',
+ },
+ },
+) {
+ subtest $test->{desc}, sub {
+ $report->$_($test->{updates}->{$_}) for keys %{$test->{updates}};
+ $report->$_(undef) for qw/ whensent send_method_used external_id /;
+ $report->set_extra_fields({ name => 'feature_id', value => $test->{feature_id} })
+ if $test->{feature_id};
+ $report->update;
+ $body->update( { send_method => 'Open311', endpoint => 'http://bromley.endpoint.example.com', jurisdiction => 'FMS', api_key => 'test', send_comments => 1 } );
+ my $test_data;
+ FixMyStreet::override_config {
+ STAGING_FLAGS => { send_reports => 1 },
+ ALLOWED_COBRANDS => [ 'fixmystreet', 'bromley' ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $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[easting]'), 529025, 'Request had easting';
- is $c->param('attribute[northing]'), 179716, 'Request had northing';
- is $c->param('attribute[service_request_id_ext]'), $report->id, 'Request had correct ID';
- is $c->param('jurisdiction_id'), 'FMS', 'Request had correct jurisdiction';
-};
+ my $req = $test_data->{test_req_used};
+ my $c = CGI::Simple->new($req->content);
+ is $c->param($_), $test->{expected}->{$_}, "Request had correct $_"
+ for keys %{$test->{expected}};
+ };
+}
for my $test (
{
diff --git a/t/cobrand/closest.t b/t/cobrand/closest.t
index 36fe78a01..6d28bb6f1 100644
--- a/t/cobrand/closest.t
+++ b/t/cobrand/closest.t
@@ -72,8 +72,18 @@ FixMyStreet::override_config {
$near = $c->find_closest_address_for_rss($report);
ok !$near, 'no closest address for RSS if not cached';
+
+ my $json = $mech->get_ok_json('/ajax/closest?lat=55&lon=-1');
+ is_deeply $json, {"road"=> "Constitution Hill","full_address"=>"Constitution Hill, London, SW1A"};
+};
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'fixmystreet',
+ MAPIT_URL => 'http://mapit.uk/',
+ BING_MAPS_API_KEY => 'test',
+}, sub {
+ my $json = $mech->get_ok_json('/ajax/closest?lat=55.952055&lon=-3.189579');
+ is_deeply $json, {"road"=> "Constitution Hill","full_address"=>"Constitution Hill, London, SW1A"};
};
-END {
- done_testing();
-}
+done_testing();
diff --git a/t/cobrand/fixmystreet.t b/t/cobrand/fixmystreet.t
index 30d5765a2..57ab51198 100644
--- a/t/cobrand/fixmystreet.t
+++ b/t/cobrand/fixmystreet.t
@@ -18,6 +18,9 @@ FixMyStreet::override_config {
$data = FixMyStreet::Script::UpdateAllReports::generate_dashboard($body);
};
+FixMyStreet::App->log->disable('info');
+END { FixMyStreet::App->log->enable('info'); }
+
FixMyStreet::override_config {
MAPIT_URL => 'http://mapit.uk/',
TEST_DASHBOARD_DATA => $data,
@@ -29,8 +32,7 @@ FixMyStreet::override_config {
is $mech->uri->path, '/about/council-dashboard';
$mech->submit_form_ok({ with_fields => { username => 'someone@somewhere.example.org' }});
- $mech->content_contains('We will be in touch');
- # XXX Check email arrives
+ $mech->content_contains('did not recognise your email');
$mech->log_in_ok('someone@somewhere.example.org');
$mech->get_ok('/reports/Birmingham/summary');
diff --git a/t/cobrand/form_extras.t b/t/cobrand/form_extras.t
index 84ded5bc1..df76ccbe1 100644
--- a/t/cobrand/form_extras.t
+++ b/t/cobrand/form_extras.t
@@ -2,7 +2,10 @@ package FixMyStreet::Cobrand::Tester;
use parent 'FixMyStreet::Cobrand::FixMyStreet';
sub report_form_extras {
- ( { name => 'address', required => 1 }, { name => 'passport', required => 0 } )
+ (
+ { name => 'address', required => 1 },
+ { name => 'passport', required => 0, validator => sub { die "Invalid number\n" if $_[0] && $_[0] !~ /^P/; return $_[0] } },
+ )
}
# To allow a testing template override
@@ -30,6 +33,7 @@ FixMyStreet::override_config {
$mech->get_ok('/around');
$mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB', } }, "submit location" );
$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 => {
@@ -38,13 +42,24 @@ FixMyStreet::override_config {
name => 'Joe Bloggs',
may_show_name => '1',
username => 'test-1@example.com',
- passport => '123456',
password_register => '',
}
},
- "submit details without address, with passport",
+ "submit details without address or passport",
);
$mech->content_like(qr{<label for="form_address">Address</label>\s*<p class='form-error'>This information is required</p>}, 'Address is required');
+ $mech->content_lacks("<p class='form-error'>Invalid number", 'Passport is optional');
+
+ $mech->submit_form_ok( {
+ button => 'submit_register',
+ with_fields => {
+ passport => '123456',
+ }
+ },
+ "submit details with bad passport",
+ );
+ $mech->content_like(qr{<label for="form_address">Address</label>\s*<p class='form-error'>This information is required</p>}, 'Address is required');
+ $mech->content_like(qr{<p class='form-error'>Invalid number}, 'Passport format wrong');
$mech->content_contains('value="123456" name="passport"', 'Passport number reshown');
$mech->submit_form_ok( {
@@ -55,11 +70,23 @@ FixMyStreet::override_config {
},
"submit details, now with address",
);
+ $mech->content_lacks('This information is required', 'Address is present');
+ $mech->content_like(qr{<p class='form-error'>Invalid number}, 'Passport format wrong');
+ $mech->content_contains('value="123456" name="passport"', 'Passport number reshown');
+
+ $mech->submit_form_ok( {
+ button => 'submit_register',
+ with_fields => {
+ passport => 'P123456',
+ }
+ },
+ "submit details with correct passport",
+ );
$mech->content_contains('Now check your email');
my $problem = FixMyStreet::DB->resultset('Problem')->search({}, { order_by => '-id' })->first;
is $problem->get_extra_metadata('address'), 'My address', 'Address is stored';
- is $problem->get_extra_metadata('passport'), '123456', 'Passport number is stored';
+ is $problem->get_extra_metadata('passport'), 'P123456', 'Passport number is stored';
};
END {
diff --git a/t/cobrand/oxfordshire.t b/t/cobrand/oxfordshire.t
index ee30e7e0b..19a82742a 100644
--- a/t/cobrand/oxfordshire.t
+++ b/t/cobrand/oxfordshire.t
@@ -81,8 +81,8 @@ subtest 'Exor file looks okay' => sub {
$mech->log_in_ok( $superuser->email );
$mech->get_ok('/admin/exordefects');
$mech->submit_form_ok( { with_fields => {
- start_date => '05/05/2017',
- end_date => '05/05/2017',
+ 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");
@@ -120,8 +120,8 @@ subtest 'Exor file looks okay' => sub {
$i++;
}
$mech->submit_form_ok( { with_fields => {
- start_date => '05/05/2017',
- end_date => '05/05/2017',
+ 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;
@@ -159,6 +159,7 @@ EOF
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);
@@ -185,57 +186,6 @@ subtest 'Reports are marked as inspected correctly' => sub {
};
};
-subtest 'response times messages displayed' => sub {
- my $oxfordshire = $mech->create_body_ok(
- 2237, 'Oxfordshire County Council'
- );
- my $contact = $mech->create_contact_ok(
- body_id => $oxfordshire->id,
- category => 'Pothole',
- email => 'pothole@example.com',
- );
-
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'oxfordshire' ],
- MAPIT_URL => 'http://mapit.uk/',
- }, sub {
- $mech->log_out_ok;
- $mech->clear_emails_ok;
-
- $mech->get_ok('/around');
- $mech->submit_form_ok( {
- with_fields => { pc => 'OX20 1SZ' }
- },
- "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',
- detail => 'Test report details.',
- photo1 => '',
- username => 'test-2@example.com',
- name => 'Test User',
- category => 'Pothole',
- }
- },
- "submit details"
- );
-
- $mech->text_contains('Problems in the Pothole category are generally responded');
- my $email = $mech->get_email;
- ok $email, 'got and email';
- like $mech->get_text_body_from_email, qr/Problems in the Pothole category/, 'emails contains response time message';
- my $url = $mech->get_link_from_email($email);
- $mech->get_ok($url);
- $mech->text_contains('Problems in the Pothole category are generally responded')
- };
-};
-
END {
done_testing();
}
diff --git a/t/cobrand/rutland.t b/t/cobrand/rutland.t
new file mode 100644
index 000000000..4d3c4befd
--- /dev/null
+++ b/t/cobrand/rutland.t
@@ -0,0 +1,61 @@
+use CGI::Simple;
+use FixMyStreet::TestMech;
+use FixMyStreet::Script::Reports;
+my $mech = FixMyStreet::TestMech->new;
+
+# Create test data
+my $user = $mech->create_user_ok( 'rutland@example.com' );
+my $body = $mech->create_body_ok( 2482, 'Rutland County Council');
+my $contact = $mech->create_contact_ok(
+ body_id => $body->id,
+ category => 'Other',
+ email => 'LIGHT',
+);
+$contact->update;
+
+my @reports = $mech->create_problems_for_body( 1, $body->id, 'Test', {
+ cobrand => 'rutland',
+ user => $user,
+});
+my $report = $reports[0];
+
+for my $update ('in progress', 'unable to fix') {
+ FixMyStreet::DB->resultset('Comment')->find_or_create( {
+ problem_state => $update,
+ problem_id => $report->id,
+ user_id => $user->id,
+ name => 'User',
+ mark_fixed => 'f',
+ text => "This update marks it as $update",
+ state => 'confirmed',
+ confirmed => 'now()',
+ anonymous => 'f',
+ } );
+}
+
+subtest 'testing special Open311 behaviour', sub {
+ $report->set_extra_fields();
+ $report->update;
+ $body->update( { send_method => 'Open311', endpoint => 'http://rutland.endpoint.example.com', jurisdiction => 'FMS', api_key => 'test', send_comments => 1 } );
+ my $test_data;
+ FixMyStreet::override_config {
+ STAGING_FLAGS => { send_reports => 1 },
+ ALLOWED_COBRANDS => [ 'fixmystreet', 'rutland' ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $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]'), $report->title, 'Request had title';
+ is $c->param('attribute[description]'), $report->detail, 'Request had description';
+ is $c->param('attribute[external_id]'), $report->id, 'Request had correct ID';
+ is $c->param('jurisdiction_id'), 'FMS', 'Request had correct jurisdiction';
+};
+
+done_testing();
diff --git a/t/cobrand/zurich.t b/t/cobrand/zurich.t
index 385f7f077..eccb0c8eb 100644
--- a/t/cobrand/zurich.t
+++ b/t/cobrand/zurich.t
@@ -23,6 +23,7 @@ my $mech = FixMyStreet::TestMech->new;
use FixMyStreet;
my $cobrand = FixMyStreet::Cobrand::Zurich->new();
+$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";
@@ -48,7 +49,7 @@ sub reset_report_state {
$report->unset_extra_metadata('closed_overdue');
$report->unset_extra_metadata('closure_status');
$report->whensent(undef);
- $report->state('unconfirmed');
+ $report->state('submitted');
$report->created($created) if $created;
$report->update;
}
@@ -109,7 +110,7 @@ subtest "set up superuser" => sub {
};
my @reports = $mech->create_problems_for_body( 1, $division->id, 'Test', {
- state => 'unconfirmed',
+ state => 'submitted',
confirmed => undef,
cobrand => 'zurich',
areas => ',423017,',
@@ -125,6 +126,89 @@ FixMyStreet::override_config {
$mech->content_contains('&Uuml;berpr&uuml;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";
+};
+
+subtest "Banners are displayed correctly" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'zurich' ],
+ MAP_TYPE => 'Zurich,OSM',
+ }, sub {
+ for my $test (
+ {
+ description => 'new report',
+ state => 'submitted',
+ banner_id => 'closed',
+ banner_text => 'Erfasst'
+ },
+ {
+ description => 'confirmed report',
+ state => 'confirmed',
+ banner_id => 'closed',
+ banner_text => 'Aufgenommen',
+ },
+ {
+ description => 'fixed report',
+ state => 'fixed - council',
+ banner_id => 'fixed',
+ banner_text => 'Beantwortet',
+ },
+ {
+ description => 'closed report',
+ state => 'external',
+ banner_id => 'closed',
+ banner_text => 'Extern',
+ },
+ {
+ description => 'in progress report',
+ state => 'in progress',
+ banner_id => 'progress',
+ banner_text => 'In Bearbeitung',
+ },
+ {
+ description => 'planned report',
+ state => 'feedback pending',
+ banner_id => 'progress',
+ banner_text => 'In Bearbeitung',
+ },
+ {
+ description => 'jurisdiction unknown',
+ state => 'jurisdiction unknown',
+ banner_id => 'fixed',
+ banner_text => 'Zust\x{e4}ndigkeit unbekannt',
+ },
+ ) {
+ subtest "banner for $test->{description}" => sub {
+ $report->state( $test->{state} );
+ $report->update;
+
+ $mech->get_ok("/report/" . $report->id);
+ is $mech->uri->path, "/report/" . $report->id, "at /report/" . $report->id;
+ my $banner = $mech->extract_problem_banner;
+ if ( $banner->{text} ) {
+ $banner->{text} =~ s/^ //g;
+ $banner->{text} =~ s/ $//g;
+ }
+
+ is $banner->{id}, $test->{banner_id}, 'banner id';
+ if ($test->{banner_text}) {
+ like_string( $banner->{text}, qr/$test->{banner_text}/i, 'banner text is ' . $test->{banner_text} );
+ } else {
+ is $banner->{text}, $test->{banner_text}, 'banner text';
+ }
+
+ };
+ }
+ $report->update({ state => 'submitted' });
+ };
+};
+
# Check logging in to deal with this report
FixMyStreet::override_config {
ALLOWED_COBRANDS => [ 'zurich' ],
@@ -158,7 +242,7 @@ subtest "changing of categories" => sub {
);
}
- # full Categories dropdown is hidden for unconfirmed reports
+ # full Categories dropdown is hidden for submitted reports
$report->update({ state => 'confirmed' });
# put report into known category
@@ -269,17 +353,18 @@ subtest "report_edit" => sub {
$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->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, 'planned', 'Marking hidden actually sets state to planned');
+ 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 );
@@ -289,6 +374,12 @@ subtest "report_edit" => sub {
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->get( '/report/' . $report->id);
+ is $mech->res->code, 410;
reset_report_state($report);
is ( $report->get_extra_metadata('moderated_overdue'), undef, 'Sanity check' );
@@ -404,6 +495,12 @@ subtest 'SDM' => sub {
$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');
+
$mech->get_ok( '/report/' . $report->id );
$mech->content_contains('In Bearbeitung');
$mech->content_contains('Test Test');
@@ -416,7 +513,7 @@ subtest 'SDM' => sub {
$mech->clear_emails_ok;
$report->discard_changes;
- is $report->state, 'planned', 'Report now in planned state';
+ is $report->state, 'feedback pending', 'Report now in feedback pending state';
subtest 'send_back' => sub {
FixMyStreet::override_config {
@@ -441,8 +538,8 @@ subtest 'SDM' => sub {
$mech->get_ok( '/admin/report_edit/' . $report->id );
$mech->submit_form_ok( { button => 'not_contactable', form_number => 2 } );
$report->discard_changes;
- is $report->state, 'planned', 'Report sent back to Rueckmeldung ausstehend state';
- is $report->get_extra_metadata('closure_status'), 'partial', 'Report sent back to partial (not_contactable) state';
+ 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';
};
};
@@ -458,7 +555,7 @@ FixMyStreet::override_config {
};
reset_report_state($report);
-$report->update({ state => 'planned' });
+$report->update({ state => 'feedback pending' });
$mech->content_contains( 'report_edit/' . $report->id );
$mech->content_contains( DateTime->now->strftime("%d.%m.%Y") );
@@ -493,9 +590,9 @@ like $email->header('From'), qr/do-not-reply\@example.org/, 'from line looks cor
like $email->body, qr/FINAL UPDATE/, 'body looks correct';
$mech->clear_emails_ok;
-# Assign planned (via confirmed), don't confirm email
+# Assign feedback pending (via confirmed), don't confirm email
@reports = $mech->create_problems_for_body( 1, $division->id, 'Second', {
- state => 'unconfirmed',
+ state => 'submitted',
confirmed => undef,
cobrand => 'zurich',
areas => ',423017,',
@@ -509,7 +606,7 @@ FixMyStreet::override_config {
$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 => 'planned' } } );
+ $mech->submit_form_ok( { with_fields => { state => 'feedback pending' } } );
$mech->get_ok( '/report/' . $report->id );
};
$mech->content_contains('In Bearbeitung');
@@ -536,7 +633,7 @@ $mech->email_count_is(0);
# Report assigned to third party
@reports = $mech->create_problems_for_body( 1, $division->id, 'Third', {
- state => 'unconfirmed',
+ state => 'submitted',
confirmed => undef,
cobrand => 'zurich',
areas => ',423017,',
@@ -551,8 +648,8 @@ subtest "external report triggers email" => sub {
}, sub {
# required to see body_external field
- $report->state('planned');
- $report->set_extra_metadata('closure_status' => 'closed');
+ $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;
@@ -568,7 +665,7 @@ subtest "external report triggers email" => sub {
$report->discard_changes;
$mech->get_ok( '/report/' . $report->id );
};
- is ($report->state, 'closed', 'Report was closed correctly');
+ is ($report->state, 'external', 'Report was closed correctly');
$mech->content_contains('Extern')
or die $mech->content;
$mech->content_contains('Third Test');
@@ -589,8 +686,8 @@ subtest "external report triggers email" => sub {
}, sub {
$mech->get_ok( '/admin' );
# required to see body_external field
- $report->state('planned');
- $report->set_extra_metadata('closure_status' => 'closed');
+ $report->state('feedback pending');
+ $report->set_extra_metadata('closure_status' => 'external');
$report->set_extra_metadata('public_response' => 'Freundliche Gruesse Ihre Stadt Zuerich');
$report->update;
@@ -625,10 +722,10 @@ subtest "external report triggers email" => sub {
}, sub {
# set as wish
$report->discard_changes;
- $report->state('planned');
- $report->set_extra_metadata('closure_status' => 'investigating');
+ $report->state('feedback pending');
+ $report->set_extra_metadata('closure_status' => 'wish');
$report->update;
- is ($report->state, 'planned', 'Sanity check') or die;
+ is ($report->state, 'feedback pending', 'Sanity check') or die;
$mech->get_ok( '/admin/report_edit/' . $report->id );
@@ -639,6 +736,9 @@ subtest "external report triggers email" => sub {
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;
@@ -658,12 +758,12 @@ subtest "external report triggers email" => sub {
}, sub {
# set as extern
reset_report_state($report);
- $report->state('planned');
- $report->set_extra_metadata('closure_status' => 'closed');
+ $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, 'planned', 'Sanity check') or die;
+ is ($report->state, 'feedback pending', 'Sanity check') or die;
$mech->get_ok( '/admin/report_edit/' . $report->id );
@@ -865,7 +965,7 @@ subtest "test admin_log" => sub {
# XXX: following is dependent on all of test up till now, rewrite to explicitly
# test which things need to be logged!
is scalar @entries, 4, 'State changes logged';
- is $entries[-1]->action, 'state change to closed', 'State change logged as expected';
+ is $entries[-1]->action, 'state change to external', 'State change logged as expected';
};
subtest 'email images to external partners' => sub {
@@ -885,7 +985,7 @@ subtest 'email images to external partners' => sub {
# The below email comparison must not have an external message.
$report->unset_extra_metadata('external_message');
$report->update({
- state => 'closed',
+ state => 'external',
photo => $fileid,
external_body => $external_body->id,
});
@@ -937,9 +1037,9 @@ subtest 'Status update shown as appropriate' => sub {
}, sub {
# ALL closed states must hide the public_response edit, and public ones
# must show the answer in blue.
- for (['planned', 1, 0, 0],
+ for (['feedback pending', 1, 0, 0],
['fixed - council', 0, 1, 0],
- ['closed', 0, 1, 0],
+ ['external', 0, 1, 0],
['hidden', 0, 0, 1])
{
my ($state, $update, $public, $user_response) = @$_;
diff --git a/t/map/tests.t b/t/map/tests.t
index 1123133e4..e6749b813 100644
--- a/t/map/tests.t
+++ b/t/map/tests.t
@@ -3,9 +3,11 @@ use Test::More;
my $requires = {
'Angus' => 'angus/js.js',
+ 'BathNES' => 'bathnes/js.js',
'Bing' => 'map-bing-ol.js',
'Bristol' => 'bristol/js.js',
'Bromley' => 'bromley/map.js',
+ 'Buckinghamshire' => 'buckinghamshire/js.js',
'FMS' => 'map-fms.js',
'Google' => 'map-google.js',
'GoogleOL' => 'map-google-ol.js',
diff --git a/t/open311.t b/t/open311.t
index b41d42b55..4dc1b2959 100644
--- a/t/open311.t
+++ b/t/open311.t
@@ -133,8 +133,38 @@ for my $test (
}
],
params => [
- [ 'attribute[title]', 'A title', 'extra paramater used correctly' ]
- ]
+ [ 'attribute[title]', 'A title', 'extra parameter used correctly' ]
+ ],
+ debug_contains => 'attribute\[title\]: A title',
+ },
+ {
+ desc => 'undef extra values handled',
+ extra => [
+ {
+ name => 'title',
+ value => undef,
+ }
+ ],
+ params => [
+ [ 'attribute[title]', '', 'undef extra parameter used correctly' ]
+ ],
+ # multi line warnings are not handled well so just match the
+ # first line
+ warning => qr/POST requests.xml/,
+ debug_contains => 'attribute\[title\]: $',
+ },
+ {
+ desc => '0 extra values handled',
+ extra => [
+ {
+ name => 'title',
+ value => 0,
+ }
+ ],
+ params => [
+ [ 'attribute[title]', '0', '0 extra parameter used correctly' ]
+ ],
+ debug_contains => 'attribute\[title\]: 0',
},
{
desc => 'first and last names in extra used correctly',
@@ -178,11 +208,24 @@ for my $test (
my $extra = { url => 'http://example.com/report/1', };
- my $results = make_service_req( $problem, $extra, $problem->category,
-'<?xml version="1.0" encoding="utf-8"?><service_requests><request><service_request_id>248</service_request_id></request></service_requests>'
- );
+ my $results;
+ if ( $test->{warning} ) {
+ warnings_exist {
+ $results = make_service_req( $problem, $extra, $problem->category,
+ '<?xml version="1.0" encoding="utf-8"?><service_requests><request><service_request_id>248</service_request_id></request></service_requests>'
+ );
+ } [ $test->{warning} ], 'warning generated by service request call';
+ } else {
+ $results = make_service_req( $problem, $extra, $problem->category,
+ '<?xml version="1.0" encoding="utf-8"?><service_requests><request><service_request_id>248</service_request_id></request></service_requests>'
+ );
+ }
my $c = CGI::Simple->new( $results->{req}->content );
+ if ( $test->{debug_contains} ) {
+ like $results->{o}->debug_details, qr/$test->{debug_contains}/m, 'extra handled correctly in debug';
+ }
+
for my $param ( @{ $test->{params} } ) {
is $c->param( $param->[0] ), $param->[1], $param->[2];
}
@@ -196,6 +239,12 @@ for my $test (
first_name => 'Nom',
last_name => 'de Report',
},
+ {
+ desc => 'Check single word name handled correctly',
+ name => 'Nom',
+ first_name => 'Nom',
+ last_name => '',
+ }
) {
subtest $test->{desc} => sub {
$problem->extra( undef );
@@ -482,7 +531,7 @@ for my $test (
desc => 'update name taken from extra if available',
comment_name => 'First Last',
user_name => 'Personal Family',
- extra => { first_name => 'Forename', last_name => 'Surname' },
+ extra => { first_name => 'Forename', last_name => 'Surname', title => 'Ms' },
first_name => 'Forename',
last_name => 'Surname'
},
@@ -756,5 +805,5 @@ sub _make_req {
my $req = $o->test_req_used;
- return { res => $res, req => $req };
+ return { res => $res, req => $req, o => $o };
}
diff --git a/t/open311/getservicerequests.t b/t/open311/getservicerequests.t
new file mode 100644
index 000000000..57f112e2f
--- /dev/null
+++ b/t/open311/getservicerequests.t
@@ -0,0 +1,427 @@
+#!/usr/bin/env perl
+
+use FixMyStreet::TestMech;
+
+use_ok( 'Open311' );
+use_ok( 'Open311::GetServiceRequests' );
+use DateTime;
+use DateTime::Format::W3CDTF;
+use Test::MockObject::Extends;
+
+my $mech = FixMyStreet::TestMech->new;
+
+my $user = $mech->create_user_ok('system_user@example.com', name => 'test users');
+my $body = $mech->create_body_ok(2482, 'Bromley');
+my $contact = $mech->create_contact_ok( body_id => $body->id, category => 'Sidewalk and Curb Issues', email => 'sidewalks' );
+
+my $dtf = DateTime::Format::W3CDTF->new;
+
+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>Sidewalk and Curb Issues</service_name>
+<service_code>sidewalks</service_code>
+<description>This is a sidewalk problem</description>
+<agency_responsible></agency_responsible>
+<service_notice></service_notice>
+<requested_datetime>2010-04-14T06:37:38-08:00</requested_datetime>
+<updated_datetime>2010-04-14T06:37:38-08:00</updated_datetime>
+<expected_datetime>2010-04-15T06:37:38-08:00</expected_datetime>
+<lat>51.4021</lat>
+<long>0.01578</long>
+</request>
+<request>
+<service_request_id>638345</service_request_id>
+<status>investigating</status>
+<status_notes>This is a for a different issue.</status_notes>
+<service_name>Not Sidewalk and Curb Issues</service_name>
+<service_code>not_sidewalks</service_code>
+<description>This is a problem</description>
+<agency_responsible></agency_responsible>
+<service_notice></service_notice>
+<requested_datetime>2010-04-15T06:37:38-08:00</requested_datetime>
+<updated_datetime>2010-04-15T06:37:38-08:00</updated_datetime>
+<expected_datetime>2010-04-15T06:37:38-08:00</expected_datetime>
+<lat>51.4021</lat>
+<long>0.01578</long>
+</request>
+</service_requests>
+};
+
+my $o = Open311->new(
+ jurisdiction => 'mysociety',
+ endpoint => 'http://example.com',
+ test_mode => 1,
+ test_get_returns => { 'requests.xml' => $requests_xml }
+);
+
+my $p1_date = $dtf->parse_datetime('2010-04-14T06:37:38-08:00')
+ ->set_time_zone(
+ FixMyStreet->time_zone || FixMyStreet->local_time_zone
+ );
+my $p2_date = $dtf->parse_datetime('2010-04-15T06:37:38-08:00')
+ ->set_time_zone(
+ FixMyStreet->time_zone || FixMyStreet->local_time_zone
+ );
+my $start_date = $p1_date->clone;
+$start_date->add( hours => -2);
+my $end_date = $p2_date->clone;
+$end_date->add( hours => 2);
+
+
+subtest 'basic parsing checks' => sub {
+ my $update = Open311::GetServiceRequests->new(
+ system_user => $user,
+ start_date => $start_date,
+ end_date => $end_date
+ );
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $update->create_problems( $o, $body );
+ };
+
+
+ my $p = FixMyStreet::DB->resultset('Problem')->search(
+ { external_id => 638344 }
+ )->first;
+
+ ok $p, 'Found problem';
+ is $p->title, 'Sidewalk and Curb Issues problem', 'correct problem title';
+ is $p->detail, 'This is a sidewalk problem', 'correct problem description';
+ is $p->created, $p1_date, 'Problem has correct creation date';
+ is $p->confirmed, $p1_date, 'Problem has correct confirmed date';
+ is $p->whensent, $p1_date, 'Problem has whensent set';
+ is $p->state, 'confirmed', 'correct problem state';
+ is $p->user->id, $user->id, 'user set to system user';
+ is $p->category, 'Sidewalk and Curb Issues', 'correct problem category';
+
+ my $p2 = FixMyStreet::DB->resultset('Problem')->search( { external_id => 638345 } )->first;
+ ok $p2, 'second problem found';
+ ok $p2->whensent, 'second problem marked sent';
+ is $p2->state, 'investigating', 'second problem correct state';
+ is $p2->category, 'Other', 'category falls back to Other';
+};
+
+subtest 'check problems not re-created' => sub {
+ my $update = Open311::GetServiceRequests->new( system_user => $user );
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $update->create_problems( $o, $body );
+ };
+
+ my $count = FixMyStreet::DB->resultset('Problem')->count;
+
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $update->create_problems( $o, $body );
+ };
+
+ my $after_count = FixMyStreet::DB->resultset('Problem')->count;
+
+ is $count, $after_count, "problems not re-created";
+};
+
+for my $test (
+ {
+ desc => 'problem with no id is not created',
+ detail => 'This is a problem with no service_code',
+ subs => { id => '', desc => 'This is a problem with service code' },
+ },
+ {
+ desc => 'problem with no lat is not created',
+ detail => 'This is a problem with no lat',
+ subs => { lat => '', desc => 'This is a problem with no lat' },
+ },
+ {
+ desc => 'problem with no long is not created',
+ detail => 'This is a problem with no long',
+ subs => { long => '', desc => 'This is a problem with no long' },
+ },
+ {
+ desc => 'problem with bad lat/long is not created',
+ detail => 'This is a problem with bad lat/long',
+ subs => { lat => '51', long => 0.1, desc => 'This is a problem with bad lat/long' },
+ },
+) {
+ subtest $test->{desc} => sub {
+ my $xml = prepare_xml( $test->{subs} );
+ my $o = Open311->new(
+ jurisdiction => 'mysociety',
+ endpoint => 'http://example.com',
+ test_mode => 1,
+ test_get_returns => { 'requests.xml' => $xml}
+ );
+
+ my $count = FixMyStreet::DB->resultset('Problem')->count;
+ my $update = Open311::GetServiceRequests->new( system_user => $user );
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $update->create_problems( $o, $body );
+ };
+ my $after_count = FixMyStreet::DB->resultset('Problem')->count;
+
+ is $count, $after_count, "problems not created";
+
+ my $with_text = FixMyStreet::DB->resultset('Problem')->search( {
+ detail => $test->{detail}
+ } )->count;
+
+ is $with_text, 0, 'no matching problem created';
+ };
+}
+
+my $date = DateTime->new(
+ year => 2010,
+ month => 4,
+ day => 14,
+ hour => 6,
+ minute => 37
+);
+
+for my $test (
+ {
+ start_date => '1',
+ end_date => '',
+ desc => 'do not process if only a start_date',
+ subs => {},
+ },
+ {
+ start_date => '',
+ end_date => '1',
+ desc => 'do not process if only an end_date',
+ subs => {},
+ },
+) {
+ subtest $test->{desc} => sub {
+ my $xml = prepare_xml( $test->{subs} );
+ my $o = Open311->new(
+ jurisdiction => 'mysociety',
+ endpoint => 'http://example.com',
+ test_mode => 1,
+ test_get_returns => { 'requests.xml' => $xml}
+ );
+
+ my $update = Open311::GetServiceRequests->new(
+ start_date => $test->{start_date},
+ end_date => $test->{end_date},
+ system_user => $user,
+ );
+ my $ret = $update->create_problems( $o, $body );
+
+ is $ret, 0, 'failed correctly'
+ };
+}
+
+$date = DateTime->new(
+ year => 2010,
+ month => 4,
+ day => 14,
+ hour => 6,
+ minute => 37
+);
+
+for my $test (
+ {
+ start_date => $date->clone->add(hours => -2),
+ end_date => $date->clone->add(hours => -1),
+ desc => 'do not process if update time after end_date',
+ subs => {},
+ },
+ {
+ start_date => $date->clone->add(hours => 2),
+ end_date => $date->clone->add(hours => 4),
+ desc => 'do not process if update time before start_date',
+ subs => {},
+ },
+ {
+ start_date => $date->clone->add(hours => -2),
+ end_date => $date->clone->add(hours => 4),
+ desc => 'do not process if update time is bad',
+ subs => { update_time => '2010/12/12' },
+ },
+) {
+ subtest $test->{desc} => sub {
+ my $xml = prepare_xml( $test->{subs} );
+ my $o = Open311->new(
+ jurisdiction => 'mysociety',
+ endpoint => 'http://example.com',
+ test_mode => 1,
+ test_get_returns => { 'requests.xml' => $xml}
+ );
+
+ my $update = Open311::GetServiceRequests->new(
+ start_date => $test->{start_date},
+ end_date => $test->{end_date},
+ system_user => $user,
+ );
+ my $count = FixMyStreet::DB->resultset('Problem')->count;
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $update->create_problems( $o, $body );
+ };
+ my $after = FixMyStreet::DB->resultset('Problem')->count;
+
+ is $count, $after, 'problem not added';
+ };
+}
+
+subtest 'check fetch_all body setting ignores date errors' => sub {
+ my $xml = prepare_xml({ id => '12345678' });
+
+ $body->update( {
+ send_method => 'Open311',
+ fetch_problems => 1,
+ comment_user_id => $user->id,
+ endpoint => 'http://open311.localhost/',
+ api_key => 'KEY',
+ jurisdiction => 'test',
+ } );
+ $body->set_extra_metadata( fetch_all_problems => 1 );
+ $body->update();
+
+ my $update = Open311::GetServiceRequests->new(
+ verbose => 1,
+ system_user => $user,
+ );
+ $update = Test::MockObject::Extends->new($update);
+
+ $update->mock('create_open311_object', sub {
+ return Open311->new(
+ jurisdiction => 'mysociety',
+ endpoint => 'http://example.com',
+ test_mode => 1,
+ test_get_returns => { 'requests.xml' => $xml}
+ );
+ } );
+
+ my $count = FixMyStreet::DB->resultset('Problem')->count;
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $update->fetch;
+ };
+
+ my $after = FixMyStreet::DB->resultset('Problem')->count;
+
+ is $after, $count + 1, 'problem created';
+};
+
+for my $test (
+ {
+ desc => 'convert easting/northing to lat/long',
+ subs => { lat => 168935, long => 540315 },
+ expected => { lat => 51.402096, long => 0.015784 },
+ },
+) {
+ subtest $test->{desc} => sub {
+ my $xml = prepare_xml( $test->{subs} );
+ my $o = Open311->new(
+ jurisdiction => 'mysociety',
+ endpoint => 'http://example.com',
+ test_mode => 1,
+ test_get_returns => { 'requests.xml' => $xml}
+ );
+
+ my $update = Open311::GetServiceRequests->new(
+ system_user => $user,
+ convert_latlong => 1,
+ start_date => $start_date,
+ end_date => $end_date
+ );
+
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $update->create_problems( $o, $body );
+ };
+
+ my $p = FixMyStreet::DB->resultset('Problem')->search(
+ { external_id => 123456 }
+ )->first;
+
+ ok $p, 'problem created';
+ is $p->latitude, $test->{expected}->{lat}, 'correct latitude';
+ is $p->longitude, $test->{expected}->{long}, 'correct longitude';
+
+ $p->delete;
+ };
+}
+
+subtest "check options passed through from body" => sub {
+ my $xml = prepare_xml( {} );
+
+ $body->update( {
+ send_method => 'Open311',
+ fetch_problems => 1,
+ comment_user_id => $user->id,
+ endpoint => 'http://open311.localhost/',
+ convert_latlong => 1,
+ api_key => 'KEY',
+ jurisdiction => 'test',
+ } );
+
+ my $o = Open311::GetServiceRequests->new();
+
+ my $props = {};
+
+ $o = Test::MockObject::Extends->new($o);
+ $o->mock('create_problems', sub {
+ my $self = shift;
+
+ $props->{convert_latlong} = $self->convert_latlong;
+ } );
+
+ $o->fetch();
+
+ ok $props->{convert_latlong}, "convert latlong set"
+};
+
+sub prepare_xml {
+ my $replacements = shift;
+
+ my %defaults = (
+ desc => 'this is a problem',
+ lat => 51.4021,
+ long => 0.01578,
+ id => 123456,
+ update_time => '2010-04-14T06:37:38-08:00',
+ %$replacements
+ );
+
+ my $xml = qq[<?xml version="1.0" encoding="utf-8"?>
+<service_requests>
+<request>
+<service_request_id>XXX_ID</service_request_id>
+<status>open</status>
+<status_notes></status_notes>
+<service_name>Sidewalk and Curb Issues</service_name>
+<service_code>sidewalks</service_code>
+<description>XXX_DESC</description>
+<agency_responsible></agency_responsible>
+<service_notice></service_notice>
+<requested_datetime>2010-04-14T06:37:38-08:00</requested_datetime>
+<updated_datetime>XXX_UPDATE_TIME</updated_datetime>
+<expected_datetime>2010-04-15T06:37:38-08:00</expected_datetime>
+<lat>XXX_LAT</lat>
+<long>XXX_LONG</long>
+</request>
+</service_requests>
+];
+
+ for my $key (keys %defaults) {
+ my $string = 'XXX_' . uc $key;
+ $xml =~ s/$string/$defaults{$key}/;
+ }
+
+ return $xml;
+}
+
+done_testing();
diff --git a/t/open311/getservicerequestupdates.t b/t/open311/getservicerequestupdates.t
index da427e505..3c279d776 100644
--- a/t/open311/getservicerequestupdates.t
+++ b/t/open311/getservicerequestupdates.t
@@ -1,6 +1,7 @@
#!/usr/bin/env perl
use FixMyStreet::Test;
+use Test::Output;
use CGI::Simple;
use LWP::Protocol::PSGI;
use t::Mock::Static;
@@ -149,7 +150,7 @@ for my $test (
comment_status => 'OPEN',
mark_fixed=> 0,
mark_open => 0,
- problem_state => undef,
+ problem_state => 'confirmed',
end_state => 'confirmed',
},
{
@@ -357,6 +358,19 @@ for my $test (
end_state => 'investigating',
},
{
+ desc => 'unchanging state does not trigger auto-response template',
+ description => '',
+ xml_description => '',
+ external_id => 638344,
+ start_state => 'investigating',
+ comment_status => 'INVESTIGATING',
+ mark_fixed => 0,
+ mark_open => 0,
+ problem_state => 'investigating',
+ end_state => 'investigating',
+ comment_state => 'hidden',
+ },
+ {
desc => 'open status does not re-open hidden report',
description => 'This is a note',
external_id => 638344,
@@ -388,6 +402,7 @@ for my $test (
is $c->mark_fixed, $test->{mark_fixed}, 'mark_closed correct';
is $c->problem_state, $test->{problem_state}, 'problem_state correct';
is $c->mark_open, $test->{mark_open}, 'mark_open correct';
+ is $c->state, $test->{comment_state} || 'confirmed', 'comment state correct';
is $problem->state, $test->{end_state}, 'correct problem state';
$problem->comments->delete;
};
@@ -649,6 +664,95 @@ subtest 'check that existing comments are not duplicated' => sub {
is $problem->comments->count, 2, 'if comments are deleted then they are added';
};
+subtest 'check that external_status_code is stored correctly' => sub {
+ my $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?>
+ <service_requests_updates>
+ <request_update>
+ <update_id>638344</update_id>
+ <service_request_id>@{[ $problem->external_id ]}</service_request_id>
+ <status>open</status>
+ <description>This is a note</description>
+ <updated_datetime>UPDATED_DATETIME</updated_datetime>
+ <external_status_code>060</external_status_code>
+ </request_update>
+ <request_update>
+ <update_id>638354</update_id>
+ <service_request_id>@{[ $problem->external_id ]}</service_request_id>
+ <status>open</status>
+ <description>This is a different note</description>
+ <updated_datetime>UPDATED_DATETIME2</updated_datetime>
+ <external_status_code>101</external_status_code>
+ </request_update>
+ </service_requests_updates>
+ };
+
+ $problem->comments->delete;
+
+ my $dt2 = $dt->clone->subtract( hours => 1 );
+ $requests_xml =~ s/UPDATED_DATETIME2/$dt/;
+ $requests_xml =~ s/UPDATED_DATETIME/$dt2/;
+
+ 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 => $user,
+ );
+
+ $update->update_comments( $o, $bodies{2482} );
+
+ $problem->discard_changes;
+ is $problem->comments->count, 2, 'two comments after fetching updates';
+
+ my @comments = $problem->comments->search(undef, { order_by => [ 'created' ] } )->all;
+
+ is $comments[0]->get_extra_metadata('external_status_code'), "060", "correct external status code on first comment";
+ is $comments[1]->get_extra_metadata('external_status_code'), "101", "correct external status code on second comment";
+
+ is $problem->get_extra_metadata('external_status_code'), "101", "correct external status code";
+
+};
+
+subtest 'check that external_status_code triggers auto-responses' => sub {
+ my $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?>
+ <service_requests_updates>
+ <request_update>
+ <update_id>638344</update_id>
+ <service_request_id>@{[ $problem->external_id ]}</service_request_id>
+ <status>open</status>
+ <description></description>
+ <updated_datetime>UPDATED_DATETIME</updated_datetime>
+ <external_status_code>060</external_status_code>
+ </request_update>
+ </service_requests_updates>
+ };
+
+ my $response_template = $bodies{2482}->response_templates->create({
+ title => "Acknowledgement",
+ text => "Thank you for your report. We will provide an update within 24 hours.",
+ auto_response => 1,
+ external_status_code => "060"
+ });
+
+ $problem->comments->delete;
+
+ $requests_xml =~ s/UPDATED_DATETIME/$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 => $user,
+ );
+
+ $update->update_comments( $o, $bodies{2482} );
+
+ $problem->discard_changes;
+ is $problem->comments->count, 1, 'one comment after fetching updates';
+
+ my $comment = $problem->comments->first;
+
+ is $problem->comments->first->text, "Thank you for your report. We will provide an update within 24 hours.", "correct external status code on first comment";
+};
+
foreach my $test ( {
desc => 'check that closed and then open comment results in correct state',
dt1 => $dt->clone->subtract( hours => 1 ),
@@ -782,6 +886,53 @@ foreach my $test ( {
}
}
+foreach my $test ( {
+ desc => 'normally blank text produces a warning',
+ num_alerts => 1,
+ blank_updates_permitted => 0,
+ },
+ {
+ desc => 'no warning if blank updates permitted',
+ num_alerts => 1,
+ blank_updates_permitted => 1,
+ },
+) {
+ subtest $test->{desc} => sub {
+ my $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?>
+ <service_requests_updates>
+ <request_update>
+ <update_id>638344</update_id>
+ <service_request_id>@{[ $problem->external_id ]}</service_request_id>
+ <status>closed</status>
+ <description></description>
+ <updated_datetime>UPDATED_DATETIME</updated_datetime>
+ </request_update>
+ </service_requests_updates>
+ };
+
+ $problem->state( 'confirmed' );
+ $problem->lastupdate( $dt->clone->subtract( hours => 3 ) );
+ $problem->update;
+
+ $requests_xml =~ s/UPDATED_DATETIME/$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 => $user,
+ blank_updates_permitted => $test->{blank_updates_permitted},
+ );
+
+ if ( $test->{blank_updates_permitted} ) {
+ stderr_is { $update->update_comments( $o, $bodies{2482} ) } '', 'No error message'
+ } else {
+ stderr_like { $update->update_comments( $o, $bodies{2482} ) } qr/Couldn't determine update text for/, 'Error message displayed'
+ }
+ $problem->discard_changes;
+ $problem->comments->delete;
+ }
+}
+
done_testing();
sub setup_xml {
diff --git a/t/open311/populate-service-list.t b/t/open311/populate-service-list.t
index 7d4f491c6..b54b1c242 100644
--- a/t/open311/populate-service-list.t
+++ b/t/open311/populate-service-list.t
@@ -192,67 +192,6 @@ subtest 'check conflicting contacts not changed' => sub {
is $contact_count, 4, 'correct number of contacts';
};
-subtest 'check meta data population' => sub {
- my $processor = Open311::PopulateServiceList->new();
-
- my $meta_xml = '<?xml version="1.0" encoding="utf-8"?>
-<service_definition>
- <service_code>100</service_code>
- <attributes>
- <attribute>
- <variable>true</variable>
- <code>type</code>
- <datatype>string</datatype>
- <required>true</required>
- <datatype_description>Type of bin</datatype_description>
- <order>1</order>
- <description>Type of bin</description>
- </attribute>
- </attributes>
-</service_definition>
- ';
-
- my $contact = FixMyStreet::DB->resultset('Contact')->find_or_create(
- {
- body_id => 1,
- email => '001',
- category => 'Bins left out 24x7',
- state => 'confirmed',
- editor => $0,
- whenedited => \'current_timestamp',
- note => 'test contact',
- }
- );
-
- my $o = Open311->new(
- jurisdiction => 'mysociety',
- endpoint => 'http://example.com',
- test_mode => 1,
- test_get_returns => { 'services/100.xml' => $meta_xml }
- );
-
- $processor->_current_open311( $o );
- $processor->_current_body( $bromley );
- $processor->_current_service( { service_code => 100 } );
-
- $processor->_add_meta_to_contact( $contact );
-
- my $extra = [ {
- variable => 'true',
- code => 'type',
- datatype => 'string',
- required => 'true',
- datatype_description => 'Type of bin',
- order => 1,
- description => 'Type of bin'
-
- } ];
-
- $contact->discard_changes;
-
- is_deeply $contact->get_extra_fields, $extra, 'meta data saved';
-};
-
for my $test (
{
desc => 'check meta data added to existing contact',
@@ -527,7 +466,7 @@ subtest 'check attribute ordering' => sub {
is_deeply $contact->get_extra_fields, $extra, 'meta data re-ordered correctly';
};
-subtest 'check bromely skip code' => sub {
+subtest 'check Bromley skip code' => sub {
my $processor = Open311::PopulateServiceList->new();
my $meta_xml = '<?xml version="1.0" encoding="utf-8"?>
@@ -598,7 +537,14 @@ subtest 'check bromely skip code' => sub {
datatype_description => 'Type of bin',
order => 1,
description => 'Type of bin'
-
+ }, {
+ automated => 'hidden_field',
+ variable => 'true',
+ code => 'prow_reference',
+ datatype => 'string',
+ required => 'false',
+ order => 101,
+ description => 'Right of way reference'
} ];
$contact->discard_changes;
diff --git a/t/script/inactive.t b/t/script/inactive.t
new file mode 100644
index 000000000..4d78b385f
--- /dev/null
+++ b/t/script/inactive.t
@@ -0,0 +1,71 @@
+use FixMyStreet::TestMech;
+
+use_ok 'FixMyStreet::Script::Inactive';
+
+my $in = FixMyStreet::Script::Inactive->new( anonymize => 6, email => 3 );
+my $mech = FixMyStreet::TestMech->new;
+
+my $user = FixMyStreet::DB->resultset("User")->find_or_create({ email => 'test@example.com' });
+my $t = DateTime->new(year => 2016, month => 1, day => 1, hour => 12);
+$user->last_active($t);
+$user->update;
+
+my $user_inactive = FixMyStreet::DB->resultset("User")->find_or_create({ email => 'inactive@example.com' });
+$t = DateTime->now->subtract(months => 4);
+$user_inactive->last_active($t);
+$user_inactive->update;
+
+my @problems;
+for (my $m = 1; $m <= 12; $m++) {
+ my $t = DateTime->new(year => 2017, month => $m, day => 1, hour => 12);
+ push @problems, $mech->create_problems_for_body(1, 2237, 'Title', {
+ dt => $t,
+ lastupdate => "$t",
+ state => $m % 2 ? 'fixed - user' : 'confirmed',
+ });
+}
+
+$mech->create_comment_for_problem($problems[0], $user, 'Name', 'Update', 0, 'confirmed', $problems[0]->state);
+FixMyStreet::DB->resultset("Alert")->create({ alert_type => 'new_updates', parameter => $problems[2]->id, user => $user });
+
+subtest 'Anonymization of inactive fixed/closed reports' => sub {
+ $in->reports;
+
+ my $count = FixMyStreet::DB->resultset("Problem")->search({ user_id => $user->id })->count;
+ is $count, 6, 'Six non-anonymised';
+
+ my $comment = FixMyStreet::DB->resultset("Comment")->first;
+ my $alert = FixMyStreet::DB->resultset("Alert")->first;
+ is $comment->anonymous, 1, 'Comment anonymized';
+ is $comment->user->email, 'removed-automatically@example.org', 'Comment user anonymized';
+ is $alert->user->email, 'removed-automatically@example.org', 'Alert anonymized';
+ isnt $alert->whendisabled, undef, 'Alert disabled';
+
+ $mech->create_comment_for_problem($problems[0], $user, 'Name 2', 'Update', 0, 'confirmed', $problems[0]->state);
+ $comment = FixMyStreet::DB->resultset("Comment")->search({ name => 'Name 2' })->first;
+
+ $in->reports;
+ $comment->discard_changes;
+ is $comment->anonymous, 1, 'Comment anonymized';
+ is $comment->user->email, 'removed-automatically@example.org', 'Comment user anonymized';
+};
+
+subtest 'Closing updates on inactive fixed/closed reports' => sub {
+ my $in = FixMyStreet::Script::Inactive->new( close => 1 );
+ $in->reports;
+ $problems[2]->discard_changes;
+ is $problems[2]->get_extra_metadata('closed_updates'), 1, 'Closed to updates';
+ # TODO Visit page, check closed for updates
+};
+
+subtest 'Anonymization of inactive users' => sub {
+ $in->users;
+
+ my $email = $mech->get_email;
+ like $email->as_string, qr/inactive\@example.com/, 'Inactive email sent';
+
+ $user->discard_changes;
+ is $user->email, 'removed-' . $user->id . '@example.org', 'User has been anonymized';
+};
+
+done_testing;
diff --git a/t/sendreport/open311.t b/t/sendreport/open311.t
index 1eb5535aa..26764dc19 100644
--- a/t/sendreport/open311.t
+++ b/t/sendreport/open311.t
@@ -1,4 +1,16 @@
+package FixMyStreet::Cobrand::Tester;
+
+use parent 'FixMyStreet::Cobrand::FixMyStreet';
+
+sub open311_config {
+ my ($self, $row, $h, $params) = @_;
+ $params->{multi_photos} = 1;
+}
+
+package main;
+
use CGI::Simple;
+use Path::Tiny;
use FixMyStreet::Script::Reports;
use FixMyStreet::TestMech;
my $mech = FixMyStreet::TestMech->new;
@@ -25,6 +37,7 @@ subtest 'testing Open311 behaviour', sub {
FixMyStreet::override_config {
STAGING_FLAGS => { send_reports => 1 },
ALLOWED_COBRANDS => [ 'fixmystreet' ],
+ MAPIT_URL => 'http://mapit.uk/',
}, sub {
$test_data = FixMyStreet::Script::Reports::send();
};
@@ -41,4 +54,75 @@ subtest 'testing Open311 behaviour', sub {
is $c->param('jurisdiction_id'), 'FMS', 'Request had correct jurisdiction';
};
+my ($photo_report) = $mech->create_problems_for_body( 1, $body->id, 'Test', {
+ cobrand => 'fixmystreet',
+ category => 'Potholes',
+ user => $user,
+});
+my $sample_file = path(__FILE__)->parent->parent->child("app/controller/sample.jpg");
+my $UPLOAD_DIR = File::Temp->newdir();
+my @files = map { $_ x 40 . ".jpeg" } (1..3);
+$sample_file->copy(path($UPLOAD_DIR, $_)) for @files;
+$photo_report->photo(join(',', @files));
+$photo_report->update;
+
+subtest 'test report with multiple photos only sends one', sub {
+ $body->update( { send_method => 'Open311', endpoint => 'http://endpoint.example.com', jurisdiction => 'FMS', api_key => 'test' } );
+ my $test_data;
+
+ FixMyStreet::override_config {
+ STAGING_FLAGS => { send_reports => 1 },
+ ALLOWED_COBRANDS => [ 'fixmystreet' ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $test_data = FixMyStreet::Script::Reports::send();
+ };
+ $photo_report->discard_changes;
+ ok $photo_report->whensent, 'Report marked as sent';
+ is $photo_report->send_method_used, 'Open311', 'Report sent via Open311';
+ is $photo_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[easting]'), 529025, 'Request had easting';
+ is $c->param('attribute[northing]'), 179716, 'Request had northing';
+ is $c->param('attribute[fixmystreet_id]'), $photo_report->id, 'Request had correct ID';
+ is $c->param('jurisdiction_id'), 'FMS', 'Request had correct jurisdiction';
+ my @media = $c->param('media_url');
+ is_deeply \@media, [
+ 'http://www.example.org/photo/' . $photo_report->id .'.0.full.jpeg?11111111'
+ ], 'One photo in media_url';
+};
+
+$photo_report->whensent(undef);
+$photo_report->cobrand('tester');
+$photo_report->send_method_used('');
+$photo_report->update();
+
+subtest 'test sending multiple photos', sub {
+ $body->update( { send_method => 'Open311', endpoint => 'http://endpoint.example.com', jurisdiction => 'FMS', api_key => 'test' } );
+ my $test_data;
+
+ FixMyStreet::override_config {
+ STAGING_FLAGS => { send_reports => 1 },
+ ALLOWED_COBRANDS => [ 'tester' ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $test_data = FixMyStreet::Script::Reports::send();
+ };
+ $photo_report->discard_changes;
+ ok $photo_report->whensent, 'Report marked as sent';
+ is $photo_report->send_method_used, 'Open311', 'Report sent via Open311';
+ is $photo_report->external_id, 248, 'Report has right external ID';
+
+ my $req = $test_data->{test_req_used};
+ my $c = CGI::Simple->new($req->content);
+ my @media = $c->param('media_url');
+ is_deeply \@media, [
+ 'http://www.example.org/photo/' . $photo_report->id .'.0.full.jpeg?11111111',
+ 'http://www.example.org/photo/' . $photo_report->id .'.1.full.jpeg?22222222',
+ 'http://www.example.org/photo/' . $photo_report->id .'.2.full.jpeg?33333333'
+ ], 'Multiple photos in media_url';
+};
+
done_testing();