From 2f8e3f7b86650d2b05b346615ac9f5fb7e8dcdb5 Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Thu, 25 Jan 2018 19:40:24 +0000 Subject: Split up admin test file into many separate files. --- t/app/controller/admin.t | 1696 +--------------------------- t/app/controller/admin/bodies.t | 165 +++ t/app/controller/admin/defecttypes.t | 193 ++++ t/app/controller/admin/permissions.t | 196 ++++ t/app/controller/admin/priorities.t | 102 ++ t/app/controller/admin/report_edit.t | 556 +++++++++ t/app/controller/admin/reportextrafields.t | 316 ++++++ t/app/controller/admin/search.t | 121 ++ t/app/controller/admin/states.t | 24 + t/app/controller/admin/stats.t | 12 + t/app/controller/admin/templates.t | 183 +++ t/app/controller/admin/translations.t | 191 ++++ t/app/controller/admin/update_edit.t | 383 +++++++ t/app/controller/admin/users.t | 413 +++++++ t/app/controller/admin_defecttypes.t | 193 ---- t/app/controller/admin_permissions.t | 196 ---- t/app/controller/admin_reportextrafields.t | 316 ------ t/app/controller/admin_states.t | 24 - t/app/controller/admin_translations.t | 191 ---- 19 files changed, 2857 insertions(+), 2614 deletions(-) create mode 100644 t/app/controller/admin/bodies.t create mode 100644 t/app/controller/admin/defecttypes.t create mode 100644 t/app/controller/admin/permissions.t create mode 100644 t/app/controller/admin/priorities.t create mode 100644 t/app/controller/admin/report_edit.t create mode 100644 t/app/controller/admin/reportextrafields.t create mode 100644 t/app/controller/admin/search.t create mode 100644 t/app/controller/admin/states.t create mode 100644 t/app/controller/admin/stats.t create mode 100644 t/app/controller/admin/templates.t create mode 100644 t/app/controller/admin/translations.t create mode 100644 t/app/controller/admin/update_edit.t create mode 100644 t/app/controller/admin/users.t delete mode 100644 t/app/controller/admin_defecttypes.t delete mode 100644 t/app/controller/admin_permissions.t delete mode 100644 t/app/controller/admin_reportextrafields.t delete mode 100644 t/app/controller/admin_states.t delete mode 100644 t/app/controller/admin_translations.t diff --git a/t/app/controller/admin.t b/t/app/controller/admin.t index 91a28a5fc..b69a711c8 100644 --- a/t/app/controller/admin.t +++ b/t/app/controller/admin.t @@ -1,27 +1,14 @@ use FixMyStreet::TestMech; -# avoid wide character warnings from the category change message -use open ':std', ':encoding(UTF-8)'; my $mech = FixMyStreet::TestMech->new; 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'); -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); -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'); - -my $user3; - my $dt = DateTime->new( year => 2011, month => 04, @@ -56,6 +43,8 @@ my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( whensent => $dt->ymd . ' ' . $dt->hms, } ); +my $report_id = $report->id; +ok $report, "created test report - $report_id"; my $alert = FixMyStreet::App->model('DB::Alert')->find_or_create( { @@ -138,1458 +127,6 @@ subtest 'check summary counts' => sub { ok $mech->host('www.fixmystreet.com'); }; -# This override is wrapped around ALL the /admin/body tests -FixMyStreet::override_config { - MAPIT_URL => 'http://mapit.uk/', - MAPIT_TYPES => [ 'UTA' ], - BASE_URL => 'http://www.example.org', -}, sub { - -my $body = $mech->create_body_ok(2650, 'Aberdeen City Council'); -$mech->get_ok('/admin/body/' . $body->id); -$mech->content_contains('Aberdeen City Council'); -$mech->content_like(qr{AB\d\d}); -$mech->content_contains("http://www.example.org/around"); - -subtest 'check contact creation' => sub { - $mech->get_ok('/admin/body/' . $body->id); - - $mech->submit_form_ok( { with_fields => { - category => 'test category', - email => 'test@example.com', - note => 'test note', - non_public => undef, - state => 'unconfirmed', - } } ); - - $mech->content_contains( 'test category' ); - $mech->content_contains( 'test@example.com' ); - $mech->content_contains( 'test note' ); - $mech->content_like( qr/\s*unconfirmed\s*<\/td>/ ); # No private - - $mech->submit_form_ok( { with_fields => { - category => 'private category', - email => 'test@example.com', - note => 'test note', - non_public => 'on', - } } ); - - $mech->content_contains( 'private category' ); - $mech->content_like( qr{test\@example.com\s*\s*\s*confirmed\s*
\s*\s*Private\s*\s*} ); - - $mech->submit_form_ok( { with_fields => { - category => 'test/category', - email => 'test@example.com', - note => 'test/note', - non_public => 'on', - } } ); - $mech->get_ok('/admin/body/' . $body->id . '/test/category'); - $mech->content_contains('

test/category

'); -}; - -subtest 'check contact editing' => sub { - $mech->get_ok('/admin/body/' . $body->id .'/test%20category'); - - $mech->submit_form_ok( { with_fields => { - email => 'test2@example.com', - note => 'test2 note', - non_public => undef, - } } ); - - $mech->content_contains( 'test category' ); - $mech->content_like( qr{test2\@example.com\s*\s*\s*unconfirmed\s*} ); - $mech->content_contains( 'test2 note' ); - - $mech->get_ok('/admin/body/' . $body->id . '/test%20category'); - $mech->submit_form_ok( { with_fields => { - email => 'test2@example.com, test3@example.com', - note => 'test3 note', - } } ); - - $mech->content_contains( 'test2@example.com,test3@example.com' ); - - $mech->get_ok('/admin/body/' . $body->id . '/test%20category'); - $mech->content_contains( 'test2@example.com,test3@example.com' ); - - $mech->submit_form_ok( { with_fields => { - email => 'test2@example.com', - note => 'test2 note', - non_public => 'on', - } } ); - - $mech->content_like( qr{test2\@example.com\s*\s*\s*unconfirmed\s*
\s*\s*Private\s*\s*} ); - - $mech->get_ok('/admin/body/' . $body->id . '/test%20category'); - $mech->content_contains( 'test2@example.com' ); -}; - -subtest 'check contact updating' => sub { - $mech->get_ok('/admin/body/' . $body->id . '/test%20category'); - $mech->content_like(qr{test2\@example.com[^<]*[^<]*unconfirmed}s); - - $mech->get_ok('/admin/body/' . $body->id); - - $mech->form_number( 1 ); - $mech->tick( 'confirmed', 'test category' ); - $mech->submit_form_ok({form_number => 1}); - - $mech->content_like(qr'test2@example.com[^<]*\s*confirmed's); - $mech->get_ok('/admin/body/' . $body->id . '/test%20category'); - $mech->content_like(qr{test2\@example.com[^<]*[^<]*confirmed}s); -}; - -$body->update({ send_method => undef }); - -subtest 'check open311 configuring' => sub { - $mech->get_ok('/admin/body/' . $body->id); - $mech->content_lacks('Council contacts configured via Open311'); - - $mech->form_number(3); - $mech->submit_form_ok( - { - with_fields => { - api_key => 'api key', - endpoint => 'http://example.com/open311', - jurisdiction => 'mySociety', - send_comments => 0, - send_method => 'Open311', - } - } - ); - $mech->content_contains('Council contacts configured via Open311'); - $mech->content_contains('Values updated'); - - my $conf = FixMyStreet::App->model('DB::Body')->find( $body->id ); - is $conf->endpoint, 'http://example.com/open311', 'endpoint configured'; - is $conf->api_key, 'api key', 'api key configured'; - is $conf->jurisdiction, 'mySociety', 'jurisdiction configures'; - - $mech->form_number(3); - $mech->submit_form_ok( - { - with_fields => { - api_key => 'new api key', - endpoint => 'http://example.org/open311', - jurisdiction => 'open311', - send_comments => 0, - send_method => 'Open311', - } - } - ); - - $mech->content_contains('Values updated'); - - $conf = FixMyStreet::App->model('DB::Body')->find( $body->id ); - is $conf->endpoint, 'http://example.org/open311', 'endpoint updated'; - is $conf->api_key, 'new api key', 'api key updated'; - is $conf->jurisdiction, 'open311', 'jurisdiction configures'; -}; - -subtest 'check text output' => sub { - $mech->get_ok('/admin/body/' . $body->id . '?text=1'); - is $mech->content_type, 'text/plain'; - $mech->content_contains('test category'); - $mech->content_lacks('model('DB::AdminLog')->search( - { - object_type => 'problem', - object_id => $report->id - }, - { - order_by => { -desc => 'id' }, - } -); - -is $log_entries->count, 0, 'no admin log entries'; - -my $report_id = $report->id; -ok $report, "created test report - $report_id"; - -foreach my $test ( - { - description => 'edit report title', - fields => { - title => 'Report to Edit', - detail => 'Detail for Report to Edit', - state => 'confirmed', - name => 'Test User', - username => $user->email, - anonymous => 0, - flagged => undef, - non_public => undef, - }, - changes => { title => 'Edited Report', }, - log_entries => [qw/edit/], - resend => 0, - }, - { - description => 'edit report description', - fields => { - title => 'Edited Report', - detail => 'Detail for Report to Edit', - state => 'confirmed', - name => 'Test User', - username => $user->email, - anonymous => 0, - flagged => undef, - non_public => undef, - }, - changes => { detail => 'Edited Detail', }, - log_entries => [qw/edit edit/], - resend => 0, - }, - { - description => 'edit report user name', - fields => { - title => 'Edited Report', - detail => 'Edited Detail', - state => 'confirmed', - name => 'Test User', - username => $user->email, - anonymous => 0, - flagged => undef, - non_public => undef, - }, - changes => { name => 'Edited User', }, - log_entries => [qw/edit edit edit/], - resend => 0, - user => $user, - }, - { - description => 'edit report set flagged true', - fields => { - title => 'Edited Report', - detail => 'Edited Detail', - state => 'confirmed', - name => 'Edited User', - username => $user->email, - anonymous => 0, - flagged => undef, - non_public => undef, - }, - changes => { - flagged => 'on', - }, - log_entries => [qw/edit edit edit edit/], - resend => 0, - user => $user, - }, - { - description => 'edit report user email', - fields => { - title => 'Edited Report', - detail => 'Edited Detail', - state => 'confirmed', - name => 'Edited User', - username => $user->email, - anonymous => 0, - flagged => 'on', - non_public => undef, - }, - changes => { username => $user2->email, }, - log_entries => [qw/edit edit edit edit edit/], - resend => 0, - user => $user2, - }, - { - description => 'change state to unconfirmed', - fields => { - title => 'Edited Report', - detail => 'Edited Detail', - state => 'confirmed', - name => 'Edited User', - username => $user2->email, - anonymous => 0, - flagged => 'on', - non_public => undef, - }, - expect_comment => 1, - changes => { state => 'unconfirmed' }, - log_entries => [qw/edit state_change edit edit edit edit edit/], - resend => 0, - }, - { - description => 'change state to confirmed', - fields => { - title => 'Edited Report', - detail => 'Edited Detail', - state => 'unconfirmed', - name => 'Edited User', - username => $user2->email, - anonymous => 0, - flagged => 'on', - non_public => undef, - }, - expect_comment => 1, - changes => { state => 'confirmed' }, - log_entries => [qw/edit state_change edit state_change edit edit edit edit edit/], - resend => 0, - }, - { - description => 'change state to fixed', - fields => { - title => 'Edited Report', - detail => 'Edited Detail', - state => 'confirmed', - name => 'Edited User', - username => $user2->email, - anonymous => 0, - flagged => 'on', - non_public => undef, - }, - expect_comment => 1, - changes => { state => 'fixed' }, - log_entries => - [qw/edit state_change edit state_change edit state_change edit edit edit edit edit/], - resend => 0, - }, - { - description => 'change state to hidden', - fields => { - title => 'Edited Report', - detail => 'Edited Detail', - state => 'fixed', - name => 'Edited User', - username => $user2->email, - anonymous => 0, - flagged => 'on', - non_public => undef, - }, - expect_comment => 1, - changes => { state => 'hidden' }, - log_entries => [ - qw/edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/ - ], - resend => 0, - }, - { - description => 'edit and change state', - fields => { - title => 'Edited Report', - detail => 'Edited Detail', - state => 'hidden', - name => 'Edited User', - username => $user2->email, - anonymous => 0, - flagged => 'on', - non_public => undef, - }, - expect_comment => 1, - changes => { - state => 'confirmed', - anonymous => 1, - }, - log_entries => [ - qw/edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/ - ], - resend => 0, - }, - { - description => 'resend', - fields => { - title => 'Edited Report', - detail => 'Edited Detail', - state => 'confirmed', - name => 'Edited User', - username => $user2->email, - anonymous => 1, - flagged => 'on', - non_public => undef, - }, - changes => {}, - log_entries => [ - qw/resend edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/ - ], - resend => 1, - }, - { - description => 'non public', - fields => { - title => 'Edited Report', - detail => 'Edited Detail', - state => 'confirmed', - name => 'Edited User', - username => $user2->email, - anonymous => 1, - flagged => 'on', - non_public => undef, - }, - changes => { - non_public => 'on', - }, - log_entries => [ - qw/edit resend edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/ - ], - resend => 0, - }, - { - description => 'change state to investigating as body superuser', - fields => { - title => 'Edited Report', - detail => 'Edited Detail', - state => 'confirmed', - name => 'Edited User', - username => $user2->email, - anonymous => 1, - flagged => 'on', - non_public => 'on', - }, - expect_comment => 1, - user_body => $oxfordshire, - changes => { state => 'investigating' }, - log_entries => [ - qw/edit state_change edit resend edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/ - ], - resend => 0, - }, - { - description => 'change state to in progess and change category as body superuser', - fields => { - title => 'Edited Report', - detail => 'Edited Detail', - state => 'investigating', - name => 'Edited User', - username => $user2->email, - anonymous => 1, - flagged => 'on', - non_public => 'on', - }, - expect_comment => 1, - expected_text => '*Category changed from ‘Other’ to ‘Potholes’*', - user_body => $oxfordshire, - changes => { state => 'in progress', category => 'Potholes' }, - log_entries => [ - qw/edit state_change edit state_change edit resend edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/ - ], - resend => 0, - }, - ) -{ - subtest $test->{description} => sub { - $report->comments->delete; - $log_entries->reset; - - if ( $test->{user_body} ) { - $superuser->from_body( $test->{user_body}->id ); - $superuser->update; - } - - $mech->get_ok("/admin/report_edit/$report_id"); - - @{$test->{fields}}{'external_id', 'external_body', 'external_team', 'category'} = (13, "", "", "Other"); - is_deeply( $mech->visible_form_values(), $test->{fields}, 'initial form values' ); - - my $new_fields = { - %{ $test->{fields} }, - %{ $test->{changes} }, - }; - - if ( $test->{resend} ) { - $mech->click_ok( 'resend' ); - } else { - $mech->submit_form_ok( { with_fields => $new_fields }, 'form_submitted' ); - } - - is_deeply( $mech->visible_form_values(), $new_fields, 'changed form values' ); - is $log_entries->count, scalar @{$test->{log_entries}}, 'log entry count'; - is $log_entries->next->action, $_, 'log entry added' for @{ $test->{log_entries} }; - - $report->discard_changes; - - if ($report->state eq 'confirmed' && $report->whensent) { - $mech->content_contains( 'type="submit" name="resend"', 'resend button' ); - } else { - $mech->content_lacks( 'type="submit" name="resend"', 'no resend button' ); - } - - $test->{changes}->{flagged} = 1 if $test->{changes}->{flagged}; - $test->{changes}->{non_public} = 1 if $test->{changes}->{non_public}; - - is $report->$_, $test->{changes}->{$_}, "$_ updated" for grep { $_ ne 'username' } keys %{ $test->{changes} }; - - if ( $test->{user} ) { - is $report->user->id, $test->{user}->id, 'user changed'; - } - - if ( $test->{resend} ) { - $mech->content_contains( 'That problem will now be resent' ); - is $report->whensent, undef, 'mark report to resend'; - } - - if ( $test->{expect_comment} ) { - my $comment = $report->comments->first; - ok $comment, 'report status change creates comment'; - is $report->comments->count, 1, 'report only has one comment'; - if ($test->{expected_text}) { - is $comment->text, $test->{expected_text}, 'comment has expected text'; - } else { - is $comment->text, '', 'comment has no text'; - } - if ( $test->{user_body} ) { - ok $comment->get_extra_metadata('is_body_user'), 'body user metadata set'; - ok !$comment->get_extra_metadata('is_superuser'), 'superuser metadata not set'; - is $comment->name, $test->{user_body}->name, 'comment name is body name'; - } else { - ok !$comment->get_extra_metadata('is_body_user'), 'body user metadata not set'; - ok $comment->get_extra_metadata('is_superuser'), 'superuser metadata set'; - is $comment->name, _('an administrator'), 'comment name is admin'; - } - } else { - is $report->comments->count, 0, 'report has no comments'; - } - - $superuser->from_body(undef); - $superuser->update; - }; -} - -FixMyStreet::override_config { - ALLOWED_COBRANDS => 'fixmystreet', -}, sub { - -subtest 'change report category' => sub { - my ($ox_report) = $mech->create_problems_for_body(1, $oxfordshire->id, 'Unsure', { - category => 'Potholes', - areas => ',2237,2421,', # Cached used by categories_for_point... - latitude => 51.7549262252, - longitude => -1.25617899435, - whensent => \'current_timestamp', - }); - $mech->get_ok("/admin/report_edit/" . $ox_report->id); - - $mech->submit_form_ok( { with_fields => { category => 'Traffic lights' } }, 'form_submitted' ); - $ox_report->discard_changes; - is $ox_report->category, 'Traffic lights'; - isnt $ox_report->whensent, undef; - is $ox_report->comments->count, 1, "Comment created for update"; - is $ox_report->comments->first->text, '*Category changed from ‘Potholes’ to ‘Traffic lights’*', 'Comment text correct'; - - $mech->submit_form_ok( { with_fields => { category => 'Graffiti' } }, 'form_submitted' ); - $ox_report->discard_changes; - is $ox_report->category, 'Graffiti'; - is $ox_report->whensent, undef; -}; - -}; - -subtest 'change email to new user' => sub { - $log_entries->delete; - $mech->get_ok("/admin/report_edit/$report_id"); - my $fields = { - title => $report->title, - detail => $report->detail, - state => $report->state, - name => $report->name, - username => $report->user->email, - category => 'Potholes', - anonymous => 1, - flagged => 'on', - non_public => 'on', - external_id => '13', - external_body => '', - external_team => '', - }; - - is_deeply( $mech->visible_form_values(), $fields, 'initial form values' ); - - my $changes = { - username => 'test3@example.com' - }; - - $user3 = FixMyStreet::App->model('DB::User')->find( { email => 'test3@example.com' } ); - - ok !$user3, 'user not in database'; - - my $new_fields = { - %{ $fields }, - %{ $changes }, - }; - - $mech->submit_form_ok( - { - with_fields => $new_fields, - } - ); - - is $log_entries->count, 1, 'created admin log entries'; - is $log_entries->first->action, 'edit', 'log action'; - is_deeply( $mech->visible_form_values(), $new_fields, 'changed form values' ); - - $user3 = FixMyStreet::App->model('DB::User')->find( { email => 'test3@example.com' } ); - - $report->discard_changes; - - ok $user3, 'new user created'; - is $report->user_id, $user3->id, 'user changed to new user'; -}; - -subtest 'adding email to abuse list from report page' => sub { - my $email = $report->user->email; - - my $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $email } ); - $abuse->delete if $abuse; - - $mech->get_ok( '/admin/report_edit/' . $report->id ); - $mech->content_contains('Ban user'); - - $mech->click_ok('banuser'); - - $mech->content_contains('User added to abuse list'); - $mech->content_contains('User in abuse table'); - - $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $email } ); - ok $abuse, 'entry created in abuse table'; - - $mech->get_ok( '/admin/report_edit/' . $report->id ); - $mech->content_contains('User in abuse table'); -}; - -subtest 'remove user from abuse list from edit user page' => sub { - my $abuse = FixMyStreet::App->model('DB::Abuse')->find_or_create( { email => $user->email } ); - $mech->get_ok( '/admin/user_edit/' . $user->id ); - $mech->content_contains('User in abuse table'); - - $mech->click_ok('unban'); - - $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $user->email } ); - ok !$abuse, 'record removed from abuse table'; -}; - -subtest 'remove user with phone account from abuse list from edit user page' => sub { - my $abuse_user = $mech->create_user_ok('01234 456789'); - my $abuse = FixMyStreet::App->model('DB::Abuse')->find_or_create( { email => $abuse_user->phone } ); - $mech->get_ok( '/admin/user_edit/' . $abuse_user->id ); - $mech->content_contains('User in abuse table'); - my $abuse_found = FixMyStreet::App->model('DB::Abuse')->find( { email => $abuse_user->phone } ); - ok $abuse_found, 'user in abuse table'; - - $mech->click_ok('unban'); - - $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $user->phone } ); - ok !$abuse, 'record removed from abuse table'; -}; - -subtest 'no option to remove user already in abuse list' => sub { - my $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $user->email } ); - $abuse->delete if $abuse; - $mech->get_ok( '/admin/user_edit/' . $user->id ); - $mech->content_lacks('User in abuse table'); -}; - -subtest 'flagging user from report page' => sub { - $report->user->flagged(0); - $report->user->update; - - $mech->get_ok( '/admin/report_edit/' . $report->id ); - $mech->content_contains('Flag user'); - - $mech->click_ok('flaguser'); - - $mech->content_contains('User flagged'); - $mech->content_contains('Remove flag'); - - $report->discard_changes; - ok $report->user->flagged, 'user flagged'; - - $mech->get_ok( '/admin/report_edit/' . $report->id ); - $mech->content_contains('Remove flag'); -}; - -subtest 'unflagging user from report page' => sub { - $report->user->flagged(1); - $report->user->update; - - $mech->get_ok( '/admin/report_edit/' . $report->id ); - $mech->content_contains('Remove flag'); - - $mech->click_ok('removeuserflag'); - - $mech->content_contains('User flag removed'); - $mech->content_contains('Flag user'); - - $report->discard_changes; - ok !$report->user->flagged, 'user not flagged'; - - $mech->get_ok( '/admin/report_edit/' . $report->id ); - $mech->content_contains('Flag user'); -}; - -$log_entries->delete; - -my $update = FixMyStreet::App->model('DB::Comment')->create( - { - text => 'this is an update', - user => $user, - state => 'confirmed', - problem => $report, - mark_fixed => 0, - anonymous => 1, - } -); - -$log_entries = FixMyStreet::App->model('DB::AdminLog')->search( - { - object_type => 'update', - object_id => $update->id - }, - { - order_by => { -desc => 'id' }, - } -); - -is $log_entries->count, 0, 'no admin log entries'; - -for my $test ( - { - desc => 'edit update text', - fields => { - text => 'this is an update', - state => 'confirmed', - name => '', - anonymous => 1, - username => 'test@example.com', - }, - changes => { - text => 'this is a changed update', - }, - log_count => 1, - log_entries => [qw/edit/], - }, - { - desc => 'edit update name', - fields => { - text => 'this is a changed update', - state => 'confirmed', - name => '', - anonymous => 1, - username => 'test@example.com', - }, - changes => { - name => 'A User', - }, - log_count => 2, - log_entries => [qw/edit edit/], - }, - { - desc => 'edit update anonymous', - fields => { - text => 'this is a changed update', - state => 'confirmed', - name => 'A User', - anonymous => 1, - username => 'test@example.com', - }, - changes => { - anonymous => 0, - }, - log_count => 3, - log_entries => [qw/edit edit edit/], - }, - { - desc => 'edit update user', - fields => { - text => 'this is a changed update', - state => 'confirmed', - name => 'A User', - anonymous => 0, - username => 'test@example.com', - }, - changes => { - username => 'test2@example.com', - }, - log_count => 4, - log_entries => [qw/edit edit edit edit/], - user => $user2, - }, - { - desc => 'edit update state', - fields => { - text => 'this is a changed update', - state => 'confirmed', - name => 'A User', - anonymous => 0, - username => 'test2@example.com', - }, - changes => { - state => 'unconfirmed', - }, - log_count => 5, - log_entries => [qw/state_change edit edit edit edit/], - }, - { - desc => 'edit update state and text', - fields => { - text => 'this is a changed update', - state => 'unconfirmed', - name => 'A User', - anonymous => 0, - username => 'test2@example.com', - }, - changes => { - text => 'this is a twice changed update', - state => 'confirmed', - }, - log_count => 7, - log_entries => [qw/edit state_change state_change edit edit edit edit/], - }, -) { - subtest $test->{desc} => sub { - $log_entries->reset; - $mech->get_ok('/admin/update_edit/' . $update->id ); - - is_deeply $mech->visible_form_values, $test->{fields}, 'initial form values'; - - my $to_submit = { - %{ $test->{fields} }, - %{ $test->{changes} } - }; - - $mech->submit_form_ok( { with_fields => $to_submit } ); - - is_deeply $mech->visible_form_values, $to_submit, 'submitted form values'; - - is $log_entries->count, $test->{log_count}, 'number of log entries'; - is $log_entries->next->action, $_, 'log action' for @{ $test->{log_entries} }; - - $update->discard_changes; - - is $update->$_, $test->{changes}->{$_} for grep { $_ ne 'username' } keys %{ $test->{changes} }; - if ( $test->{changes}{state} && $test->{changes}{state} eq 'confirmed' ) { - isnt $update->confirmed, undef; - } - - if ( $test->{user} ) { - is $update->user->id, $test->{user}->id, 'update user'; - } - }; -} - -my $westminster = $mech->create_body_ok(2504, 'Westminster City Council'); -$report->bodies_str($westminster->id); -$report->update; - -for my $test ( - { - desc => 'user is problem owner', - problem_user => $user, - update_user => $user, - update_fixed => 0, - update_reopen => 0, - update_state => undef, - user_body => undef, - content => 'user is problem owner', - }, - { - desc => 'user is body user', - problem_user => $user, - update_user => $user2, - update_fixed => 0, - update_reopen => 0, - update_state => undef, - user_body => $westminster->id, - content => 'user is from same council as problem - ' . $westminster->id, - }, - { - desc => 'update changed problem state', - problem_user => $user, - update_user => $user2, - update_fixed => 0, - update_reopen => 0, - update_state => 'planned', - user_body => $westminster->id, - content => 'Update changed problem state to planned', - }, - { - desc => 'update marked problem as fixed', - problem_user => $user, - update_user => $user3, - update_fixed => 1, - update_reopen => 0, - update_state => undef, - user_body => undef, - content => 'Update marked problem as fixed', - }, - { - desc => 'update reopened problem', - problem_user => $user, - update_user => $user, - update_fixed => 0, - update_reopen => 1, - update_state => undef, - user_body => undef, - content => 'Update reopened problem', - }, -) { - subtest $test->{desc} => sub { - $report->user( $test->{problem_user} ); - $report->update; - - $update->user( $test->{update_user} ); - $update->problem_state( $test->{update_state} ); - $update->mark_fixed( $test->{update_fixed} ); - $update->mark_open( $test->{update_reopen} ); - $update->update; - - $test->{update_user}->from_body( $test->{user_body} ); - $test->{update_user}->update; - - $mech->get_ok('/admin/update_edit/' . $update->id ); - $mech->content_contains( $test->{content} ); - }; -} - -subtest 'editing update email creates new user if required' => sub { - my $user = FixMyStreet::App->model('DB::User')->find( { email => 'test4@example.com' } ); - - $user->delete if $user; - - my $fields = { - text => 'this is a changed update', - state => 'confirmed', - name => 'A User', - anonymous => 0, - username => 'test4@example.com', - }; - - $mech->submit_form_ok( { with_fields => $fields } ); - - $user = FixMyStreet::App->model('DB::User')->find( { email => 'test4@example.com' } ); - - is_deeply $mech->visible_form_values, $fields, 'submitted form values'; - - ok $user, 'new user created'; - - $update->discard_changes; - is $update->user->id, $user->id, 'update set to new user'; -}; - -subtest 'adding email to abuse list from update page' => sub { - my $email = $update->user->email; - - my $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $email } ); - $abuse->delete if $abuse; - - $mech->get_ok( '/admin/update_edit/' . $update->id ); - $mech->content_contains('Ban user'); - - $mech->click_ok('banuser'); - - $mech->content_contains('User added to abuse list'); - $mech->content_contains('User in abuse table'); - - $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $email } ); - ok $abuse, 'entry created in abuse table'; - - $mech->get_ok( '/admin/update_edit/' . $update->id ); - $mech->content_contains('User in abuse table'); -}; - -subtest 'flagging user from update page' => sub { - $update->user->flagged(0); - $update->user->update; - - $mech->get_ok( '/admin/update_edit/' . $update->id ); - $mech->content_contains('Flag user'); - - $mech->click_ok('flaguser'); - - $mech->content_contains('User flagged'); - $mech->content_contains('Remove flag'); - - $update->discard_changes; - ok $update->user->flagged, 'user flagged'; - - $mech->get_ok( '/admin/update_edit/' . $update->id ); - $mech->content_contains('Remove flag'); -}; - -subtest 'unflagging user from update page' => sub { - $update->user->flagged(1); - $update->user->update; - - $mech->get_ok( '/admin/update_edit/' . $update->id ); - $mech->content_contains('Remove flag'); - - $mech->click_ok('removeuserflag'); - - $mech->content_contains('User flag removed'); - $mech->content_contains('Flag user'); - - $update->discard_changes; - ok !$update->user->flagged, 'user not flagged'; - - $mech->get_ok( '/admin/update_edit/' . $update->id ); - $mech->content_contains('Flag user'); -}; - -subtest 'hiding comment marked as fixed reopens report' => sub { - $update->mark_fixed( 1 ); - $update->update; - - $report->state('fixed - user'); - $report->update; - - my $fields = { - text => 'this is a changed update', - state => 'hidden', - name => 'A User', - anonymous => 0, - username => 'test2@example.com', - }; - - $mech->submit_form_ok( { with_fields => $fields } ); - - $report->discard_changes; - is $report->state, 'confirmed', 'report reopened'; - $mech->content_contains('Problem marked as open'); -}; - -$log_entries->delete; - -subtest 'report search' => sub { - $update->discard_changes; - $update->state('confirmed'); - $update->user($report->user); - $update->update; - - $mech->get_ok('/admin/reports'); - $mech->get_ok('/admin/reports?search=' . $report->id ); - - $mech->content_contains( $report->title ); - my $r_id = $report->id; - $mech->content_like( qr{href="http://[^/]*[^.]/report/$r_id"[^>]*>$r_id} ); - - $mech->get_ok('/admin/reports?search=' . $report->external_id); - $mech->content_like( qr{href="http://[^/]*[^.]/report/$r_id"[^>]*>$r_id} ); - - $mech->get_ok('/admin/reports?search=ref:' . $report->external_id); - $mech->content_like( qr{href="http://[^/]*[^.]/report/$r_id"[^>]*>$r_id} ); - - $mech->get_ok('/admin/reports?search=' . $report->user->email); - - my $u_id = $update->id; - $mech->content_like( qr{href="http://[^/]*[^.]/report/$r_id"[^>]*>$r_id} ); - $mech->content_like( qr{href="http://[^/]*[^.]/report/$r_id#update_$u_id"[^>]*>$u_id} ); - - $update->state('hidden'); - $update->update; - - $mech->get_ok('/admin/reports?search=' . $report->user->email); - $mech->content_like( qr{]*hidden[^>]*> \s* \s* $u_id \s* }xs ); - - $report->state('hidden'); - $report->update; - - $mech->get_ok('/admin/reports?search=' . $report->user->email); - $mech->content_like( qr{]*hidden[^>]*> \s* ]*> \s* $r_id \s* }xs ); - - $report->state('fixed - user'); - $report->update; - - $mech->get_ok('/admin/reports?search=' . $report->user->email); - $mech->content_like( qr{href="http://[^/]*[^.]/report/$r_id"[^>]*>$r_id} ); -}; - -subtest 'search abuse' => sub { - $mech->get_ok( '/admin/users?search=example' ); - $mech->content_like(qr{test4\@example.com.*\s*.*?\s*User in abuse table}s); -}; - -subtest 'show flagged entries' => sub { - $report->flagged( 1 ); - $report->update; - - $user->flagged( 1 ); - $user->update; - - $mech->get_ok('/admin/flagged'); - $mech->content_contains( $report->title ); - $mech->content_contains( $user->email ); -}; - -my $haringey = $mech->create_body_ok(2509, 'Haringey Borough Council'); - -subtest 'user search' => sub { - $mech->get_ok('/admin/users'); - $mech->get_ok('/admin/users?search=' . $user->name); - - $mech->content_contains( $user->name); - my $u_id = $user->id; - $mech->content_like( qr{user_edit/$u_id">Edit} ); - - $mech->get_ok('/admin/users?search=' . $user->email); - - $mech->content_like( qr{user_edit/$u_id">Edit} ); - - $user->from_body($haringey->id); - $user->update; - $mech->get_ok('/admin/users?search=' . $haringey->id ); - $mech->content_contains('Haringey'); -}; - -subtest 'search does not show user from another council' => sub { - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'oxfordshire' ], - }, sub { - $mech->get_ok('/admin/users'); - $mech->get_ok('/admin/users?search=' . $user->name); - - $mech->content_contains( "Searching found no users." ); - - $mech->get_ok('/admin/users?search=' . $user->email); - $mech->content_contains( "Searching found no users." ); - }; -}; - -subtest 'user_edit does not show user from another council' => sub { - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'oxfordshire' ], - }, sub { - $mech->get('/admin/user_edit/' . $user->id); - ok !$mech->res->is_success(), "want a bad response"; - is $mech->res->code, 404, "got 404"; - }; -}; - -$log_entries = FixMyStreet::App->model('DB::AdminLog')->search( - { - object_type => 'user', - object_id => $user->id - }, - { - order_by => { -desc => 'id' }, - } -); - -is $log_entries->count, 0, 'no admin log entries'; - -$user->flagged( 0 ); -$user->update; - -my $southend = $mech->create_body_ok(2607, 'Southend-on-Sea Borough Council'); - -for my $test ( - { - desc => 'add user - blank form', - fields => { - email => '', email_verified => 0, - phone => '', phone_verified => 0, - }, - error => ['Please verify at least one of email/phone', 'Please enter a name'], - }, - { - desc => 'add user - blank, verify phone', - fields => { - email => '', email_verified => 0, - phone => '', phone_verified => 1, - }, - error => ['Please enter a valid email or phone number', 'Please enter a name'], - }, - { - desc => 'add user - bad email', - fields => { - name => 'Norman', - email => 'bademail', email_verified => 0, - phone => '', phone_verified => 0, - }, - error => ['Please enter a valid email'], - }, - { - desc => 'add user - bad phone', - fields => { - name => 'Norman', - phone => '01214960000000', phone_verified => 1, - }, - error => ['Please check your phone number is correct'], - }, - { - desc => 'add user - landline', - fields => { - name => 'Norman Name', - phone => '+441214960000', - phone_verified => 1, - }, - error => ['Please enter a mobile number'], - }, - { - desc => 'add user - good details', - fields => { - name => 'Norman Name', - phone => '+61491570156', - phone_verified => 1, - }, - }, -) { - subtest $test->{desc} => sub { - $mech->get_ok('/admin/users'); - $mech->submit_form_ok( { with_fields => $test->{fields} } ); - if ($test->{error}) { - $mech->content_contains($_) for @{$test->{error}}; - } else { - $mech->content_contains('Updated'); - } - }; -} - -my %default_perms = ( - "permissions[moderate]" => undef, - "permissions[planned_reports]" => undef, - "permissions[report_edit]" => undef, - "permissions[report_edit_category]" => undef, - "permissions[report_edit_priority]" => undef, - "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, - "permissions[user_manage_permissions]" => undef, - "permissions[user_assign_body]" => undef, - "permissions[user_assign_areas]" => undef, - "permissions[template_edit]" => undef, - "permissions[responsepriority_edit]" => undef, - "permissions[category_edit]" => undef, - trusted_bodies => undef, -); - -# Start this section with user having no name -# Regression test for mysociety/fixmystreetforcouncils#250 -$user->update({ name => '' }); - -FixMyStreet::override_config { - MAPIT_URL => 'http://mapit.uk/', -}, sub { - for my $test ( - { - desc => 'edit user name', - fields => { - name => '', - email => 'test@example.com', - body => $haringey->id, - phone => '', - flagged => undef, - is_superuser => undef, - area_id => '', - %default_perms, - }, - changes => { - name => 'Changed User', - }, - log_count => 1, - log_entries => [qw/edit/], - }, - { - desc => 'edit user email', - fields => { - name => 'Changed User', - email => 'test@example.com', - body => $haringey->id, - phone => '', - flagged => undef, - is_superuser => undef, - area_id => '', - %default_perms, - }, - changes => { - email => 'changed@example.com', - }, - log_count => 2, - log_entries => [qw/edit edit/], - }, - { - desc => 'edit user body', - fields => { - name => 'Changed User', - email => 'changed@example.com', - body => $haringey->id, - phone => '', - flagged => undef, - is_superuser => undef, - area_id => '', - %default_perms, - }, - changes => { - body => $southend->id, - }, - log_count => 3, - log_entries => [qw/edit edit edit/], - }, - { - desc => 'edit user flagged', - fields => { - name => 'Changed User', - email => 'changed@example.com', - body => $southend->id, - phone => '', - flagged => undef, - is_superuser => undef, - area_id => '', - %default_perms, - }, - changes => { - flagged => 'on', - }, - log_count => 4, - log_entries => [qw/edit edit edit edit/], - }, - { - desc => 'edit user remove flagged', - fields => { - name => 'Changed User', - email => 'changed@example.com', - body => $southend->id, - phone => '', - flagged => 'on', - is_superuser => undef, - area_id => '', - %default_perms, - }, - changes => { - flagged => undef, - }, - log_count => 4, - log_entries => [qw/edit edit edit edit/], - }, - { - desc => 'edit user add is_superuser', - fields => { - name => 'Changed User', - email => 'changed@example.com', - body => $southend->id, - phone => '', - flagged => undef, - is_superuser => undef, - area_id => '', - %default_perms, - }, - changes => { - is_superuser => 'on', - }, - removed => [ - keys %default_perms, - ], - log_count => 5, - log_entries => [qw/edit edit edit edit edit/], - }, - { - desc => 'edit user remove is_superuser', - fields => { - name => 'Changed User', - email => 'changed@example.com', - body => $southend->id, - phone => '', - flagged => undef, - is_superuser => 'on', - area_id => '', - }, - changes => { - is_superuser => undef, - }, - added => { - %default_perms, - }, - log_count => 5, - log_entries => [qw/edit edit edit edit edit/], - }, - ) { - subtest $test->{desc} => sub { - $mech->get_ok( '/admin/user_edit/' . $user->id ); - - my $visible = $mech->visible_form_values; - is_deeply $visible, $test->{fields}, 'expected user'; - - my $expected = { - %{ $test->{fields} }, - %{ $test->{changes} } - }; - - $mech->submit_form_ok( { with_fields => $expected } ); - - # Some actions cause visible fields to be added/removed - foreach my $x (@{ $test->{removed} }) { - delete $expected->{$x}; - } - if ( $test->{added} ) { - $expected = { - %$expected, - %{ $test->{added} } - }; - } - - $visible = $mech->visible_form_values; - is_deeply $visible, $expected, 'user updated'; - - $mech->content_contains( 'Updated!' ); - }; - } -}; - -FixMyStreet::override_config { - MAPIT_URL => 'http://mapit.uk/', - SMS_AUTHENTICATION => 1, -}, sub { - subtest "Test edit user add verified phone" => sub { - $mech->get_ok( '/admin/user_edit/' . $user->id ); - $mech->submit_form_ok( { with_fields => { - phone => '+61491570157', - phone_verified => 1, - } } ); - $mech->content_contains( 'Updated!' ); - }; - - subtest "Test changing user to an existing one" => sub { - my $existing_user = $mech->create_user_ok('existing@example.com', name => 'Existing User'); - $mech->create_problems_for_body(2, 2514, 'Title', { user => $existing_user }); - my $count = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id })->count; - $mech->get_ok( '/admin/user_edit/' . $user->id ); - $mech->submit_form_ok( { with_fields => { email => 'existing@example.com' } }, 'submit email change' ); - is $mech->uri->path, '/admin/user_edit/' . $existing_user->id, 'redirected'; - my $p = FixMyStreet::DB->resultset('Problem')->search({ user_id => $existing_user->id })->count; - is $p, $count + 2, 'reports merged'; - }; - -}; - -subtest "Anonymizing user from admin" => sub { - my $user = $mech->create_user_ok('existing@example.com', name => 'Existing User'); - my $count_p = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id })->count; - my $count_u = FixMyStreet::DB->resultset('Comment')->search({ user_id => $user->id })->count; - $mech->get_ok( '/admin/user_edit/' . $user->id ); - $mech->submit_form_ok({ button => 'anon_everywhere' }); - my $c = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id, anonymous => 1 })->count; - is $c, $count_p; - $c = FixMyStreet::DB->resultset('Comment')->search({ user_id => $user->id, anonymous => 1 })->count; - is $c, $count_u; -}; - -subtest "Hiding user's reports from admin" => sub { - my $user = $mech->create_user_ok('existing@example.com', name => 'Existing User'); - my $count_p = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id })->count; - my $count_u = FixMyStreet::DB->resultset('Comment')->search({ user_id => $user->id })->count; - $mech->get_ok( '/admin/user_edit/' . $user->id ); - $mech->submit_form_ok({ button => 'hide_everywhere' }); - my $c = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id, state => 'hidden' })->count; - is $c, $count_p; - $c = FixMyStreet::DB->resultset('Comment')->search({ user_id => $user->id, state => 'hidden' })->count; - is $c, $count_u; -}; - -subtest "Test setting a report from unconfirmed to something else doesn't cause a front end error" => sub { - $report->update( { confirmed => undef, state => 'unconfirmed', non_public => 0 } ); - $mech->get_ok("/admin/report_edit/$report_id"); - $mech->submit_form_ok( { with_fields => { state => 'investigating' } } ); - $report->discard_changes; - ok( $report->confirmed, 'report has a confirmed timestamp' ); - $mech->get_ok("/report/$report_id"); -}; - subtest "Check admin_base_url" => sub { my $rs = FixMyStreet::App->model('DB::Problem'); my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($report->cobrand)->new(); @@ -1603,10 +140,6 @@ subtest "Check admin_base_url" => sub { $mech->log_out_ok; subtest "Users without from_body can't access admin" => sub { - $user = FixMyStreet::App->model('DB::User')->find( { email => 'existing@example.com' } ); - $user->from_body( undef ); - $user->update; - $mech->log_in_ok( $user->email ); ok $mech->get('/admin'); @@ -1654,229 +187,4 @@ subtest "Users with from_body can't access fixmystreet.com admin" => sub { }; }; -subtest "response templates can be added" => sub { - is $oxfordshire->response_templates->count, 0, "No response templates yet"; - $mech->log_in_ok( $superuser->email ); - $mech->get_ok( "/admin/templates/" . $oxfordshire->id . "/new" ); - - my $fields = { - title => "Report acknowledgement", - text => "Thank you for your report. We will respond shortly.", - auto_response => undef, - "contacts[".$oxfordshirecontact->id."]" => 1, - }; - $mech->submit_form_ok( { with_fields => $fields } ); - - is $oxfordshire->response_templates->count, 1, "Response template was added"; -}; - -subtest "response templates are included on page" => sub { - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'oxfordshire' ], - }, sub { - $report->update({ category => $oxfordshirecontact->category, bodies_str => $oxfordshire->id }); - $mech->log_in_ok( $oxfordshireuser->email ); - - $mech->get_ok("/report/" . $report->id); - $mech->content_contains( $oxfordshire->response_templates->first->text ); - - $mech->log_out_ok; - }; -}; - -subtest "auto-response templates that duplicate a single category can't be added" => sub { - $mech->delete_response_template($_) for $oxfordshire->response_templates; - my $template = $oxfordshire->response_templates->create({ - title => "Report fixed - potholes", - text => "Thank you for your report. This problem has been fixed.", - auto_response => 1, - state => 'fixed - council', - }); - $template->contact_response_templates->find_or_create({ - contact_id => $oxfordshirecontact->id, - }); - is $oxfordshire->response_templates->count, 1, "Initial response template was created"; - - - $mech->log_in_ok( $superuser->email ); - $mech->get_ok( "/admin/templates/" . $oxfordshire->id . "/new" ); - - # This response template has the same category & state as an existing one - # so won't be allowed. - my $fields = { - title => "Report marked fixed - potholes", - text => "Thank you for your report. This pothole has been fixed.", - auto_response => 'on', - state => 'fixed - council', - "contacts[".$oxfordshirecontact->id."]" => 1, - }; - $mech->submit_form_ok( { with_fields => $fields } ); - is $mech->uri->path, '/admin/templates/' . $oxfordshire->id . '/new', 'not redirected'; - $mech->content_contains( 'Please correct the errors below' ); - $mech->content_contains( 'There is already an auto-response template for this category/state.' ); - - is $oxfordshire->response_templates->count, 1, "Duplicate response template wasn't added"; -}; - -subtest "auto-response templates that duplicate all categories can't be added" => sub { - $mech->delete_response_template($_) for $oxfordshire->response_templates; - $oxfordshire->response_templates->create({ - title => "Report investigating - all cats", - text => "Thank you for your report. This problem has been fixed.", - auto_response => 1, - state => 'fixed - council', - }); - is $oxfordshire->response_templates->count, 1, "Initial response template was created"; - - - $mech->log_in_ok( $superuser->email ); - $mech->get_ok( "/admin/templates/" . $oxfordshire->id . "/new" ); - - # There's already a response template for all categories and this state, so - # this new template won't be allowed. - my $fields = { - title => "Report investigating - single cat", - text => "Thank you for your report. This problem has been fixed.", - auto_response => 'on', - state => 'fixed - council', - "contacts[".$oxfordshirecontact->id."]" => 1, - }; - $mech->submit_form_ok( { with_fields => $fields } ); - is $mech->uri->path, '/admin/templates/' . $oxfordshire->id . '/new', 'not redirected'; - $mech->content_contains( 'Please correct the errors below' ); - $mech->content_contains( 'There is already an auto-response template for this category/state.' ); - - - is $oxfordshire->response_templates->count, 1, "Duplicate response template wasn't added"; -}; - -subtest "all-category auto-response templates that duplicate a single category can't be added" => sub { - $mech->delete_response_template($_) for $oxfordshire->response_templates; - my $template = $oxfordshire->response_templates->create({ - title => "Report fixed - potholes", - text => "Thank you for your report. This problem has been fixed.", - auto_response => 1, - state => 'fixed - council', - }); - $template->contact_response_templates->find_or_create({ - contact_id => $oxfordshirecontact->id, - }); - is $oxfordshire->response_templates->count, 1, "Initial response template was created"; - - - $mech->log_in_ok( $superuser->email ); - $mech->get_ok( "/admin/templates/" . $oxfordshire->id . "/new" ); - - # This response template is implicitly for all categories, but there's - # already a template for a specific category in this state, so it won't be - # allowed. - my $fields = { - title => "Report marked fixed - all cats", - text => "Thank you for your report. This problem has been fixed.", - auto_response => 'on', - state => 'fixed - council', - }; - $mech->submit_form_ok( { with_fields => $fields } ); - is $mech->uri->path, '/admin/templates/' . $oxfordshire->id . '/new', 'not redirected'; - $mech->content_contains( 'Please correct the errors below' ); - $mech->content_contains( 'There is already an auto-response template for this category/state.' ); - - is $oxfordshire->response_templates->count, 1, "Duplicate response template wasn't added"; -}; - - - -$mech->log_in_ok( $superuser->email ); - -subtest "response priorities can be added" => sub { - is $oxfordshire->response_priorities->count, 0, "No response priorities yet"; - $mech->get_ok( "/admin/responsepriorities/" . $oxfordshire->id . "/new" ); - - my $fields = { - name => "Cat 1A", - description => "Fixed within 24 hours", - deleted => undef, - is_default => undef, - "contacts[".$oxfordshirecontact->id."]" => 1, - }; - $mech->submit_form_ok( { with_fields => $fields } ); - - is $oxfordshire->response_priorities->count, 1, "Response priority was added to body"; - is $oxfordshirecontact->response_priorities->count, 1, "Response priority 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 priority"; - 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 ); - - $mech->content_contains( $oxfordshire->response_priorities->first->name ); - $mech->content_contains( $oxfordshire->response_priorities->first->description ); -}; - -subtest "response priorities are limited by body" => sub { - my $bromleypriority = $bromley->response_priorities->create( { - deleted => 0, - name => "Bromley Cat 0", - } ); - - is $bromley->response_priorities->count, 1, "Response priority was added to Bromley"; - is $oxfordshire->response_priorities->count, 1, "Response priority wasn't added to Oxfordshire"; - - $mech->get_ok( "/admin/responsepriorities/" . $oxfordshire->id ); - $mech->content_lacks( $bromleypriority->name ); - - $mech->get_ok( "/admin/responsepriorities/" . $bromley->id ); - $mech->content_contains( $bromleypriority->name ); -}; - -$mech->log_out_ok; - -subtest "response priorities can't be viewed across councils" => sub { - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'oxfordshire' ], - }, sub { - $oxfordshireuser->user_body_permissions->create({ - body => $oxfordshire, - permission_type => 'responsepriority_edit', - }); - $mech->log_in_ok( $oxfordshireuser->email ); - $mech->get_ok( "/admin/responsepriorities/" . $oxfordshire->id ); - $mech->content_contains( $oxfordshire->response_priorities->first->name ); - - - $mech->get( "/admin/responsepriorities/" . $bromley->id ); - ok !$mech->res->is_success(), "want a bad response"; - is $mech->res->code, 404, "got 404"; - - my $bromley_priority_id = $bromley->response_priorities->first->id; - $mech->get( "/admin/responsepriorities/" . $bromley->id . "/" . $bromley_priority_id ); - ok !$mech->res->is_success(), "want a bad response"; - is $mech->res->code, 404, "got 404"; - }; -}; - -subtest "smoke view some stats pages" => sub { - $mech->log_in_ok( $superuser->email ); - $mech->get_ok('/admin/stats/fix-rate'); - $mech->get_ok('/admin/stats/questionnaire'); -}; - done_testing(); diff --git a/t/app/controller/admin/bodies.t b/t/app/controller/admin/bodies.t new file mode 100644 index 000000000..9bdf8fb9a --- /dev/null +++ b/t/app/controller/admin/bodies.t @@ -0,0 +1,165 @@ +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 ); + +# This override is wrapped around ALL the /admin/body tests +FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + MAPIT_TYPES => [ 'UTA' ], + BASE_URL => 'http://www.example.org', +}, sub { + +my $body = $mech->create_body_ok(2650, 'Aberdeen City Council'); +$mech->get_ok('/admin/body/' . $body->id); +$mech->content_contains('Aberdeen City Council'); +$mech->content_like(qr{AB\d\d}); +$mech->content_contains("http://www.example.org/around"); + +subtest 'check contact creation' => sub { + $mech->get_ok('/admin/body/' . $body->id); + + $mech->submit_form_ok( { with_fields => { + category => 'test category', + email => 'test@example.com', + note => 'test note', + non_public => undef, + state => 'unconfirmed', + } } ); + + $mech->content_contains( 'test category' ); + $mech->content_contains( 'test@example.com' ); + $mech->content_contains( 'test note' ); + $mech->content_like( qr/\s*unconfirmed\s*<\/td>/ ); # No private + + $mech->submit_form_ok( { with_fields => { + category => 'private category', + email => 'test@example.com', + note => 'test note', + non_public => 'on', + } } ); + + $mech->content_contains( 'private category' ); + $mech->content_like( qr{test\@example.com\s*\s*\s*confirmed\s*
\s*\s*Private\s*\s*} ); + + $mech->submit_form_ok( { with_fields => { + category => 'test/category', + email => 'test@example.com', + note => 'test/note', + non_public => 'on', + } } ); + $mech->get_ok('/admin/body/' . $body->id . '/test/category'); + $mech->content_contains('

test/category

'); +}; + +subtest 'check contact editing' => sub { + $mech->get_ok('/admin/body/' . $body->id .'/test%20category'); + + $mech->submit_form_ok( { with_fields => { + email => 'test2@example.com', + note => 'test2 note', + non_public => undef, + } } ); + + $mech->content_contains( 'test category' ); + $mech->content_like( qr{test2\@example.com\s*\s*\s*unconfirmed\s*} ); + $mech->content_contains( 'test2 note' ); + + $mech->get_ok('/admin/body/' . $body->id . '/test%20category'); + $mech->submit_form_ok( { with_fields => { + email => 'test2@example.com, test3@example.com', + note => 'test3 note', + } } ); + + $mech->content_contains( 'test2@example.com,test3@example.com' ); + + $mech->get_ok('/admin/body/' . $body->id . '/test%20category'); + $mech->content_contains( 'test2@example.com,test3@example.com' ); + + $mech->submit_form_ok( { with_fields => { + email => 'test2@example.com', + note => 'test2 note', + non_public => 'on', + } } ); + + $mech->content_like( qr{test2\@example.com\s*\s*\s*unconfirmed\s*
\s*\s*Private\s*\s*} ); + + $mech->get_ok('/admin/body/' . $body->id . '/test%20category'); + $mech->content_contains( 'test2@example.com' ); +}; + +subtest 'check contact updating' => sub { + $mech->get_ok('/admin/body/' . $body->id . '/test%20category'); + $mech->content_like(qr{test2\@example.com[^<]*[^<]*unconfirmed}s); + + $mech->get_ok('/admin/body/' . $body->id); + + $mech->form_number( 1 ); + $mech->tick( 'confirmed', 'test category' ); + $mech->submit_form_ok({form_number => 1}); + + $mech->content_like(qr'test2@example.com[^<]*\s*confirmed's); + $mech->get_ok('/admin/body/' . $body->id . '/test%20category'); + $mech->content_like(qr{test2\@example.com[^<]*[^<]*confirmed}s); +}; + +$body->update({ send_method => undef }); + +subtest 'check open311 configuring' => sub { + $mech->get_ok('/admin/body/' . $body->id); + $mech->content_lacks('Council contacts configured via Open311'); + + $mech->form_number(3); + $mech->submit_form_ok( + { + with_fields => { + api_key => 'api key', + endpoint => 'http://example.com/open311', + jurisdiction => 'mySociety', + send_comments => 0, + send_method => 'Open311', + } + } + ); + $mech->content_contains('Council contacts configured via Open311'); + $mech->content_contains('Values updated'); + + my $conf = FixMyStreet::App->model('DB::Body')->find( $body->id ); + is $conf->endpoint, 'http://example.com/open311', 'endpoint configured'; + is $conf->api_key, 'api key', 'api key configured'; + is $conf->jurisdiction, 'mySociety', 'jurisdiction configures'; + + $mech->form_number(3); + $mech->submit_form_ok( + { + with_fields => { + api_key => 'new api key', + endpoint => 'http://example.org/open311', + jurisdiction => 'open311', + send_comments => 0, + send_method => 'Open311', + } + } + ); + + $mech->content_contains('Values updated'); + + $conf = FixMyStreet::App->model('DB::Body')->find( $body->id ); + is $conf->endpoint, 'http://example.org/open311', 'endpoint updated'; + is $conf->api_key, 'new api key', 'api key updated'; + is $conf->jurisdiction, 'open311', 'jurisdiction configures'; +}; + +subtest 'check text output' => sub { + $mech->get_ok('/admin/body/' . $body->id . '?text=1'); + is $mech->content_type, 'text/plain'; + $mech->content_contains('test category'); + $mech->content_lacks('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 new file mode 100644 index 000000000..7944cc0b1 --- /dev/null +++ b/t/app/controller/admin/permissions.t @@ -0,0 +1,196 @@ +use FixMyStreet::TestMech; + +my $mech = FixMyStreet::TestMech->new; + +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'); +my $oxfordshireuser = $mech->create_user_ok('counciluser@example.com', name => 'Council User', from_body => $oxfordshire); + +my $bromley = $mech->create_body_ok(2482, 'Bromley Council'); + +my $dt = DateTime->new( + year => 2011, + month => 04, + day => 16, + hour => 15, + minute => 47, + second => 23 +); + +my ($report) = $mech->create_problems_for_body(1, $oxfordshire->id, 'Test', { + areas => ',2237,', +}); +my $report_id = $report->id; +ok $report, "created test report - $report_id"; + +$mech->log_in_ok( $oxfordshireuser->email ); + +subtest "Users can't edit report without report_edit permission" => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'oxfordshire' ], + }, sub { + $mech->get("/admin/report_edit/$report_id"); + ok !$mech->res->is_success(), "want a bad response"; + is $mech->res->code, 404, "got 404, can't edit report without report_edit permission"; + }; +}; + +subtest "Users can edit report with report_edit permission" => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'oxfordshire' ], + }, sub { + $oxfordshireuser->user_body_permissions->create({ + body => $oxfordshire, + permission_type => 'report_edit', + }); + + $mech->get_ok("/admin/report_edit/$report_id"); + $mech->content_contains( $report->title ); + }; +}; + +subtest "Users can't edit another council's reports with their own council's report_edit permission" => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'oxfordshire' ], + }, sub { + $report->bodies_str($bromley->id); + $report->cobrand('bromley'); + $report->update; + + $mech->get("/admin/report_edit/$report_id"); + ok !$mech->res->is_success(), "want a bad response"; + is $mech->res->code, 404, "got 404, can't edit report with incorrect body in report_edit permission"; + }; +}; + + +FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + ALLOWED_COBRANDS => [ 'oxfordshire' ], +}, sub { + my $user2_id = $user2->id; + $report->update({ bodies_str => $oxfordshire->id }); + + foreach my $perm (0, 1) { + if ($perm) { + $oxfordshireuser->user_body_permissions->find_or_create({ + body => $oxfordshire, + permission_type => 'user_edit', + }); + } + foreach my $report_user ($user, $user2) { + $report->update({ user => $report_user }); + foreach my $from_body (undef, $bromley, $oxfordshire) { + $user2->update({ from_body => $from_body }); + my $result = ($from_body || '') eq $oxfordshire || $report->user eq $user2 ? ($perm ? 200 : 404 ) : 404; + my $u = $result == 200 ? 'can' : 'cannot'; + my $b = $from_body ? $from_body->name : 'no body'; + my $p = $perm ? 'with' : 'without'; + my $r = $report->user eq $user2 ? 'with' : 'without'; + subtest "User $u edit user for $b $p permission, $r cobrand relation" => sub { + $mech->get("/admin/user_edit/$user2_id"); + my $success = $mech->res->is_success(); + ok $result == 200 ? $success : !$success, "got correct response"; + is $mech->res->code, $result, "got $result"; + }; + } + } + } + + $oxfordshireuser->user_body_permissions->create({ + body => $oxfordshire, + permission_type => 'user_assign_body', + }); + + subtest "Users can edit users of their own council" => sub { + $mech->get_ok("/admin/user_edit/$user2_id"); + $mech->content_contains( $user2->name ); + + # We shouldn't be able to see the permissions tick boxes + $mech->content_lacks('Moderate report details'); + + $mech->submit_form_ok( { with_fields => { + name => 'Test Updated User 2', + email => $user2->email, + body => $user2->from_body->id, + phone => '', + flagged => undef, + } } ); + $user2->discard_changes; + is $user2->name, 'Test Updated User 2', 'name changed'; + }; + + $oxfordshireuser->user_body_permissions->create({ + body => $oxfordshire, + permission_type => 'user_manage_permissions', + }); + + subtest "Users can edit permissions" => sub { + is $user2->user_body_permissions->count, 0, 'user2 has no permissions'; + + $mech->get_ok("/admin/user_edit/$user2_id"); + $mech->content_contains('Moderate report details'); + + $mech->submit_form_ok( { with_fields => { + name => $user2->name, + email => $user2->email, + body => $user2->from_body->id, + phone => '', + flagged => undef, + "permissions[moderate]" => 'on', + "permissions[report_edit_category]" => undef, + "permissions[report_edit_priority]" => undef, + "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, + "permissions[user_assign_areas]" => undef, + } } ); + + ok $user2->has_body_permission_to("moderate"), "user2 has been granted moderate permission"; + }; + + $oxfordshireuser->user_body_permissions->create({ + body => $oxfordshire, + permission_type => 'user_assign_areas', + }); + + subtest "Unsetting user from_body removes all permissions and area " => sub { + is $user2->user_body_permissions->count, 1, 'user2 has 1 permission'; + + $mech->get_ok("/admin/user_edit/$user2_id"); + $mech->content_contains('Moderate report details'); + + $mech->submit_form_ok( { with_fields => { + name => $user2->name, + email => $user2->email, + body => undef, + phone => '', + flagged => undef, + "permissions[moderate]" => 'on', # NB tick box is left on deliberately + "permissions[report_edit_category]" => undef, + "permissions[report_edit_priority]" => undef, + "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, + "permissions[user_assign_areas]" => undef, + } } ); + + is $user2->user_body_permissions->count, 0, 'user2 has had permissions removed'; + is $user2->area_id, undef, 'user2 has had area removed'; + }; +}; + +$mech->log_out_ok; + +done_testing(); diff --git a/t/app/controller/admin/priorities.t b/t/app/controller/admin/priorities.t new file mode 100644 index 000000000..4eff20be7 --- /dev/null +++ b/t/app/controller/admin/priorities.t @@ -0,0 +1,102 @@ +use FixMyStreet::TestMech; + +my $mech = FixMyStreet::TestMech->new; + +my $user = $mech->create_user_ok('test@example.com', name => 'Test User'); + +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'); +my $oxfordshirecontact = $mech->create_contact_ok( body_id => $oxfordshire->id, category => 'Potholes', email => 'potholes@example.com' ); +my $oxfordshireuser = $mech->create_user_ok('counciluser@example.com', name => 'Council User', from_body => $oxfordshire); + +my $bromley = $mech->create_body_ok(2482, 'Bromley Council'); + +$mech->log_in_ok( $superuser->email ); + +subtest "response priorities can be added" => sub { + is $oxfordshire->response_priorities->count, 0, "No response priorities yet"; + $mech->get_ok( "/admin/responsepriorities/" . $oxfordshire->id . "/new" ); + + my $fields = { + name => "Cat 1A", + description => "Fixed within 24 hours", + deleted => undef, + is_default => undef, + "contacts[".$oxfordshirecontact->id."]" => 1, + }; + $mech->submit_form_ok( { with_fields => $fields } ); + + is $oxfordshire->response_priorities->count, 1, "Response priority was added to body"; + is $oxfordshirecontact->response_priorities->count, 1, "Response priority 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 priority"; + 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 ); + + $mech->content_contains( $oxfordshire->response_priorities->first->name ); + $mech->content_contains( $oxfordshire->response_priorities->first->description ); +}; + +subtest "response priorities are limited by body" => sub { + my $bromleypriority = $bromley->response_priorities->create( { + deleted => 0, + name => "Bromley Cat 0", + } ); + + is $bromley->response_priorities->count, 1, "Response priority was added to Bromley"; + is $oxfordshire->response_priorities->count, 1, "Response priority wasn't added to Oxfordshire"; + + $mech->get_ok( "/admin/responsepriorities/" . $oxfordshire->id ); + $mech->content_lacks( $bromleypriority->name ); + + $mech->get_ok( "/admin/responsepriorities/" . $bromley->id ); + $mech->content_contains( $bromleypriority->name ); +}; + +$mech->log_out_ok; + +subtest "response priorities can't be viewed across councils" => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'oxfordshire' ], + }, sub { + $oxfordshireuser->user_body_permissions->create({ + body => $oxfordshire, + permission_type => 'responsepriority_edit', + }); + $mech->log_in_ok( $oxfordshireuser->email ); + $mech->get_ok( "/admin/responsepriorities/" . $oxfordshire->id ); + $mech->content_contains( $oxfordshire->response_priorities->first->name ); + + + $mech->get( "/admin/responsepriorities/" . $bromley->id ); + ok !$mech->res->is_success(), "want a bad response"; + is $mech->res->code, 404, "got 404"; + + my $bromley_priority_id = $bromley->response_priorities->first->id; + $mech->get( "/admin/responsepriorities/" . $bromley->id . "/" . $bromley_priority_id ); + ok !$mech->res->is_success(), "want a bad response"; + is $mech->res->code, 404, "got 404"; + }; +}; + +done_testing(); diff --git a/t/app/controller/admin/report_edit.t b/t/app/controller/admin/report_edit.t new file mode 100644 index 000000000..a8a0bd143 --- /dev/null +++ b/t/app/controller/admin/report_edit.t @@ -0,0 +1,556 @@ +use FixMyStreet::TestMech; +# avoid wide character warnings from the category change message +use open ':std', ':encoding(UTF-8)'; + +my $mech = FixMyStreet::TestMech->new; + +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'); +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 $oxford = $mech->create_body_ok(2421, 'Oxford City Council'); +$mech->create_contact_ok( body_id => $oxford->id, category => 'Graffiti', email => 'graffiti@example.net' ); + +my $dt = DateTime->new( + year => 2011, + month => 04, + day => 16, + hour => 15, + minute => 47, + second => 23 +); + +my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( + { + postcode => 'SW1A 1AA', + bodies_str => '2504', + areas => ',105255,11806,11828,2247,2504,', + category => 'Other', + title => 'Report to Edit', + detail => 'Detail for Report to Edit', + used_map => 't', + name => 'Test User', + anonymous => 'f', + external_id => '13', + state => 'confirmed', + confirmed => $dt->ymd . ' ' . $dt->hms, + lang => 'en-gb', + service => '', + cobrand => '', + cobrand_data => '', + send_questionnaire => 't', + latitude => '51.5016605453401', + longitude => '-0.142497580865087', + user_id => $user->id, + whensent => $dt->ymd . ' ' . $dt->hms, + } +); + +$mech->log_in_ok( $superuser->email ); + +my $log_entries = FixMyStreet::App->model('DB::AdminLog')->search( + { + object_type => 'problem', + object_id => $report->id + }, + { + order_by => { -desc => 'id' }, + } +); + +is $log_entries->count, 0, 'no admin log entries'; + +my $report_id = $report->id; +ok $report, "created test report - $report_id"; + +foreach my $test ( + { + description => 'edit report title', + fields => { + title => 'Report to Edit', + detail => 'Detail for Report to Edit', + state => 'confirmed', + name => 'Test User', + username => $user->email, + anonymous => 0, + flagged => undef, + non_public => undef, + }, + changes => { title => 'Edited Report', }, + log_entries => [qw/edit/], + resend => 0, + }, + { + description => 'edit report description', + fields => { + title => 'Edited Report', + detail => 'Detail for Report to Edit', + state => 'confirmed', + name => 'Test User', + username => $user->email, + anonymous => 0, + flagged => undef, + non_public => undef, + }, + changes => { detail => 'Edited Detail', }, + log_entries => [qw/edit edit/], + resend => 0, + }, + { + description => 'edit report user name', + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'confirmed', + name => 'Test User', + username => $user->email, + anonymous => 0, + flagged => undef, + non_public => undef, + }, + changes => { name => 'Edited User', }, + log_entries => [qw/edit edit edit/], + resend => 0, + user => $user, + }, + { + description => 'edit report set flagged true', + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'confirmed', + name => 'Edited User', + username => $user->email, + anonymous => 0, + flagged => undef, + non_public => undef, + }, + changes => { + flagged => 'on', + }, + log_entries => [qw/edit edit edit edit/], + resend => 0, + user => $user, + }, + { + description => 'edit report user email', + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'confirmed', + name => 'Edited User', + username => $user->email, + anonymous => 0, + flagged => 'on', + non_public => undef, + }, + changes => { username => $user2->email, }, + log_entries => [qw/edit edit edit edit edit/], + resend => 0, + user => $user2, + }, + { + description => 'change state to unconfirmed', + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'confirmed', + name => 'Edited User', + username => $user2->email, + anonymous => 0, + flagged => 'on', + non_public => undef, + }, + expect_comment => 1, + changes => { state => 'unconfirmed' }, + log_entries => [qw/edit state_change edit edit edit edit edit/], + resend => 0, + }, + { + description => 'change state to confirmed', + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'unconfirmed', + name => 'Edited User', + username => $user2->email, + anonymous => 0, + flagged => 'on', + non_public => undef, + }, + expect_comment => 1, + changes => { state => 'confirmed' }, + log_entries => [qw/edit state_change edit state_change edit edit edit edit edit/], + resend => 0, + }, + { + description => 'change state to fixed', + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'confirmed', + name => 'Edited User', + username => $user2->email, + anonymous => 0, + flagged => 'on', + non_public => undef, + }, + expect_comment => 1, + changes => { state => 'fixed' }, + log_entries => + [qw/edit state_change edit state_change edit state_change edit edit edit edit edit/], + resend => 0, + }, + { + description => 'change state to hidden', + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'fixed', + name => 'Edited User', + username => $user2->email, + anonymous => 0, + flagged => 'on', + non_public => undef, + }, + expect_comment => 1, + changes => { state => 'hidden' }, + log_entries => [ + qw/edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/ + ], + resend => 0, + }, + { + description => 'edit and change state', + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'hidden', + name => 'Edited User', + username => $user2->email, + anonymous => 0, + flagged => 'on', + non_public => undef, + }, + expect_comment => 1, + changes => { + state => 'confirmed', + anonymous => 1, + }, + log_entries => [ + qw/edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/ + ], + resend => 0, + }, + { + description => 'resend', + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'confirmed', + name => 'Edited User', + username => $user2->email, + anonymous => 1, + flagged => 'on', + non_public => undef, + }, + changes => {}, + log_entries => [ + qw/resend edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/ + ], + resend => 1, + }, + { + description => 'non public', + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'confirmed', + name => 'Edited User', + username => $user2->email, + anonymous => 1, + flagged => 'on', + non_public => undef, + }, + changes => { + non_public => 'on', + }, + log_entries => [ + qw/edit resend edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/ + ], + resend => 0, + }, + { + description => 'change state to investigating as body superuser', + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'confirmed', + name => 'Edited User', + username => $user2->email, + anonymous => 1, + flagged => 'on', + non_public => 'on', + }, + expect_comment => 1, + user_body => $oxfordshire, + changes => { state => 'investigating' }, + log_entries => [ + qw/edit state_change edit resend edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/ + ], + resend => 0, + }, + { + description => 'change state to in progess and change category as body superuser', + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'investigating', + name => 'Edited User', + username => $user2->email, + anonymous => 1, + flagged => 'on', + non_public => 'on', + }, + expect_comment => 1, + expected_text => '*Category changed from ‘Other’ to ‘Potholes’*', + user_body => $oxfordshire, + changes => { state => 'in progress', category => 'Potholes' }, + log_entries => [ + qw/edit state_change edit state_change edit resend edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/ + ], + resend => 0, + }, + ) +{ + subtest $test->{description} => sub { + $report->comments->delete; + $log_entries->reset; + + if ( $test->{user_body} ) { + $superuser->from_body( $test->{user_body}->id ); + $superuser->update; + } + + $mech->get_ok("/admin/report_edit/$report_id"); + + @{$test->{fields}}{'external_id', 'external_body', 'external_team', 'category'} = (13, "", "", "Other"); + is_deeply( $mech->visible_form_values(), $test->{fields}, 'initial form values' ); + + my $new_fields = { + %{ $test->{fields} }, + %{ $test->{changes} }, + }; + + if ( $test->{resend} ) { + $mech->click_ok( 'resend' ); + } else { + $mech->submit_form_ok( { with_fields => $new_fields }, 'form_submitted' ); + } + + is_deeply( $mech->visible_form_values(), $new_fields, 'changed form values' ); + is $log_entries->count, scalar @{$test->{log_entries}}, 'log entry count'; + is $log_entries->next->action, $_, 'log entry added' for @{ $test->{log_entries} }; + + $report->discard_changes; + + if ($report->state eq 'confirmed' && $report->whensent) { + $mech->content_contains( 'type="submit" name="resend"', 'resend button' ); + } else { + $mech->content_lacks( 'type="submit" name="resend"', 'no resend button' ); + } + + $test->{changes}->{flagged} = 1 if $test->{changes}->{flagged}; + $test->{changes}->{non_public} = 1 if $test->{changes}->{non_public}; + + is $report->$_, $test->{changes}->{$_}, "$_ updated" for grep { $_ ne 'username' } keys %{ $test->{changes} }; + + if ( $test->{user} ) { + is $report->user->id, $test->{user}->id, 'user changed'; + } + + if ( $test->{resend} ) { + $mech->content_contains( 'That problem will now be resent' ); + is $report->whensent, undef, 'mark report to resend'; + } + + if ( $test->{expect_comment} ) { + my $comment = $report->comments->first; + ok $comment, 'report status change creates comment'; + is $report->comments->count, 1, 'report only has one comment'; + if ($test->{expected_text}) { + is $comment->text, $test->{expected_text}, 'comment has expected text'; + } else { + is $comment->text, '', 'comment has no text'; + } + if ( $test->{user_body} ) { + ok $comment->get_extra_metadata('is_body_user'), 'body user metadata set'; + ok !$comment->get_extra_metadata('is_superuser'), 'superuser metadata not set'; + is $comment->name, $test->{user_body}->name, 'comment name is body name'; + } else { + ok !$comment->get_extra_metadata('is_body_user'), 'body user metadata not set'; + ok $comment->get_extra_metadata('is_superuser'), 'superuser metadata set'; + is $comment->name, _('an administrator'), 'comment name is admin'; + } + } else { + is $report->comments->count, 0, 'report has no comments'; + } + + $superuser->from_body(undef); + $superuser->update; + }; +} + +FixMyStreet::override_config { + ALLOWED_COBRANDS => 'fixmystreet', +}, sub { + +subtest 'change report category' => sub { + my ($ox_report) = $mech->create_problems_for_body(1, $oxfordshire->id, 'Unsure', { + category => 'Potholes', + areas => ',2237,2421,', # Cached used by categories_for_point... + latitude => 51.7549262252, + longitude => -1.25617899435, + whensent => \'current_timestamp', + }); + $mech->get_ok("/admin/report_edit/" . $ox_report->id); + + $mech->submit_form_ok( { with_fields => { category => 'Traffic lights' } }, 'form_submitted' ); + $ox_report->discard_changes; + is $ox_report->category, 'Traffic lights'; + isnt $ox_report->whensent, undef; + is $ox_report->comments->count, 1, "Comment created for update"; + is $ox_report->comments->first->text, '*Category changed from ‘Potholes’ to ‘Traffic lights’*', 'Comment text correct'; + + $mech->submit_form_ok( { with_fields => { category => 'Graffiti' } }, 'form_submitted' ); + $ox_report->discard_changes; + is $ox_report->category, 'Graffiti'; + is $ox_report->whensent, undef; +}; + +}; + +subtest 'change email to new user' => sub { + $log_entries->delete; + $mech->get_ok("/admin/report_edit/$report_id"); + my $fields = { + title => $report->title, + detail => $report->detail, + state => $report->state, + name => $report->name, + username => $report->user->email, + category => 'Potholes', + anonymous => 1, + flagged => 'on', + non_public => 'on', + external_id => '13', + external_body => '', + external_team => '', + }; + + is_deeply( $mech->visible_form_values(), $fields, 'initial form values' ); + + my $changes = { + username => 'test3@example.com' + }; + + my $user3 = FixMyStreet::App->model('DB::User')->find( { email => 'test3@example.com' } ); + + ok !$user3, 'user not in database'; + + my $new_fields = { + %{ $fields }, + %{ $changes }, + }; + + $mech->submit_form_ok( + { + with_fields => $new_fields, + } + ); + + is $log_entries->count, 1, 'created admin log entries'; + is $log_entries->first->action, 'edit', 'log action'; + is_deeply( $mech->visible_form_values(), $new_fields, 'changed form values' ); + + $user3 = FixMyStreet::App->model('DB::User')->find( { email => 'test3@example.com' } ); + + $report->discard_changes; + + ok $user3, 'new user created'; + is $report->user_id, $user3->id, 'user changed to new user'; +}; + +subtest 'adding email to abuse list from report page' => sub { + my $email = $report->user->email; + + my $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $email } ); + $abuse->delete if $abuse; + + $mech->get_ok( '/admin/report_edit/' . $report->id ); + $mech->content_contains('Ban user'); + + $mech->click_ok('banuser'); + + $mech->content_contains('User added to abuse list'); + $mech->content_contains('User in abuse table'); + + $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $email } ); + ok $abuse, 'entry created in abuse table'; + + $mech->get_ok( '/admin/report_edit/' . $report->id ); + $mech->content_contains('User in abuse table'); +}; + +subtest 'flagging user from report page' => sub { + $report->user->flagged(0); + $report->user->update; + + $mech->get_ok( '/admin/report_edit/' . $report->id ); + $mech->content_contains('Flag user'); + + $mech->click_ok('flaguser'); + + $mech->content_contains('User flagged'); + $mech->content_contains('Remove flag'); + + $report->discard_changes; + ok $report->user->flagged, 'user flagged'; + + $mech->get_ok( '/admin/report_edit/' . $report->id ); + $mech->content_contains('Remove flag'); +}; + +subtest 'unflagging user from report page' => sub { + $report->user->flagged(1); + $report->user->update; + + $mech->get_ok( '/admin/report_edit/' . $report->id ); + $mech->content_contains('Remove flag'); + + $mech->click_ok('removeuserflag'); + + $mech->content_contains('User flag removed'); + $mech->content_contains('Flag user'); + + $report->discard_changes; + ok !$report->user->flagged, 'user not flagged'; + + $mech->get_ok( '/admin/report_edit/' . $report->id ); + $mech->content_contains('Flag user'); +}; + +subtest "Test setting a report from unconfirmed to something else doesn't cause a front end error" => sub { + $report->update( { confirmed => undef, state => 'unconfirmed', non_public => 0 } ); + $mech->get_ok("/admin/report_edit/$report_id"); + $mech->submit_form_ok( { with_fields => { state => 'investigating' } } ); + $report->discard_changes; + ok( $report->confirmed, 'report has a confirmed timestamp' ); + $mech->get_ok("/report/$report_id"); +}; + +done_testing(); 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/search.t b/t/app/controller/admin/search.t new file mode 100644 index 000000000..497ac9fd6 --- /dev/null +++ b/t/app/controller/admin/search.t @@ -0,0 +1,121 @@ +use FixMyStreet::TestMech; +# avoid wide character warnings from the category change message +use open ':std', ':encoding(UTF-8)'; + +my $mech = FixMyStreet::TestMech->new; + +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'); +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); + +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'); + +my $user3 = FixMyStreet::App->model('DB::User')->create( { email => 'test3@example.com' } ); + +my $dt = DateTime->new( + year => 2011, + month => 04, + day => 16, + hour => 15, + minute => 47, + second => 23 +); + +my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( + { + postcode => 'SW1A 1AA', + bodies_str => '2504', + areas => ',105255,11806,11828,2247,2504,', + category => 'Other', + title => 'Report to Edit', + detail => 'Detail for Report to Edit', + used_map => 't', + name => 'Test User', + anonymous => 'f', + external_id => '13', + state => 'confirmed', + confirmed => $dt->ymd . ' ' . $dt->hms, + lang => 'en-gb', + service => '', + cobrand => '', + cobrand_data => '', + send_questionnaire => 't', + latitude => '51.5016605453401', + longitude => '-0.142497580865087', + user_id => $user->id, + whensent => $dt->ymd . ' ' . $dt->hms, + } +); +my $report_id = $report->id; +ok $report, "created test report - $report_id"; + +$mech->log_in_ok( $superuser->email ); + +subtest 'show flagged entries' => sub { + $report->flagged( 1 ); + $report->update; + $mech->get_ok('/admin/flagged'); + $mech->content_contains( $report->title ); +}; + +my $update = FixMyStreet::App->model('DB::Comment')->create( + { + text => 'this is an update', + user => $user, + state => 'confirmed', + problem => $report, + mark_fixed => 0, + anonymous => 1, + } +); + +subtest 'report search' => sub { + $mech->get_ok('/admin/reports'); + $mech->get_ok('/admin/reports?search=' . $report->id ); + + $mech->content_contains( $report->title ); + my $r_id = $report->id; + $mech->content_like( qr{href="http://[^/]*[^.]/report/$r_id"[^>]*>$r_id} ); + + $mech->get_ok('/admin/reports?search=' . $report->external_id); + $mech->content_like( qr{href="http://[^/]*[^.]/report/$r_id"[^>]*>$r_id} ); + + $mech->get_ok('/admin/reports?search=ref:' . $report->external_id); + $mech->content_like( qr{href="http://[^/]*[^.]/report/$r_id"[^>]*>$r_id} ); + + $mech->get_ok('/admin/reports?search=' . $report->user->email); + + my $u_id = $update->id; + $mech->content_like( qr{href="http://[^/]*[^.]/report/$r_id"[^>]*>$r_id} ); + $mech->content_like( qr{href="http://[^/]*[^.]/report/$r_id#update_$u_id"[^>]*>$u_id} ); + + $update->state('hidden'); + $update->update; + + $mech->get_ok('/admin/reports?search=' . $report->user->email); + $mech->content_like( qr{]*hidden[^>]*> \s* \s* $u_id \s* }xs ); + + $report->state('hidden'); + $report->update; + + $mech->get_ok('/admin/reports?search=' . $report->user->email); + $mech->content_like( qr{]*hidden[^>]*> \s* ]*> \s* $r_id \s* }xs ); + + $report->state('fixed - user'); + $report->update; + + $mech->get_ok('/admin/reports?search=' . $report->user->email); + $mech->content_like( qr{href="http://[^/]*[^.]/report/$r_id"[^>]*>$r_id} ); +}; + +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/stats.t b/t/app/controller/admin/stats.t new file mode 100644 index 000000000..dae51d31f --- /dev/null +++ b/t/app/controller/admin/stats.t @@ -0,0 +1,12 @@ +use FixMyStreet::TestMech; + +my $mech = FixMyStreet::TestMech->new; +my $superuser = $mech->create_user_ok('superuser@example.com', name => 'Super User', is_superuser => 1); + +subtest "smoke view some stats pages" => sub { + $mech->log_in_ok( $superuser->email ); + $mech->get_ok('/admin/stats/fix-rate'); + $mech->get_ok('/admin/stats/questionnaire'); +}; + +done_testing(); diff --git a/t/app/controller/admin/templates.t b/t/app/controller/admin/templates.t new file mode 100644 index 000000000..179a1afcb --- /dev/null +++ b/t/app/controller/admin/templates.t @@ -0,0 +1,183 @@ +use FixMyStreet::TestMech; + +my $mech = FixMyStreet::TestMech->new; + +my $user = $mech->create_user_ok('test@example.com', name => 'Test User'); + +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'); +my $oxfordshirecontact = $mech->create_contact_ok( body_id => $oxfordshire->id, category => 'Potholes', email => 'potholes@example.com' ); +my $oxfordshireuser = $mech->create_user_ok('counciluser@example.com', name => 'Council User', from_body => $oxfordshire); + +my $dt = DateTime->new( + year => 2011, + month => 04, + day => 16, + hour => 15, + minute => 47, + second => 23 +); + +my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( + { + postcode => 'SW1A 1AA', + bodies_str => '2504', + areas => ',105255,11806,11828,2247,2504,', + category => 'Other', + title => 'Report to Edit', + detail => 'Detail for Report to Edit', + used_map => 't', + name => 'Test User', + anonymous => 'f', + external_id => '13', + state => 'confirmed', + confirmed => $dt->ymd . ' ' . $dt->hms, + lang => 'en-gb', + service => '', + cobrand => '', + cobrand_data => '', + send_questionnaire => 't', + latitude => '51.5016605453401', + longitude => '-0.142497580865087', + user_id => $user->id, + whensent => $dt->ymd . ' ' . $dt->hms, + } +); + +$mech->log_in_ok( $superuser->email ); + +my $report_id = $report->id; +ok $report, "created test report - $report_id"; + +subtest "response templates can be added" => sub { + is $oxfordshire->response_templates->count, 0, "No response templates yet"; + $mech->log_in_ok( $superuser->email ); + $mech->get_ok( "/admin/templates/" . $oxfordshire->id . "/new" ); + + my $fields = { + title => "Report acknowledgement", + text => "Thank you for your report. We will respond shortly.", + auto_response => undef, + "contacts[".$oxfordshirecontact->id."]" => 1, + }; + $mech->submit_form_ok( { with_fields => $fields } ); + + is $oxfordshire->response_templates->count, 1, "Response template was added"; +}; + +subtest "response templates are included on page" => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'oxfordshire' ], + }, sub { + $report->update({ category => $oxfordshirecontact->category, bodies_str => $oxfordshire->id }); + $mech->log_in_ok( $oxfordshireuser->email ); + + $mech->get_ok("/report/" . $report->id); + $mech->content_contains( $oxfordshire->response_templates->first->text ); + + $mech->log_out_ok; + }; +}; + +subtest "auto-response templates that duplicate a single category can't be added" => sub { + $mech->delete_response_template($_) for $oxfordshire->response_templates; + my $template = $oxfordshire->response_templates->create({ + title => "Report fixed - potholes", + text => "Thank you for your report. This problem has been fixed.", + auto_response => 1, + state => 'fixed - council', + }); + $template->contact_response_templates->find_or_create({ + contact_id => $oxfordshirecontact->id, + }); + is $oxfordshire->response_templates->count, 1, "Initial response template was created"; + + + $mech->log_in_ok( $superuser->email ); + $mech->get_ok( "/admin/templates/" . $oxfordshire->id . "/new" ); + + # This response template has the same category & state as an existing one + # so won't be allowed. + my $fields = { + title => "Report marked fixed - potholes", + text => "Thank you for your report. This pothole has been fixed.", + auto_response => 'on', + state => 'fixed - council', + "contacts[".$oxfordshirecontact->id."]" => 1, + }; + $mech->submit_form_ok( { with_fields => $fields } ); + is $mech->uri->path, '/admin/templates/' . $oxfordshire->id . '/new', 'not redirected'; + $mech->content_contains( 'Please correct the errors below' ); + $mech->content_contains( 'There is already an auto-response template for this category/state.' ); + + is $oxfordshire->response_templates->count, 1, "Duplicate response template wasn't added"; +}; + +subtest "auto-response templates that duplicate all categories can't be added" => sub { + $mech->delete_response_template($_) for $oxfordshire->response_templates; + $oxfordshire->response_templates->create({ + title => "Report investigating - all cats", + text => "Thank you for your report. This problem has been fixed.", + auto_response => 1, + state => 'fixed - council', + }); + is $oxfordshire->response_templates->count, 1, "Initial response template was created"; + + + $mech->log_in_ok( $superuser->email ); + $mech->get_ok( "/admin/templates/" . $oxfordshire->id . "/new" ); + + # There's already a response template for all categories and this state, so + # this new template won't be allowed. + my $fields = { + title => "Report investigating - single cat", + text => "Thank you for your report. This problem has been fixed.", + auto_response => 'on', + state => 'fixed - council', + "contacts[".$oxfordshirecontact->id."]" => 1, + }; + $mech->submit_form_ok( { with_fields => $fields } ); + is $mech->uri->path, '/admin/templates/' . $oxfordshire->id . '/new', 'not redirected'; + $mech->content_contains( 'Please correct the errors below' ); + $mech->content_contains( 'There is already an auto-response template for this category/state.' ); + + + is $oxfordshire->response_templates->count, 1, "Duplicate response template wasn't added"; +}; + +subtest "all-category auto-response templates that duplicate a single category can't be added" => sub { + $mech->delete_response_template($_) for $oxfordshire->response_templates; + my $template = $oxfordshire->response_templates->create({ + title => "Report fixed - potholes", + text => "Thank you for your report. This problem has been fixed.", + auto_response => 1, + state => 'fixed - council', + }); + $template->contact_response_templates->find_or_create({ + contact_id => $oxfordshirecontact->id, + }); + is $oxfordshire->response_templates->count, 1, "Initial response template was created"; + + + $mech->log_in_ok( $superuser->email ); + $mech->get_ok( "/admin/templates/" . $oxfordshire->id . "/new" ); + + # This response template is implicitly for all categories, but there's + # already a template for a specific category in this state, so it won't be + # allowed. + my $fields = { + title => "Report marked fixed - all cats", + text => "Thank you for your report. This problem has been fixed.", + auto_response => 'on', + state => 'fixed - council', + }; + $mech->submit_form_ok( { with_fields => $fields } ); + is $mech->uri->path, '/admin/templates/' . $oxfordshire->id . '/new', 'not redirected'; + $mech->content_contains( 'Please correct the errors below' ); + $mech->content_contains( 'There is already an auto-response template for this category/state.' ); + + is $oxfordshire->response_templates->count, 1, "Duplicate response template wasn't added"; +}; + +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/admin/update_edit.t b/t/app/controller/admin/update_edit.t new file mode 100644 index 000000000..6ddbdbdfc --- /dev/null +++ b/t/app/controller/admin/update_edit.t @@ -0,0 +1,383 @@ +use FixMyStreet::TestMech; +# avoid wide character warnings from the category change message +use open ':std', ':encoding(UTF-8)'; + +my $mech = FixMyStreet::TestMech->new; + +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 $user3 = FixMyStreet::App->model('DB::User')->create( { email => 'test3@example.com' } ); + +my $dt = DateTime->new( + year => 2011, + month => 04, + day => 16, + hour => 15, + minute => 47, + second => 23 +); + +my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( + { + postcode => 'SW1A 1AA', + bodies_str => '2504', + areas => ',105255,11806,11828,2247,2504,', + category => 'Other', + title => 'Report to Edit', + detail => 'Detail for Report to Edit', + used_map => 't', + name => 'Test User', + anonymous => 'f', + external_id => '13', + state => 'confirmed', + confirmed => $dt->ymd . ' ' . $dt->hms, + lang => 'en-gb', + service => '', + cobrand => '', + cobrand_data => '', + send_questionnaire => 't', + latitude => '51.5016605453401', + longitude => '-0.142497580865087', + user_id => $user->id, + whensent => $dt->ymd . ' ' . $dt->hms, + } +); + +$mech->log_in_ok( $superuser->email ); + +my $report_id = $report->id; +ok $report, "created test report - $report_id"; + +my $update = FixMyStreet::App->model('DB::Comment')->create( + { + text => 'this is an update', + user => $user, + state => 'confirmed', + problem => $report, + mark_fixed => 0, + anonymous => 1, + } +); + +my $log_entries = FixMyStreet::App->model('DB::AdminLog')->search( + { + object_type => 'update', + object_id => $update->id + }, + { + order_by => { -desc => 'id' }, + } +); + +is $log_entries->count, 0, 'no admin log entries'; + +for my $test ( + { + desc => 'edit update text', + fields => { + text => 'this is an update', + state => 'confirmed', + name => '', + anonymous => 1, + username => 'test@example.com', + }, + changes => { + text => 'this is a changed update', + }, + log_count => 1, + log_entries => [qw/edit/], + }, + { + desc => 'edit update name', + fields => { + text => 'this is a changed update', + state => 'confirmed', + name => '', + anonymous => 1, + username => 'test@example.com', + }, + changes => { + name => 'A User', + }, + log_count => 2, + log_entries => [qw/edit edit/], + }, + { + desc => 'edit update anonymous', + fields => { + text => 'this is a changed update', + state => 'confirmed', + name => 'A User', + anonymous => 1, + username => 'test@example.com', + }, + changes => { + anonymous => 0, + }, + log_count => 3, + log_entries => [qw/edit edit edit/], + }, + { + desc => 'edit update user', + fields => { + text => 'this is a changed update', + state => 'confirmed', + name => 'A User', + anonymous => 0, + username => 'test@example.com', + }, + changes => { + username => 'test2@example.com', + }, + log_count => 4, + log_entries => [qw/edit edit edit edit/], + user => $user2, + }, + { + desc => 'edit update state', + fields => { + text => 'this is a changed update', + state => 'confirmed', + name => 'A User', + anonymous => 0, + username => 'test2@example.com', + }, + changes => { + state => 'unconfirmed', + }, + log_count => 5, + log_entries => [qw/state_change edit edit edit edit/], + }, + { + desc => 'edit update state and text', + fields => { + text => 'this is a changed update', + state => 'unconfirmed', + name => 'A User', + anonymous => 0, + username => 'test2@example.com', + }, + changes => { + text => 'this is a twice changed update', + state => 'confirmed', + }, + log_count => 7, + log_entries => [qw/edit state_change state_change edit edit edit edit/], + }, +) { + subtest $test->{desc} => sub { + $log_entries->reset; + $mech->get_ok('/admin/update_edit/' . $update->id ); + + is_deeply $mech->visible_form_values, $test->{fields}, 'initial form values'; + + my $to_submit = { + %{ $test->{fields} }, + %{ $test->{changes} } + }; + + $mech->submit_form_ok( { with_fields => $to_submit } ); + + is_deeply $mech->visible_form_values, $to_submit, 'submitted form values'; + + is $log_entries->count, $test->{log_count}, 'number of log entries'; + is $log_entries->next->action, $_, 'log action' for @{ $test->{log_entries} }; + + $update->discard_changes; + + is $update->$_, $test->{changes}->{$_} for grep { $_ ne 'username' } keys %{ $test->{changes} }; + if ( $test->{changes}{state} && $test->{changes}{state} eq 'confirmed' ) { + isnt $update->confirmed, undef; + } + + if ( $test->{user} ) { + is $update->user->id, $test->{user}->id, 'update user'; + } + }; +} + +my $westminster = $mech->create_body_ok(2504, 'Westminster City Council'); +$report->bodies_str($westminster->id); +$report->update; + +for my $test ( + { + desc => 'user is problem owner', + problem_user => $user, + update_user => $user, + update_fixed => 0, + update_reopen => 0, + update_state => undef, + user_body => undef, + content => 'user is problem owner', + }, + { + desc => 'user is body user', + problem_user => $user, + update_user => $user2, + update_fixed => 0, + update_reopen => 0, + update_state => undef, + user_body => $westminster->id, + content => 'user is from same council as problem - ' . $westminster->id, + }, + { + desc => 'update changed problem state', + problem_user => $user, + update_user => $user2, + update_fixed => 0, + update_reopen => 0, + update_state => 'planned', + user_body => $westminster->id, + content => 'Update changed problem state to planned', + }, + { + desc => 'update marked problem as fixed', + problem_user => $user, + update_user => $user3, + update_fixed => 1, + update_reopen => 0, + update_state => undef, + user_body => undef, + content => 'Update marked problem as fixed', + }, + { + desc => 'update reopened problem', + problem_user => $user, + update_user => $user, + update_fixed => 0, + update_reopen => 1, + update_state => undef, + user_body => undef, + content => 'Update reopened problem', + }, +) { + subtest $test->{desc} => sub { + $report->user( $test->{problem_user} ); + $report->update; + + $update->user( $test->{update_user} ); + $update->problem_state( $test->{update_state} ); + $update->mark_fixed( $test->{update_fixed} ); + $update->mark_open( $test->{update_reopen} ); + $update->update; + + $test->{update_user}->from_body( $test->{user_body} ); + $test->{update_user}->update; + + $mech->get_ok('/admin/update_edit/' . $update->id ); + $mech->content_contains( $test->{content} ); + }; +} + +subtest 'editing update email creates new user if required' => sub { + my $user = FixMyStreet::App->model('DB::User')->find( { email => 'test4@example.com' } ); + + $user->delete if $user; + + my $fields = { + text => 'this is a changed update', + state => 'confirmed', + name => 'A User', + anonymous => 0, + username => 'test4@example.com', + }; + + $mech->submit_form_ok( { with_fields => $fields } ); + + $user = FixMyStreet::App->model('DB::User')->find( { email => 'test4@example.com' } ); + + is_deeply $mech->visible_form_values, $fields, 'submitted form values'; + + ok $user, 'new user created'; + + $update->discard_changes; + is $update->user->id, $user->id, 'update set to new user'; +}; + +subtest 'adding email to abuse list from update page' => sub { + my $email = $update->user->email; + + my $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $email } ); + $abuse->delete if $abuse; + + $mech->get_ok( '/admin/update_edit/' . $update->id ); + $mech->content_contains('Ban user'); + + $mech->click_ok('banuser'); + + $mech->content_contains('User added to abuse list'); + $mech->content_contains('User in abuse table'); + + $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $email } ); + ok $abuse, 'entry created in abuse table'; + + $mech->get_ok( '/admin/update_edit/' . $update->id ); + $mech->content_contains('User in abuse table'); +}; + +subtest 'flagging user from update page' => sub { + $update->user->flagged(0); + $update->user->update; + + $mech->get_ok( '/admin/update_edit/' . $update->id ); + $mech->content_contains('Flag user'); + + $mech->click_ok('flaguser'); + + $mech->content_contains('User flagged'); + $mech->content_contains('Remove flag'); + + $update->discard_changes; + ok $update->user->flagged, 'user flagged'; + + $mech->get_ok( '/admin/update_edit/' . $update->id ); + $mech->content_contains('Remove flag'); +}; + +subtest 'unflagging user from update page' => sub { + $update->user->flagged(1); + $update->user->update; + + $mech->get_ok( '/admin/update_edit/' . $update->id ); + $mech->content_contains('Remove flag'); + + $mech->click_ok('removeuserflag'); + + $mech->content_contains('User flag removed'); + $mech->content_contains('Flag user'); + + $update->discard_changes; + ok !$update->user->flagged, 'user not flagged'; + + $mech->get_ok( '/admin/update_edit/' . $update->id ); + $mech->content_contains('Flag user'); +}; + +subtest 'hiding comment marked as fixed reopens report' => sub { + $update->mark_fixed( 1 ); + $update->update; + + $report->state('fixed - user'); + $report->update; + + my $fields = { + text => 'this is a changed update', + state => 'hidden', + name => 'A User', + anonymous => 0, + username => 'test2@example.com', + }; + + $mech->submit_form_ok( { with_fields => $fields } ); + + $report->discard_changes; + is $report->state, 'confirmed', 'report reopened'; + $mech->content_contains('Problem marked as open'); +}; + +done_testing(); diff --git a/t/app/controller/admin/users.t b/t/app/controller/admin/users.t new file mode 100644 index 000000000..e6cf51449 --- /dev/null +++ b/t/app/controller/admin/users.t @@ -0,0 +1,413 @@ +use FixMyStreet::TestMech; + +my $mech = FixMyStreet::TestMech->new; + +my $user = $mech->create_user_ok('test@example.com', name => 'Test User'); + +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'); +my $haringey = $mech->create_body_ok(2509, 'Haringey Borough Council'); +my $southend = $mech->create_body_ok(2607, 'Southend-on-Sea Borough Council'); + +$mech->log_in_ok( $superuser->email ); + +subtest 'search abuse' => sub { + my $abuse = FixMyStreet::App->model('DB::Abuse')->find_or_create( { email => $user->email } ); + $mech->get_ok( '/admin/users?search=example' ); + $mech->content_like(qr{test\@example.com.*\s*.*?\s*User in abuse table}s); +}; + +subtest 'remove user from abuse list from edit user page' => sub { + $mech->get_ok( '/admin/user_edit/' . $user->id ); + $mech->content_contains('User in abuse table'); + + $mech->click_ok('unban'); + + my $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $user->email } ); + ok !$abuse, 'record removed from abuse table'; +}; + +subtest 'remove user with phone account from abuse list from edit user page' => sub { + my $abuse_user = $mech->create_user_ok('01234 456789'); + my $abuse = FixMyStreet::App->model('DB::Abuse')->find_or_create( { email => $abuse_user->phone } ); + $mech->get_ok( '/admin/user_edit/' . $abuse_user->id ); + $mech->content_contains('User in abuse table'); + my $abuse_found = FixMyStreet::App->model('DB::Abuse')->find( { email => $abuse_user->phone } ); + ok $abuse_found, 'user in abuse table'; + + $mech->click_ok('unban'); + + $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $user->phone } ); + ok !$abuse, 'record removed from abuse table'; +}; + +subtest 'no option to remove user already in abuse list' => sub { + my $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $user->email } ); + $abuse->delete if $abuse; + $mech->get_ok( '/admin/user_edit/' . $user->id ); + $mech->content_lacks('User in abuse table'); +}; + +subtest 'show flagged entries' => sub { + $user->flagged( 1 ); + $user->update; + + $mech->get_ok('/admin/flagged'); + $mech->content_contains( $user->email ); + + $user->flagged( 0 ); + $user->update; +}; + +subtest 'user search' => sub { + $mech->get_ok('/admin/users'); + $mech->get_ok('/admin/users?search=' . $user->name); + + $mech->content_contains( $user->name); + my $u_id = $user->id; + $mech->content_like( qr{user_edit/$u_id">Edit} ); + + $mech->get_ok('/admin/users?search=' . $user->email); + + $mech->content_like( qr{user_edit/$u_id">Edit} ); + + $user->from_body($haringey->id); + $user->update; + $mech->get_ok('/admin/users?search=' . $haringey->id ); + $mech->content_contains('Haringey'); +}; + +subtest 'search does not show user from another council' => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'oxfordshire' ], + }, sub { + $mech->get_ok('/admin/users'); + $mech->get_ok('/admin/users?search=' . $user->name); + + $mech->content_contains( "Searching found no users." ); + + $mech->get_ok('/admin/users?search=' . $user->email); + $mech->content_contains( "Searching found no users." ); + }; +}; + +subtest 'user_edit does not show user from another council' => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'oxfordshire' ], + }, sub { + $mech->get('/admin/user_edit/' . $user->id); + ok !$mech->res->is_success(), "want a bad response"; + is $mech->res->code, 404, "got 404"; + }; +}; + +for my $test ( + { + desc => 'add user - blank form', + fields => { + email => '', email_verified => 0, + phone => '', phone_verified => 0, + }, + error => ['Please verify at least one of email/phone', 'Please enter a name'], + }, + { + desc => 'add user - blank, verify phone', + fields => { + email => '', email_verified => 0, + phone => '', phone_verified => 1, + }, + error => ['Please enter a valid email or phone number', 'Please enter a name'], + }, + { + desc => 'add user - bad email', + fields => { + name => 'Norman', + email => 'bademail', email_verified => 0, + phone => '', phone_verified => 0, + }, + error => ['Please enter a valid email'], + }, + { + desc => 'add user - bad phone', + fields => { + name => 'Norman', + phone => '01214960000000', phone_verified => 1, + }, + error => ['Please check your phone number is correct'], + }, + { + desc => 'add user - landline', + fields => { + name => 'Norman Name', + phone => '+441214960000', + phone_verified => 1, + }, + error => ['Please enter a mobile number'], + }, + { + desc => 'add user - good details', + fields => { + name => 'Norman Name', + phone => '+61491570156', + phone_verified => 1, + }, + }, +) { + subtest $test->{desc} => sub { + $mech->get_ok('/admin/users'); + $mech->submit_form_ok( { with_fields => $test->{fields} } ); + if ($test->{error}) { + $mech->content_contains($_) for @{$test->{error}}; + } else { + $mech->content_contains('Updated'); + } + }; +} + +my %default_perms = ( + "permissions[moderate]" => undef, + "permissions[planned_reports]" => undef, + "permissions[report_edit]" => undef, + "permissions[report_edit_category]" => undef, + "permissions[report_edit_priority]" => undef, + "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, + "permissions[user_manage_permissions]" => undef, + "permissions[user_assign_body]" => undef, + "permissions[user_assign_areas]" => undef, + "permissions[template_edit]" => undef, + "permissions[responsepriority_edit]" => undef, + "permissions[category_edit]" => undef, + trusted_bodies => undef, +); + +# Start this section with user having no name +# Regression test for mysociety/fixmystreetforcouncils#250 +$user->update({ name => '' }); + +FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', +}, sub { + for my $test ( + { + desc => 'edit user name', + fields => { + name => '', + email => 'test@example.com', + body => $haringey->id, + phone => '', + flagged => undef, + is_superuser => undef, + area_id => '', + %default_perms, + }, + changes => { + name => 'Changed User', + }, + log_count => 1, + log_entries => [qw/edit/], + }, + { + desc => 'edit user email', + fields => { + name => 'Changed User', + email => 'test@example.com', + body => $haringey->id, + phone => '', + flagged => undef, + is_superuser => undef, + area_id => '', + %default_perms, + }, + changes => { + email => 'changed@example.com', + }, + log_count => 2, + log_entries => [qw/edit edit/], + }, + { + desc => 'edit user body', + fields => { + name => 'Changed User', + email => 'changed@example.com', + body => $haringey->id, + phone => '', + flagged => undef, + is_superuser => undef, + area_id => '', + %default_perms, + }, + changes => { + body => $southend->id, + }, + log_count => 3, + log_entries => [qw/edit edit edit/], + }, + { + desc => 'edit user flagged', + fields => { + name => 'Changed User', + email => 'changed@example.com', + body => $southend->id, + phone => '', + flagged => undef, + is_superuser => undef, + area_id => '', + %default_perms, + }, + changes => { + flagged => 'on', + }, + log_count => 4, + log_entries => [qw/edit edit edit edit/], + }, + { + desc => 'edit user remove flagged', + fields => { + name => 'Changed User', + email => 'changed@example.com', + body => $southend->id, + phone => '', + flagged => 'on', + is_superuser => undef, + area_id => '', + %default_perms, + }, + changes => { + flagged => undef, + }, + log_count => 4, + log_entries => [qw/edit edit edit edit/], + }, + { + desc => 'edit user add is_superuser', + fields => { + name => 'Changed User', + email => 'changed@example.com', + body => $southend->id, + phone => '', + flagged => undef, + is_superuser => undef, + area_id => '', + %default_perms, + }, + changes => { + is_superuser => 'on', + }, + removed => [ + keys %default_perms, + ], + log_count => 5, + log_entries => [qw/edit edit edit edit edit/], + }, + { + desc => 'edit user remove is_superuser', + fields => { + name => 'Changed User', + email => 'changed@example.com', + body => $southend->id, + phone => '', + flagged => undef, + is_superuser => 'on', + area_id => '', + }, + changes => { + is_superuser => undef, + }, + added => { + %default_perms, + }, + log_count => 5, + log_entries => [qw/edit edit edit edit edit/], + }, + ) { + subtest $test->{desc} => sub { + $mech->get_ok( '/admin/user_edit/' . $user->id ); + + my $visible = $mech->visible_form_values; + is_deeply $visible, $test->{fields}, 'expected user'; + + my $expected = { + %{ $test->{fields} }, + %{ $test->{changes} } + }; + + $mech->submit_form_ok( { with_fields => $expected } ); + + # Some actions cause visible fields to be added/removed + foreach my $x (@{ $test->{removed} }) { + delete $expected->{$x}; + } + if ( $test->{added} ) { + $expected = { + %$expected, + %{ $test->{added} } + }; + } + + $visible = $mech->visible_form_values; + is_deeply $visible, $expected, 'user updated'; + + $mech->content_contains( 'Updated!' ); + }; + } +}; + +FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + SMS_AUTHENTICATION => 1, +}, sub { + subtest "Test edit user add verified phone" => sub { + $mech->get_ok( '/admin/user_edit/' . $user->id ); + $mech->submit_form_ok( { with_fields => { + phone => '+61491570157', + phone_verified => 1, + } } ); + $mech->content_contains( 'Updated!' ); + }; + + subtest "Test changing user to an existing one" => sub { + my $existing_user = $mech->create_user_ok('existing@example.com', name => 'Existing User'); + $mech->create_problems_for_body(2, 2514, 'Title', { user => $existing_user }); + my $count = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id })->count; + $mech->get_ok( '/admin/user_edit/' . $user->id ); + $mech->submit_form_ok( { with_fields => { email => 'existing@example.com' } }, 'submit email change' ); + is $mech->uri->path, '/admin/user_edit/' . $existing_user->id, 'redirected'; + my $p = FixMyStreet::DB->resultset('Problem')->search({ user_id => $existing_user->id })->count; + is $p, $count + 2, 'reports merged'; + }; + +}; + +$user = $mech->create_user_ok('test@example.com', name => 'Test User'); + +subtest "Anonymizing user from admin" => sub { + $mech->create_problems_for_body(4, 2237, 'Title'); + my $count_p = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id })->count; + my $count_u = FixMyStreet::DB->resultset('Comment')->search({ user_id => $user->id })->count; + $mech->get_ok( '/admin/user_edit/' . $user->id ); + $mech->submit_form_ok({ button => 'anon_everywhere' }); + my $c = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id, anonymous => 1 })->count; + is $c, $count_p; + $c = FixMyStreet::DB->resultset('Comment')->search({ user_id => $user->id, anonymous => 1 })->count; + is $c, $count_u; +}; + +subtest "Hiding user's reports from admin" => sub { + my $count_p = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id })->count; + my $count_u = FixMyStreet::DB->resultset('Comment')->search({ user_id => $user->id })->count; + $mech->get_ok( '/admin/user_edit/' . $user->id ); + $mech->submit_form_ok({ button => 'hide_everywhere' }); + my $c = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id, state => 'hidden' })->count; + is $c, $count_p; + $c = FixMyStreet::DB->resultset('Comment')->search({ user_id => $user->id, state => 'hidden' })->count; + is $c, $count_u; +}; + +done_testing(); diff --git a/t/app/controller/admin_defecttypes.t b/t/app/controller/admin_defecttypes.t deleted file mode 100644 index e7d0e42af..000000000 --- a/t/app/controller/admin_defecttypes.t +++ /dev/null @@ -1,193 +0,0 @@ -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 deleted file mode 100644 index 7944cc0b1..000000000 --- a/t/app/controller/admin_permissions.t +++ /dev/null @@ -1,196 +0,0 @@ -use FixMyStreet::TestMech; - -my $mech = FixMyStreet::TestMech->new; - -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'); -my $oxfordshireuser = $mech->create_user_ok('counciluser@example.com', name => 'Council User', from_body => $oxfordshire); - -my $bromley = $mech->create_body_ok(2482, 'Bromley Council'); - -my $dt = DateTime->new( - year => 2011, - month => 04, - day => 16, - hour => 15, - minute => 47, - second => 23 -); - -my ($report) = $mech->create_problems_for_body(1, $oxfordshire->id, 'Test', { - areas => ',2237,', -}); -my $report_id = $report->id; -ok $report, "created test report - $report_id"; - -$mech->log_in_ok( $oxfordshireuser->email ); - -subtest "Users can't edit report without report_edit permission" => sub { - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'oxfordshire' ], - }, sub { - $mech->get("/admin/report_edit/$report_id"); - ok !$mech->res->is_success(), "want a bad response"; - is $mech->res->code, 404, "got 404, can't edit report without report_edit permission"; - }; -}; - -subtest "Users can edit report with report_edit permission" => sub { - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'oxfordshire' ], - }, sub { - $oxfordshireuser->user_body_permissions->create({ - body => $oxfordshire, - permission_type => 'report_edit', - }); - - $mech->get_ok("/admin/report_edit/$report_id"); - $mech->content_contains( $report->title ); - }; -}; - -subtest "Users can't edit another council's reports with their own council's report_edit permission" => sub { - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'oxfordshire' ], - }, sub { - $report->bodies_str($bromley->id); - $report->cobrand('bromley'); - $report->update; - - $mech->get("/admin/report_edit/$report_id"); - ok !$mech->res->is_success(), "want a bad response"; - is $mech->res->code, 404, "got 404, can't edit report with incorrect body in report_edit permission"; - }; -}; - - -FixMyStreet::override_config { - MAPIT_URL => 'http://mapit.uk/', - ALLOWED_COBRANDS => [ 'oxfordshire' ], -}, sub { - my $user2_id = $user2->id; - $report->update({ bodies_str => $oxfordshire->id }); - - foreach my $perm (0, 1) { - if ($perm) { - $oxfordshireuser->user_body_permissions->find_or_create({ - body => $oxfordshire, - permission_type => 'user_edit', - }); - } - foreach my $report_user ($user, $user2) { - $report->update({ user => $report_user }); - foreach my $from_body (undef, $bromley, $oxfordshire) { - $user2->update({ from_body => $from_body }); - my $result = ($from_body || '') eq $oxfordshire || $report->user eq $user2 ? ($perm ? 200 : 404 ) : 404; - my $u = $result == 200 ? 'can' : 'cannot'; - my $b = $from_body ? $from_body->name : 'no body'; - my $p = $perm ? 'with' : 'without'; - my $r = $report->user eq $user2 ? 'with' : 'without'; - subtest "User $u edit user for $b $p permission, $r cobrand relation" => sub { - $mech->get("/admin/user_edit/$user2_id"); - my $success = $mech->res->is_success(); - ok $result == 200 ? $success : !$success, "got correct response"; - is $mech->res->code, $result, "got $result"; - }; - } - } - } - - $oxfordshireuser->user_body_permissions->create({ - body => $oxfordshire, - permission_type => 'user_assign_body', - }); - - subtest "Users can edit users of their own council" => sub { - $mech->get_ok("/admin/user_edit/$user2_id"); - $mech->content_contains( $user2->name ); - - # We shouldn't be able to see the permissions tick boxes - $mech->content_lacks('Moderate report details'); - - $mech->submit_form_ok( { with_fields => { - name => 'Test Updated User 2', - email => $user2->email, - body => $user2->from_body->id, - phone => '', - flagged => undef, - } } ); - $user2->discard_changes; - is $user2->name, 'Test Updated User 2', 'name changed'; - }; - - $oxfordshireuser->user_body_permissions->create({ - body => $oxfordshire, - permission_type => 'user_manage_permissions', - }); - - subtest "Users can edit permissions" => sub { - is $user2->user_body_permissions->count, 0, 'user2 has no permissions'; - - $mech->get_ok("/admin/user_edit/$user2_id"); - $mech->content_contains('Moderate report details'); - - $mech->submit_form_ok( { with_fields => { - name => $user2->name, - email => $user2->email, - body => $user2->from_body->id, - phone => '', - flagged => undef, - "permissions[moderate]" => 'on', - "permissions[report_edit_category]" => undef, - "permissions[report_edit_priority]" => undef, - "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, - "permissions[user_assign_areas]" => undef, - } } ); - - ok $user2->has_body_permission_to("moderate"), "user2 has been granted moderate permission"; - }; - - $oxfordshireuser->user_body_permissions->create({ - body => $oxfordshire, - permission_type => 'user_assign_areas', - }); - - subtest "Unsetting user from_body removes all permissions and area " => sub { - is $user2->user_body_permissions->count, 1, 'user2 has 1 permission'; - - $mech->get_ok("/admin/user_edit/$user2_id"); - $mech->content_contains('Moderate report details'); - - $mech->submit_form_ok( { with_fields => { - name => $user2->name, - email => $user2->email, - body => undef, - phone => '', - flagged => undef, - "permissions[moderate]" => 'on', # NB tick box is left on deliberately - "permissions[report_edit_category]" => undef, - "permissions[report_edit_priority]" => undef, - "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, - "permissions[user_assign_areas]" => undef, - } } ); - - is $user2->user_body_permissions->count, 0, 'user2 has had permissions removed'; - is $user2->area_id, undef, 'user2 has had area removed'; - }; -}; - -$mech->log_out_ok; - -done_testing(); diff --git a/t/app/controller/admin_reportextrafields.t b/t/app/controller/admin_reportextrafields.t deleted file mode 100644 index fb06665f4..000000000 --- a/t/app/controller/admin_reportextrafields.t +++ /dev/null @@ -1,316 +0,0 @@ -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 deleted file mode 100644 index 60ffe5b88..000000000 --- a/t/app/controller/admin_states.t +++ /dev/null @@ -1,24 +0,0 @@ -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 deleted file mode 100644 index f5c32baa6..000000000 --- a/t/app/controller/admin_translations.t +++ /dev/null @@ -1,191 +0,0 @@ -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(); -- cgit v1.2.3