diff options
author | Marius Halden <marius.h@lden.org> | 2017-11-03 16:13:59 +0100 |
---|---|---|
committer | Marius Halden <marius.h@lden.org> | 2017-11-03 16:13:59 +0100 |
commit | 42d874db498d0fabae92d0c87acf99054d92391b (patch) | |
tree | d0cf5afdee3d244c4e5da6fe1ab9acba620634df /t/app/controller | |
parent | 19a7c5dda85a47a68040c742791e9cd9d3e52be6 (diff) | |
parent | dc7613329c275cd158fdde8faf1c0e301f5b7202 (diff) |
Merge tag 'v2.2' into fiksgatami-dev
Diffstat (limited to 't/app/controller')
38 files changed, 1699 insertions, 450 deletions
diff --git a/t/app/controller/about.t b/t/app/controller/about.t index cec50abfa..04d902bc5 100644 --- a/t/app/controller/about.t +++ b/t/app/controller/about.t @@ -1,11 +1,12 @@ -use utf8; -use strict; -use warnings; +package FixMyStreet::Cobrand::Tester; +use parent 'FixMyStreet::Cobrand::Default'; +sub path_to_web_templates { [ FixMyStreet->path_to( 't', 'app', 'controller', 'templates') ] } -use Test::More; -use Test::WWW::Mechanize::Catalyst 'FixMyStreet::App'; +package main; -ok( my $mech = Test::WWW::Mechanize::Catalyst->new, 'Created mech object' ); +use FixMyStreet::TestMech; + +ok( my $mech = FixMyStreet::TestMech->new, 'Created mech object' ); # check that we can get the page $mech->get_ok('/faq'); @@ -30,4 +31,22 @@ FixMyStreet::override_config { $mech->content_contains('html class="no-js" lang="nb"'); }; +$mech->get_ok('/'); +$mech->content_contains('Report a problem'); +$mech->content_lacks('STATIC FRONT PAGE'); +$mech->get('/report'); +is $mech->res->code, 200, "got 200"; +is $mech->res->previous->code, 302, "got 302 for redirect"; +is $mech->uri->path, '/', 'redirected to front page'; + +FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'tester' ], +}, sub { + $mech->get_ok('/'); + $mech->content_contains('STATIC FRONT PAGE'); + $mech->get_ok('/report'); + is $mech->res->previous, undef, 'No redirect'; + $mech->content_contains('Report a problem'); +}; + done_testing(); diff --git a/t/app/controller/admin.t b/t/app/controller/admin.t index 5f8abe5a6..bd0f9e408 100644 --- a/t/app/controller/admin.t +++ b/t/app/controller/admin.t @@ -1,7 +1,3 @@ -use strict; -use warnings; -use Test::More; - use FixMyStreet::TestMech; my $mech = FixMyStreet::TestMech->new; @@ -12,7 +8,7 @@ my $user2 = $mech->create_user_ok('test2@example.com', name => 'Test User 2'); my $superuser = $mech->create_user_ok('superuser@example.com', name => 'Super User', is_superuser => 1); -my $oxfordshire = $mech->create_body_ok(2237, 'Oxfordshire County Council', id => 2237); +my $oxfordshire = $mech->create_body_ok(2237, 'Oxfordshire County Council'); my $oxfordshirecontact = $mech->create_contact_ok( body_id => $oxfordshire->id, category => 'Potholes', email => 'potholes@example.com' ); $mech->create_contact_ok( body_id => $oxfordshire->id, category => 'Traffic lights', email => 'lights@example.com' ); my $oxfordshireuser = $mech->create_user_ok('counciluser@example.com', name => 'Council User', from_body => $oxfordshire); @@ -20,13 +16,9 @@ my $oxfordshireuser = $mech->create_user_ok('counciluser@example.com', name => ' my $oxford = $mech->create_body_ok(2421, 'Oxford City Council'); $mech->create_contact_ok( body_id => $oxford->id, category => 'Graffiti', email => 'graffiti@example.net' ); -my $bromley = $mech->create_body_ok(2482, 'Bromley Council', id => 2482); - -my $user3 = $mech->create_user_ok('test3@example.com', name => 'Test User 2'); +my $bromley = $mech->create_body_ok(2482, 'Bromley Council'); -if ( $user3 ) { - $mech->delete_user( $user3 ); -} +my $user3; my $dt = DateTime->new( year => 2011, @@ -119,7 +111,7 @@ subtest 'check summary counts' => sub { my ($num_alerts) = $mech->content =~ /(\d+) confirmed alerts/; my ($num_qs) = $mech->content =~ /(\d+) questionnaires sent/; - $report->bodies_str(2237); + $report->bodies_str($oxfordshire->id); $report->cobrand('oxfordshire'); $report->update; @@ -158,16 +150,6 @@ $mech->content_like(qr{AB\d\d}); $mech->content_contains("http://www.example.org/around"); subtest 'check contact creation' => sub { - my $contact = FixMyStreet::App->model('DB::Contact')->search( - { body_id => $body->id, category => [ 'test category', 'test/category' ] } - ); - $contact->delete_all; - - my $history = FixMyStreet::App->model('DB::ContactsHistory')->search( - { body_id => $body->id, category => [ 'test category', 'test/category' ] } - ); - $history->delete_all; - $mech->get_ok('/admin/body/' . $body->id); $mech->submit_form_ok( { with_fields => { @@ -175,13 +157,13 @@ subtest 'check contact creation' => sub { email => 'test@example.com', note => 'test note', non_public => undef, - confirmed => 0, + state => 'unconfirmed', } } ); $mech->content_contains( 'test category' ); $mech->content_contains( 'test@example.com' ); $mech->content_contains( '<td>test note' ); - $mech->content_contains( 'Private: No' ); + $mech->content_like( qr/<td>\s*unconfirmed\s*<\/td>/ ); # No private $mech->submit_form_ok( { with_fields => { category => 'private category', @@ -191,7 +173,7 @@ subtest 'check contact creation' => sub { } } ); $mech->content_contains( 'private category' ); - $mech->content_contains( 'Private: Yes' ); + $mech->content_like( qr{test\@example.com\s*</td>\s*<td>\s*confirmed\s*<br>\s*<small>\s*Private\s*</small>\s*</td>} ); $mech->submit_form_ok( { with_fields => { category => 'test/category', @@ -200,7 +182,7 @@ subtest 'check contact creation' => sub { non_public => 'on', } } ); $mech->get_ok('/admin/body/' . $body->id . '/test/category'); - + $mech->content_contains('<h1>test/category</h1>'); }; subtest 'check contact editing' => sub { @@ -213,9 +195,8 @@ subtest 'check contact editing' => sub { } } ); $mech->content_contains( 'test category' ); - $mech->content_contains( 'test2@example.com' ); + $mech->content_like( qr{test2\@example.com\s*</td>\s*<td>\s*unconfirmed\s*</td>} ); $mech->content_contains( '<td>test2 note' ); - $mech->content_contains( 'Private: No' ); $mech->get_ok('/admin/body/' . $body->id . '/test%20category'); $mech->submit_form_ok( { with_fields => { @@ -228,14 +209,13 @@ subtest 'check contact editing' => sub { $mech->get_ok('/admin/body/' . $body->id . '/test%20category'); $mech->content_contains( '<td><strong>test2@example.com,test3@example.com' ); - $mech->get_ok('/admin/body/' . $body->id . '/test%20category'); $mech->submit_form_ok( { with_fields => { email => 'test2@example.com', note => 'test2 note', non_public => 'on', } } ); - $mech->content_contains( 'Private: Yes' ); + $mech->content_like( qr{test2\@example.com\s*</td>\s*<td>\s*unconfirmed\s*<br>\s*<small>\s*Private\s*</small>\s*</td>} ); $mech->get_ok('/admin/body/' . $body->id . '/test%20category'); $mech->content_contains( '<td><strong>test2@example.com' ); @@ -243,7 +223,7 @@ subtest 'check contact editing' => sub { subtest 'check contact updating' => sub { $mech->get_ok('/admin/body/' . $body->id . '/test%20category'); - $mech->content_like(qr{test2\@example.com</strong>[^<]*</td>[^<]*<td>No}s); + $mech->content_like(qr{test2\@example.com</strong>[^<]*</td>[^<]*<td>unconfirmed}s); $mech->get_ok('/admin/body/' . $body->id); @@ -251,9 +231,9 @@ subtest 'check contact updating' => sub { $mech->tick( 'confirmed', 'test category' ); $mech->submit_form_ok({form_number => 1}); - $mech->content_like(qr'test2@example.com</td>[^<]*<td>\s*Confirmed: Yes's); + $mech->content_like(qr'test2@example.com</td>[^<]*<td>\s*confirmed's); $mech->get_ok('/admin/body/' . $body->id . '/test%20category'); - $mech->content_like(qr{test2\@example.com[^<]*</td>[^<]*<td><strong>Yes}s); + $mech->content_like(qr{test2\@example.com[^<]*</td>[^<]*<td><strong>confirmed}s); }; $body->update({ send_method => undef }); @@ -1197,6 +1177,7 @@ my %default_perms = ( "permissions[report_inspect]" => undef, "permissions[report_instruct]" => undef, "permissions[contribute_as_another_user]" => undef, + "permissions[contribute_as_anonymous_user]" => undef, "permissions[contribute_as_body]" => undef, "permissions[view_body_contribute_details]" => undef, "permissions[user_edit]" => undef, @@ -1489,6 +1470,7 @@ subtest "response priorities can be added" => sub { name => "Cat 1A", description => "Fixed within 24 hours", deleted => undef, + is_default => undef, "contacts[".$oxfordshirecontact->id."]" => 1, }; $mech->submit_form_ok( { with_fields => $fields } ); @@ -1497,6 +1479,25 @@ subtest "response priorities can be added" => sub { is $oxfordshirecontact->response_priorities->count, 1, "Response template was added to contact"; }; +subtest "response priorities can set to default" => sub { + my $priority_id = $oxfordshire->response_priorities->first->id; + is $oxfordshire->response_priorities->count, 1, "Response priority exists"; + $mech->get_ok( "/admin/responsepriorities/" . $oxfordshire->id . "/$priority_id" ); + + my $fields = { + name => "Cat 1A", + description => "Fixed within 24 hours", + deleted => undef, + is_default => 1, + "contacts[".$oxfordshirecontact->id."]" => 1, + }; + $mech->submit_form_ok( { with_fields => $fields } ); + + is $oxfordshire->response_priorities->count, 1, "Still one response priority"; + is $oxfordshirecontact->response_priorities->count, 1, "Still one response template"; + ok $oxfordshire->response_priorities->first->is_default, "Response priority set to default"; +}; + subtest "response priorities can be listed" => sub { $mech->get_ok( "/admin/responsepriorities/" . $oxfordshire->id ); @@ -1546,15 +1547,4 @@ subtest "response priorities can't be viewed across councils" => sub { }; }; -END { - $mech->delete_user( $user ); - $mech->delete_user( $user2 ); - $mech->delete_user( $user3 ); - $mech->delete_user( $superuser ); - $mech->delete_user( 'test4@example.com' ); - $mech->delete_body( $oxfordshire ); - $mech->delete_body( $oxford ); - $mech->delete_body( $bromley ); - $mech->delete_body( $westminster ); - done_testing(); -} +done_testing(); diff --git a/t/app/controller/admin_defecttypes.t b/t/app/controller/admin_defecttypes.t new file mode 100644 index 000000000..e7d0e42af --- /dev/null +++ b/t/app/controller/admin_defecttypes.t @@ -0,0 +1,193 @@ +use FixMyStreet::TestMech; + +my $mech = FixMyStreet::TestMech->new; + +FixMyStreet::override_config { ALLOWED_COBRANDS => ['bromley'], }, sub { + subtest 'check defecttypes menu not available' => sub { + my $body = $mech->create_body_ok( 2482, 'Bromley Council' ); + + my $user = $mech->create_user_ok( + 'bromley@example.com', + name => 'Test User', + from_body => $body + ); + + $mech->log_in_ok( $user->email ); + + $mech->get_ok('/admin'); + $mech->content_lacks('Defect Types'); + + is $mech->get('/admin/defecttypes')->code, 404, '404 if no permission'; + is $mech->get('/admin/defecttypes/' . $body->id)->code, 404, '404 if no permission'; + + $mech->log_out_ok(); + }; +}; + +FixMyStreet::override_config { ALLOWED_COBRANDS => ['oxfordshire'], }, sub { + + my $body = $mech->create_body_ok( 2237, 'Oxfordshire County Council' ); + + my $user = $mech->create_user_ok( + 'oxford@example.com', + name => 'Test User', + from_body => $body + ); + + $mech->log_in_ok( $user->email ); + + my $contact = $mech->create_contact_ok( + body_id => $body->id, + category => 'Traffic lights', + email => 'lights@example.com' + ); + + subtest 'check defecttypes menu not available without permissions' => sub { + $mech->get_ok('/admin'); + $mech->content_lacks('Defect Types'); + + is $mech->get('/admin/defecttypes')->code, 404, '404 if no permission'; + is $mech->get('/admin/defecttypes/' . $body->id)->code, 404, '404 if no permission'; + }; + + $user->user_body_permissions->create( { + body => $body, + permission_type => 'defect_type_edit', + } ); + + subtest 'check defecttypes menu available with permissions' => sub { + $mech->get_ok('/admin'); + $mech->content_contains('Defect Types'); + $mech->get_ok('/admin/defecttypes'); + is $mech->res->previous->code, 302, 'index redirects...'; + is $mech->uri->path, '/admin/defecttypes/' . $body->id, '...to body page'; + }; + + subtest 'check missing defect type is 404' => sub { + is $mech->get( '/admin/defecttypes/' . $body->id . '/299')->code, 404; + }; + + subtest 'check adding a defect type' => sub { + $mech->get_ok( '/admin/defecttypes/' . $body->id . '/new' ); + + $mech->content_contains('Traffic lights'); + + $mech->submit_form_ok( { + with_fields => { + name => 'A defect', + description => 'This is a new defect', + } } ); + + $mech->content_contains('New defect'); + }; + + subtest 'check editing a defect type' => sub { + my $defect = FixMyStreet::App->model('DB::DefectType')->search( { + name => 'A defect', + body_id => $body->id + } )->first; + + $mech->get_ok( '/admin/defecttypes/' . $body->id . '/' . $defect->id ); + + $mech->submit_form_ok( { + with_fields => { + name => 'Updated defect', + description => 'This is a new defect', + } + }, + 'submitted form' + ); + + $mech->content_lacks('A defect'); + $mech->content_contains('Updated defect'); + + my $defects = FixMyStreet::App->model('DB::DefectType')->search( { + body_id => $body->id + } ); + + is $defects->count, 1, 'only 1 defect'; + }; + + subtest 'check adding a category to a defect' => sub { + my $defect = FixMyStreet::App->model('DB::DefectType')->search( { + name => 'Updated defect', + body_id => $body->id + } )->first; + + is $defect->contact_defect_types->count, 0, + 'defect has no contact types'; + + $mech->get_ok( '/admin/defecttypes/' . $body->id . '/' . $defect->id ); + + $mech->submit_form_ok( { + with_fields => { + name => 'Updated defect', + description => 'This is a new defect', + categories => [ $contact->id ], + } + }, + 'submitted form' + ); + + $mech->content_contains('Traffic lights'); + + $defect->discard_changes; + is $defect->contact_defect_types->count, 1, 'defect has a contact type'; + is $defect->contact_defect_types->first->contact->category, + 'Traffic lights', 'defect has correct contact type'; + }; + + subtest 'check removing category from a defect' => sub { + my $defect = FixMyStreet::App->model('DB::DefectType')->search( { + name => 'Updated defect', + body_id => $body->id + } )->first; + + is $defect->contact_defect_types->count, 1, + 'defect has one contact types'; + + $mech->get_ok( '/admin/defecttypes/' . $body->id . '/' . $defect->id ); + + $mech->submit_form_ok( { + with_fields => { + name => 'Updated defect', + description => 'This is a new defect', + categories => '', + } + }, + 'submitted form' + ); + + $mech->content_lacks('Traffic lights'); + + $defect->discard_changes; + is $defect->contact_defect_types->count, 0, + 'defect has no contact type'; + }; + + subtest 'check adding codes to a defect' => sub { + my $defect = FixMyStreet::App->model('DB::DefectType')->search( { + name => 'Updated defect', + body_id => $body->id + } )->first; + + $mech->get_ok( '/admin/defecttypes/' . $body->id . '/' . $defect->id ); + + $mech->submit_form_ok( { + with_fields => { + name => 'Updated defect', + description => 'This is a new defect', + 'extra[activity_code]' => 1, + 'extra[defect_code]' => 2, + } + }, + 'submitted form' + ); + + $defect->discard_changes; + is_deeply $defect->get_extra_metadata, + { activity_code => 1, defect_code => 2 }, 'defect codes set'; + }; +}; + +done_testing(); diff --git a/t/app/controller/admin_permissions.t b/t/app/controller/admin_permissions.t index dd256173d..7944cc0b1 100644 --- a/t/app/controller/admin_permissions.t +++ b/t/app/controller/admin_permissions.t @@ -1,7 +1,3 @@ -use strict; -use warnings; -use Test::More; - use FixMyStreet::TestMech; my $mech = FixMyStreet::TestMech->new; @@ -10,17 +6,10 @@ my $user = $mech->create_user_ok('test@example.com', name => 'Test User'); my $user2 = $mech->create_user_ok('test2@example.com', name => 'Test User 2'); my $superuser = $mech->create_user_ok('superuser@example.com', name => 'Super User', is_superuser => 1); -my $oxfordshire = $mech->create_body_ok(2237, 'Oxfordshire County Council', id => 2237); +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); -my $bromley = $mech->create_body_ok(2482, 'Bromley Council', id => 2482); - -END { - $mech->delete_user( $user ); - $mech->delete_user( $user2 ); - $mech->delete_user( $superuser ); - $mech->delete_user( $oxfordshireuser ); -} +my $bromley = $mech->create_body_ok(2482, 'Bromley Council'); my $dt = DateTime->new( year => 2011, @@ -157,6 +146,7 @@ FixMyStreet::override_config { "permissions[report_inspect]" => undef, "permissions[report_instruct]" => undef, "permissions[contribute_as_another_user]" => undef, + "permissions[contribute_as_anonymous_user]" => undef, "permissions[contribute_as_body]" => undef, "permissions[user_edit]" => undef, "permissions[user_manage_permissions]" => undef, @@ -189,6 +179,7 @@ FixMyStreet::override_config { "permissions[report_inspect]" => undef, "permissions[report_instruct]" => undef, "permissions[contribute_as_another_user]" => undef, + "permissions[contribute_as_anonymous_user]" => undef, "permissions[contribute_as_body]" => undef, "permissions[user_edit]" => undef, "permissions[user_manage_permissions]" => undef, diff --git a/t/app/controller/admin_reportextrafields.t b/t/app/controller/admin_reportextrafields.t new file mode 100644 index 000000000..fb06665f4 --- /dev/null +++ b/t/app/controller/admin_reportextrafields.t @@ -0,0 +1,316 @@ +use strict; +use warnings; + +package FixMyStreet::Cobrand::Tester; + +use parent 'FixMyStreet::Cobrand::FixMyStreet'; + +sub allow_report_extra_fields { 1 } + +sub area_types { [ 'UTA' ] } + + +package FixMyStreet::Cobrand::SecondTester; + +use parent 'FixMyStreet::Cobrand::FixMyStreet'; + +sub allow_report_extra_fields { 1 } + +sub area_types { [ 'UTA' ] } + + +package FixMyStreet::Cobrand::NoExtras; + +use parent 'FixMyStreet::Cobrand::FixMyStreet'; + +sub allow_report_extra_fields { 0 } + +sub area_types { [ 'UTA' ] } + +package main; + +use FixMyStreet::TestMech; + +# disable info logs for this test run +FixMyStreet::App->log->disable('info'); +END { FixMyStreet::App->log->enable('info'); } + +my $mech = FixMyStreet::TestMech->new; + +my $user = $mech->create_user_ok('superuser@example.com', name => 'Super User', is_superuser => 1); +my $body = $mech->create_body_ok(2237, 'Oxfordshire County Council'); +my $contact = $mech->create_contact_ok( body_id => $body->id, category => 'Potholes', email => 'potholes@example.com' ); + +my $body2 = $mech->create_body_ok(2651, 'Edinburgh City Council'); +my $contact2 = $mech->create_contact_ok( body_id => $body2->id, category => 'Potholes', email => 'potholes@example.com' ); + + +FixMyStreet::override_config { + ALLOWED_COBRANDS => [ { 'tester' => '.' } ], + MAPIT_URL => 'http://mapit.uk/', + LANGUAGES => [ + 'en-gb,English,en_GB', + 'de,German,de_DE' + ] +}, sub { + $mech->log_in_ok( $user->email ); + + subtest 'add extra fields to Contacts' => sub { + my $contact_extra_fields = []; + + is_deeply $contact->get_extra_fields, $contact_extra_fields, 'contact has empty extra fields'; + $mech->get_ok("/admin/body/" . $body->id . "/" . $contact->category); + + $mech->submit_form_ok( { with_fields => { + "metadata[0].order" => "1", + "metadata[0].code" => "string_test", + "metadata[0].required" => "on", + "metadata[0].notice" => "", + "metadata[0].description" => "this is a test description", + "metadata[0].datatype_description" => "hint here", + "metadata[0].datatype" => "string", + "note" => "Added extra field", + }}); + $mech->content_contains('Values updated'); + + push @$contact_extra_fields, { + order => "1", + code => "string_test", + required => "true", + variable => "true", + description => "this is a test description", + datatype_description => "hint here", + datatype => "string", + }; + $contact->discard_changes; + is_deeply $contact->get_extra_fields, $contact_extra_fields, 'new string field was added'; + + + $mech->get_ok("/admin/body/" . $body->id . "/" . $contact->category); + $mech->submit_form_ok( { with_fields => { + "metadata[1].order" => "2", + "metadata[1].code" => "list_test", + "metadata[1].required" => undef, + "metadata[1].notice" => "", + "metadata[1].description" => "this field is a list", + "metadata[1].datatype_description" => "", + "metadata[1].datatype" => "list", + "metadata[1].values[0].key" => "key1", + "metadata[1].values[0].name" => "name1", + "note" => "Added extra list field", + }}); + $mech->content_contains('Values updated'); + + push @$contact_extra_fields, { + order => "2", + code => "list_test", + required => "false", + variable => "true", + description => "this field is a list", + datatype_description => "", + datatype => "singlevaluelist", + values => [ + { name => "name1", key => "key1" }, + ] + }; + $contact->discard_changes; + is_deeply $contact->get_extra_fields, $contact_extra_fields, 'new list field was added'; + + $contact->set_extra_fields(); + $contact->update; + }; + + subtest 'Create and update new ReportExtraFields' => sub { + my $extra_fields = []; + + my $model = FixMyStreet::App->model('DB::ReportExtraFields'); + is $model->count, 0, 'no ReportExtraFields yet'; + + $mech->get_ok("/admin/reportextrafields/new"); + $mech->submit_form_ok({ with_fields => { + name => "Test extra fields", + cobrand => "tester", + language => undef, + "metadata[0].order" => "1", + "metadata[0].code" => "string_test", + "metadata[0].required" => "on", + "metadata[0].notice" => "", + "metadata[0].description" => "this is a test description", + "metadata[0].datatype_description" => "hint here", + "metadata[0].datatype" => "string", + }}); + is $model->count, 1, 'new ReportExtraFields created'; + + my $object = $model->first; + push @$extra_fields, { + order => "1", + code => "string_test", + required => "true", + variable => "true", + description => "this is a test description", + datatype_description => "hint here", + datatype => "string", + }; + is_deeply $object->get_extra_fields, $extra_fields, 'new string field was added'; + is $object->cobrand, 'tester', 'Correct cobrand set'; + is $object->language, undef, 'Correct language set'; + + $mech->get_ok("/admin/reportextrafields/" . $object->id); + $mech->submit_form_ok( { with_fields => { + "language" => "en-gb", + "metadata[1].order" => "2", + "metadata[1].code" => "list_test", + "metadata[1].required" => undef, + "metadata[1].notice" => "", + "metadata[1].description" => "this field is a list", + "metadata[1].datatype_description" => "", + "metadata[1].datatype" => "list", + "metadata[1].values[0].key" => "key1", + "metadata[1].values[0].name" => "name1", + }}); + + push @$extra_fields, { + order => "2", + code => "list_test", + required => "false", + variable => "true", + description => "this field is a list", + datatype_description => "", + datatype => "singlevaluelist", + values => [ + { name => "name1", key => "key1" }, + ] + }; + $object->discard_changes; + is_deeply $object->get_extra_fields, $extra_fields, 'new list field was added'; + is $object->language, "en-gb", "Correct language was set"; + + $mech->get_ok("/admin/reportextrafields/" . $object->id); + $mech->submit_form_ok( { with_fields => { + "metadata[1].values[1].key" => "key2", + "metadata[1].values[1].name" => "name2", + }}); + + push @{$extra_fields->[1]->{values}}, { name => "name2", key => "key2" }; + $object->discard_changes; + is_deeply $object->get_extra_fields, $extra_fields, 'options can be added to list field'; + }; + + subtest 'Fields appear on /report/new' => sub { + $mech->get_ok("/report/new?longitude=-1.351488&latitude=51.847235&category=" . $contact->category); + $mech->content_contains("this is a test description"); + $mech->content_contains("this field is a list"); + }; +}; + +FixMyStreet::override_config { + ALLOWED_COBRANDS => [ { 'tester' => '.' } ], + MAPIT_URL => 'http://mapit.uk/', + LANGUAGES => [ 'de,German,de_DE' ] +}, sub { + subtest 'Language-specific fields are missing from /report/new for other language' => sub { + $mech->get_ok("/report/new?longitude=-1.351488&latitude=51.847235&category=" . $contact->category); + $mech->content_lacks("this is a test description"); + $mech->content_lacks("this field is a list"); + }; +}; + +FixMyStreet::override_config { + ALLOWED_COBRANDS => [ { 'secondtester' => '.' } ], + MAPIT_URL => 'http://mapit.uk/', + LANGUAGES => [ 'en-gb,English,en_GB' ] +}, sub { + subtest 'Cobrand-specific fields are missing from /report/new for other cobrand' => sub { + $mech->get_ok("/report/new?longitude=-1.351488&latitude=51.847235&category=" . $contact->category); + $mech->content_lacks("this is a test description"); + $mech->content_lacks("this field is a list"); + }; +}; + +FixMyStreet::override_config { + ALLOWED_COBRANDS => [ { 'noextras' => '.' } ], + MAPIT_URL => 'http://mapit.uk/', + LANGUAGES => [ 'en-gb,English,en_GB' ] +}, sub { + subtest "Extra fields are missing from cobrand that doesn't allow them" => sub { + my $object = FixMyStreet::App->model('DB::ReportExtraFields')->first; + $object->update({ language => "", cobrand => ""}); + + $mech->get_ok("/report/new?longitude=-1.351488&latitude=51.847235&category=" . $contact->category); + $mech->content_lacks("this is a test description"); + $mech->content_lacks("this field is a list"); + }; +}; + +FixMyStreet::App->model('DB::ReportExtraFields')->delete_all; +$mech->log_out_ok; + +subtest 'Reports are created with correct extra metadata' => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'tester' ], + MAPIT_URL => 'http://mapit.uk/', + }, sub { + my $model = FixMyStreet::App->model('DB::ReportExtraFields'); + my $extra_fields = $model->find_or_create({ + name => "Test extra fields", + language => "", + cobrand => "" + }); + $extra_fields->push_extra_fields({ + order => "1", + code => "string_test", + required => "true", + variable => "true", + description => "this is a test description", + datatype_description => "hint here", + datatype => "string", + }); + $extra_fields->push_extra_fields({ + order => "2", + code => "list_test", + required => "false", + variable => "true", + description => "this field is a list", + datatype_description => "", + datatype => "singlevaluelist", + values => [ + { name => "name1", key => "key1" }, + ] + }); + $extra_fields->update; + + my $user = $mech->create_user_ok('testuser@example.com', name => 'Test User'); + $mech->log_in_ok($user->email); + + $mech->get_ok('/report/new?latitude=55.952055&longitude=-3.189579'); + $mech->content_contains($contact2->category); + + my $extra_id = $extra_fields->id; + $mech->submit_form_ok( { + with_fields => { + title => "Test Report", + detail => "This is a test report", + category => $contact2->category, + "extra[$extra_id]string_test" => "Problem meta string", + "extra[$extra_id]list_test" => "key1", + } + } ); + + my $report = $user->problems->first; + is_deeply $report->get_extra_fields, [ + { + name => 'string_test', + description => 'this is a test description', + value => 'Problem meta string', + }, + { + name => 'list_test', + description => 'this field is a list', + value => 'key1', + } + ], 'Report has correct extra data'; + }; +}; + + +done_testing(); diff --git a/t/app/controller/admin_states.t b/t/app/controller/admin_states.t new file mode 100644 index 000000000..60ffe5b88 --- /dev/null +++ b/t/app/controller/admin_states.t @@ -0,0 +1,24 @@ +use FixMyStreet::TestMech; + +my $mech = FixMyStreet::TestMech->new; + +my $user = $mech->create_user_ok('superuser@example.com', name => 'Super User', is_superuser => 1); + +$mech->log_in_ok( $user->email ); + +subtest 'basic states admin' => sub { + $mech->get_ok('/admin/states'); + $mech->submit_form_ok({ button => 'new', with_fields => { label => 'third party', type => 'closed', name => 'Third party referral' } }); + $mech->content_contains('Third party referral'); + $mech->content_contains('Fixed'); + $mech->submit_form_ok({ button => 'delete:fixed' }); + $mech->content_lacks('Fixed'); + $mech->submit_form_ok({ form_number => 2, button => 'new_fixed' }); + $mech->content_contains('Fixed'); + $mech->submit_form_ok({ with_fields => { 'name:third party' => 'Third party incident' } }); + $mech->content_contains('Third party incident'); +}; + +# TODO Language tests + +done_testing; diff --git a/t/app/controller/admin_translations.t b/t/app/controller/admin_translations.t new file mode 100644 index 000000000..f5c32baa6 --- /dev/null +++ b/t/app/controller/admin_translations.t @@ -0,0 +1,191 @@ +use FixMyStreet::TestMech; + +my $mech = FixMyStreet::TestMech->new; + +my $superuser = $mech->create_user_ok('superuser@example.com', name => 'Super User', is_superuser => 1); + +$mech->log_in_ok( $superuser->email ); + +FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + MAPIT_TYPES => [ 'UTA' ], +}, sub { + +my $body = $mech->create_body_ok(2650, 'Aberdeen City Council'); +$mech->create_contact_ok( body_id => $body->id, category => 'Traffic lights', email => 'lights@example.com' ); + +subtest 'check no translations if one language' => sub { + $mech->get_ok('/admin/body/' . $body->id . '/Traffic%20lights'); + + $mech->content_lacks( 'Translations' ); + +}; + +}; + +FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + MAPIT_TYPES => [ 'UTA' ], + LANGUAGES => [ + 'en-gb,English,en_GB', + 'de,German,de_DE' + ] +}, sub { + +my $body = $mech->create_body_ok(2650, 'Aberdeen City Council'); +$mech->create_contact_ok( body_id => $body->id, category => 'Traffic lights', email => 'lights@example.com' ); + +my $body2 = $mech->create_body_ok(2643, 'Arun District Council'); + +FixMyStreet::DB->resultset("Translation")->create({ + lang => "de", + tbl => "body", + object_id => $body2->id, + col => "name", + msgstr => "DE Arun", +}); + +subtest 'check translations if multiple languages' => sub { + $mech->get_ok('/admin/body/' . $body->id . '/Traffic%20lights'); + + $mech->content_contains( 'Translations' ); +}; + +subtest 'check add category with translation' => sub { + $mech->get_ok('/admin/body/' . $body2->id); + + $mech->content_contains('DE Arun'); + + $mech->submit_form_ok( { with_fields => { + category => 'Potholes', + translation_de => 'DE potholes', + email => 'potholes@example.org', + } } ); + + # check that error page includes translations + $mech->content_lacks('DE Arun'); + $mech->content_contains('DE potholes'); + + $mech->submit_form_ok( { with_fields => { + category => 'Potholes', + translation_de => 'DE potholes', + email => 'potholes@example.org', + note => 'adding category with translation', + } } ); + + $mech->content_contains('DE Arun'); + $mech->content_lacks('DE potholes'); + + $mech->get_ok('/admin/body/' . $body2->id . '/Potholes'); + + $mech->content_contains( 'DE potholes' ); +}; + +subtest 'check add category translation' => sub { + $mech->get_ok('/admin/body/' . $body->id . '/Traffic%20lights'); + + $mech->content_lacks( 'DE Traffic lights' ); + + $mech->submit_form_ok( { with_fields => { + translation_de => 'DE Traffic lights', + note => 'updating translation', + } } ); + + $mech->get_ok('/admin/body/' . $body->id . '/Traffic%20lights'); + + $mech->content_contains( 'DE Traffic lights' ); +}; + +subtest 'check replace category translation' => sub { + $mech->get_ok('/admin/body/' . $body->id . '/Traffic%20lights'); + + $mech->content_contains( 'DE Traffic lights' ); + + $mech->submit_form_ok( { with_fields => { + translation_de => 'German Traffic lights', + note => 'updating translation', + } } ); + + $mech->get_ok('/admin/body/' . $body->id . '/Traffic%20lights'); + + $mech->content_lacks( 'DE Traffic lights' ); + $mech->content_contains( 'German Traffic lights' ); +}; + +subtest 'delete category translation' => sub { + $mech->get_ok('/admin/body/' . $body->id . '/Traffic%20lights'); + $mech->content_contains( 'German Traffic lights' ); + + $mech->submit_form_ok( { with_fields => { + translation_de => '', + note => 'updating translation', + } } ); + + $mech->get_ok('/admin/body/' . $body->id . '/Traffic%20lights'); + + $mech->content_lacks( 'DE German Traffic lights' ); +}; + +subtest 'check add body translation' => sub { + $mech->get_ok('/admin/body/' . $body->id); + + $mech->content_lacks( 'DE Aberdeen' ); + + $mech->submit_form_ok( { with_fields => { + send_method => 'email', + translation_de => 'DE Aberdeen', + } } ); + + $mech->content_contains( 'DE Aberdeen' ); +}; + +subtest 'check replace body translation' => sub { + $mech->get_ok('/admin/body/' . $body->id); + + $mech->content_contains( 'DE Aberdeen' ); + + $mech->submit_form_ok( { with_fields => { + send_method => 'email', + translation_de => 'German Aberdeen', + } } ); + + $mech->content_lacks( 'DE Aberdeen' ); + $mech->content_contains( 'German Aberdeen' ); +}; + +subtest 'delete body translation' => sub { + $mech->get_ok('/admin/body/' . $body->id); + $mech->content_contains( 'German Aberdeen' ); + + $mech->submit_form_ok( { with_fields => { + send_method => 'email', + translation_de => '', + } } ); + + $mech->content_lacks( 'DE German Aberdeen' ); +}; + +subtest 'check add body with translation' => sub { + $mech->get_ok('/admin/bodies/'); + $mech->submit_form_ok( { with_fields => { + area_ids => 2643, + send_method => 'email', + translation_de => 'DE A Body', + } } ); + + # check that error page includes translations + $mech->content_contains( 'DE A Body' ); + + $mech->submit_form_ok( { with_fields => { + name => 'A body', + area_ids => 2643, + send_method => 'email', + translation_de => 'DE A Body', + } } ); + + $mech->follow_link_ok({ text => 'A body' }); + $mech->content_contains( 'DE A Body' ); +} +}; + +done_testing(); diff --git a/t/app/controller/alert.t b/t/app/controller/alert.t index cb5949b8f..ce3c2ef9b 100644 --- a/t/app/controller/alert.t +++ b/t/app/controller/alert.t @@ -1,6 +1,3 @@ -use strict; -use warnings; -use Test::More; use LWP::Protocol::PSGI; use FixMyStreet::TestMech; @@ -27,7 +24,7 @@ FixMyStreet::override_config { $mech->get_ok('/alert/list?pc=EH1 1BB'); $mech->title_like(qr/^Local RSS feeds and email alerts/); - $mech->content_contains('Here are the types of local problem alerts for ‘EH1 1BB’'); + $mech->content_like(qr/Local RSS feeds and email alerts for .EH1 1BB/); $mech->content_contains('html class="no-js" lang="en-gb"'); $mech->content_contains('Problems within 10.0km'); $mech->content_contains('rss/pc/EH11BB/2'); @@ -50,8 +47,10 @@ FixMyStreet::override_config { $mech->get_ok('/alert/list?pc='); $mech->content_contains('To find out what local alerts we have for you'); + # Two-tier council $mech->get_ok('/alert/list?pc=GL502PR'); - $mech->content_contains('Problems within the boundary of'); + $mech->content_contains('Problems in an area'); + $mech->content_contains('Reports by destination'); $mech->get_ok('/alert/subscribe?rss=1&type=local&pc=ky16+8yg&rss=Give+me+an+RSS+feed&rznvy=' ); $mech->content_contains('Please select the feed you want'); diff --git a/t/app/controller/alert_new.t b/t/app/controller/alert_new.t index ea38f7c25..97a19b3b8 100644 --- a/t/app/controller/alert_new.t +++ b/t/app/controller/alert_new.t @@ -1,9 +1,6 @@ -use strict; -use warnings; -use Test::More; - use FixMyStreet::TestMech; use FixMyStreet::App; +use FixMyStreet::Script::Alerts; my $mech = FixMyStreet::TestMech->new; @@ -291,7 +288,7 @@ for my $test ( }; } -$mech->create_body_ok(2226, 'Gloucestershire County Council'); +my $gloucester = $mech->create_body_ok(2226, 'Gloucestershire County Council'); $mech->create_body_ok(2326, 'Cheltenham Borough Council'); subtest "Test two-tier council alerts" => sub { @@ -438,7 +435,7 @@ subtest "Test normal alert signups and that alerts are sent" => sub { FixMyStreet::override_config { MAPIT_URL => 'http://mapit.uk/', }, sub { - FixMyStreet::App->model('DB::AlertType')->email_alerts(); + FixMyStreet::Script::Alerts::send(); }; # TODO Note the below will fail if the db has an existing alert that matches $mech->email_count_is(3); @@ -478,6 +475,85 @@ subtest "Test normal alert signups and that alerts are sent" => sub { $mech->delete_user($user2); }; +subtest "Test alerts are correct for no-text updates" => sub { + $mech->delete_user( 'reporter@example.com' ); + $mech->delete_user( 'alerts@example.com' ); + + my $user1 = $mech->create_user_ok('reporter@example.com', name => 'Reporter User' ); + my $user2 = $mech->create_user_ok('alerts@example.com', name => 'Alert User' ); + my $user3 = $mech->create_user_ok('staff@example.com', name => 'Staff User', from_body => $gloucester ); + my $dt = DateTime->now(time_zone => 'Europe/London')->add(days => 2); + + my $dt_parser = FixMyStreet::App->model('DB')->schema->storage->datetime_parser; + + my $report_time = '2011-03-01 12:00:00'; + my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( { + postcode => 'EH1 1BB', + bodies_str => '1', + areas => ',11808,135007,14419,134935,2651,20728,', + category => 'Street lighting', + title => 'Testing', + detail => 'Testing Detail', + used_map => 1, + name => $user1->name, + anonymous => 0, + state => 'fixed - user', + confirmed => $dt_parser->format_datetime($dt), + lastupdate => $dt_parser->format_datetime($dt), + whensent => $dt_parser->format_datetime($dt->clone->add( minutes => 5 )), + lang => 'en-gb', + service => '', + cobrand => 'default', + cobrand_data => '', + send_questionnaire => 1, + latitude => '55.951963', + longitude => '-3.189944', + user_id => $user1->id, + } ); + my $report_id = $report->id; + ok $report, "created test report - $report_id"; + + my $alert = FixMyStreet::App->model('DB::Alert')->create( { + parameter => $report_id, + alert_type => 'new_updates', + user => $user2, + } )->confirm; + ok $alert, 'created alert for other user'; + + my $update = FixMyStreet::App->model('DB::Comment')->create( { + problem_id => $report_id, + user_id => $user3->id, + name => 'Staff User', + mark_fixed => 'false', + text => '', + state => 'confirmed', + confirmed => $dt->clone->add( hours => 9 ), + anonymous => 'f', + } ); + my $update_id = $update->id; + ok $update, "created test update from staff user - $update_id"; + + $mech->clear_emails_ok; + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + }, sub { + FixMyStreet::Script::Alerts::send(); + }; + + $mech->email_count_is(1); + my $email = $mech->get_email; + my $body = $mech->get_text_body_from_email($email); + like $body, qr/The following updates have been left on this report:/, 'email is about updates to existing report'; + like $body, qr/Staff User/, 'Update comes from correct user'; + + my @urls = $mech->get_link_from_email($email, 1); + is $urls[0], "http://www.example.org/report/" . $report_id, "Correct report URL in email"; + + $mech->delete_user($user1); + $mech->delete_user($user2); + $mech->delete_user($user3); +}; + subtest "Test signature template is used from cobrand" => sub { $mech->delete_user( 'reporter@example.com' ); $mech->delete_user( 'alerts@example.com' ); diff --git a/t/app/controller/around.t b/t/app/controller/around.t index c8aca04aa..fbb4e76cd 100644 --- a/t/app/controller/around.t +++ b/t/app/controller/around.t @@ -1,7 +1,3 @@ -use strict; -use warnings; -use Test::More; - use FixMyStreet::TestMech; my $mech = FixMyStreet::TestMech->new; diff --git a/t/app/controller/auth.t b/t/app/controller/auth.t index 3a11cfc4a..cb7d16969 100644 --- a/t/app/controller/auth.t +++ b/t/app/controller/auth.t @@ -1,7 +1,3 @@ -use strict; -use warnings; - -use Test::More; use Test::MockModule; use FixMyStreet::TestMech; @@ -9,12 +5,10 @@ my $mech = FixMyStreet::TestMech->new; my $test_email = 'test@example.com'; my $test_email2 = 'test@example.net'; +my $test_email3 = 'newuser@example.org'; my $test_password = 'foobar'; -$mech->delete_user($test_email); END { - $mech->delete_user($test_email); - $mech->delete_user($test_email2); done_testing(); } @@ -286,6 +280,94 @@ subtest "sign in but have email form autofilled" => sub { is $mech->uri->path, '/my', "redirected to correct page"; }; +$mech->log_out_ok; + +subtest "sign in with uppercase email" => sub { + $mech->get_ok('/auth'); + my $uc_test_email = uc $test_email; + $mech->submit_form_ok( + { + form_name => 'general_auth', + fields => { + email => $uc_test_email, + password_sign_in => $test_password, + }, + button => 'sign_in', + }, + "sign in with '$uc_test_email' and auto-completed name" + ); + is $mech->uri->path, '/my', "redirected to correct page"; + + $mech->content_contains($test_email); + $mech->content_lacks($uc_test_email); + + my $count = FixMyStreet::App->model('DB::User')->search( { email => $uc_test_email } )->count; + is $count, 0, "uppercase user wasn't created"; +}; + + +FixMyStreet::override_config { + SIGNUPS_DISABLED => 1, +}, sub { + subtest 'signing in with an unknown email address disallowed' => sub { + $mech->log_out_ok; + # create a new account + $mech->clear_emails_ok; + $mech->get_ok('/auth'); + $mech->submit_form_ok( + { + form_name => 'general_auth', + fields => { email => $test_email3, }, + button => 'email_sign_in', + }, + "create a new account" + ); + + ok $mech->email_count_is(0); + + my $count = FixMyStreet::App->model('DB::User')->search( { email => $test_email3 } )->count; + is $count, 0, "no user exists"; + }; + + subtest 'signing in as known email address with new password is allowed' => sub { + my $new_password = "myshinynewpassword"; + + $mech->clear_emails_ok; + $mech->get_ok('/auth'); + $mech->submit_form_ok( + { + form_name => 'general_auth', + fields => { + email => "$test_email", + password_register => $new_password, + r => 'faq', # Just as a test + }, + button => 'email_sign_in', + }, + "email_sign_in with '$test_email'" + ); -# more test: -# TODO: test that email are always lowercased + $mech->not_logged_in_ok; + + ok $mech->email_count_is(1); + my $link = $mech->get_link_from_email; + $mech->get_ok($link); + is $mech->uri->path, '/faq', "redirected to the Help page"; + + $mech->log_out_ok; + + $mech->get_ok('/auth'); + $mech->submit_form_ok( + { + form_name => 'general_auth', + fields => { + email => $test_email, + password_sign_in => $new_password, + }, + button => 'sign_in', + }, + "sign in with '$test_email' and new password" + ); + is $mech->uri->path, '/my', "redirected to correct page"; + }; +}; diff --git a/t/app/controller/auth_social.t b/t/app/controller/auth_social.t index 09fdf22d3..726d264bd 100644 --- a/t/app/controller/auth_social.t +++ b/t/app/controller/auth_social.t @@ -1,6 +1,3 @@ -use strict; -use warnings; -use Test::More; use Test::MockModule; use LWP::Protocol::PSGI; use LWP::Simple; @@ -254,6 +251,5 @@ for my $tw_state ( 'refused', 'existing UID', 'no email' ) { }; END { - $mech->delete_problems_for_body('2345'); done_testing(); } diff --git a/t/app/controller/contact.t b/t/app/controller/contact.t index 7c2769b9c..c1039d15b 100644 --- a/t/app/controller/contact.t +++ b/t/app/controller/contact.t @@ -1,7 +1,3 @@ -use strict; -use warnings; -use Test::More; - use FixMyStreet::TestMech; my $mech = FixMyStreet::TestMech->new; @@ -214,6 +210,7 @@ for my $test ( # we santise this when we submit so need to remove it delete $test->{fields}->{id} if $test->{fields}->{id} and $test->{fields}->{id} eq 'invalid'; + $test->{fields}->{'extra.phone'} = ''; is_deeply $mech->visible_form_values, $test->{fields}, 'form values'; }; } @@ -327,6 +324,7 @@ for my $test ( # we santise this when we submit so need to remove it delete $test->{fields}->{id} if $test->{fields}->{id} and $test->{fields}->{id} eq 'invalid'; + $test->{fields}->{'extra.phone'} = ''; is_deeply $mech->visible_form_values, $test->{fields}, 'form values'; if ( $test->{fields}->{dest} and $test->{fields}->{dest} eq 'update' ) { @@ -382,6 +380,41 @@ for my $test ( }; } +for my $test ( + { + fields => { + em => 'test@example.com', + name => 'A name', + subject => 'A subject', + message => 'A message', + dest => 'from_council', + success_url => '/faq', + }, + url_should_be => 'http://localhost/faq', + }, + { + fields => { + em => 'test@example.com', + name => 'A name', + subject => 'A subject', + message => 'A message', + dest => 'from_council', + success_url => 'http://www.example.com', + }, + url_should_be => 'http://www.example.com', + }, + ) +{ + subtest 'check user can be redirected to a custom URL after contact form is submitted' => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'fixmystreet' ], + }, sub { + $mech->post('/contact/submit', $test->{fields}); + is $mech->uri->as_string, $test->{url_should_be}; + } + }; +} + $problem_main->delete; done_testing(); diff --git a/t/app/controller/council.t b/t/app/controller/council.t index 11898995a..41398ae61 100644 --- a/t/app/controller/council.t +++ b/t/app/controller/council.t @@ -1,14 +1,9 @@ -use strict; -use warnings; -use Test::More; +use FixMyStreet::Test; - -use Catalyst::Test 'FixMyStreet::App'; use_ok( 'FixMyStreet::App::Controller::Council' ); TODO: { local $TODO = 'need to write some tests for this'; - } done_testing(); diff --git a/t/app/controller/dashboard.t b/t/app/controller/dashboard.t index 903affdcf..457eceade 100644 --- a/t/app/controller/dashboard.t +++ b/t/app/controller/dashboard.t @@ -1,6 +1,3 @@ -use strict; -use warnings; -use Test::More; use Test::MockTime ':all'; use FixMyStreet::TestMech; @@ -62,9 +59,8 @@ FixMyStreet::override_config { body_id => $body->id, category => $contact, email => "$contact\@example.org", - confirmed => 1, + state => 'confirmed', whenedited => DateTime->now, - deleted => 0, editor => 'test', note => 'test', } @@ -132,7 +128,7 @@ FixMyStreet::override_config { }, { desc => 'confirmed last 2 weeks with no state', - dt => $now->clone->subtract( weeks => 2 ), + dt => $now->clone->subtract( weeks => 2, hours => 1 ), counts => [1,2,4,4], report_counts => [2, 1, 1], }, @@ -535,12 +531,12 @@ FixMyStreet::override_config { desc => 'Selecting no state does nothing', p1 => { state => 'fixed - user', - conf_dt => DateTime->now(), + conf_dt => DateTime->now()->subtract( minutes => 1 ), category => 'Potholes', }, p2 => { state => 'confirmed', - conf_dt => DateTime->now(), + conf_dt => DateTime->now()->subtract( minutes => 1 ), category => 'Litter', }, state => '', @@ -549,35 +545,24 @@ FixMyStreet::override_config { }, { desc => 'limit by state works', - state => 'fixed', + state => 'fixed - council', report_counts => [2,0,0], report_counts_after => [1,0,0], }, { - desc => 'planned counted as action scheduled', - p1 => { - state => 'planned', - conf_dt => DateTime->now(), - category => 'Potholes', - }, - state => 'action scheduled', - report_counts => [3,0,0], - report_counts_after => [1,0,0], - }, - { desc => 'All fixed states count as fixed', p1 => { state => 'fixed - council', - conf_dt => DateTime->now(), + conf_dt => DateTime->now()->subtract( minutes => 1 ), category => 'Potholes', }, p2 => { state => 'fixed', - conf_dt => DateTime->now(), + conf_dt => DateTime->now()->subtract( minutes => 1 ), category => 'Potholes', }, state => 'fixed', - report_counts => [5,0,0], + report_counts => [4,0,0], report_counts_after => [3,0,0], }, ) { @@ -608,6 +593,7 @@ FixMyStreet::override_config { detail => "this report\nis split across\nseveral lines", state => "confirmed", conf_dt => DateTime->now(), + areas => 62883, } ); $mech->get_ok('/dashboard?export=1'); open my $data_handle, '<', \$mech->content; @@ -616,7 +602,37 @@ FixMyStreet::override_config { while ( my $row = $csv->getline( $data_handle ) ) { push @rows, $row; } - is scalar @rows, 7, '1 (header) + 6 (reports) = 7 lines'; + is scalar @rows, 6, '1 (header) + 5 (reports) = 6 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', + 'Nearest Postcode', + 'Ward', + 'Easting', + 'Northing', + 'Report URL', + ], + 'Column headers look correct'; + + is $rows[5]->[14], 'Bradford-on-Avon', 'Ward column is name not ID'; + + is $rows[5]->[15], '610591', 'Correct Easting conversion'; + is $rows[5]->[16], '126573', 'Correct Northing conversion'; }; }; restore_time; diff --git a/t/app/controller/index.t b/t/app/controller/index.t index 6b28a03d2..be4da6034 100644 --- a/t/app/controller/index.t +++ b/t/app/controller/index.t @@ -1,7 +1,3 @@ -use strict; -use warnings; -use Test::More; - use FixMyStreet::TestMech; my $mech = FixMyStreet::TestMech->new; @@ -75,7 +71,7 @@ ok $mech->get('/report/' . $edinburgh_problems[2]->id); is $mech->res->code, 403, 'page forbidden'; is $problem_rs->count, $num+5; -my $oxon = $mech->create_body_ok(2237, 'Oxfordshire County Council', id => 2237); +my $oxon = $mech->create_body_ok(2237, 'Oxfordshire County Council'); subtest "prefilters /around if user has categories" => sub { my $user = $mech->log_in_ok('test@example.com'); my $categories = [ @@ -92,7 +88,5 @@ subtest "prefilters /around if user has categories" => sub { }; END { - $mech->delete_problems_for_body( 2651 ); - $mech->delete_body($oxon); done_testing(); } diff --git a/t/app/controller/json.t b/t/app/controller/json.t index b2cea674f..8ee472f5d 100644 --- a/t/app/controller/json.t +++ b/t/app/controller/json.t @@ -1,8 +1,3 @@ -use strict; -use warnings; - -use Test::More; - use FixMyStreet::TestMech; my $mech = FixMyStreet::TestMech->new; @@ -116,6 +111,4 @@ is_deeply # ], "correct response"; -$mech->delete_user($user); - done_testing(); diff --git a/t/app/controller/moderate.t b/t/app/controller/moderate.t index 10287ab22..c3c77866b 100644 --- a/t/app/controller/moderate.t +++ b/t/app/controller/moderate.t @@ -1,8 +1,3 @@ -use strict; -use warnings; -use Test::More; -use utf8; - use FixMyStreet::TestMech; use FixMyStreet::App; use Data::Dumper; @@ -16,9 +11,6 @@ my $body = $mech->create_body_ok( $BROMLEY_ID, 'Bromley Council' ); my $dt = DateTime->now; my $user = $mech->create_user_ok('test-moderation@example.com', name => 'Test User'); -$user->user_body_permissions->delete_all; -$user->discard_changes; - my $user2 = $mech->create_user_ok('test-moderation2@example.com', name => 'Test User 2'); sub create_report { @@ -104,8 +96,8 @@ subtest 'Problem moderation' => sub { $mech->content_like(qr/Moderated by Bromley Council/); $report->discard_changes; - is $report->title, 'Good [...] good'; - is $report->detail, 'Good [...] good [...]improved'; + is $report->title, 'Good good'; + is $report->detail, 'Good good improved'; }; subtest 'Revert title and text' => sub { @@ -199,8 +191,8 @@ subtest 'Problem 2' => sub { $mech->base_like( qr{\Q$REPORT2_URL\E} ); $report2->discard_changes; - is $report2->title, 'Good [...] good'; - is $report2->detail, 'Good [...] good [...]improved'; + is $report2->title, 'Good good'; + is $report2->detail, 'Good good improved'; $mech->submit_form_ok({ with_fields => { %problem_prepopulated, @@ -244,7 +236,7 @@ subtest 'updates' => sub { $mech->base_like( qr{\Q$REPORT_URL\E} ); $update->discard_changes; - is $update->text, 'update good good [...] good', + is $update->text, 'update good good good', }; subtest 'Revert text' => sub { @@ -328,7 +320,7 @@ subtest 'Update 2' => sub { }}) or die $mech->content; $update2->discard_changes; - is $update2->text, 'update good good [...] good', + is $update2->text, 'update good good good', }; subtest 'Now stop being a staff user' => sub { @@ -348,11 +340,4 @@ subtest 'And do it as a superuser' => sub { $mech->content_contains('Moderated by a FixMyStreet administrator'); }; -$update->delete; -$update2->delete; -$report->moderation_original_data->delete; -$report->delete; -$report2->delete; -$mech->delete_user($user); - done_testing(); diff --git a/t/app/controller/my.t b/t/app/controller/my.t index 00070ed81..8b4a25c26 100644 --- a/t/app/controller/my.t +++ b/t/app/controller/my.t @@ -1,17 +1,17 @@ -use strict; -use warnings; - -use Test::More; - use FixMyStreet::TestMech; my $mech = FixMyStreet::TestMech->new; $mech->get_ok('/my'); is $mech->uri->path, '/auth', "got sent to the sign in page"; -$mech->create_problems_for_body(1, 1234, 'Test Title'); +$mech->get_ok('/my/anonymize'); +is $mech->uri->path, '/auth', "got sent to the sign in page"; + +my @problems = $mech->create_problems_for_body(3, 1234, 'Test Title'); +$problems[1]->update({anonymous => 1}); + my $other_user = FixMyStreet::DB->resultset('User')->find_or_create({ email => 'another@example.com' }); -$mech->create_problems_for_body(1, 1234, 'Another Title', { user => $other_user }); +my @other = $mech->create_problems_for_body(1, 1234, 'Another Title', { user => $other_user }); my $user = $mech->log_in_ok( 'test@example.com' ); $mech->get_ok('/my'); @@ -20,9 +20,46 @@ is $mech->uri->path, '/my', "stayed on '/my' page"; $mech->content_contains('Test Title'); $mech->content_lacks('Another Title'); -done_testing(); +my @update; +my $i = 0; +foreach ($user, $user, $other_user) { + $update[$i] = FixMyStreet::App->model('DB::Comment')->create({ + text => 'this is an update', + user => $_, + state => 'confirmed', + problem => $problems[0], + mark_fixed => 0, + confirmed => \'current_timestamp', + anonymous => $i % 2, + }); + $i++; +} -END { - $mech->delete_user($user); - $mech->delete_user($other_user); +foreach ( + { type => 'problem', id => 0, result => 404, desc => 'nothing' }, + { type => 'problem', obj => $problems[0], result => 200, desc => 'own report' }, + { type => 'problem', obj => $problems[1], result => 400, desc => 'already anon report' }, + { type => 'problem', obj => $other[0], result => 400, desc => 'other user report' }, + { type => 'update', id => -1, result => 400, desc => 'non-existent update' }, + { type => 'update', obj => $update[0], result => 200, desc => 'own update' }, + { type => 'update', obj => $update[1], result => 400, desc => 'already anon update' }, + { type => 'update', obj => $update[2], result => 400, desc => 'other user update' }, +) { + my $id = $_->{id} // $_->{obj}->id; + $mech->get("/my/anonymize?$_->{type}=$id"); + is $mech->res->code, $_->{result}, "Got $_->{result} fetching $_->{desc}"; + if ($_->{result} == 200) { + $mech->submit_form_ok( { button => 'hide' }, 'Submit button to hide name' ); + $_->{obj}->discard_changes; + is $_->{obj}->anonymous, 1, 'Object now made anonymous'; + $_->{obj}->update({anonymous => 0}); + } } + +$mech->get("/my/anonymize?problem=" . $problems[0]->id); +$mech->submit_form_ok( { button => 'hide_everywhere' }, 'Submit button to hide name everywhere' ); +is $problems[0]->discard_changes->anonymous, 1, 'Problem from form made anonymous'; +is $problems[2]->discard_changes->anonymous, 1, 'Other user problem made anonymous'; +is $update[0]->discard_changes->anonymous, 1, 'User update made anonymous'; + +done_testing(); diff --git a/t/app/controller/my_planned.t b/t/app/controller/my_planned.t index fa463e61e..51ea0297e 100644 --- a/t/app/controller/my_planned.t +++ b/t/app/controller/my_planned.t @@ -1,15 +1,10 @@ -use strict; -use warnings; - -use Test::More; - use FixMyStreet::TestMech; my $mech = FixMyStreet::TestMech->new; $mech->get_ok('/my/planned'); is $mech->uri->path, '/auth', "got sent to the sign in page"; -my $body = $mech->create_body_ok(2237, 'Oxfordshire'); +my $body = $mech->create_body_ok(2237, 'Oxfordshire County Council'); my ($problem) = $mech->create_problems_for_body(1, $body->id, 'Test Title'); $mech->get_ok($problem->url); @@ -39,11 +34,11 @@ $mech->get_ok('/my/planned'); $mech->content_contains('Test Title'); $mech->get_ok($problem->url); -$mech->content_contains('Shortlisted'); +$mech->text_contains('Shortlisted'); $mech->submit_form_ok({ with_fields => { 'shortlist-remove' => 1 } }); -$mech->content_contains('Shortlist'); +$mech->text_contains('Shortlist'); $mech->submit_form_ok({ with_fields => { 'shortlist-add' => 1 } }); -$mech->content_contains('Shortlisted'); +$mech->text_contains('Shortlisted'); $mech->get_ok('/my/planned?sort=shortlist&ajax=1'); $mech->content_contains('shortlist-up'); @@ -57,8 +52,29 @@ $mech->get_ok('/my/planned?ajax=1'); $mech->content_contains('shortlist-up'); $mech->content_contains('shortlist-down'); -done_testing(); +subtest "POSTing multiple problems to my/planned/change adds all to shortlist" => sub { + my ($problem1, $problem2, $problem3) = $mech->create_problems_for_body(3, $body->id, 'New Problem'); + + # Grab CSRF token + $mech->get_ok($problem1->url); + my ($csrf) = $mech->content =~ /meta content="([^"]*)" name="csrf-token"/; + + $mech->post_ok( '/my/planned/change_multiple', { + 'ids[]' => [ + $problem1->id, + $problem2->id, + $problem3->id, + ], + token => $csrf, + } + ); + + $mech->get_ok($problem1->url); + $mech->text_contains('Shortlisted'); + $mech->get_ok($problem2->url); + $mech->text_contains('Shortlisted'); + $mech->get_ok($problem3->url); + $mech->text_contains('Shortlisted'); +}; -END { - $mech->delete_user($user); -} +done_testing(); diff --git a/t/app/controller/open311.t b/t/app/controller/open311.t index 9b0a6f8af..29cd38129 100644 --- a/t/app/controller/open311.t +++ b/t/app/controller/open311.t @@ -1,8 +1,3 @@ -use strict; -use warnings; - -use Test::More; - use FixMyStreet::TestMech; my $mech = FixMyStreet::TestMech->new; diff --git a/t/app/controller/page_not_found.t b/t/app/controller/page_not_found.t index 3c2bc3c3d..30a24df09 100644 --- a/t/app/controller/page_not_found.t +++ b/t/app/controller/page_not_found.t @@ -1,11 +1,6 @@ -use strict; -use warnings; +use FixMyStreet::TestMech; -use Test::More tests => 4; - -use Test::WWW::Mechanize::Catalyst 'FixMyStreet::App'; - -my $mech = Test::WWW::Mechanize::Catalyst->new; +my $mech = FixMyStreet::TestMech->new; # homepage ok $mech->get_ok('/'); @@ -16,3 +11,5 @@ my $res = $mech->get($path_to_404); ok !$res->is_success(), "want a bad response"; is $res->code, 404, "got 404"; $mech->content_contains($path_to_404); + +done_testing(); diff --git a/t/app/controller/photo.t b/t/app/controller/photo.t index ad857b5e3..dbbc697d7 100644 --- a/t/app/controller/photo.t +++ b/t/app/controller/photo.t @@ -1,10 +1,3 @@ -use strict; -use utf8; # sign in error message has – in it -use warnings; -use feature 'say'; -use Test::More; -use utf8; - use FixMyStreet::TestMech; use FixMyStreet::App; use Web::Scraper; diff --git a/t/app/controller/questionnaire.t b/t/app/controller/questionnaire.t index f42908a3e..c6d112df7 100644 --- a/t/app/controller/questionnaire.t +++ b/t/app/controller/questionnaire.t @@ -1,6 +1,3 @@ -use strict; -use warnings; -use Test::More; use DateTime; use FixMyStreet::TestMech; @@ -8,15 +5,6 @@ use FixMyStreet::App::Controller::Questionnaire; ok( my $mech = FixMyStreet::TestMech->new, 'Created mech object' ); -# Make sure there's no outstanding questionnaire emails to be sent -FixMyStreet::App->model('DB::Questionnaire')->send_questionnaires( { - site => 'fixmystreet' -} ); -$mech->clear_emails_ok; - -# create a test user and report -$mech->delete_user('test@example.com'); - my $user = $mech->create_user_ok('test@example.com', name => 'Test User'); my $dt = DateTime->now()->subtract( weeks => 5 ); @@ -458,5 +446,4 @@ FixMyStreet::override_config { is $plain->header('Content-Type'), 'text/plain; charset="utf-8"', 'email is in right encoding'; }; -$mech->delete_user('test@example.com'); done_testing(); diff --git a/t/app/controller/report_as_other.t b/t/app/controller/report_as_other.t index 551a59481..daa213e8c 100644 --- a/t/app/controller/report_as_other.t +++ b/t/app/controller/report_as_other.t @@ -1,7 +1,3 @@ -use strict; -use warnings; -use Test::More; - use FixMyStreet::TestMech; use FixMyStreet::App; @@ -80,6 +76,20 @@ subtest "Body user, has permission to add report as another (existing) user" => push @users, $report->user; }; +subtest "Body user, has permission to add report as anonymous user" => sub { + my $report = add_report( + 'contribute_as_anonymous_user', + form_as => 'anonymous_user', + title => "Test Report", + detail => 'Test report details.', + category => 'Street lighting', + ); + is $report->name, 'Oxfordshire County Council', 'report name is body'; + is $report->user->name, 'Body User', 'user name unchanged'; + is $report->user->id, $user->id, 'user matches'; + is $report->anonymous, 1, 'report anonymous'; +}; + subtest "Body user, has permission to add update as council" => sub { my $update = add_update( 'contribute_as_body', @@ -123,12 +133,19 @@ subtest "Body user, has permission to add update as another (existing) user" => like $mech->get_text_body_from_email, qr/Your update has been logged/; }; -done_testing(); +subtest "Body user, has permission to add update as anonymous user" => sub { + my $update = add_update( + 'contribute_as_anonymous_user', + form_as => 'anonymous_user', + update => 'Test Update', + ); + is $update->name, 'Oxfordshire County Council', 'update name is body'; + is $update->user->name, 'Body User', 'user name unchanged'; + is $update->user->id, $user->id, 'user matches'; + is $update->anonymous, 1, 'update anonymous'; +}; -END { - $mech->delete_body($body); - $mech->delete_user($_) for @users; -} +done_testing(); sub start_report { my $permission = shift; diff --git a/t/app/controller/report_display.t b/t/app/controller/report_display.t index b35a4a026..4d73a5204 100644 --- a/t/app/controller/report_display.t +++ b/t/app/controller/report_display.t @@ -1,7 +1,3 @@ -use strict; -use warnings; -use Test::More; - use FixMyStreet::TestMech; use Web::Scraper; use Path::Class; @@ -10,8 +6,6 @@ use DateTime; my $mech = FixMyStreet::TestMech->new; -# create a test user and report -$mech->delete_user('test@example.com'); my $user = $mech->create_user_ok('test@example.com', name => 'Test User'); my $user2 = $mech->create_user_ok('test2@example.com', name => 'Other User'); @@ -41,11 +35,6 @@ subtest "check that no id redirects to homepage" => sub { is $mech->uri->path, '/', "at home page"; }; -subtest "test id=NNN redirects to /NNN" => sub { - $mech->get_ok("/report?id=$report_id"); - is $mech->uri->path, "/report/$report_id", "at /report/$report_id"; -}; - subtest "test bad council email clients web links" => sub { $mech->get_ok("/report/3D$report_id"); is $mech->uri->path, "/report/$report_id", "at /report/$report_id"; @@ -324,7 +313,7 @@ for my $test ( date => DateTime->now, state => 'investigating', banner_id => 'progress', - banner_text => 'progress', + banner_text => 'investigating', fixed => 0 }, { @@ -332,7 +321,7 @@ for my $test ( date => DateTime->now, state => 'action scheduled', banner_id => 'progress', - banner_text => 'progress', + banner_text => 'action scheduled', fixed => 0 }, { @@ -340,7 +329,7 @@ for my $test ( date => DateTime->now, state => 'planned', banner_id => 'progress', - banner_text => 'progress', + banner_text => 'planned', fixed => 0 }, { @@ -530,7 +519,7 @@ subtest "Zurich banners are displayed correctly" => sub { }; }; -my $oxfordshire = $mech->create_body_ok(2237, 'Oxfordshire County Council', id => 2237); +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); subtest "check user details show when a user has correct permissions" => sub { @@ -551,14 +540,14 @@ subtest "check user details show when a user has correct permissions" => sub { $mech->log_in_ok( $oxfordshireuser->email ); ok $mech->get("/report/$report_id"), "get '/report/$report_id'"; is $mech->extract_problem_meta, - 'Reported in the Roads category by Oxfordshire County Council (Council User) at 15:17, Tue 10 January 2012', + 'Reported in the Roads category by Oxfordshire County Council (Council User) at 15:17, Tue 10 January 2012 (Hide your name?)', 'correct problem meta information'; ok $oxfordshireuser->user_body_permissions->delete_all, "Remove view_body_contribute_details permissions"; ok $mech->get("/report/$report_id"), "get '/report/$report_id'"; is $mech->extract_problem_meta, - 'Reported in the Roads category by Oxfordshire County Council at 15:17, Tue 10 January 2012', + 'Reported in the Roads category by Oxfordshire County Council at 15:17, Tue 10 January 2012 (Hide your name?)', 'correct problem meta information for user without relevant permissions'; $mech->log_out_ok; @@ -578,12 +567,10 @@ subtest "check brackets don't appear when username and report name are the same" $mech->log_in_ok( $oxfordshireuser->email ); ok $mech->get("/report/$report_id"), "get '/report/$report_id'"; is $mech->extract_problem_meta, - 'Reported in the Roads category by Council User at 15:17, Tue 10 January 2012', + 'Reported in the Roads category by Council User at 15:17, Tue 10 January 2012 (Hide your name?)', 'correct problem meta information'; }; END { - $mech->delete_user('test@example.com'); - $mech->delete_body($westminster); done_testing(); } diff --git a/t/app/controller/report_import.t b/t/app/controller/report_import.t index b956b61ae..47113198e 100644 --- a/t/app/controller/report_import.t +++ b/t/app/controller/report_import.t @@ -1,7 +1,3 @@ -use strict; -use warnings; -use Test::More; - use FixMyStreet::TestMech; use FixMyStreet::App; use Web::Scraper; @@ -386,7 +382,3 @@ subtest "Submit a correct entry (with location) to cobrand" => sub { }; done_testing(); - -END { - $mech->delete_body($body); -} diff --git a/t/app/controller/report_inspect.t b/t/app/controller/report_inspect.t index 69e43ad99..5bbbdff79 100644 --- a/t/app/controller/report_inspect.t +++ b/t/app/controller/report_inspect.t @@ -1,14 +1,12 @@ -use strict; -use warnings; -use Test::More; - use FixMyStreet::TestMech; my $mech = FixMyStreet::TestMech->new; -my $brum = $mech->create_body_ok(2514, 'Birmingham City Council', id => 2514); -my $oxon = $mech->create_body_ok(2237, 'Oxfordshire County Council', id => 2237); +my $brum = $mech->create_body_ok(2514, 'Birmingham City Council'); +my $oxon = $mech->create_body_ok(2237, 'Oxfordshire County Council', { can_be_devolved => 1 } ); my $contact = $mech->create_contact_ok( body_id => $oxon->id, category => 'Cows', email => 'cows@example.net' ); +my $contact2 = $mech->create_contact_ok( body_id => $oxon->id, category => 'Sheep', email => 'SHEEP', send_method => 'Open311' ); +my $contact3 = $mech->create_contact_ok( body_id => $oxon->id, category => 'Badgers', email => 'badgers@example.net' ); my $rp = FixMyStreet::DB->resultset("ResponsePriority")->create({ body => $oxon, name => 'High Priority', @@ -17,20 +15,22 @@ FixMyStreet::DB->resultset("ContactResponsePriority")->create({ contact => $contact, response_priority => $rp, }); -my $wodc = $mech->create_body_ok(2420, 'West Oxfordshire District Council', id => 2420); +my $wodc = $mech->create_body_ok(2420, 'West Oxfordshire District Council'); $mech->create_contact_ok( body_id => $wodc->id, category => 'Horses', email => 'horses@example.net' ); -my ($report, $report2) = $mech->create_problems_for_body(2, $oxon->id, 'Test', { +my ($report, $report2, $report3) = $mech->create_problems_for_body(3, $oxon->id, 'Test', { category => 'Cows', cobrand => 'fixmystreet', areas => ',2237,2420', whensent => \'current_timestamp', latitude => 51.847693, longitude => -1.355908, }); my $report_id = $report->id; my $report2_id = $report2->id; +my $report3_id = $report3->id; my $user = $mech->log_in_ok('test@example.com'); +$user->set_extra_metadata('categories', [ $contact->id ]); $user->update( { from_body => $oxon } ); FixMyStreet::override_config { @@ -57,24 +57,44 @@ FixMyStreet::override_config { }; subtest "test basic inspect submission" => sub { - $mech->submit_form_ok({ button => 'save', with_fields => { traffic_information => 'Yes', state => 'Action Scheduled', include_update => undef } }); + $mech->submit_form_ok({ button => 'save', with_fields => { traffic_information => 'Yes', state => 'Action scheduled', include_update => undef } }); $report->discard_changes; + my $alert = FixMyStreet::App->model('DB::Alert')->find( + { user => $user, alert_type => 'new_updates', confirmed => 1, } + ); + is $report->state, 'action scheduled', 'report state changed'; is $report->get_extra_metadata('traffic_information'), 'Yes', 'report data changed'; + ok defined( $alert ) , 'sign up for alerts'; }; subtest "test inspect & instruct submission" => sub { - $report->unset_extra_metadata('inspected'); + $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_instruct' }); + $user->user_body_permissions->create({ body => $oxon, permission_type => 'planned_reports' }); $report->state('confirmed'); $report->update; - $report->inspection_log_entry->delete; my $reputation = $report->user->get_extra_metadata("reputation"); $mech->get_ok("/report/$report_id"); - $mech->submit_form_ok({ button => 'save', with_fields => { public_update => "This is a public update.", include_update => "1", state => 'action scheduled' } }); + $mech->submit_form_ok({ button => 'save', with_fields => { + public_update => "This is a public update.", include_update => "1", + state => 'action scheduled', raise_defect => 1, + } }); + $mech->get_ok("/report/$report_id"); + $mech->submit_form_ok({ with_fields => { + update => "This is a second public update, of normal update form, no actual change.", + } }); $report->discard_changes; - is $report->comments->first->text, "This is a public update.", 'Update was created'; + my $comment = ($report->comments( undef, { order_by => { -desc => 'id' } } )->all)[1]->text; + is $comment, "This is a public update.", 'Update was created'; is $report->get_extra_metadata('inspected'), 1, 'report marked as inspected'; is $report->user->get_extra_metadata('reputation'), $reputation, "User reputation wasn't changed"; + $mech->get_ok("/report/$report_id"); + my $meta = $mech->extract_update_metas; + like $meta->[0], qr/State changed to: Action scheduled/, 'First update mentions action scheduled'; + like $meta->[2], qr/Posted by .*defect raised/, 'Update mentions defect raised'; + + $user->unset_extra_metadata('categories'); + $user->update; }; subtest "test update is required when instructing" => sub { @@ -94,8 +114,9 @@ FixMyStreet::override_config { $mech->get_ok("/report/$report_id"); $mech->submit_form_ok({ button => 'save', with_fields => { latitude => 55, longitude => -2 } }); $mech->content_contains('Invalid location'); - $mech->submit_form_ok({ button => 'save', with_fields => { latitude => 51.754926, longitude => -1.256179 } }); + $mech->submit_form_ok({ button => 'save', with_fields => { latitude => 51.754926, longitude => -1.256179, include_update => undef } }); $mech->content_lacks('Invalid location'); + $user->user_body_permissions->search({ body_id => $oxon->id, permission_type => 'planned_reports' })->delete; }; subtest "test duplicate reports are shown" => sub { @@ -103,6 +124,8 @@ FixMyStreet::override_config { $report->set_extra_metadata('duplicate_of' => $report2->id); $report->state('duplicate'); $report->update; + $report2->set_extra_metadata('duplicates' => [ $report->id ]); + $report2->update; $mech->get_ok("/report/$report_id"); $mech->content_contains($report2->title); @@ -113,6 +136,8 @@ FixMyStreet::override_config { $report->unset_extra_metadata('duplicate_of'); $report->state($old_state); $report->update; + $report2->unset_extra_metadata('duplicates'); + $report2->update; }; subtest "marking a report as a duplicate with update correctly sets update status" => sub { @@ -122,13 +147,27 @@ FixMyStreet::override_config { $mech->get_ok("/report/$report_id"); $mech->submit_form_ok({ button => 'save', with_fields => { state => 'Duplicate', duplicate_of => $report2->id, public_update => "This is a duplicate.", include_update => "1" } }); $report->discard_changes; + $report2->discard_changes; is $report->state, 'duplicate', 'report marked as duplicate'; is $report->comments->search({ problem_state => 'duplicate' })->count, 1, 'update marking report as duplicate was left'; + is $report->get_extra_metadata('duplicate_of'), $report2->id; + is_deeply $report2->get_extra_metadata('duplicates'), [ $report->id ]; $report->update({ state => $old_state }); }; + subtest "changing state does not add another alert" =>sub { + $mech->get_ok("/report/$report_id"); + $mech->submit_form_ok({ button => 'save', with_fields => { state => 'Investigating', public_update => "We're investigating.", include_update => "1" } }); + + my $alert_count = FixMyStreet::App->model('DB::Alert')->search( + { user_id => $user->id, alert_type => 'new_updates', confirmed => 1, parameter => $report_id } + )->count(); + + is $alert_count, 1 , 'User has only one alert'; + }; + subtest "marking a report as a duplicate doesn't clobber user-provided update" => sub { my $old_state = $report->state; $report->comments->delete_all; @@ -151,6 +190,54 @@ FixMyStreet::override_config { $report->update({ state => $old_state }); }; + subtest "post-inspect redirect is to the right place if URL set" => sub { + $user->user_body_permissions->create({ body => $oxon, permission_type => 'planned_reports' }); + $mech->get_ok("/report/$report_id"); + my $update_text = "This text was entered as an update by the user."; + $mech->submit_form_ok({ button => 'save', with_fields => { + public_update => $update_text, + include_update => "1", + post_inspect_url => "/" + }}); + is $mech->res->code, 200, "got 200"; + is $mech->res->previous->code, 302, "got 302 for redirect"; + is $mech->uri->path, '/', 'redirected to front page'; + $user->user_body_permissions->search({ body_id => $oxon->id, permission_type => 'planned_reports' })->delete; + }; + + subtest "post-inspect redirect is to the right place if URL not set" => sub { + $user->user_body_permissions->create({ body => $oxon, permission_type => 'planned_reports' }); + $user->set_extra_metadata(categories => [ $contact->id ]); + $user->update; + $mech->get_ok("/report/$report_id"); + my $update_text = "This text was entered as an update by the user."; + $mech->submit_form_ok({ button => 'save', with_fields => { + public_update => $update_text, + include_update => "1", + post_inspect_url => "" + }}); + is $mech->res->code, 200, "got 200"; + is $mech->res->previous->code, 302, "got 302 for redirect"; + is $mech->uri->path, '/around', 'redirected to /around'; + my %params = $mech->uri->query_form; + is $params{lat}, $report->latitude, "latitude param is correct"; + is $params{lon}, $report->longitude, "longitude param is correct"; + is $params{filter_category}, $contact->category, "categories param is correct"; + $user->user_body_permissions->search({ body_id => $oxon->id, permission_type => 'planned_reports' })->delete; + }; + + subtest "default response priorities display correctly" => sub { + $mech->get_ok("/report/$report_id"); + $mech->content_contains('Priority</label', 'report priority list present'); + like $mech->content, qr/<select name="priority" id="problem_priority" class="form-control">[^<]*<option value="" selecte/s, 'blank priority option is selected'; + $mech->content_lacks('value="' . $rp->id . '" selected>High', 'non default priority not selected'); + + $rp->update({ is_default => 1}); + $mech->get_ok("/report/$report_id"); + unlike $mech->content, qr/<select name="priority" id="problem_priority" class="form-control">[^<]*<option value="" selecte/s, 'blank priority option not selected'; + $mech->content_contains('value="' . $rp->id . '" selected>High', 'default priority selected'); + }; + foreach my $test ( { type => 'report_edit_priority', priority => 1 }, { type => 'report_edit_category', category => 1 }, @@ -191,21 +278,40 @@ FixMyStreet::override_config { }; subtest "test positive reputation" => sub { + $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_instruct' }); $report->unset_extra_metadata('inspected'); $report->update; $report->inspection_log_entry->delete if $report->inspection_log_entry; my $reputation = $report->user->get_extra_metadata("reputation") || 0; $mech->get_ok("/report/$report_id"); - $mech->submit_form_ok({ button => 'save', with_fields => { state => 'action scheduled', include_update => undef } }); + $mech->submit_form_ok({ button => 'save', with_fields => { + state => 'in progress', include_update => undef, + } }); $report->discard_changes; - is $report->get_extra_metadata('inspected'), 1, 'report marked as inspected'; + is $report->get_extra_metadata('inspected'), undef, 'report not marked as inspected'; + + $mech->submit_form_ok({ button => 'save', with_fields => { + state => 'action scheduled', include_update => undef, + } }); + $report->discard_changes; + is $report->get_extra_metadata('inspected'), undef, 'report not marked as inspected'; is $report->user->get_extra_metadata('reputation'), $reputation+1, "User reputation was increased"; + + $mech->submit_form_ok({ button => 'save', with_fields => { + state => 'action scheduled', include_update => undef, + raise_defect => 1, + } }); + $report->discard_changes; + is $report->get_extra_metadata('inspected'), 1, 'report marked as inspected'; + $mech->get_ok("/report/$report_id"); + my $meta = $mech->extract_update_metas; + like $meta->[-1], qr/Updated by .*defect raised/, 'Update mentions defect raised'; }; subtest "Oxfordshire-specific traffic management options are shown" => sub { $report->update({ state => 'confirmed' }); $mech->get_ok("/report/$report_id"); - $mech->submit_form_ok({ button => 'save', with_fields => { traffic_information => 'Signs and Cones', state => 'Action Scheduled', include_update => undef } }); + $mech->submit_form_ok({ button => 'save', with_fields => { traffic_information => 'Signs and Cones', state => 'Action scheduled', include_update => undef } }); $report->discard_changes; is $report->state, 'action scheduled', 'report state changed'; is $report->get_extra_metadata('traffic_information'), 'Signs and Cones', 'report data changed'; @@ -217,6 +323,28 @@ FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'oxfordshire', 'fixmystreet' ], BASE_URL => 'http://fixmystreet.site', }, sub { + subtest "test report not resent when category changes if send_method doesn't change" => sub { + $mech->get_ok("/report/$report3_id"); + $mech->submit_form(button => 'save', with_fields => { category => 'Badgers', include_update => undef, }); + + $report3->discard_changes; + is $report3->category, "Badgers", "Report in correct category"; + isnt $report3->whensent, undef, "Report not marked as unsent"; + is $report3->bodies_str, $oxon->id, "Reported to OCC"; + }; + + subtest "test resending when send_method changes" => sub { + $mech->get_ok("/report/$report3_id"); + # Then change the category to the other category within the same council, + # which should cause it to be resent because it has a different send method + $mech->submit_form(button => 'save', with_fields => { category => 'Sheep', include_update => undef, }); + + $report3->discard_changes; + is $report3->category, "Sheep", "Report in correct category"; + is $report3->whensent, undef, "Report marked as unsent"; + is $report3->bodies_str, $oxon->id, "Reported to OCC"; + }; + subtest "test category/body changes" => sub { $mech->host('oxfordshire.fixmystreet.site'); $report->update({ state => 'confirmed' }); @@ -242,7 +370,5 @@ FixMyStreet::override_config { END { - $mech->delete_body($oxon); - $mech->delete_body($brum); done_testing(); } diff --git a/t/app/controller/report_interest_count.t b/t/app/controller/report_interest_count.t index 3cb80ea5f..04f567615 100644 --- a/t/app/controller/report_interest_count.t +++ b/t/app/controller/report_interest_count.t @@ -1,6 +1,3 @@ -use strict; -use warnings; - package FixMyStreet::Cobrand::Tester; use parent 'FixMyStreet::Cobrand::Default'; @@ -11,8 +8,6 @@ sub can_support_problems { package main; -use Test::More; - use FixMyStreet::TestMech; use Web::Scraper; use Path::Class; @@ -20,8 +15,6 @@ use DateTime; my $mech = FixMyStreet::TestMech->new; -# create a test user and report -$mech->delete_user('test@example.com'); my $user = $mech->create_user_ok('test@example.com', name => 'Test User'); my $dt = DateTime->new( @@ -133,6 +126,5 @@ subtest 'check support details not shown if not enabled in cobrand' => sub { }; END { - $mech->delete_user('test@example.com'); done_testing(); } diff --git a/t/app/controller/report_new.t b/t/app/controller/report_new.t index 71090cd26..ab6b5d78e 100644 --- a/t/app/controller/report_new.t +++ b/t/app/controller/report_new.t @@ -1,8 +1,3 @@ -use strict; -use utf8; # sign in error message has – in it -use warnings; -use Test::More; - use FixMyStreet::TestMech; use FixMyStreet::App; use Web::Scraper; @@ -41,13 +36,11 @@ for my $body ( { area_id => 2226, name => 'Gloucestershire County Council' }, { area_id => 2326, name => 'Cheltenham Borough Council' }, { area_id => 2504, name => 'Westminster City Council' }, - # The next three have fixed IDs because bits of the code rely on - # the body ID === MapIt area ID. - { area_id => 2482, name => 'Bromley Council', id => 2482 }, - { area_id => 2227, name => 'Hampshire County Council', id => 2227 }, - { area_id => 2333, name => 'Hart Council', id => 2333 }, + { area_id => 2482, name => 'Bromley Council' }, + { area_id => 2227, name => 'Hampshire County Council' }, + { area_id => 2333, name => 'Hart Council' }, ) { - my $body_obj = $mech->create_body_ok($body->{area_id}, $body->{name}, id => $body->{id}); + my $body_obj = $mech->create_body_ok($body->{area_id}, $body->{name}); push @bodies, $body_obj; $body_ids{$body->{area_id}} = $body_obj->id; } @@ -897,6 +890,32 @@ foreach my $test ( } +subtest "Test inactive categories" => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ { fixmystreet => '.' } ], + BASE_URL => 'https://www.fixmystreet.com', + MAPIT_URL => 'http://mapit.uk/', + }, sub { + # Around and New report have both categories + $mech->get_ok('/around?pc=GL50+2PR'); + $mech->content_contains('Potholes'); + $mech->content_contains('Trees'); + $mech->get_ok("/report/new?lat=$saved_lat&lon=$saved_lon"); + $mech->content_contains('Potholes'); + $mech->content_contains('Trees'); + $contact2->update( { state => 'inactive' } ); # Potholes + # But when Potholes is inactive, it's not on New report + $mech->get_ok('/around?pc=GL50+2PR'); + $mech->content_contains('Potholes'); + $mech->content_contains('Trees'); + $mech->get_ok("/report/new?lat=$saved_lat&lon=$saved_lon"); + $mech->content_lacks('Potholes'); + $mech->content_contains('Trees'); + # Change back + $contact2->update( { state => 'confirmed' } ); + }; +}; + subtest "test report creation for a category that is non public" => sub { $mech->log_out_ok; $mech->clear_emails_ok; @@ -1635,8 +1654,46 @@ subtest "extra google analytics code displayed on email confirmation problem cre }; }; -done_testing(); +subtest "inspectors get redirected directly to the report page" => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ { fixmystreet => '.' } ], + BASE_URL => 'https://www.fixmystreet.com', + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $mech->log_out_ok; -END { - $mech->delete_body($_) foreach @bodies; -} + my $user = $mech->create_user_ok('inspector@example.org', name => 'inspector', from_body => $bodies[0]); + $user->user_body_permissions->find_or_create({ + body => $bodies[0], + permission_type => 'planned_reports', + }); + + $mech->log_in_ok('inspector@example.org'); + $mech->get_ok('/'); + $mech->submit_form_ok( { with_fields => { pc => 'GL50 2PR' } }, + "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 => "Inspector report", + detail => 'Inspector report details.', + photo1 => '', + name => 'Joe Bloggs', + may_show_name => '1', + phone => '07903 123 456', + category => 'Trees', + } + }, + "submit good details" + ); + + like $mech->uri->path, qr/\/report\/[0-9]+/, 'Redirects directly to report'; + } +}; + +done_testing(); diff --git a/t/app/controller/report_new_mobile.t b/t/app/controller/report_new_mobile.t index 3dfb99b2f..296007ce3 100644 --- a/t/app/controller/report_new_mobile.t +++ b/t/app/controller/report_new_mobile.t @@ -1,4 +1,3 @@ -use Test::More; use FixMyStreet::TestMech; use LWP::Protocol::PSGI; use t::Mock::MapItZurich; @@ -37,6 +36,5 @@ subtest "Check signed up for alert when logged in" => sub { }; END { - $mech->delete_user('user@example.org'); done_testing(); } diff --git a/t/app/controller/report_new_open311.t b/t/app/controller/report_new_open311.t index e3a464f88..9a4a81182 100644 --- a/t/app/controller/report_new_open311.t +++ b/t/app/controller/report_new_open311.t @@ -1,7 +1,3 @@ -use strict; -use warnings; -use Test::More; - use FixMyStreet::TestMech; use FixMyStreet::App; use Web::Scraper; @@ -176,7 +172,3 @@ foreach my $test ( } done_testing(); - -END { - $mech->delete_body($body); -} diff --git a/t/app/controller/report_updates.t b/t/app/controller/report_updates.t index de153978b..0526b2fd7 100644 --- a/t/app/controller/report_updates.t +++ b/t/app/controller/report_updates.t @@ -1,7 +1,3 @@ -use strict; -use warnings; -use Test::More; - use FixMyStreet::TestMech; use Web::Scraper; use Path::Class; @@ -9,10 +5,6 @@ use DateTime; my $mech = FixMyStreet::TestMech->new; -# create a test user and report -$mech->delete_user('commenter@example.com'); -$mech->delete_user('test@example.com'); - my $user = $mech->create_user_ok('test@example.com', name => 'Test User'); my $user2 = $mech->create_user_ok('commenter@example.com', name => 'Commenter'); @@ -101,8 +93,7 @@ for my $test ( anonymous => 't', mark_fixed => 'true', mark_open => 'false', - meta => -'Posted anonymously at 15:47, Sat 16 April 2011, marked as fixed', + meta => [ 'State changed to: Fixed', 'Posted anonymously at 15:47, Sat 16 April 2011' ] }, { description => 'named user, anon is true, reopened', @@ -110,7 +101,7 @@ for my $test ( anonymous => 't', mark_fixed => 'false', mark_open => 'true', - meta => 'Posted anonymously at 15:47, Sat 16 April 2011, reopened', + meta => [ 'State changed to: Open', 'Posted anonymously at 15:47, Sat 16 April 2011' ] } ) { @@ -126,20 +117,21 @@ for my $test ( $mech->content_contains('This is some update text'); my $meta = $mech->extract_update_metas; - is scalar @$meta, 1, 'number of updates'; - is $meta->[0], $test->{meta}; + my $test_meta = ref $test->{meta} ? $test->{meta} : [ $test->{meta} ]; + is scalar @$meta, scalar @$test_meta, 'number of updates'; + is_deeply $meta, $test_meta; }; } subtest "updates displayed on report with empty bodies_str" => sub { my $old_bodies_str = $report->bodies_str; $report->update({ bodies_str => undef }); - $comment->update({ problem_state => 'fixed' , mark_open => 'false', mark_fixed => 'false' }); + $comment->update({ problem_state => 'fixed - user' , mark_open => 'false', mark_fixed => 'false' }); $mech->get_ok("/report/$report_id"); my $meta = $mech->extract_update_metas; - is scalar @$meta, 1, 'update displayed'; + is scalar @$meta, 2, 'update displayed'; $report->update({ bodies_str => $old_bodies_str }); }; @@ -193,10 +185,11 @@ subtest "several updates shown in correct order" => sub { $mech->get_ok("/report/$report_id"); my $meta = $mech->extract_update_metas; - is scalar @$meta, 3, 'number of updates'; + is scalar @$meta, 4, '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], 'Posted anonymously at 08:12, Tue 15 March 2011, marked as fixed', 'third 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'; }; for my $test ( @@ -587,9 +580,10 @@ for my $test ( name => $user->name, may_show_name => 1, update => 'Set state to fixed', - state => 'fixed', + state => 'fixed - council', }, state => 'fixed - council', + meta => 'fixed', }, { desc => 'from authority user marks report as action scheduled', @@ -620,7 +614,6 @@ for my $test ( state => 'internal referral', }, state => 'internal referral', - meta => "an internal referral", }, { desc => 'from authority user marks report as not responsible', @@ -642,7 +635,6 @@ for my $test ( state => 'duplicate', }, state => 'duplicate', - meta => 'a duplicate report', }, { desc => 'from authority user marks report as internal referral', @@ -653,7 +645,6 @@ for my $test ( state => 'internal referral', }, state => 'internal referral', - meta => 'an internal referral', }, { desc => 'from authority user marks report sent to two councils as fixed', @@ -661,9 +652,10 @@ for my $test ( name => $user->name, may_show_name => 1, update => 'Set state to fixed', - state => 'fixed', + state => 'fixed - council', }, state => 'fixed - council', + meta => 'fixed', report_bodies => $body->id . ',2505', }, { @@ -672,9 +664,10 @@ for my $test ( name => $user->name, may_show_name => 1, update => 'Set state to fixed', - state => 'fixed', + state => 'fixed - council', }, state => 'fixed - council', + meta => 'fixed', report_bodies => $body->id . ',2505', view_username => 1 }, @@ -716,19 +709,13 @@ for my $test ( my $update_meta = $mech->extract_update_metas; my $meta_state = $test->{meta} || $test->{fields}->{state}; - if ( $test->{reopened} ) { - like $update_meta->[0], qr/reopened$/, 'update meta says reopened'; - } elsif ( $test->{state} eq 'duplicate' ) { - like $update_meta->[0], qr/closed as $meta_state$/, 'update meta includes state change'; - } else { - like $update_meta->[0], qr/marked as $meta_state$/, 'update meta includes state change'; - } + like $update_meta->[0], qr/$meta_state/i, 'update meta includes state change'; if ($test->{view_username}) { - like $update_meta->[0], qr{Westminster City Council \(Test User\)}, 'update meta includes council and user name'; + like $update_meta->[1], qr{Westminster City Council \(Test User\)}, 'update meta includes council and user name'; $user->user_body_permissions->delete_all; } else { - like $update_meta->[0], qr{Westminster City Council}, 'update meta includes council name'; + like $update_meta->[1], qr{Westminster City Council}, 'update meta includes council name'; $mech->content_contains( '<strong>Westminster City Council</strong>', 'council name in bold'); } @@ -756,24 +743,22 @@ subtest 'check meta correct for comments marked confirmed but not marked open' = $mech->get_ok( "/report/" . $report->id ); my $update_meta = $mech->extract_update_metas; - unlike $update_meta->[0], qr/reopened$/, + unlike $update_meta->[0], qr/Open/, 'update meta does not say reopened'; $comment->update( { mark_open => 1, problem_state => undef } ); $mech->get_ok( "/report/" . $report->id ); $update_meta = $mech->extract_update_metas; - unlike $update_meta->[0], qr/marked as open$/, - 'update meta does not says marked as open'; - like $update_meta->[0], qr/reopened$/, 'update meta does say reopened'; + like $update_meta->[0], qr/Open/, 'update meta does say open'; $comment->update( { mark_open => 0, problem_state => undef } ); $mech->get_ok( "/report/" . $report->id ); $update_meta = $mech->extract_update_metas; - unlike $update_meta->[0], qr/marked as open$/, + unlike $update_meta->[0], qr/Open/, 'update meta does not says marked as open'; - unlike $update_meta->[0], qr/reopened$/, 'update meta does not say reopened'; + unlike $update_meta->[0], qr/Open/, 'update meta does not say reopened'; }; subtest "check first comment with no status change has no status in meta" => sub { @@ -787,7 +772,7 @@ subtest "check first comment with no status change has no status in meta" => sub $mech->get_ok("/report/$report_id"); my $update_meta = $mech->extract_update_metas; - unlike $update_meta->[0], qr/marked as|reopened/, 'update meta does not include state change'; + unlike $update_meta->[0], qr/State changed to/, 'update meta does not include state change'; }; subtest "check comment with no status change has not status in meta" => sub { @@ -817,7 +802,7 @@ subtest "check comment with no status change has not status in meta" => sub { $mech->get_ok("/report/$report_id"); $report->discard_changes; - my @updates = $report->comments->all; + my @updates = $report->comments->search(undef, { order_by => ['created', 'id'] })->all; is scalar @updates, 2, 'correct number of updates'; my $update = pop @updates; @@ -825,7 +810,7 @@ subtest "check comment with no status change has not status in meta" => sub { is $report->state, 'fixed - council', 'correct report state'; is $update->problem_state, 'fixed - council', 'correct update state'; my $update_meta = $mech->extract_update_metas; - unlike $update_meta->[1], qr/marked as/, 'update meta does not include state change'; + unlike $update_meta->[1], qr/State changed to/, 'update meta does not include state change'; $user->from_body( $body->id ); $user->update; @@ -850,7 +835,7 @@ subtest "check comment with no status change has not status in meta" => sub { $mech->get_ok("/report/$report_id"); $report->discard_changes; - @updates = $report->comments->search(undef, { order_by => 'created' })->all;; + @updates = $report->comments->search(undef, { order_by => ['created', 'id'] })->all; is scalar @updates, 3, 'correct number of updates'; @@ -859,9 +844,9 @@ subtest "check comment with no status change has not status in meta" => sub { is $report->state, 'investigating', 'correct report state'; is $update->problem_state, 'investigating', 'correct update state'; $update_meta = $mech->extract_update_metas; - like $update_meta->[0], qr/marked as fixed/, 'first update meta says fixed'; - unlike $update_meta->[1], qr/marked as/, 'second update meta does not include state change'; - like $update_meta->[2], qr/marked as investigating/, 'third update meta says investigating'; + like $update_meta->[0], qr/fixed/i, 'first update meta says fixed'; + unlike $update_meta->[2], qr/State changed to/, 'second update meta does not include state change'; + like $update_meta->[3], qr/investigating/i, 'third update meta says investigating'; my $dt = DateTime->now( time_zone => "local" )->add( seconds => 1 ); $comment = FixMyStreet::App->model('DB::Comment')->find_or_create( @@ -880,7 +865,7 @@ subtest "check comment with no status change has not status in meta" => sub { $mech->get_ok("/report/$report_id"); $report->discard_changes; - @updates = $report->comments->search(undef, { order_by => 'created' })->all;; + @updates = $report->comments->search(undef, { order_by => ['created', 'id'] })->all;; is scalar @updates, 4, 'correct number of updates'; $update = pop @updates; @@ -888,10 +873,10 @@ subtest "check comment with no status change has not status in meta" => sub { is $report->state, 'investigating', 'correct report state'; is $update->problem_state, undef, 'no update state'; $update_meta = $mech->extract_update_metas; - like $update_meta->[0], qr/marked as fixed/, 'first update meta says fixed'; - unlike $update_meta->[1], qr/marked as/, 'second update meta does not include state change'; - like $update_meta->[2], qr/marked as investigating/, 'third update meta says investigating'; - unlike $update_meta->[3], qr/marked as/, 'fourth update meta has no state change'; + like $update_meta->[0], qr/fixed/i, 'first update meta says fixed'; + unlike $update_meta->[2], qr/State changed to/, 'second update meta does not include state change'; + like $update_meta->[3], qr/investigating/i, 'third update meta says investigating'; + unlike $update_meta->[5], qr/State changed to/, 'fourth update meta has no state change'; }; subtest 'check meta correct for second comment marking as reopened' => sub { @@ -912,7 +897,7 @@ subtest 'check meta correct for second comment marking as reopened' => sub { $mech->get_ok( "/report/" . $report->id ); my $update_meta = $mech->extract_update_metas; - like $update_meta->[0], qr/fixed$/, 'update meta says fixed'; + like $update_meta->[0], qr/fixed/i, 'update meta says fixed'; $comment = FixMyStreet::App->model('DB::Comment')->create( { @@ -930,9 +915,51 @@ subtest 'check meta correct for second comment marking as reopened' => sub { $mech->get_ok( "/report/" . $report->id ); $update_meta = $mech->extract_update_metas; - like $update_meta->[1], qr/reopened$/, 'update meta says reopened'; + like $update_meta->[2], qr/Open/, 'update meta says reopened'; +}; + +subtest "check first comment with status change but no text is displayed" => sub { + $user->from_body( $body->id ); + $user->update; + + $report->comments->delete; + + my $comment = FixMyStreet::App->model('DB::Comment')->create( + { + user => $user, + name => $user->from_body->name, + problem_id => $report->id, + text => '', + confirmed => DateTime->now( time_zone => 'local'), + problem_state => 'investigating', + anonymous => 0, + mark_open => 0, + mark_fixed => 0, + state => 'confirmed', + } + ); + $mech->log_in_ok( $user->email ); + + $mech->get_ok("/report/$report_id"); + + my $update_meta = $mech->extract_update_metas; + like $update_meta->[1], qr/Updated by/, 'updated by meta if no text'; + unlike $update_meta->[1], qr/Test User/, 'commenter name not included'; + like $update_meta->[0], qr/investigating/i, 'update meta includes state change'; + + ok $user->user_body_permissions->create({ + body => $body, + permission_type => 'view_body_contribute_details' + }), 'Give user view_body_contribute_details permissions'; + + $mech->get_ok("/report/$report_id"); + $update_meta = $mech->extract_update_metas; + like $update_meta->[1], qr/Updated by/, 'updated by meta if no text'; + like $update_meta->[1], qr/Test User/, 'commenter name included if user has view contribute permission'; + like $update_meta->[0], qr/investigating/i, 'update meta includes state change'; }; + $user->from_body(undef); $user->update; @@ -1662,23 +1689,23 @@ for my $test ( }, { desc => 'update fixed without marking as open leaves state unchanged', - initial_state => 'fixed', + initial_state => 'fixed - user', expected_form_fields => { reopen => undef, }, submitted_form_fields => { reopen => 0, }, - end_state => 'fixed', + end_state => 'fixed - user', }, { desc => 'update unable to fix without marking as fixed leaves state unchanged', initial_state => 'unable to fix', expected_form_fields => { - fixed => undef, + reopen => undef, }, submitted_form_fields => { - fixed => 0, + reopen => 0, }, end_state => 'unable to fix', }, @@ -1686,10 +1713,10 @@ for my $test ( desc => 'update internal referral without marking as fixed leaves state unchanged', initial_state => 'internal referral', expected_form_fields => { - fixed => undef, + reopen => undef, }, submitted_form_fields => { - fixed => 0, + reopen => 0, }, end_state => 'internal referral', }, @@ -1697,10 +1724,10 @@ for my $test ( desc => 'update not responsible without marking as fixed leaves state unchanged', initial_state => 'not responsible', expected_form_fields => { - fixed => undef, + reopen => undef, }, submitted_form_fields => { - fixed => 0, + reopen => 0, }, end_state => 'not responsible', }, @@ -1708,10 +1735,10 @@ for my $test ( desc => 'update duplicate without marking as fixed leaves state unchanged', initial_state => 'duplicate', expected_form_fields => { - fixed => undef, + reopen => undef, }, submitted_form_fields => { - fixed => 0, + reopen => 0, }, end_state => 'duplicate', }, @@ -1761,7 +1788,7 @@ for my $test ( }, { desc => 'cannot mark fixed as fixed, can mark as not fixed', - initial_state => 'fixed', + initial_state => 'fixed - user', expected_form_fields => { reopen => undef, }, @@ -1771,48 +1798,48 @@ for my $test ( end_state => 'confirmed', }, { - desc => 'can mark unable to fix as fixed, cannot mark not closed', + desc => 'cannot mark unable to fix as fixed, can reopen', initial_state => 'unable to fix', expected_form_fields => { - fixed => undef, + reopen => undef, }, submitted_form_fields => { - fixed => 1, + reopen => 1, }, - end_state => 'fixed - user', + end_state => 'confirmed', }, { - desc => 'can mark internal referral as fixed, cannot mark not closed', + desc => 'cannot mark internal referral as fixed, can reopen', initial_state => 'internal referral', expected_form_fields => { - fixed => undef, + reopen => undef, }, submitted_form_fields => { - fixed => 1, + reopen => 1, }, - end_state => 'fixed - user', + end_state => 'confirmed', }, { - desc => 'can mark not responsible as fixed, cannot mark not closed', + desc => 'cannot mark not responsible as fixed, can reopen', initial_state => 'not responsible', expected_form_fields => { - fixed => undef, + reopen => undef, }, submitted_form_fields => { - fixed => 1, + reopen => 1, }, - end_state => 'fixed - user', + end_state => 'confirmed', }, { - desc => 'can mark duplicate as fixed, cannot mark not closed', + desc => 'cannot mark duplicate as fixed, can reopen', initial_state => 'duplicate', expected_form_fields => { - fixed => undef, + reopen => undef, }, submitted_form_fields => { - fixed => 1, + reopen => 1, }, - end_state => 'fixed - user', + end_state => 'confirmed', }, ) { subtest $test->{desc} => sub { @@ -1884,7 +1911,4 @@ subtest 'check cannot answer other user\'s creator fixed questionnaire' => sub { $mech->content_contains( "I'm afraid we couldn't locate your problem in the database." ) }; -ok $comment->delete, 'deleted comment'; -$mech->delete_user('commenter@example.com'); -$mech->delete_user('test@example.com'); done_testing(); diff --git a/t/app/controller/reports.t b/t/app/controller/reports.t index a21d3ad65..f3958a0a5 100644 --- a/t/app/controller/reports.t +++ b/t/app/controller/reports.t @@ -1,26 +1,39 @@ -use strict; -use warnings; -use Test::More; +use Test::MockTime qw(:all); use FixMyStreet::TestMech; use mySociety::MaPit; use FixMyStreet::App; +use FixMyStreet::Script::UpdateAllReports; use DateTime; +set_absolute_time('2017-07-07T16:00:00'); +END { + restore_time; +} + ok( my $mech = FixMyStreet::TestMech->new, 'Created mech object' ); +# Run the cron script with empty database +FixMyStreet::Script::UpdateAllReports::generate_dashboard(); + $mech->create_body_ok(2514, 'Birmingham City Council'); my $body_edin_id = $mech->create_body_ok(2651, 'City of Edinburgh Council')->id; my $body_west_id = $mech->create_body_ok(2504, 'Westminster City Council')->id; my $body_fife_id = $mech->create_body_ok(2649, 'Fife Council')->id; my $body_slash_id = $mech->create_body_ok(10000, 'Electricity/Gas Council')->id; -$mech->delete_problems_for_body( $body_west_id ); -$mech->delete_problems_for_body( $body_edin_id ); -$mech->delete_problems_for_body( $body_fife_id ); +my @edinburgh_problems = $mech->create_problems_for_body(3, $body_edin_id, 'All reports', { category => 'Potholes' }); +my @westminster_problems = $mech->create_problems_for_body(5, $body_west_id, 'All reports', { category => 'Graffiti' }); +my @fife_problems = $mech->create_problems_for_body(15, $body_fife_id, 'All reports', { category => 'Flytipping' }); + +my $west_trans = FixMyStreet::DB->resultset('Translation')->find_or_create({ + tbl => 'body', + object_id => $body_west_id, + col => 'name', + lang => 'de', + msgstr => 'De Westminster' +}); -my @edinburgh_problems = $mech->create_problems_for_body(3, $body_edin_id, 'All reports'); -my @westminster_problems = $mech->create_problems_for_body(5, $body_west_id, 'All reports'); -my @fife_problems = $mech->create_problems_for_body(15, $body_fife_id, 'All reports'); +ok $west_trans, 'created westminster translation'; is scalar @westminster_problems, 5, 'correct number of westminster problems created'; is scalar @edinburgh_problems, 3, 'correct number of edinburgh problems created'; @@ -86,30 +99,21 @@ $fife_problems[10]->update( { }); # Run the cron script that makes the data for /reports so we don't get an error. -system( "bin/update-all-reports" ); +FixMyStreet::Script::UpdateAllReports::generate_dashboard(); # check that we can get the page $mech->get_ok('/reports'); -$mech->title_like(qr{Summary reports}); +$mech->title_like(qr{Dashboard}); $mech->content_contains('Birmingham'); -my $stats = $mech->extract_report_stats; - -is $stats->{'City of Edinburgh Council'}->[1], 2, 'correct number of new reports for Edinburgh'; -is $stats->{'City of Edinburgh Council'}->[2], 1, 'correct number of older reports for Edinburgh'; - -is $stats->{'Westminster City Council'}->[1], 5, 'correct number of reports for Westminster'; - -is $stats->{'Fife Council'}->[1], 5, 'correct number of new reports for Fife'; -is $stats->{'Fife Council'}->[2], 4, 'correct number of old reports for Fife'; -is $stats->{'Fife Council'}->[3], 1, 'correct number of unknown reports for Fife'; -is $stats->{'Fife Council'}->[4], 3, 'correct number of fixed reports for Fife'; -is $stats->{'Fife Council'}->[5], 1, 'correct number of older fixed reports for Fife'; +$mech->content_contains('"Apr","May","Jun","Jul"'); +$mech->content_contains('5,9,10,22'); +$mech->content_contains('2,3,4,4'); FixMyStreet::override_config { MAPIT_URL => 'http://mapit.uk/', }, sub { - $mech->follow_link_ok( { text_regex => qr/Birmingham/ } ); + $mech->submit_form_ok( { with_fields => { body => $body_edin_id } }, 'Submitted dropdown okay' ); $mech->get_ok('/reports/Westminster'); }; @@ -124,54 +128,44 @@ FixMyStreet::override_config { MAPIT_URL => 'http://mapit.uk/', }, sub { $mech->get_ok('/reports'); - $mech->follow_link_ok({ url_regex => qr{/reports/Electricity_Gas\+Council} }); + $mech->submit_form_ok({ with_fields => { body => $body_slash_id } }, 'Submitted dropdown okay'); is $mech->uri->path, '/reports/Electricity_Gas+Council', 'Path is correct'; - $mech->get_ok('/reports/City+of+Edinburgh?t=new'); + $mech->get_ok('/reports/City+of+Edinburgh?status=open'); }; $problems = $mech->extract_problem_list; -is scalar @$problems, 2, 'correct number of new problems displayed'; +is scalar @$problems, 3, 'correct number of open problems displayed'; FixMyStreet::override_config { MAPIT_URL => 'http://mapit.uk/', }, sub { - $mech->get_ok('/reports/City+of+Edinburgh?t=older'); + $mech->get_ok('/reports/City+of+Edinburgh?status=closed'); }; $problems = $mech->extract_problem_list; -is scalar @$problems, 1, 'correct number of older problems displayed'; +is scalar @$problems, 0, 'correct number of closed problems displayed'; for my $test ( { - desc => 'new fife problems on report page', - type => 'new', - expected => 5 + desc => 'open fife problems on report page', + type => 'open', + expected => 10 }, { - desc => 'older fife problems on report page', - type => 'older', - expected => 4 - }, - { - desc => 'unknown fife problems on report page', - type => 'unknown', - expected => 1 + desc => 'closed fife problems on report page', + type => 'closed', + expected => 0 }, { desc => 'fixed fife problems on report page', type => 'fixed', - expected => 3 - }, - { - desc => 'older_fixed fife problems on report page', - type => 'older_fixed', - expected => 1 + expected => 4 }, ) { subtest $test->{desc} => sub { FixMyStreet::override_config { MAPIT_URL => 'http://mapit.uk/', }, sub { - $mech->get_ok('/reports/Fife+Council?t=' . $test->{type}); + $mech->get_ok('/reports/Fife+Council?status=' . $test->{type}); }; $problems = $mech->extract_problem_list; @@ -192,14 +186,14 @@ is scalar @$problems, 4, 'only public problems are displayed'; $mech->content_lacks('All reports Test 3 for ' . $body_west_id, 'non public problem is not visible'); +# No change to numbers if report is non-public $mech->get_ok('/reports'); -$stats = $mech->extract_report_stats; -is $stats->{'Westminster City Council'}->[1], 5, 'non public reports included in stats'; +$mech->content_contains('"Apr","May","Jun","Jul"'); +$mech->content_contains('5,9,10,22'); subtest "test fiksgatami all reports page" => sub { FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'fiksgatami' ], - MAPIT_URL => 'http://mapit.nuug.no/', }, sub { $mech->create_body_ok(3, 'Oslo'); ok $mech->host("fiksgatami.no"), 'change host to fiksgatami'; @@ -220,7 +214,7 @@ subtest "test greenwich all reports page" => sub { body_id => $body->id, category => 'Deleted', email => 'deleted@example.com', - deleted => 1 + state => 'deleted', ); ok $mech->host("greenwich.fixmystreet.com"), 'change host to greenwich'; $mech->get_ok('/reports/Royal+Borough+of+Greenwich'); @@ -283,4 +277,92 @@ subtest "it lists shortlisted reports" => sub { }; }; +subtest "it allows body users to filter by subtypes" => sub { + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/' + }, sub { + my $body = FixMyStreet::App->model('DB::Body')->find( $body_edin_id ); + my $user = $mech->log_in_ok( 'test@example.com' ); + $user->update({ from_body => $body }); + + my ($investigating_problem) = $mech->create_problems_for_body(1, $body_edin_id, 'Investigating report'); + my ($scheduled_problem) = $mech->create_problems_for_body(1, $body_edin_id, 'A Scheduled report'); + my ($in_progress_problem) = $mech->create_problems_for_body(1, $body_edin_id, 'In progress report'); + + $investigating_problem->update({ state => 'investigating' }); + $scheduled_problem->update({ state => 'action scheduled' }); + $in_progress_problem->update({ state => 'in progress' }); + + $mech->get_ok('/reports/City+of+Edinburgh+Council'); + $mech->content_contains('<option value="investigating">Investigating</option>'); + $mech->content_contains('<option value="in progress">In progress</option>'); + $mech->content_contains('<option value="action scheduled">Action scheduled</option>'); + $mech->content_contains('<option value="unable to fix">No further action</option>'); + $mech->content_contains('<option value="not responsible">Not responsible</option>'); + $mech->content_contains('<option value="internal referral">Internal referral</option>'); + $mech->content_contains('<option value="duplicate">Duplicate</option>'); + + $mech->get_ok('/reports/City+of+Edinburgh+Council?status=investigating'); + + $in_progress_problem->discard_changes(); + + $mech->content_contains('Investigating report'); + $mech->content_lacks('In progress report'); + $mech->content_lacks('A Scheduled report'); + + $mech->get_ok('/reports/City+of+Edinburgh+Council?status=in progress'); + + $mech->content_lacks('Investigating report'); + $mech->content_contains('In progress report'); + $mech->content_lacks('A Scheduled report'); + }; +}; + +subtest "it does not allow non body users to filter by subtypes" => sub { + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/' + }, sub { + my $user = $mech->log_in_ok( 'test@example.com' ); + $user->update({ from_body => undef }); + + $mech->get_ok('/reports/City+of+Edinburgh+Council'); + $mech->content_lacks('<option value="investigating">Investigating</option>'); + $mech->content_lacks('<option value="in progress">In progress</option>'); + $mech->content_lacks('<option value="action scheduled">Action scheduled</option>'); + $mech->content_lacks('<option value="unable to fix">No further action</option>'); + $mech->content_lacks('<option value="not responsible">Not responsible</option>'); + $mech->content_lacks('<option value="internal referral">Internal referral</option>'); + $mech->content_lacks('<option value="duplicate">Duplicate</option>'); + }; +}; + +subtest "it does not allow body users to filter subcategories for other bodies" => sub { + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/' + }, sub { + my $body = FixMyStreet::App->model('DB::Body')->find( $body_west_id ); + my $user = $mech->log_in_ok( 'test@example.com' ); + $user->update({ from_body => $body }); + + $mech->get_ok('/reports/City+of+Edinburgh+Council'); + + $mech->content_lacks('<option value="investigating">Investigating</option>'); + $mech->content_lacks('<option value="in progress">In progress</option>'); + $mech->content_lacks('<option value="action scheduled">Action scheduled</option>'); + $mech->content_lacks('<option value="unable to fix">No further action</option>'); + $mech->content_lacks('<option value="not responsible">Not responsible</option>'); + $mech->content_lacks('<option value="internal referral">Internal referral</option>'); + $mech->content_lacks('<option value="duplicate">Duplicate</option>'); + }; +}; + +subtest "can use translated body name" => sub { + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $mech->get_ok('/reports/De Westminster'); + $mech->title_like(qr/Westminster City Council/); + }; +}; + done_testing(); diff --git a/t/app/controller/root.t b/t/app/controller/root.t new file mode 100644 index 000000000..ddf659b77 --- /dev/null +++ b/t/app/controller/root.t @@ -0,0 +1,76 @@ +use FixMyStreet::TestMech; + +ok( my $mech = FixMyStreet::TestMech->new, 'Created mech object' ); + +my @urls = ( + "/", + "/contact", + "/about/faq", + "/around?longitude=-1.351488&latitude=51.847235" +); + + +FixMyStreet::override_config { + LOGIN_REQUIRED => 0, + MAPIT_URL => 'http://mapit.uk/' +}, sub { + subtest 'LOGIN_REQUIRED = 0 behaves correctly' => sub { + foreach my $url (@urls) { + $mech->get_ok($url); + is $mech->res->code, 200, "got 200 for page"; + is $mech->res->previous, undef, 'No redirect'; + } + }; +}; + + +FixMyStreet::override_config { + LOGIN_REQUIRED => 1, + MAPIT_URL => 'http://mapit.uk/' +}, sub { + subtest 'LOGIN_REQUIRED = 1 redirects to /auth if not logged in' => sub { + foreach my $url (@urls) { + $mech->get_ok($url); + is $mech->res->code, 200, "got 200 for final destination"; + is $mech->res->previous->code, 302, "got 302 for redirect"; + is $mech->uri->path, '/auth'; + } + }; + + subtest 'LOGIN_REQUIRED = 1 does not redirect if logged in' => sub { + $mech->log_in_ok('user@example.org'); + foreach my $url (@urls) { + $mech->get_ok($url); + is $mech->res->code, 200, "got 200 for final destination"; + is $mech->res->previous, undef, 'No redirect'; + } + $mech->log_out_ok; + }; + + subtest 'LOGIN_REQUIRED = 1 allows whitelisted URLs' => sub { + my @whitelist = ( + '/auth', + '/js/translation_strings.en-gb.js' + ); + + foreach my $url (@whitelist) { + $mech->get_ok($url); + is $mech->res->code, 200, "got 200 for final destination"; + is $mech->res->previous, undef, 'No redirect'; + } + }; + + subtest 'LOGIN_REQUIRED = 1 404s blacklisted URLs' => sub { + my @blacklist = ( + '/offline/appcache', + ); + + foreach my $url (@blacklist) { + $mech->get($url); + ok !$mech->res->is_success(), "want a bad response"; + is $mech->res->code, 404, "got 404"; + } + }; +}; + +done_testing(); diff --git a/t/app/controller/rss.t b/t/app/controller/rss.t index bec504760..5ec7bfae7 100644 --- a/t/app/controller/rss.t +++ b/t/app/controller/rss.t @@ -1,7 +1,3 @@ -use strict; -use warnings; -use Test::More; - use FixMyStreet::TestMech; use FixMyStreet::App; @@ -197,6 +193,4 @@ subtest "check RSS feeds on cobrand have correct URLs for non-cobrand reports" = $mech->content_contains($expected2, 'cobrand area report point to cobrand url'); }; -$mech->delete_user( $user1 ); - done_testing(); diff --git a/t/app/controller/templates/about/homepage.html b/t/app/controller/templates/about/homepage.html new file mode 100644 index 000000000..c8d5c1eb3 --- /dev/null +++ b/t/app/controller/templates/about/homepage.html @@ -0,0 +1,3 @@ +<p> + THIS IS A STATIC FRONT PAGE. +</p> diff --git a/t/app/controller/token.t b/t/app/controller/token.t index ac88f4f7a..858838865 100644 --- a/t/app/controller/token.t +++ b/t/app/controller/token.t @@ -1,8 +1,3 @@ -use strict; -use warnings; -use Test::More; -use utf8; - use FixMyStreet::TestMech; use FixMyStreet::App; |