aboutsummaryrefslogtreecommitdiffstats
path: root/t/app
diff options
context:
space:
mode:
Diffstat (limited to 't/app')
-rw-r--r--t/app/controller/admin.t419
-rw-r--r--t/app/controller/alert_new.t229
-rw-r--r--t/app/controller/around.t49
-rw-r--r--t/app/controller/auth.t185
-rw-r--r--t/app/controller/auth_phone.t90
-rw-r--r--t/app/controller/auth_profile.t355
-rw-r--r--t/app/controller/auth_social.t12
-rw-r--r--t/app/controller/dashboard.t788
-rw-r--r--t/app/controller/index.t6
-rw-r--r--t/app/controller/moderate.t34
-rw-r--r--t/app/controller/my_planned.t152
-rw-r--r--t/app/controller/report_as_other.t8
-rw-r--r--t/app/controller/report_display.t2
-rw-r--r--t/app/controller/report_import.t6
-rw-r--r--t/app/controller/report_inspect.t289
-rw-r--r--t/app/controller/report_new.t97
-rw-r--r--t/app/controller/report_new_open311.t5
-rw-r--r--t/app/controller/report_new_text.t371
-rw-r--r--t/app/controller/report_update_text.t307
-rw-r--r--t/app/controller/report_updates.t256
-rw-r--r--t/app/controller/reports.t31
-rw-r--r--t/app/controller/rss.t7
-rw-r--r--t/app/model/extra.t1
-rw-r--r--t/app/model/photoset.t4
24 files changed, 2756 insertions, 947 deletions
diff --git a/t/app/controller/admin.t b/t/app/controller/admin.t
index bd0f9e408..398ce8ea6 100644
--- a/t/app/controller/admin.t
+++ b/t/app/controller/admin.t
@@ -1,4 +1,6 @@
use FixMyStreet::TestMech;
+# avoid wide character warnings from the category change message
+use open ':std', ':encoding(UTF-8)';
my $mech = FixMyStreet::TestMech->new;
@@ -287,6 +289,7 @@ 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('<body');
};
@@ -316,7 +319,7 @@ foreach my $test (
detail => 'Detail for Report to Edit',
state => 'confirmed',
name => 'Test User',
- email => $user->email,
+ username => $user->email,
anonymous => 0,
flagged => undef,
non_public => undef,
@@ -332,7 +335,7 @@ foreach my $test (
detail => 'Detail for Report to Edit',
state => 'confirmed',
name => 'Test User',
- email => $user->email,
+ username => $user->email,
anonymous => 0,
flagged => undef,
non_public => undef,
@@ -348,7 +351,7 @@ foreach my $test (
detail => 'Edited Detail',
state => 'confirmed',
name => 'Test User',
- email => $user->email,
+ username => $user->email,
anonymous => 0,
flagged => undef,
non_public => undef,
@@ -365,7 +368,7 @@ foreach my $test (
detail => 'Edited Detail',
state => 'confirmed',
name => 'Edited User',
- email => $user->email,
+ username => $user->email,
anonymous => 0,
flagged => undef,
non_public => undef,
@@ -384,12 +387,12 @@ foreach my $test (
detail => 'Edited Detail',
state => 'confirmed',
name => 'Edited User',
- email => $user->email,
+ username => $user->email,
anonymous => 0,
flagged => 'on',
non_public => undef,
},
- changes => { email => $user2->email, },
+ changes => { username => $user2->email, },
log_entries => [qw/edit edit edit edit edit/],
resend => 0,
user => $user2,
@@ -401,11 +404,12 @@ foreach my $test (
detail => 'Edited Detail',
state => 'confirmed',
name => 'Edited User',
- email => $user2->email,
+ 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,
@@ -417,11 +421,12 @@ foreach my $test (
detail => 'Edited Detail',
state => 'unconfirmed',
name => 'Edited User',
- email => $user2->email,
+ 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,
@@ -433,11 +438,12 @@ foreach my $test (
detail => 'Edited Detail',
state => 'confirmed',
name => 'Edited User',
- email => $user2->email,
+ 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/],
@@ -450,11 +456,12 @@ foreach my $test (
detail => 'Edited Detail',
state => 'fixed',
name => 'Edited User',
- email => $user2->email,
+ 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/
@@ -468,11 +475,12 @@ foreach my $test (
detail => 'Edited Detail',
state => 'hidden',
name => 'Edited User',
- email => $user2->email,
+ username => $user2->email,
anonymous => 0,
flagged => 'on',
non_public => undef,
},
+ expect_comment => 1,
changes => {
state => 'confirmed',
anonymous => 1,
@@ -489,7 +497,7 @@ foreach my $test (
detail => 'Edited Detail',
state => 'confirmed',
name => 'Edited User',
- email => $user2->email,
+ username => $user2->email,
anonymous => 1,
flagged => 'on',
non_public => undef,
@@ -507,7 +515,7 @@ foreach my $test (
detail => 'Edited Detail',
state => 'confirmed',
name => 'Edited User',
- email => $user2->email,
+ username => $user2->email,
anonymous => 1,
flagged => 'on',
non_public => undef,
@@ -520,10 +528,58 @@ foreach my $test (
],
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");
@@ -555,7 +611,7 @@ foreach my $test (
$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 'email' } keys %{ $test->{changes} };
+ is $report->$_, $test->{changes}->{$_}, "$_ updated" for grep { $_ ne 'username' } keys %{ $test->{changes} };
if ( $test->{user} ) {
is $report->user->id, $test->{user}->id, 'user changed';
@@ -565,6 +621,31 @@ foreach my $test (
$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;
};
}
@@ -586,6 +667,8 @@ subtest 'change report category' => sub {
$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;
@@ -603,8 +686,8 @@ subtest 'change email to new user' => sub {
detail => $report->detail,
state => $report->state,
name => $report->name,
- email => $report->user->email,
- category => 'Other',
+ username => $report->user->email,
+ category => 'Potholes',
anonymous => 1,
flagged => 'on',
non_public => 'on',
@@ -616,12 +699,10 @@ subtest 'change email to new user' => sub {
is_deeply( $mech->visible_form_values(), $fields, 'initial form values' );
my $changes = {
- email => 'test3@example.com'
+ username => 'test3@example.com'
};
- $user3 =
- FixMyStreet::App->model('DB::User')
- ->find( { email => 'test3@example.com', name => 'Test User 2' } );
+ $user3 = FixMyStreet::App->model('DB::User')->find( { email => 'test3@example.com' } );
ok !$user3, 'user not in database';
@@ -640,9 +721,7 @@ subtest 'change email to new user' => sub {
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', name => 'Test User 2' } );
+ $user3 = FixMyStreet::App->model('DB::User')->find( { email => 'test3@example.com' } );
$report->discard_changes;
@@ -657,18 +736,50 @@ subtest 'adding email to abuse list from report page' => sub {
$abuse->delete if $abuse;
$mech->get_ok( '/admin/report_edit/' . $report->id );
- $mech->content_contains('Ban email address');
+ $mech->content_contains('Ban user');
$mech->click_ok('banuser');
- $mech->content_contains('Email added to abuse list');
- $mech->content_contains('<small>(Email in abuse table)</small>');
+ $mech->content_contains('User added to abuse list');
+ $mech->content_contains('<small>User in abuse table</small>');
$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('<small>(Email in abuse table)</small>');
+ $mech->content_contains('<small>User in abuse table</small>');
+};
+
+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 {
@@ -742,7 +853,7 @@ for my $test (
state => 'confirmed',
name => '',
anonymous => 1,
- email => 'test@example.com',
+ username => 'test@example.com',
},
changes => {
text => 'this is a changed update',
@@ -757,7 +868,7 @@ for my $test (
state => 'confirmed',
name => '',
anonymous => 1,
- email => 'test@example.com',
+ username => 'test@example.com',
},
changes => {
name => 'A User',
@@ -772,7 +883,7 @@ for my $test (
state => 'confirmed',
name => 'A User',
anonymous => 1,
- email => 'test@example.com',
+ username => 'test@example.com',
},
changes => {
anonymous => 0,
@@ -787,11 +898,10 @@ for my $test (
state => 'confirmed',
name => 'A User',
anonymous => 0,
- email => $update->user->email,
- email => 'test@example.com',
+ username => 'test@example.com',
},
changes => {
- email => 'test2@example.com',
+ username => 'test2@example.com',
},
log_count => 4,
log_entries => [qw/edit edit edit edit/],
@@ -804,7 +914,7 @@ for my $test (
state => 'confirmed',
name => 'A User',
anonymous => 0,
- email => 'test2@example.com',
+ username => 'test2@example.com',
},
changes => {
state => 'unconfirmed',
@@ -819,7 +929,7 @@ for my $test (
state => 'unconfirmed',
name => 'A User',
anonymous => 0,
- email => 'test2@example.com',
+ username => 'test2@example.com',
},
changes => {
text => 'this is a twice changed update',
@@ -849,7 +959,7 @@ for my $test (
$update->discard_changes;
- is $update->$_, $test->{changes}->{$_} for grep { $_ ne 'email' } keys %{ $test->{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;
}
@@ -935,9 +1045,7 @@ for my $test (
}
subtest 'editing update email creates new user if required' => sub {
- my $user = FixMyStreet::App->model('DB::User')->find(
- { email => 'test4@example.com' }
- );
+ my $user = FixMyStreet::App->model('DB::User')->find( { email => 'test4@example.com' } );
$user->delete if $user;
@@ -946,14 +1054,12 @@ subtest 'editing update email creates new user if required' => sub {
state => 'hidden',
name => 'A User',
anonymous => 0,
- email => 'test4@example.com',
+ username => 'test4@example.com',
};
$mech->submit_form_ok( { with_fields => $fields } );
- $user = FixMyStreet::App->model('DB::User')->find(
- { email => 'test4@example.com' }
- );
+ $user = FixMyStreet::App->model('DB::User')->find( { email => 'test4@example.com' } );
is_deeply $mech->visible_form_values, $fields, 'submitted form values';
@@ -970,18 +1076,18 @@ subtest 'adding email to abuse list from update page' => sub {
$abuse->delete if $abuse;
$mech->get_ok( '/admin/update_edit/' . $update->id );
- $mech->content_contains('Ban email address');
+ $mech->content_contains('Ban user');
$mech->click_ok('banuser');
- $mech->content_contains('Email added to abuse list');
- $mech->content_contains('<small>(Email in abuse table)</small>');
+ $mech->content_contains('User added to abuse list');
+ $mech->content_contains('<small>User in abuse table</small>');
$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('<small>(Email in abuse table)</small>');
+ $mech->content_contains('<small>User in abuse table</small>');
};
subtest 'flagging user from update page' => sub {
@@ -1029,13 +1135,12 @@ subtest 'hiding comment marked as fixed reopens report' => sub {
$report->state('fixed - user');
$report->update;
-
my $fields = {
text => 'this is a changed update',
state => 'hidden',
name => 'A User',
anonymous => 0,
- email => 'test2@example.com',
+ username => 'test2@example.com',
};
$mech->submit_form_ok( { with_fields => $fields } );
@@ -1092,7 +1197,7 @@ subtest 'report search' => sub {
subtest 'search abuse' => sub {
$mech->get_ok( '/admin/users?search=example' );
- $mech->content_like(qr{test4\@example.com.*</td>\s*<td>.*?</td>\s*<td>\(Email in abuse table}s);
+ $mech->content_like(qr{test4\@example.com.*</td>\s*<td>.*?</td>\s*<td>User in abuse table}s);
};
subtest 'show flagged entries' => sub {
@@ -1168,6 +1273,69 @@ $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,
@@ -1190,6 +1358,10 @@ my %default_perms = (
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 {
@@ -1197,7 +1369,7 @@ FixMyStreet::override_config {
{
desc => 'edit user name',
fields => {
- name => 'Test User',
+ name => '',
email => 'test@example.com',
body => $haringey->id,
phone => '',
@@ -1358,6 +1530,32 @@ FixMyStreet::override_config {
}
};
+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 "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");
@@ -1380,6 +1578,7 @@ 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;
@@ -1460,6 +1659,108 @@ subtest "response templates are included on page" => sub {
};
};
+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 {
@@ -1475,8 +1776,8 @@ subtest "response priorities can be added" => sub {
};
$mech->submit_form_ok( { with_fields => $fields } );
- is $oxfordshire->response_priorities->count, 1, "Response template was added to body";
- is $oxfordshirecontact->response_priorities->count, 1, "Response template was added to contact";
+ 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 {
@@ -1494,7 +1795,7 @@ subtest "response priorities can set to default" => sub {
$mech->submit_form_ok( { with_fields => $fields } );
is $oxfordshire->response_priorities->count, 1, "Still one response priority";
- is $oxfordshirecontact->response_priorities->count, 1, "Still one response template";
+ is $oxfordshirecontact->response_priorities->count, 1, "Still one response priority";
ok $oxfordshire->response_priorities->first->is_default, "Response priority set to default";
};
@@ -1511,8 +1812,8 @@ subtest "response priorities are limited by body" => sub {
name => "Bromley Cat 0",
} );
- is $bromley->response_priorities->count, 1, "Response template was added to Bromley";
- is $oxfordshire->response_priorities->count, 1, "Response template wasn't added to Oxfordshire";
+ 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 );
@@ -1547,4 +1848,10 @@ subtest "response priorities can't be viewed across councils" => sub {
};
};
+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/alert_new.t b/t/app/controller/alert_new.t
index 97a19b3b8..4e8fd1b29 100644
--- a/t/app/controller/alert_new.t
+++ b/t/app/controller/alert_new.t
@@ -475,7 +475,7 @@ subtest "Test normal alert signups and that alerts are sent" => sub {
$mech->delete_user($user2);
};
-subtest "Test alerts are correct for no-text updates" => sub {
+subtest "Test alerts are not sent for no-text updates" => sub {
$mech->delete_user( 'reporter@example.com' );
$mech->delete_user( 'alerts@example.com' );
@@ -513,6 +513,40 @@ subtest "Test alerts are correct for no-text updates" => sub {
my $report_id = $report->id;
ok $report, "created test report - $report_id";
+ my $report2 = FixMyStreet::App->model('DB::Problem')->create( {
+ postcode => 'EH1 1BB',
+ bodies_str => '1',
+ areas => ',11808,135007,14419,134935,2651,20728,',
+ category => 'Street lighting',
+ title => 'Testing',
+ detail => 'Testing Detail',
+ used_map => 1,
+ name => $user1->name,
+ anonymous => 0,
+ state => 'fixed - user',
+ confirmed => $dt_parser->format_datetime($dt),
+ lastupdate => $dt_parser->format_datetime($dt),
+ whensent => $dt_parser->format_datetime($dt->clone->add( minutes => 5 )),
+ lang => 'en-gb',
+ service => '',
+ cobrand => 'default',
+ cobrand_data => '',
+ send_questionnaire => 1,
+ latitude => '55.951963',
+ longitude => '-3.189944',
+ user_id => $user1->id,
+ } );
+ my $report2_id = $report2->id;
+ ok $report2, "created test report - $report2_id";
+
+ # Must be first
+ my $alert2 = FixMyStreet::App->model('DB::Alert')->create( {
+ parameter => $report2_id,
+ alert_type => 'new_updates',
+ user => $user2,
+ } )->confirm;
+ ok $alert2, 'created alert for other user';
+
my $alert = FixMyStreet::App->model('DB::Alert')->create( {
parameter => $report_id,
alert_type => 'new_updates',
@@ -533,6 +567,92 @@ subtest "Test alerts are correct for no-text updates" => sub {
my $update_id = $update->id;
ok $update, "created test update from staff user - $update_id";
+ my $update2 = FixMyStreet::App->model('DB::Comment')->create( {
+ problem_id => $report2_id,
+ user_id => $user3->id,
+ name => 'Staff User',
+ mark_fixed => 'false',
+ text => 'This is a normal update',
+ state => 'confirmed',
+ confirmed => $dt->clone->add( hours => 9 ),
+ anonymous => 'f',
+ } );
+ my $update2_id = $update2->id;
+ ok $update2, "created test update from staff user - $update2_id";
+
+ $mech->clear_emails_ok;
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ FixMyStreet::Script::Alerts::send();
+ };
+
+ $mech->email_count_is(1);
+
+ $mech->delete_user($user1);
+ $mech->delete_user($user2);
+ $mech->delete_user($user3);
+};
+
+subtest "Test no marked as confirmed added to alerts" => sub {
+ $mech->delete_user( 'reporter@example.com' );
+ $mech->delete_user( 'alerts@example.com' );
+
+ my $user1 = $mech->create_user_ok('reporter@example.com', name => 'Reporter User' );
+ my $user2 = $mech->create_user_ok('alerts@example.com', name => 'Alert User' );
+ my $user3 = $mech->create_user_ok('staff@example.com', name => 'Staff User', from_body => $gloucester );
+ my $dt = DateTime->now(time_zone => 'Europe/London')->add(days => 2);
+
+ my $dt_parser = FixMyStreet::App->model('DB')->schema->storage->datetime_parser;
+
+ my $report_time = '2011-03-01 12:00:00';
+ my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( {
+ postcode => 'EH1 1BB',
+ bodies_str => '1',
+ areas => ',11808,135007,14419,134935,2651,20728,',
+ category => 'Street lighting',
+ title => 'Testing',
+ detail => 'Testing Detail',
+ used_map => 1,
+ name => $user1->name,
+ anonymous => 0,
+ state => 'confirmed',
+ confirmed => $dt_parser->format_datetime($dt),
+ lastupdate => $dt_parser->format_datetime($dt),
+ whensent => $dt_parser->format_datetime($dt->clone->add( minutes => 5 )),
+ lang => 'en-gb',
+ service => '',
+ cobrand => 'default',
+ cobrand_data => '',
+ send_questionnaire => 1,
+ latitude => '55.951963',
+ longitude => '-3.189944',
+ user_id => $user1->id,
+ } );
+ my $report_id = $report->id;
+ ok $report, "created test report - $report_id";
+
+ my $alert = FixMyStreet::App->model('DB::Alert')->create( {
+ parameter => $report_id,
+ alert_type => 'new_updates',
+ user => $user2,
+ } )->confirm;
+ ok $alert, 'created alert for other user';
+
+ my $update = FixMyStreet::App->model('DB::Comment')->create( {
+ problem_id => $report_id,
+ user_id => $user3->id,
+ name => 'Staff User',
+ mark_fixed => 'false',
+ text => 'this is update',
+ state => 'confirmed',
+ problem_state => 'confirmed',
+ confirmed => $dt->clone->add( hours => 9 ),
+ anonymous => 'f',
+ } );
+ my $update_id = $update->id;
+ ok $update, "created test update from staff user - $update_id";
+
$mech->clear_emails_ok;
FixMyStreet::override_config {
MAPIT_URL => 'http://mapit.uk/',
@@ -545,15 +665,116 @@ subtest "Test alerts are correct for no-text updates" => sub {
my $body = $mech->get_text_body_from_email($email);
like $body, qr/The following updates have been left on this report:/, 'email is about updates to existing report';
like $body, qr/Staff User/, 'Update comes from correct user';
-
- my @urls = $mech->get_link_from_email($email, 1);
- is $urls[0], "http://www.example.org/report/" . $report_id, "Correct report URL in email";
+ unlike $body, qr/State changed to: Open/s, 'no marked as confirmed text';
$mech->delete_user($user1);
$mech->delete_user($user2);
$mech->delete_user($user3);
};
+for my $test (
+ {
+ update_text => '',
+ problem_state => 'investigating',
+ expected_text => 'State changed to: Investigating',
+ desc => 'comment changing status included in email',
+ },
+ {
+ update_text => 'Category changed to Potholes',
+ problem_state => '',
+ expected_text => 'Category changed to Potholes',
+ desc => 'comment about category included',
+ },
+ {
+ update_text => 'Category changed to Potholes',
+ problem_state => 'investigating',
+ expected_text => 'Category changed to Potholes.*Investigating',
+ desc => 'comment about category and status change included',
+ },
+) {
+ subtest $test->{desc} => sub {
+ $mech->delete_user( 'reporter@example.com' );
+ $mech->delete_user( 'alerts@example.com' );
+
+ my $user1 = $mech->create_user_ok('reporter@example.com', name => 'Reporter User' );
+ my $user2 = $mech->create_user_ok('alerts@example.com', name => 'Alert User' );
+ my $user3 = $mech->create_user_ok('staff@example.com', name => 'Staff User', from_body => $gloucester );
+ my $dt = DateTime->now(time_zone => 'Europe/London')->add(days => 2);
+
+ my $dt_parser = FixMyStreet::App->model('DB')->schema->storage->datetime_parser;
+
+ my $report_time = '2011-03-01 12:00:00';
+ my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( {
+ postcode => 'EH1 1BB',
+ bodies_str => '1',
+ areas => ',11808,135007,14419,134935,2651,20728,',
+ category => 'Street lighting',
+ title => 'Testing',
+ detail => 'Testing Detail',
+ used_map => 1,
+ name => $user1->name,
+ anonymous => 0,
+ state => 'confirmed',
+ confirmed => $dt_parser->format_datetime($dt),
+ lastupdate => $dt_parser->format_datetime($dt),
+ whensent => $dt_parser->format_datetime($dt->clone->add( minutes => 5 )),
+ lang => 'en-gb',
+ service => '',
+ cobrand => 'default',
+ cobrand_data => '',
+ send_questionnaire => 1,
+ latitude => '55.951963',
+ longitude => '-3.189944',
+ user_id => $user1->id,
+ } );
+ my $report_id = $report->id;
+ ok $report, "created test report - $report_id";
+
+ my $alert = FixMyStreet::App->model('DB::Alert')->create( {
+ parameter => $report_id,
+ alert_type => 'new_updates',
+ user => $user2,
+ } )->confirm;
+ ok $alert, 'created alert for other user';
+
+ my $update = FixMyStreet::App->model('DB::Comment')->create( {
+ problem_id => $report_id,
+ user_id => $user3->id,
+ name => 'Staff User',
+ mark_fixed => 'false',
+ text => $test->{update_text},
+ problem_state => $test->{problem_state},
+ state => 'confirmed',
+ confirmed => $dt->clone->add( hours => 9 ),
+ anonymous => 'f',
+ } );
+ my $update_id = $update->id;
+ ok $update, "created test update from staff user - $update_id";
+
+ $mech->clear_emails_ok;
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ FixMyStreet::Script::Alerts::send();
+ };
+
+ $mech->email_count_is(1);
+ my $expected_text = $test->{expected_text};
+ my $email = $mech->get_email;
+ my $body = $mech->get_text_body_from_email($email);
+ like $body, qr/The following updates have been left on this report:/, 'email is about updates to existing report';
+ like $body, qr/Staff User/, 'Update comes from correct user';
+ like $body, qr/$expected_text/s, 'Expected text present';
+
+ my @urls = $mech->get_link_from_email($email, 1);
+ is $urls[0], "http://www.example.org/report/" . $report_id, "Correct report URL in email";
+
+ $mech->delete_user($user1);
+ $mech->delete_user($user2);
+ $mech->delete_user($user3);
+ };
+}
+
subtest "Test signature template is used from cobrand" => sub {
$mech->delete_user( 'reporter@example.com' );
$mech->delete_user( 'alerts@example.com' );
diff --git a/t/app/controller/around.t b/t/app/controller/around.t
index fbb4e76cd..d1254edb7 100644
--- a/t/app/controller/around.t
+++ b/t/app/controller/around.t
@@ -1,3 +1,5 @@
+use Test::MockModule;
+
use FixMyStreet::TestMech;
my $mech = FixMyStreet::TestMech->new;
@@ -92,15 +94,22 @@ foreach my $test (
};
}
-subtest 'check non public reports are not displayed on around page' => sub {
- my $params = {
- postcode => 'EH1 1BB',
- latitude => 55.9519637512,
- longitude => -3.17492254484,
- };
- my @edinburgh_problems =
- $mech->create_problems_for_body( 5, 2651, 'Around page', $params );
+my @edinburgh_problems = $mech->create_problems_for_body( 5, 2651, 'Around page', {
+ postcode => 'EH1 1BB',
+ latitude => 55.9519637512,
+ longitude => -3.17492254484,
+});
+subtest 'check lookup by reference' => sub {
+ $mech->get_ok('/');
+ $mech->submit_form_ok( { with_fields => { pc => 'ref:12345' } }, 'bad ref');
+ $mech->content_contains('Searching found no reports');
+ my $id = $edinburgh_problems[0]->id;
+ $mech->submit_form_ok( { with_fields => { pc => "ref:$id" } }, 'good ref');
+ is $mech->uri->path, "/report/$id", "redirected to report page";
+};
+
+subtest 'check non public reports are not displayed on around page' => sub {
$mech->get_ok('/');
FixMyStreet::override_config {
ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ],
@@ -128,7 +137,7 @@ subtest 'check non public reports are not displayed on around page' => sub {
};
-subtest 'check category and status filtering works on /ajax' => sub {
+subtest 'check category and status filtering works on /around?ajax' => sub {
my $categories = [ 'Pothole', 'Vegetation', 'Flytipping' ];
my $params = {
postcode => 'OX1 1ND',
@@ -150,21 +159,35 @@ subtest 'check category and status filtering works on /ajax' => sub {
}
}
- my $json = $mech->get_ok_json( '/ajax?bbox=' . $bbox );
+ my $json = $mech->get_ok_json( '/around?ajax=1&bbox=' . $bbox );
my $pins = $json->{pins};
is scalar @$pins, 6, 'correct number of reports when no filters';
- $json = $mech->get_ok_json( '/ajax?filter_category=Pothole&bbox=' . $bbox );
+ $json = $mech->get_ok_json( '/around?ajax=1&filter_category=Pothole&bbox=' . $bbox );
$pins = $json->{pins};
is scalar @$pins, 2, 'correct number of Pothole reports';
- $json = $mech->get_ok_json( '/ajax?status=open&bbox=' . $bbox );
+ $json = $mech->get_ok_json( '/around?ajax=1&status=open&bbox=' . $bbox );
$pins = $json->{pins};
is scalar @$pins, 3, 'correct number of open reports';
- $json = $mech->get_ok_json( '/ajax?status=fixed&filter_category=Vegetation&bbox=' . $bbox );
+ $json = $mech->get_ok_json( '/around?ajax=1&status=fixed&filter_category=Vegetation&bbox=' . $bbox );
$pins = $json->{pins};
is scalar @$pins, 1, 'correct number of fixed Vegetation reports';
};
+subtest 'check skip_around skips around page' => sub {
+ my $cobrand = Test::MockModule->new('FixMyStreet::Cobrand::Default');
+ $cobrand->mock('skip_around_page', sub { 1 });
+ $cobrand->mock('country', sub { 1 });
+
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->get('/around?latitude=51.754926&longitude=-1.256179');
+ is $mech->res->code, 302, "around page is a redirect";
+ is $mech->uri->path, '/report/new', "and redirects to /report/new";
+ };
+};
+
done_testing();
diff --git a/t/app/controller/auth.t b/t/app/controller/auth.t
index cb7d16969..8d60137a2 100644
--- a/t/app/controller/auth.t
+++ b/t/app/controller/auth.t
@@ -4,7 +4,6 @@ use FixMyStreet::TestMech;
my $mech = FixMyStreet::TestMech->new;
my $test_email = 'test@example.com';
-my $test_email2 = 'test@example.net';
my $test_email3 = 'newuser@example.org';
my $test_password = 'foobar';
@@ -41,8 +40,8 @@ for my $test (
$mech->submit_form_ok(
{
form_name => 'general_auth',
- fields => { email => $email, },
- button => 'email_sign_in',
+ fields => { username => $email, },
+ button => 'sign_in_by_code',
},
"try to create an account with email '$email'"
);
@@ -60,8 +59,8 @@ $mech->get_ok('/auth');
$mech->submit_form_ok(
{
form_name => 'general_auth',
- fields => { email => $test_email, },
- button => 'email_sign_in',
+ fields => { username => $test_email, password_register => $test_password },
+ button => 'sign_in_by_code',
},
"create an account for '$test_email'"
);
@@ -101,125 +100,6 @@ $mech->not_logged_in_ok;
$mech->log_out_ok;
}
-# get a sign in email and change password
-{
- $mech->clear_emails_ok;
- $mech->get_ok('/auth');
- $mech->submit_form_ok(
- {
- form_name => 'general_auth',
- fields => {
- email => "$test_email",
- r => 'faq', # Just as a test
- },
- button => 'email_sign_in',
- },
- "email_sign_in with '$test_email'"
- );
-
- # rest is as before so no need to test
-
- # follow link and change password - check not prompted for old password
- $mech->not_logged_in_ok;
-
- my $link = $mech->get_link_from_email;
- $mech->get_ok($link);
- is $mech->uri->path, '/faq', "redirected to the Help page";
-
- $mech->get_ok('/auth/change_password');
-
- ok my $form = $mech->form_name('change_password'),
- "found change password form";
- is_deeply [ sort grep { $_ } map { $_->name } $form->inputs ], #
- [ 'confirm', 'new_password', 'token' ],
- "check we got expected fields (ie not old_password)";
-
- # check the various ways the form can be wrong
- for my $test (
- { new => '', conf => '', err => 'enter a password', },
- { new => 'secret', conf => '', err => 'do not match', },
- { new => '', conf => 'secret', err => 'do not match', },
- { new => 'secret', conf => 'not_secret', err => 'do not match', },
- )
- {
- $mech->get_ok('/auth/change_password');
- $mech->content_lacks( $test->{err}, "did not find expected error" );
- $mech->submit_form_ok(
- {
- form_name => 'change_password',
- fields =>
- { new_password => $test->{new}, confirm => $test->{conf}, },
- },
- "change_password with '$test->{new}' and '$test->{conf}'"
- );
- $mech->content_contains( $test->{err}, "found expected error" );
- }
-
- my $user =
- FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
- ok $user, "got a user";
- ok !$user->password, "user has no password";
-
- $mech->get_ok('/auth/change_password');
- $mech->submit_form_ok(
- {
- form_name => 'change_password',
- fields =>
- { new_password => $test_password, confirm => $test_password, },
- },
- "change_password with '$test_password' and '$test_password'"
- );
- is $mech->uri->path, '/auth/change_password',
- "still on change password page";
- $mech->content_contains( 'password has been changed',
- "found password changed" );
-
- $user->discard_changes();
- ok $user->password, "user now has a password";
-}
-
-subtest "Test change email page" => sub {
- # Still signed in from the above test
- $mech->get_ok('/my');
- $mech->follow_link_ok({url => '/auth/change_email'});
- $mech->submit_form_ok(
- { with_fields => { email => "" } },
- "submit blank change email form"
- );
- $mech->content_contains( 'Please enter your email', "found expected error" );
- $mech->submit_form_ok({ with_fields => { email => $test_email2 } }, "change_email to $test_email2");
- is $mech->uri->path, '/auth/change_email', "still on change email page";
- $mech->content_contains( 'Now check your email', "found check your email" );
- my $link = $mech->get_link_from_email;
- $mech->get_ok($link);
- is $mech->uri->path, '/auth/change_email/success', "redirected to the change_email page";
- $mech->content_contains('successfully confirmed');
- ok(FixMyStreet::App->model('DB::User')->find( { email => $test_email2 } ), "got a user");
-
- ok(FixMyStreet::App->model('DB::User')->create( { email => $test_email } ), "created old user");
- $mech->submit_form_ok({ with_fields => { email => $test_email } },
- "change_email back to $test_email"
- );
- is $mech->uri->path, '/auth/change_email', "still on change email page";
- $mech->content_contains( 'Now check your email', "found check your email" );
- $link = $mech->get_link_from_email;
- $mech->get_ok($link);
- is $mech->uri->path, '/auth/change_email/success', "redirected to the change_email page";
- $mech->content_contains('successfully confirmed');
-
- # Test you can't click the link if logged out
- $mech->submit_form_ok({ with_fields => { email => $test_email } },
- "change_email back to $test_email"
- );
- is $mech->uri->path, '/auth/change_email', "still on change email page";
- $mech->content_contains( 'Now check your email', "found check your email" );
- $link = $mech->get_link_from_email;
- $mech->log_out_ok;
- $mech->get_ok($link);
- isnt $mech->uri->path, '/auth/change_email/success', "not redirected to the change_email page";
- $mech->content_contains('Sorry');
-};
-
foreach my $remember_me ( '1', '0' ) {
subtest "sign in using valid details (remember_me => '$remember_me')" => sub {
$mech->get_ok('/auth');
@@ -227,11 +107,11 @@ foreach my $remember_me ( '1', '0' ) {
{
form_name => 'general_auth',
fields => {
- email => $test_email,
+ username => $test_email,
password_sign_in => $test_password,
remember_me => ( $remember_me ? 1 : undef ),
},
- button => 'sign_in',
+ button => 'sign_in_by_password',
},
"sign in with '$test_email' & '$test_password'"
);
@@ -253,15 +133,15 @@ $mech->submit_form_ok(
{
form_name => 'general_auth',
fields => {
- email => $test_email,
+ username => $test_email,
password_sign_in => 'not the password',
},
- button => 'sign_in',
+ button => 'sign_in_by_password',
},
"sign in with '$test_email' & 'not the password'"
);
is $mech->uri->path, '/auth', "redirected to correct page";
-$mech->content_contains( 'problem with your email/password combination', 'found error message' );
+$mech->content_contains( 'problem with your login information', 'found error message' );
subtest "sign in but have email form autofilled" => sub {
$mech->get_ok('/auth');
@@ -269,11 +149,11 @@ subtest "sign in but have email form autofilled" => sub {
{
form_name => 'general_auth',
fields => {
- email => $test_email,
+ username => $test_email,
password_sign_in => $test_password,
name => 'Auto-completed from elsewhere',
},
- button => 'sign_in',
+ button => 'sign_in_by_password',
},
"sign in with '$test_email' and auto-completed name"
);
@@ -289,10 +169,10 @@ subtest "sign in with uppercase email" => sub {
{
form_name => 'general_auth',
fields => {
- email => $uc_test_email,
+ username => $uc_test_email,
password_sign_in => $test_password,
},
- button => 'sign_in',
+ button => 'sign_in_by_password',
},
"sign in with '$uc_test_email' and auto-completed name"
);
@@ -317,8 +197,8 @@ FixMyStreet::override_config {
$mech->submit_form_ok(
{
form_name => 'general_auth',
- fields => { email => $test_email3, },
- button => 'email_sign_in',
+ fields => { username => $test_email3, },
+ button => 'sign_in_by_code',
},
"create a new account"
);
@@ -338,13 +218,13 @@ FixMyStreet::override_config {
{
form_name => 'general_auth',
fields => {
- email => "$test_email",
+ username => "$test_email",
password_register => $new_password,
r => 'faq', # Just as a test
},
- button => 'email_sign_in',
+ button => 'sign_in_by_code',
},
- "email_sign_in with '$test_email'"
+ "sign_in_by_code with '$test_email'"
);
$mech->not_logged_in_ok;
@@ -361,13 +241,38 @@ FixMyStreet::override_config {
{
form_name => 'general_auth',
fields => {
- email => $test_email,
+ username => $test_email,
password_sign_in => $new_password,
},
- button => 'sign_in',
+ button => 'sign_in_by_password',
},
"sign in with '$test_email' and new password"
);
is $mech->uri->path, '/my', "redirected to correct page";
};
};
+
+subtest "check logging in with token" => sub {
+ $mech->log_out_ok;
+ $mech->not_logged_in_ok;
+
+ my $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
+ # token needs to be 18 characters
+ $user->set_extra_metadata('access_token', '1234567890abcdefgh');
+ $user->update();
+
+ $mech->add_header('Authorization', 'Bearer 1234567890abcdefgh');
+ $mech->logged_in_ok;
+
+ $mech->delete_header('Authorization');
+ $mech->not_logged_in_ok;
+
+ $mech->get_ok('/auth/check_auth?access_token=1234567890abcdefgh');
+
+ $mech->add_header('Authorization', 'Bearer 1234567890abcdefgh');
+ $user->set_extra_metadata('access_token', 'XXXXXXXXXXXXXXXXXX');
+ $user->update();
+ $mech->not_logged_in_ok;
+
+ $mech->delete_header('Authorization');
+};
diff --git a/t/app/controller/auth_phone.t b/t/app/controller/auth_phone.t
new file mode 100644
index 000000000..dea1c3493
--- /dev/null
+++ b/t/app/controller/auth_phone.t
@@ -0,0 +1,90 @@
+use FixMyStreet::TestMech;
+
+use t::Mock::Twilio;
+
+my $twilio = t::Mock::Twilio->new;
+LWP::Protocol::PSGI->register($twilio->to_psgi_app, host => 'api.twilio.com');
+
+my $mech = FixMyStreet::TestMech->new;
+
+FixMyStreet::override_config {
+ SMS_AUTHENTICATION => 1,
+ PHONE_COUNTRY => 'GB',
+ TWILIO_ACCOUNT_SID => 'AC123',
+}, sub {
+
+ subtest 'Log in with invalid number, fail' => sub {
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok({
+ form_name => 'general_auth',
+ fields => { username => '01214960000000' },
+ button => 'sign_in_by_code',
+ }, "sign in using bad number");
+ $mech->content_contains('Please check your phone number is correct');
+ };
+
+ subtest 'Log in using landline, fail' => sub {
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok({
+ form_name => 'general_auth',
+ fields => { username => '01214960000' },
+ button => 'sign_in_by_code',
+ }, "sign in using landline");
+ $mech->content_contains('Please enter a mobile number');
+ };
+
+ subtest 'Log in using number that fails at Twilio' => sub {
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok({
+ form_name => 'general_auth',
+ fields => { username => '+18165550101' },
+ button => 'sign_in_by_code',
+ }, "sign in using failing number");
+ $mech->content_contains('Sending a confirmation text failed');
+ };
+
+ subtest 'Log in using mobile, by text' => sub {
+ $mech->submit_form_ok({
+ form_name => 'general_auth',
+ fields => { username => '+18165550100', password_register => 'secret' },
+ button => 'sign_in_by_code',
+ }, "sign in using mobile");
+
+ $mech->submit_form_ok({
+ with_fields => { code => '00000' }
+ }, 'submit incorrect code');
+ $mech->content_contains('Try again');
+
+ my $code = $twilio->get_text_code;
+ $mech->submit_form_ok({
+ with_fields => { code => $code }
+ }, 'submit correct code');
+
+ my $user = FixMyStreet::App->model('DB::User')->find( { phone => '+18165550100' } );
+ ok $user, "user created";
+ is $mech->uri->path, '/my', "redirected to the 'my' section of site";
+ $mech->logged_in_ok;
+ $mech->log_out_ok;
+ };
+
+ subtest 'Log in using mobile, by password' => sub {
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok({
+ form_name => 'general_auth',
+ fields => { username => '+18165550100', password_sign_in => 'incorrect' },
+ button => 'sign_in_by_password',
+ }, "sign in using wrong password");
+ $mech->content_contains('There was a problem');
+ $mech->submit_form_ok({
+ form_name => 'general_auth',
+ fields => { username => '+18165550100', password_sign_in => 'secret' },
+ button => 'sign_in_by_password',
+ }, "sign in using password");
+
+ is $mech->uri->path, '/my', "redirected to the 'my' section of site";
+ $mech->logged_in_ok;
+ };
+
+};
+
+done_testing();
diff --git a/t/app/controller/auth_profile.t b/t/app/controller/auth_profile.t
new file mode 100644
index 000000000..74edccfe6
--- /dev/null
+++ b/t/app/controller/auth_profile.t
@@ -0,0 +1,355 @@
+use FixMyStreet::TestMech;
+my $mech = FixMyStreet::TestMech->new;
+
+use t::Mock::Twilio;
+
+my $twilio = t::Mock::Twilio->new;
+LWP::Protocol::PSGI->register($twilio->to_psgi_app, host => 'api.twilio.com');
+
+my $test_email = 'test@example.com';
+my $test_email2 = 'test@example.net';
+my $test_password = 'foobar';
+
+END {
+ done_testing();
+}
+
+# get a sign in email and change password
+subtest "Test change password page" => sub {
+ $mech->clear_emails_ok;
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok(
+ {
+ form_name => 'general_auth',
+ fields => {
+ username => $test_email,
+ r => 'faq', # Just as a test
+ },
+ button => 'sign_in_by_code',
+ },
+ "sign_in_by_code with '$test_email'"
+ );
+
+ # follow link and change password - check not prompted for old password
+ $mech->not_logged_in_ok;
+
+ my $link = $mech->get_link_from_email;
+ $mech->get_ok($link);
+ is $mech->uri->path, '/faq', "redirected to the Help page";
+
+ $mech->get_ok('/auth/change_password');
+
+ ok my $form = $mech->form_name('change_password'),
+ "found change password form";
+ is_deeply [ sort grep { $_ } map { $_->name } $form->inputs ], #
+ [ 'confirm', 'new_password', 'token' ],
+ "check we got expected fields (ie not old_password)";
+
+ # check the various ways the form can be wrong
+ for my $test (
+ { new => '', conf => '', err => 'enter a password', },
+ { new => 'secret', conf => '', err => 'do not match', },
+ { new => '', conf => 'secret', err => 'do not match', },
+ { new => 'secret', conf => 'not_secret', err => 'do not match', },
+ )
+ {
+ $mech->get_ok('/auth/change_password');
+ $mech->content_lacks( $test->{err}, "did not find expected error" );
+ $mech->submit_form_ok(
+ {
+ form_name => 'change_password',
+ fields =>
+ { new_password => $test->{new}, confirm => $test->{conf}, },
+ },
+ "change_password with '$test->{new}' and '$test->{conf}'"
+ );
+ $mech->content_contains( $test->{err}, "found expected error" );
+ }
+
+ my $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
+ ok $user, "got a user";
+ ok !$user->password, "user has no password";
+
+ $mech->get_ok('/auth/change_password');
+ $mech->submit_form_ok(
+ {
+ form_name => 'change_password',
+ fields =>
+ { new_password => $test_password, confirm => $test_password, },
+ },
+ "change_password with '$test_password' and '$test_password'"
+ );
+ is $mech->uri->path, '/auth/change_password',
+ "still on change password page";
+ $mech->content_contains( 'password has been changed',
+ "found password changed" );
+
+ $user->discard_changes();
+ ok $user->password, "user now has a password";
+};
+
+subtest "Test change email page" => sub {
+ $mech->create_problems_for_body(1, 2514, 'Title1', { user => FixMyStreet::DB->resultset('User')->find( { email => $test_email } ) } );
+
+ # Still signed in from the above test
+ $mech->get_ok('/my');
+ $mech->follow_link_ok({url => '/auth/change_email'});
+ $mech->submit_form_ok(
+ { with_fields => { email => "" } },
+ "submit blank change email form"
+ );
+ $mech->content_contains( 'Please enter your email', "found expected error" );
+ $mech->submit_form_ok({ with_fields => { email => $test_email2 } }, "change_email to $test_email2");
+ is $mech->uri->path, '/auth/change_email', "still on change email page";
+ $mech->content_contains( 'Now check your email', "found check your email" );
+ my $link = $mech->get_link_from_email;
+ $mech->get_ok($link);
+ is $mech->uri->path, '/my', "redirected to /my page";
+ $mech->content_contains('successfully confirmed');
+ ok(FixMyStreet::App->model('DB::User')->find( { email => $test_email2 } ), "got a user");
+
+ my $p = FixMyStreet::DB->resultset("Problem")->first;
+ is $p->user->email, $test_email2, 'problem user updated';
+
+ my $user1 = FixMyStreet::App->model('DB::User')->create( { email => $test_email, email_verified => 1 } );
+ ok($user1, "created old user");
+ $mech->create_problems_for_body(1, 2514, 'Title1', { user => $user1 } );
+
+ $mech->follow_link_ok({url => '/auth/change_email'});
+ $mech->submit_form_ok({ with_fields => { email => $test_email } },
+ "change_email back to $test_email"
+ );
+ is $mech->uri->path, '/auth/change_email', "still on change email page";
+ $mech->content_contains( 'Now check your email', "found check your email" );
+ $link = $mech->get_link_from_email;
+ $mech->get_ok($link);
+ is $mech->uri->path, '/my', "redirected to /my page";
+ $mech->content_contains('successfully confirmed');
+
+ for (FixMyStreet::DB->resultset("Problem")->all) {
+ is $_->user->email, $test_email;
+ }
+
+ # Test you can't click the link if logged out
+ $mech->follow_link_ok({url => '/auth/change_email'});
+ $mech->submit_form_ok({ with_fields => { email => $test_email } },
+ "change_email back to $test_email"
+ );
+ is $mech->uri->path, '/auth/change_email', "still on change email page";
+ $mech->content_contains( 'Now check your email', "found check your email" );
+ $link = $mech->get_link_from_email;
+ $mech->log_out_ok;
+ $mech->get_ok($link);
+ isnt $mech->uri->path, '/auth/change_email/success', "not redirected to the change_email page";
+ $mech->content_contains('Sorry');
+};
+
+my $test_phone_bad = '01214960000000';
+my $test_landline = '01214960000';
+my $test_mobile = '+61491570156';
+my $test_mobile2 = '+61491570157';
+
+my $user_mob2 = FixMyStreet::App->model('DB::User')->create( {
+ phone => $test_mobile,
+ phone_verified => 1,
+ name => 'Aus Mobile user',
+} );
+$mech->create_problems_for_body(1, 2514, 'Title1', { user => $user_mob2 } );
+
+subtest "Test add/verify/change phone page" => sub {
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok({
+ with_fields => {
+ username => $test_email,
+ password_sign_in => $test_password,
+ },
+ });
+
+ $mech->follow_link_ok({url => '/auth/change_phone'});
+ $mech->submit_form_ok( { with_fields => { username => "" } }, "submit blank change phone form" );
+ is $mech->uri->path, '/my', 'redirected';
+ $mech->content_contains('successfully removed');
+
+ $mech->follow_link_ok({url => '/auth/change_phone'});
+ $mech->submit_form_ok({ with_fields => { username => $test_phone_bad } });
+ $mech->content_contains( 'Please check your phone number is correct', "found expected error" );
+
+ FixMyStreet::override_config({
+ SMS_AUTHENTICATION => 1,
+ PHONE_COUNTRY => 'GB',
+ }, sub {
+ $mech->submit_form_ok({ with_fields => { username => $test_landline } });
+ });
+ is $mech->uri->path, '/my', 'redirected';
+ $mech->content_contains('successfully added');
+
+ FixMyStreet::override_config({
+ SMS_AUTHENTICATION => 1,
+ PHONE_COUNTRY => 'GB',
+ }, sub {
+ $mech->follow_link_ok({url => '/auth/verify/phone'});
+ $mech->submit_form_ok({ with_fields => { username => $test_landline } });
+ });
+ $mech->content_contains( 'Please enter a mobile number', "found expected error" );
+
+ FixMyStreet::override_config({
+ SMS_AUTHENTICATION => 1,
+ TWILIO_ACCOUNT_SID => 'AC123',
+ }, sub {
+ $mech->submit_form_ok({ with_fields => { username => $test_mobile } });
+ });
+ is $mech->uri->path, '/auth/verify/phone', "still on change phone page";
+ $mech->content_contains( 'Now check your phone', "found check your phone" );
+
+ $mech->submit_form_ok({
+ with_fields => { code => '00000' }
+ }, 'submit incorrect code');
+ $mech->content_contains('Try again');
+
+ my $code = $twilio->get_text_code;
+ $mech->submit_form_ok({
+ with_fields => { code => $code }
+ }, 'submit correct code');
+
+ my $user = FixMyStreet::App->model('DB::User')->find( { phone => $test_mobile } );
+ ok $user, "user exists";
+ is $user->email_verified, 1;
+ is $user->email, $test_email, 'email still same';
+ is $mech->uri->path, '/my', "redirected to /my page";
+ $mech->content_contains('successfully verified');
+ $mech->logged_in_ok;
+};
+
+subtest "Test change phone to existing account" => sub {
+ $mech->get_ok('/auth');
+ FixMyStreet::override_config({
+ SMS_AUTHENTICATION => 1,
+ }, sub {
+ $mech->submit_form_ok({
+ with_fields => {
+ username => $test_mobile,
+ password_sign_in => $test_password,
+ },
+ });
+ });
+
+ $mech->follow_link_ok({url => '/auth/change_phone'});
+
+ FixMyStreet::override_config({
+ SMS_AUTHENTICATION => 1,
+ TWILIO_ACCOUNT_SID => 'AC123',
+ }, sub {
+ $mech->submit_form_ok({ with_fields => { username => $test_mobile2 } });
+ });
+ is $mech->uri->path, '/auth/change_phone', "still on change phone page";
+ $mech->content_contains( 'Now check your phone', "found check your phone" );
+
+ my $code = $twilio->get_text_code;
+ $mech->submit_form_ok({ with_fields => { code => $code } }, 'submit correct code');
+
+ my $user = FixMyStreet::App->model('DB::User')->find( { phone => $test_mobile } );
+ ok !$user, 'old user does not exist';
+ $user = FixMyStreet::App->model('DB::User')->find( { phone => $test_mobile2 } );
+ ok $user, "new mobile user exists";
+ is $user->email_verified, 1;
+ is $user->email, $test_email, 'email still same';
+ is $mech->uri->path, '/my', "redirected to /my page";
+ $mech->content_contains('successfully verified');
+
+ for (FixMyStreet::DB->resultset("Problem")->all) {
+ is $_->user->email, $test_email;
+ }
+};
+
+subtest "Test superuser can access generate token page" => sub {
+ my $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
+ ok $user->update({ is_superuser => 0 }), 'user not superuser';
+
+ $mech->log_out_ok;
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok({
+ with_fields => {
+ username => $test_email,
+ password_sign_in => $test_password,
+ },
+ });
+
+ $mech->content_lacks('Generate token');
+
+ $mech->get('/auth/generate_token');
+ is $mech->res->code, 403, "access denied";
+
+ ok $user->update({ is_superuser => 1 }), 'user is superuser';
+
+ $mech->get_ok('/my');
+ $mech->content_contains('Generate token');
+ $mech->get_ok('/auth/generate_token');
+};
+
+subtest "Test staff user can access generate token page" => sub {
+ my $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
+ ok $user->update({ is_superuser => 0 }), 'user not superuser';
+
+ $mech->log_out_ok;
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok({
+ with_fields => {
+ username => $test_email,
+ password_sign_in => $test_password,
+ },
+ });
+
+ $mech->content_lacks('Generate token');
+
+ my $body = $mech->create_body_ok(2237, 'Oxfordshire');
+
+ $mech->get('/auth/generate_token');
+ is $mech->res->code, 403, "access denied";
+
+ ok $user->update({ from_body => $body }), 'user is staff user';
+
+ $mech->get_ok('/my');
+ $mech->content_contains('Generate token');
+ $mech->get_ok('/auth/generate_token');
+};
+
+subtest "Test generate token page" => sub {
+ my $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
+ ok $user->update({ is_superuser => 1 }), 'user set to superuser';
+
+ $mech->log_out_ok;
+
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok({
+ with_fields => {
+ username => $test_email,
+ password_sign_in => $test_password,
+ },
+ });
+
+ ok !$user->get_extra_metadata('access_token');
+
+ $mech->get_ok('/my');
+ $mech->follow_link_ok({url => '/auth/generate_token'});
+ $mech->content_lacks('Token:');
+ $mech->submit_form_ok(
+ { with_fields => { generate_token => 'Generate token' } },
+ "submit generate token form"
+ );
+ $mech->content_contains( 'Your token has been generated', "token generated" );
+
+ $user->discard_changes();
+ my $token = $user->get_extra_metadata('access_token');
+ ok $token, 'access token set';
+
+ $mech->content_contains($token, 'access token displayed');
+
+ $mech->get_ok('/auth/generate_token');
+ $mech->content_contains('Current token:');
+ $mech->content_contains($token, 'access token displayed');
+ $mech->content_contains('If you generate a new token');
+
+ $mech->log_out_ok;
+ $mech->add_header('Authorization', "Bearer $token");
+ $mech->logged_in_ok;
+}
diff --git a/t/app/controller/auth_social.t b/t/app/controller/auth_social.t
index 726d264bd..031fb8d9e 100644
--- a/t/app/controller/auth_social.t
+++ b/t/app/controller/auth_social.t
@@ -102,11 +102,7 @@ for my $fb_state ( 'refused', 'no email', 'existing UID', 'okay' ) {
$mech->content_contains('We need your email address, please give it below.');
# We don't have an email, so check that we can still submit it,
# and the ID carries through the confirmation
- if ($page eq 'update') {
- $fields->{rznvy} = $fb_email;
- } else {
- $fields->{email} = $fb_email;
- }
+ $fields->{username} = $fb_email;
$fields->{name} = 'Ffion Tester';
$mech->submit_form(with_fields => $fields);
$mech->content_contains('Nearly done! Now check your email');
@@ -214,11 +210,7 @@ for my $tw_state ( 'refused', 'existing UID', 'no email' ) {
$mech->content_contains('We need your email address, please give it below.');
# We don't have an email, so check that we can still submit it,
# and the ID carries through the confirmation
- if ($page eq 'update') {
- $fields->{rznvy} = $tw_email;
- } else {
- $fields->{email} = $tw_email;
- }
+ $fields->{username} = $tw_email;
$fields->{name} = 'Ffion Tester';
$mech->submit_form(with_fields => $fields);
$mech->content_contains('Nearly done! Now check your email');
diff --git a/t/app/controller/dashboard.t b/t/app/controller/dashboard.t
index 457eceade..b53056968 100644
--- a/t/app/controller/dashboard.t
+++ b/t/app/controller/dashboard.t
@@ -1,600 +1,150 @@
use Test::MockTime ':all';
+use strict;
+use warnings;
use FixMyStreet::TestMech;
use Web::Scraper;
-my $mech = FixMyStreet::TestMech->new;
+set_absolute_time('2014-02-01T12:00:00');
-my $test_user = 'council_user@example.com';
-my $test_pass = 'password';
-my $test_council = 2651;
-my $test_ward = 20723;
+my $mech = FixMyStreet::TestMech->new;
-my $body = $mech->create_body_ok($test_council, 'City of Edinburgh Council');
+my $other_body = $mech->create_body_ok(1234, 'Some Other Council');
+my $body = $mech->create_body_ok(2651, 'City of Edinburgh Council');
+my @cats = ('Litter', 'Other', 'Potholes', 'Traffic lights');
+for my $contact ( @cats ) {
+ $mech->create_contact_ok(body_id => $body->id, category => $contact, email => "$contact\@example.org");
+}
-$mech->delete_user( $test_user );
-my $user = $mech->create_user_ok($test_user, password => $test_pass);
+my $superuser = $mech->create_user_ok('superuser@example.com', name => 'Super User', is_superuser => 1);
+my $counciluser = $mech->create_user_ok('counciluser@example.com', name => 'Council User', from_body => $body);
+my $normaluser = $mech->create_user_ok('normaluser@example.com', name => 'Normal User');
-my $p_user = $mech->create_user_ok('p_user@example.com');
+my $body_id = $body->id;
+my $area_id = '60705';
+my $alt_area_id = '62883';
-# Dashboard tests assume we are not too early in year, to allow reporting
-# within same year, as a convenience.
-set_absolute_time('2014-03-01T12:00:00');
-FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
- MAPIT_URL => 'http://mapit.uk/',
-}, sub {
+my $last_month = DateTime->now->subtract(months => 2);
+$mech->create_problems_for_body(2, $body->id, 'Title', { areas => ",$area_id,2651,", category => 'Potholes', cobrand => 'fixmystreet' });
+$mech->create_problems_for_body(3, $body->id, 'Title', { areas => ",$area_id,2651,", category => 'Traffic lights', cobrand => 'fixmystreet', dt => $last_month });
+$mech->create_problems_for_body(1, $body->id, 'Title', { areas => ",$alt_area_id,2651,", category => 'Litter', cobrand => 'fixmystreet' });
- $mech->not_logged_in_ok;
- $mech->get_ok('/dashboard');
+my @scheduled_problems = $mech->create_problems_for_body(7, $body->id, 'Title', { areas => ",$area_id,2651,", category => 'Traffic lights', cobrand => 'fixmystreet' });
+my @fixed_problems = $mech->create_problems_for_body(4, $body->id, 'Title', { areas => ",$area_id,2651,", category => 'Potholes', cobrand => 'fixmystreet' });
+my @closed_problems = $mech->create_problems_for_body(3, $body->id, 'Title', { areas => ",$area_id,2651,", category => 'Traffic lights', cobrand => 'fixmystreet' });
- $mech->content_contains( 'sign in' );
-
- $mech->submit_form(
- with_fields => { email => $test_user, password_sign_in => $test_pass }
- );
-
- is $mech->status, '404', 'If not council user get 404';
+foreach my $problem (@scheduled_problems) {
+ $problem->update({ state => 'action scheduled' });
+ $mech->create_comment_for_problem($problem, $counciluser, 'Title', 'text', 0, 'confirmed', 'action scheduled');
+}
- $user->from_body( $body->id );
- $user->update;
+foreach my $problem (@fixed_problems) {
+ $problem->update({ state => 'fixed - council' });
+ $mech->create_comment_for_problem($problem, $counciluser, 'Title', 'text', 0, 'confirmed', 'fixed');
+}
- $mech->log_out_ok;
- $mech->get_ok('/dashboard');
- $mech->submit_form_ok( {
- with_fields => { email => $test_user, password_sign_in => $test_pass }
- } );
+foreach my $problem (@closed_problems) {
+ $problem->update({ state => 'closed' });
+ $mech->create_comment_for_problem($problem, $counciluser, 'Title', 'text', 0, 'confirmed', 'closed', { confirmed => \'current_timestamp' });
+}
- $mech->content_contains( 'Area 2651' );
+my $categories = scraper {
+ process "select[name=category] > option", 'cats[]' => 'TEXT',
+ process "table[id=overview] > tr", 'rows[]' => scraper {
+ process 'td', 'cols[]' => 'TEXT'
+ },
+};
- FixMyStreet::App->model('DB::Contact')->search( { body_id => $body->id } )
- ->delete;
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
- delete_problems();
+ subtest 'not logged in, redirected to login' => sub {
+ $mech->not_logged_in_ok;
+ $mech->get_ok('/dashboard');
+ $mech->content_contains( 'sign in' );
+ };
- my @cats = qw( Grafitti Litter Potholes Other );
- for my $contact ( @cats ) {
- FixMyStreet::App->model('DB::Contact')->create(
- {
- body_id => $body->id,
- category => $contact,
- email => "$contact\@example.org",
- state => 'confirmed',
- whenedited => DateTime->now,
- editor => 'test',
- note => 'test',
- }
- );
- }
+ subtest 'normal user, 404' => sub {
+ $mech->log_in_ok( $normaluser->email );
+ $mech->get('/dashboard');
+ is $mech->status, '404', 'If not council user get 404';
+ };
- $mech->get_ok('/dashboard');
-
- my $categories = scraper {
- process "select[name=category] > option", 'cats[]' => 'TEXT',
- process "select[name=ward] > option", 'wards[]' => 'TEXT',
- process "table[id=overview] > tr", 'rows[]' => scraper {
- process 'td', 'cols[]' => 'TEXT'
- },
- process "tr[id=total] > td", 'totals[]' => 'TEXT',
- process "tr[id=fixed_council] > td", 'council[]' => 'TEXT',
- process "tr[id=fixed_user] > td", 'user[]' => 'TEXT',
- process "tr[id=total_fixed] > td", 'total_fixed[]' => 'TEXT',
- process "tr[id=in_progress] > td", 'in_progress[]' => 'TEXT',
- process "tr[id=action_scheduled] > td", 'action_scheduled[]' => 'TEXT',
- process "tr[id=investigating] > td", 'investigating[]' => 'TEXT',
- process "tr[id=marked] > td", 'marked[]' => 'TEXT',
- process "tr[id=avg_marked] > td", 'avg_marked[]' => 'TEXT',
- process "tr[id=avg_fixed] > td", 'avg_fixed[]' => 'TEXT',
- process "tr[id=not_marked] > td", 'not_marked[]' => 'TEXT',
- process "tr[id=closed] > td", 'closed[]' => 'TEXT',
- process "table[id=reports] > tr > td", 'report_lists[]' => scraper {
- process 'ul > li', 'reports[]' => 'TEXT'
- },
+ subtest 'superuser, body list' => sub {
+ $mech->log_in_ok( $superuser->email );
+ $mech->get_ok('/dashboard');
+ # Contains body name, in list of bodies
+ $mech->content_contains('Some Other Council');
+ $mech->content_contains('Edinburgh Council');
+ $mech->content_lacks('Category:');
+ $mech->get_ok('/dashboard?body=' . $body->id);
+ $mech->content_lacks('Some Other Council');
+ $mech->content_contains('Edinburgh Council');
+ $mech->content_contains('Trowbridge');
+ $mech->content_contains('Category:');
};
- my $expected_cats = [ 'All', '-- Pick a category --', @cats ];
- my $res = $categories->scrape( $mech->content );
- is_deeply( $res->{cats}, $expected_cats, 'correct list of categories' );
+ subtest 'council user, ward list' => sub {
+ $mech->log_in_ok( $counciluser->email );
+ $mech->get_ok('/dashboard');
+ $mech->content_lacks('Some Other Council');
+ $mech->content_contains('Edinburgh Council');
+ $mech->content_contains('Trowbridge');
+ $mech->content_contains('Category:');
+ };
- foreach my $row ( @{ $res->{rows} }[1 .. 11] ) {
- foreach my $col ( @{ $row->{cols} } ) {
- is $col, 0;
- }
- }
+ subtest 'area user can only see their area' => sub {
+ $counciluser->update({area_id => $area_id});
- for my $reports ( @{ $res->{report_lists} } ) {
- is_deeply $reports, {}, 'No reports';
- }
+ $mech->get_ok("/dashboard");
+ $mech->content_contains('<h1>Trowbridge</h1>');
+ $mech->get_ok("/dashboard?body=" . $other_body->id);
+ $mech->content_contains('<h1>Trowbridge</h1>');
+ $mech->get_ok("/dashboard?ward=$alt_area_id");
+ $mech->content_contains('<h1>Trowbridge</h1>');
- my $now = DateTime->now(time_zone => 'local');
- foreach my $test (
- {
- desc => 'confirmed today with no state',
- dt => $now,
- counts => [1,1,1,1],
- report_counts => [1, 0, 0],
- },
- {
- desc => 'confirmed last 7 days with no state',
- dt => $now->clone->subtract( days => 6, hours => 23 ),
- counts => [1,2,2,2],
- report_counts => [2, 0, 0],
- },
- {
- desc => 'confirmed last 8 days with no state',
- dt => $now->clone->subtract( days => 8 ),
- counts => [1,2,3,3],
- report_counts => [2, 1, 0],
- },
- {
- desc => 'confirmed last 2 weeks with no state',
- dt => $now->clone->subtract( weeks => 2, hours => 1 ),
- counts => [1,2,4,4],
- report_counts => [2, 1, 1],
- },
- {
- desc => 'confirmed this year with no state',
- dt => $now->clone->subtract( weeks => 7 ),
- counts => [1,2,4,5],
- report_counts => [2, 1, 1],
- },
- ) {
- subtest $test->{desc} => sub {
- make_problem( { state => 'confirmed', conf_dt => $test->{dt} } );
-
- $mech->get_ok('/dashboard');
- $res = $categories->scrape( $mech->content );
-
- check_row( $res, 'totals', $test->{counts} );
- check_row( $res, 'not_marked', $test->{counts} );
-
- check_report_counts( $res, $test->{report_counts} );
- };
- }
+ $counciluser->update({area_id => undef});
+ };
- delete_problems();
-
- my $is_monday = DateTime->now->day_of_week == 1 ? 1 : 0;
-
- foreach my $test (
- {
- desc => 'user fixed today',
- confirm_dt => DateTime->now->subtract( days => 1 ),
- mark_dt => DateTime->now,
- state => 'fixed - user',
- counts => {
- totals => $is_monday ? [0,1,1,1] : [1,1,1,1],
- user => [1,1,1,1],
- council => [0,0,0,0],
- avg_fixed => [0,0,0,0],
- total_fixed => [1,1,1,1],
- }
- },
- {
- desc => 'council fixed today',
- confirm_dt => DateTime->now->subtract( days => 1 ),
- mark_dt => DateTime->now,
- state => 'fixed - council',
- counts => {
- totals => $is_monday ? [0,2,2,2] : [2,2,2,2],
- user => [1,1,1,1],
- council => [1,1,1,1],
- avg_fixed => [1,1,1,1],
- total_fixed => [2,2,2,2],
- }
- },
- {
- desc => 'marked investigating today',
- confirm_dt => DateTime->now->subtract( days => 1 ),
- mark_dt => DateTime->now,
- state => 'investigating',
- counts => {
- totals => $is_monday ? [0,3,3,3] : [3,3,3,3],
- user => [1,1,1,1],
- council => [1,1,1,1],
- total_fixed => [2,2,2,2],
- avg_marked => [1,1,1,1],
- investigating => [1,1,1,1],
- marked => [1,1,1,1]
- }
- },
- {
- desc => 'marked in progress today',
- confirm_dt => DateTime->now->subtract( days => 1 ),
- mark_dt => DateTime->now,
- state => 'in progress',
- counts => {
- totals => $is_monday ? [0,4,4,4] : [4,4,4,4],
- user => [1,1,1,1],
- council => [1,1,1,1],
- total_fixed => [2,2,2,2],
- avg_marked => [1,1,1,1],
- investigating => [1,1,1,1],
- in_progress => [1,1,1,1],
- marked => [2,2,2,2]
- }
- },
- {
- desc => 'marked as action scheduled today',
- confirm_dt => DateTime->now->subtract( days => 1 ),
- mark_dt => DateTime->now,
- state => 'action scheduled',
- counts => {
- totals => $is_monday ? [ 0,5,5,5] : [5,5,5,5],
- user => [1,1,1,1],
- council => [1,1,1,1],
- total_fixed => [2,2,2,2],
- avg_marked => [1,1,1,1],
- investigating => [1,1,1,1],
- in_progress => [1,1,1,1],
- action_scheduled => [1,1,1,1],
- marked => [3,3,3,3]
- }
- },
- {
- desc => 'marked as action scheduled today, confirmed a week ago',
- confirm_dt => DateTime->now->subtract( days => 8 ),
- mark_dt => DateTime->now,
- state => 'action scheduled',
- counts => {
- totals => $is_monday ? [0,5,6,6] : [5,5,6,6],
- user => [1,1,1,1],
- council => [1,1,1,1],
- total_fixed => [2,2,2,2],
- avg_marked => [3,3,3,3],
- investigating => [1,1,1,1],
- in_progress => [1,1,1,1],
- action_scheduled => [2,2,2,2],
- marked => [4,4,4,4]
- }
- },
- {
- desc => 'marked as council fixed today, confirmed a week ago',
- confirm_dt => DateTime->now->subtract( days => 8 ),
- mark_dt => DateTime->now,
- state => 'fixed - council',
- counts => {
- totals => $is_monday ? [0,5,7,7] : [5,5,7,7],
- user => [1,1,1,1],
- council => [2,2,2,2],
- total_fixed => [3,3,3,3],
- avg_fixed => [5,5,5,5],
- avg_marked => [3,3,3,3],
- investigating => [1,1,1,1],
- in_progress => [1,1,1,1],
- action_scheduled => [2,2,2,2],
- marked => [4,4,4,4]
- }
- },
- {
- desc => 'marked as council fixed a week ago, confirmed 3 weeks ago',
- confirm_dt => DateTime->now->subtract( days => 21),
- mark_dt => DateTime->now->subtract( days => 8 ),
- state => 'fixed - council',
- counts => {
- totals => $is_monday ? [0,5,8,8] : [5,5,8,8],
- user => [1,1,1,1],
- council => [2,2,3,3],
- total_fixed => [3,3,4,4],
- avg_fixed => [5,5,7,7],
- avg_marked => [3,3,3,3],
- investigating => [1,1,1,1],
- in_progress => [1,1,1,1],
- action_scheduled => [2,2,2,2],
- marked => [4,4,4,4]
- }
- },
- {
- desc => 'marked as user fixed 6 weeks ago, confirmed 7 weeks ago',
- confirm_dt => DateTime->now->subtract( weeks => 6 ),
- mark_dt => DateTime->now->subtract( weeks => 7 ),
- state => 'fixed - user',
- counts => {
- totals => $is_monday ? [0,5,8,9] : [5,5,8,9],
- user => [1,1,1,2],
- council => [2,2,3,3],
- total_fixed => [3,3,4,5],
- avg_fixed => [5,5,7,7],
- avg_marked => [3,3,3,3],
- investigating => [1,1,1,1],
- in_progress => [1,1,1,1],
- action_scheduled => [2,2,2,2],
- marked => [4,4,4,4]
- }
- },
- {
- desc => 'marked as closed',
- confirm_dt => DateTime->now->subtract( days => 1 ),
- mark_dt => DateTime->now,
- state => 'closed',
- counts => {
- totals => $is_monday ? [0,6,9,10] : [6,6,9,10],
- user => [1,1,1,2],
- council => [2,2,3,3],
- total_fixed => [3,3,4,5],
- avg_fixed => [5,5,7,7],
- avg_marked => [2,2,2,2],
- investigating => [1,1,1,1],
- in_progress => [1,1,1,1],
- action_scheduled => [2,2,2,2],
- closed => [1,1,1,1],
- marked => [5,5,5,5]
- }
- },
- {
- desc => 'marked as planned',
- confirm_dt => DateTime->now->subtract( days => 1 ),
- mark_dt => DateTime->now,
- state => 'planned',
- counts => {
- totals => $is_monday ? [0,7,10,11] : [7,7,10,11],
- user => [1,1,1,2],
- council => [2,2,3,3],
- total_fixed => [3,3,4,5],
- avg_fixed => [5,5,7,7],
- avg_marked => [2,2,2,2],
- investigating => [1,1,1,1],
- in_progress => [1,1,1,1],
- action_scheduled => [3,3,3,3],
- closed => [1,1,1,1],
- marked => [6,6,6,6]
- }
- },
- ) {
- subtest $test->{desc} => sub {
- make_problem(
- {
- state => $test->{state},
- conf_dt => $test->{confirm_dt},
- mark_dt => $test->{mark_dt},
- }
- );
-
- $mech->get_ok('/dashboard');
- $res = $categories->scrape( $mech->content );
-
- foreach my $row ( keys %{ $test->{counts} } ) {
- check_row( $res, $row, $test->{counts}->{$row} );
- }
- };
- }
+ subtest 'The correct categories and totals shown by default' => sub {
+ $mech->get_ok("/dashboard");
+ my $expected_cats = [ 'All', @cats ];
+ my $res = $categories->scrape( $mech->content );
+ is_deeply( $res->{cats}, $expected_cats, 'correct list of categories' );
+ # Three missing as more than a month ago
+ test_table($mech->content, 1, 0, 0, 1, 0, 0, 0, 0, 2, 0, 4, 6, 7, 3, 0, 10, 10, 3, 4, 17);
+ };
- delete_problems();
-
- for my $test (
- {
- desc => 'Selecting no category does nothing',
- p1 => {
- state => 'confirmed',
- conf_dt => DateTime->now(),
- category => 'Potholes',
- },
- p2 => {
- state => 'confirmed',
- conf_dt => DateTime->now(),
- category => 'Litter',
- },
- category => '',
- counts => {
- totals => [2,2,2,2],
- },
- counts_after => {
- totals => [2,2,2,2],
- },
- report_counts => [2,0,0],
- report_counts_after => [2,0,0],
- },
- {
- desc => 'Limit display by category',
- category => 'Potholes',
- counts => {
- totals => [2,2,2,2],
- },
- counts_after => {
- totals => [1,1,1,1],
- },
- report_counts => [2,0,0],
- report_counts_after => [1,0,0],
- },
- {
- desc => 'Limit display for category with no entries',
- category => 'Grafitti',
- counts => {
- totals => [2,2,2,2],
- },
- counts_after => {
- totals => [0,0,0,0],
- },
- report_counts => [2,0,0],
- report_counts_after => [0,0,0],
- },
- {
- desc => 'Limit display by category for council fixed',
- p1 => {
- state => 'fixed - council',
- conf_dt => DateTime->now()->subtract( weeks => 1 ),
- mark_dt => DateTime->now()->subtract( weeks => 1 ),
- category => 'Potholes',
- },
- p2 => {
- state => 'fixed - council',
- conf_dt => DateTime->now()->subtract( weeks => 1 ),
- mark_dt => DateTime->now()->subtract( weeks => 1 ),
- category => 'Litter',
- },
- category => 'Potholes',
- counts => {
- council => [0,0,2,2],
- totals => [2,2,4,4],
- },
- counts_after => {
- council => [0,0,1,1],
- totals => [1,1,2,2],
- },
- report_counts => [2,2,0],
- report_counts_after => [1,1,0],
- },
- {
- desc => 'Limit display by category for user fixed',
- p1 => {
- state => 'fixed - user',
- conf_dt => DateTime->now()->subtract( weeks => 1 ),
- mark_dt => DateTime->now()->subtract( weeks => 1 ),
- category => 'Potholes',
- },
- p2 => {
- state => 'fixed - user',
- conf_dt => DateTime->now()->subtract( weeks => 1 ),
- mark_dt => DateTime->now()->subtract( weeks => 1 ),
- category => 'Litter',
- },
- category => 'Potholes',
- counts => {
- user => [0,0,2,2],
- council => [0,0,2,2],
- totals => [2,2,6,6],
- },
- counts_after => {
- user => [0,0,1,1],
- council => [0,0,1,1],
- totals => [1,1,3,3],
- },
- report_counts => [2,4,0],
- report_counts_after => [1,2,0],
- },
- {
- desc => 'Limit display by ward',
- p1 => {
- state => 'confirmed',
- conf_dt => DateTime->now()->subtract( weeks => 1 ),
- category => 'Potholes',
- # in real life it has commas around it and the search
- # uses them
- areas => ',20720,',
- },
- p2 => {
- state => 'fixed - council',
- conf_dt => DateTime->now()->subtract( weeks => 1 ),
- mark_dt => DateTime->now()->subtract( weeks => 1 ),
- category => 'Litter',
- areas => ',20720,',
- },
- ward => 20720,
- counts => {
- user => [0,0,2,2],
- council => [0,0,3,3],
- totals => [2,2,8,8],
- },
- counts_after => {
- user => [0,0,0,0],
- council => [0,0,1,1],
- totals => [0,0,2,2],
- },
- report_counts => [2,6,0],
- report_counts_after => [0,2,0],
- },
- ) {
- subtest $test->{desc} => sub {
- make_problem( $test->{p1} ) if $test->{p1};
- make_problem( $test->{p2} ) if $test->{p2};
-
- $mech->get_ok('/dashboard');
-
- $res = $categories->scrape( $mech->content );
-
- foreach my $row ( keys %{ $test->{counts} } ) {
- check_row( $res, $row, $test->{counts}->{$row} );
- }
-
- check_report_counts( $res, $test->{report_counts} );
-
- $mech->submit_form_ok( {
- with_fields => {
- category => $test->{category},
- ward => $test->{ward},
- }
- } );
-
- $res = $categories->scrape( $mech->content );
-
- foreach my $row ( keys %{ $test->{counts_after} } ) {
- check_row( $res, $row, $test->{counts_after}->{$row} );
- }
- check_report_counts( $res, $test->{report_counts_after} );
- };
- }
+ subtest 'test filters' => sub {
+ $mech->get_ok("/dashboard");
+ $mech->submit_form_ok({ with_fields => { category => 'Litter' } });
+ test_table($mech->content, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1);
+ $mech->submit_form_ok({ with_fields => { category => '', state => 'fixed - council' } });
+ test_table($mech->content, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 4, 4);
+ $mech->submit_form_ok({ with_fields => { state => 'action scheduled' } });
+ test_table($mech->content, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 7, 0, 0, 7);
+ my $start = DateTime->now->subtract(months => 3)->strftime('%Y-%m-%d');
+ my $end = DateTime->now->subtract(months => 1)->strftime('%Y-%m-%d');
+ $mech->submit_form_ok({ with_fields => { state => '', start_date => $start, end_date => $end } });
+ test_table($mech->content, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 3, 0, 0, 3);
+ };
- delete_problems();
-
- for my $test (
- {
- desc => 'Selecting no state does nothing',
- p1 => {
- state => 'fixed - user',
- conf_dt => DateTime->now()->subtract( minutes => 1 ),
- category => 'Potholes',
- },
- p2 => {
- state => 'confirmed',
- conf_dt => DateTime->now()->subtract( minutes => 1 ),
- category => 'Litter',
- },
- state => '',
- report_counts => [2,0,0],
- report_counts_after => [2,0,0],
- },
- {
- desc => 'limit by state works',
- state => 'fixed - council',
- report_counts => [2,0,0],
- report_counts_after => [1,0,0],
- },
- {
- desc => 'All fixed states count as fixed',
- p1 => {
- state => 'fixed - council',
- conf_dt => DateTime->now()->subtract( minutes => 1 ),
- category => 'Potholes',
- },
- p2 => {
- state => 'fixed',
- conf_dt => DateTime->now()->subtract( minutes => 1 ),
- category => 'Potholes',
- },
- state => 'fixed',
- report_counts => [4,0,0],
- report_counts_after => [3,0,0],
- },
- ) {
- subtest $test->{desc} => sub {
- make_problem( $test->{p1} ) if $test->{p1};
- make_problem( $test->{p2} ) if $test->{p2};
-
- $mech->get_ok('/dashboard');
-
- $res = $categories->scrape( $mech->content );
-
- check_report_counts( $res, $test->{report_counts} );
-
- $mech->submit_form_ok( {
- with_fields => {
- state => $test->{state},
- }
- } );
-
- $res = $categories->scrape( $mech->content );
-
- check_report_counts( $res, $test->{report_counts_after} );
- };
- }
+ subtest 'test grouping' => sub {
+ $mech->get_ok("/dashboard?group_by=category");
+ test_table($mech->content, 1, 0, 6, 10, 17);
+ $mech->get_ok("/dashboard?group_by=state");
+ test_table($mech->content, 3, 7, 4, 3, 17);
+ $mech->get_ok("/dashboard?start_date=2000-01-01&group_by=month");
+ test_table($mech->content, 0, 17, 17, 3, 0, 3, 3, 17, 20);
+ };
subtest 'export as csv' => sub {
- make_problem( {
+ $mech->create_problems_for_body(1, $body->id, 'Title', {
detail => "this report\nis split across\nseveral lines",
- state => "confirmed",
- conf_dt => DateTime->now(),
- areas => 62883,
- } );
+ areas => ",$alt_area_id,2651,",
+ });
$mech->get_ok('/dashboard?export=1');
open my $data_handle, '<', \$mech->content;
my $csv = Text::CSV->new( { binary => 1 } );
@@ -602,7 +152,7 @@ FixMyStreet::override_config {
while ( my $row = $csv->getline( $data_handle ) ) {
push @rows, $row;
}
- is scalar @rows, 6, '1 (header) + 5 (reports) = 6 lines';
+ is scalar @rows, 19, '1 (header) + 18 (reports) = 19 lines';
is scalar @{$rows[0]}, 18, '18 columns present';
@@ -621,7 +171,7 @@ FixMyStreet::override_config {
'Status',
'Latitude',
'Longitude',
- 'Nearest Postcode',
+ 'Query',
'Ward',
'Easting',
'Northing',
@@ -629,84 +179,40 @@ FixMyStreet::override_config {
],
'Column headers look correct';
- is $rows[5]->[14], 'Bradford-on-Avon', 'Ward column is name not ID';
-
- is $rows[5]->[15], '610591', 'Correct Easting conversion';
- is $rows[5]->[16], '126573', 'Correct Northing conversion';
+ is $rows[5]->[14], 'Trowbridge', 'Ward column is name not ID';
+ is $rows[5]->[15], '529025', 'Correct Easting conversion';
+ is $rows[5]->[16], '179716', 'Correct Northing conversion';
};
-};
-restore_time;
-
-sub make_problem {
- my $args = shift;
-
- my $p = FixMyStreet::App->model('DB::Problem')->create( {
- title => 'a problem',
- name => 'a user',
- anonymous => 1,
- detail => $args->{detail} || 'some detail',
- state => $args->{state},
- confirmed => $args->{conf_dt},
- whensent => $args->{conf_dt},
- lastupdate => $args->{mark_dt} || $args->{conf_dt},
- bodies_str => $body->id,
- postcode => 'EH99 1SP',
- latitude => '51',
- longitude => '1',
- areas => $args->{areas} || $test_ward,
- used_map => 0,
- user_id => $p_user->id,
- category => $args->{category} || 'Other',
- } );
-
- if ( $args->{state} ne 'confirmed' ) {
- my $c = FixMyStreet::App->model('DB::Comment')->create( {
- problem => $p,
- user_id => $p_user->id,
- state => 'confirmed',
- problem_state => $args->{state} =~ /^fixed - user|fixed$/ ? undef : $args->{state},
- confirmed => $args->{mark_dt},
- text => 'an update',
- mark_fixed => $args->{state} =~ /fixed/ ? 1 : 0,
- anonymous => 1,
- } );
- }
-}
-sub check_row {
- my $res = shift;
- my $row = shift;
- my $totals = shift;
+ subtest 'export as csv using token' => sub {
+ $mech->log_out_ok;
- is $res->{ $row }->[0], $totals->[0], "Correct count in $row for WTD";
- is $res->{ $row }->[1], $totals->[1], "Correct count in $row for last 7 days";
- is $res->{ $row }->[2], $totals->[2], "Correct count in $row for last 4 weeks";
- is $res->{ $row }->[3], $totals->[3], "Correct count in $row for YTD";
-}
+ $counciluser->set_extra_metadata('access_token', '1234567890abcdefgh');
+ $counciluser->update();
+
+ $mech->get_ok('/dashboard?export=1');
+ like $mech->res->header('Content-type'), qr'text/html';
+ $mech->content_lacks('Report ID');
+
+ $mech->add_header('Authorization', 'Bearer 1234567890abcdefgh');
+ $mech->get_ok('/dashboard?export=1');
+ like $mech->res->header('Content-type'), qr'text/csv';
+ $mech->content_contains('Report ID');
+ };
+};
-sub check_report_counts {
- my $res = shift;
- my $counts = shift;
-
- for my $i ( 0 .. 2 ) {
- if ( $counts->[$i] == 0 ) {
- is_deeply $res->{report_lists}->[$i], {}, "No reports for column $i";
- } else {
- if ( ref( $res->{report_lists}->[$i]->{reports} ) eq 'ARRAY' ) {
- is scalar @{ $res->{report_lists}->[$i]->{reports} }, $counts->[$i], "Correct report count for column $i";
- } else {
- fail "Correct report count for column $i ( no reports )";
- }
+sub test_table {
+ my ($content, @expected) = @_;
+ my $res = $categories->scrape( $mech->content );
+ my $i = 0;
+ foreach my $row ( @{ $res->{rows} }[1 .. 11] ) {
+ foreach my $col ( @{ $row->{cols} } ) {
+ is $col, $expected[$i++];
}
}
}
-sub delete_problems {
- FixMyStreet::App->model('DB::Comment')
- ->search( { 'problem.bodies_str' => $body->id }, { join => 'problem' } )
- ->delete;
- FixMyStreet::App->model('DB::Problem')
- ->search( { bodies_str => $body->id } )->delete();
+END {
+ restore_time;
+ done_testing();
}
-
-done_testing;
diff --git a/t/app/controller/index.t b/t/app/controller/index.t
index be4da6034..9be6dfa1e 100644
--- a/t/app/controller/index.t
+++ b/t/app/controller/index.t
@@ -8,7 +8,11 @@ subtest "check that the form goes to /around" => sub {
$mech->get_ok('/');
is $mech->uri->path, '/', "still on '/'";
- $mech->submit_form_ok( { with_fields => { pc => 'SW1A 1AA', } } );
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/'
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => 'SW1A 1AA', } } );
+ };
# check that we are at /around
is $mech->uri->path, '/around', "Got to /around";
diff --git a/t/app/controller/moderate.t b/t/app/controller/moderate.t
index c3c77866b..4b2f0cfe3 100644
--- a/t/app/controller/moderate.t
+++ b/t/app/controller/moderate.t
@@ -1,3 +1,11 @@
+package FixMyStreet::Cobrand::Tester;
+
+use parent 'FixMyStreet::Cobrand::Default';
+
+sub send_moderation_notifications { 0 }
+
+package main;
+
use FixMyStreet::TestMech;
use FixMyStreet::App;
use Data::Dumper;
@@ -176,6 +184,30 @@ subtest 'Problem moderation' => sub {
# reset
$report->update({ state => 'confirmed' });
};
+
+ subtest 'Hide report without sending email' => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { 'tester' => '.' } ]
+ }, sub {
+
+ $mech->clear_emails_ok;
+
+ $mech->get_ok($REPORT_URL);
+ $mech->submit_form_ok({ with_fields => {
+ %problem_prepopulated,
+ problem_hide => 1,
+ }});
+ $mech->base_unlike( qr{/report/}, 'redirected to front page' );
+
+ $report->discard_changes;
+ is $report->state, 'hidden', 'Is hidden';
+
+ ok $mech->email_count_is(0), "Email wasn't sent";
+
+ # reset
+ $report->update({ state => 'confirmed' });
+ }
+ };
};
$mech->content_lacks('Posted anonymously', 'sanity check');
@@ -337,7 +369,7 @@ subtest 'And do it as a superuser' => sub {
problem_title => 'Good good',
problem_detail => 'Good good improved',
}});
- $mech->content_contains('Moderated by a FixMyStreet administrator');
+ $mech->content_contains('Moderated by an administrator');
};
done_testing();
diff --git a/t/app/controller/my_planned.t b/t/app/controller/my_planned.t
index 51ea0297e..67d59e148 100644
--- a/t/app/controller/my_planned.t
+++ b/t/app/controller/my_planned.t
@@ -5,6 +5,7 @@ $mech->get_ok('/my/planned');
is $mech->uri->path, '/auth', "got sent to the sign in page";
my $body = $mech->create_body_ok(2237, 'Oxfordshire County Council');
+my $body2 = $mech->create_body_ok(2421, 'Oxford City Council');
my ($problem) = $mech->create_problems_for_body(1, $body->id, 'Test Title');
$mech->get_ok($problem->url);
@@ -77,4 +78,155 @@ subtest "POSTing multiple problems to my/planned/change adds all to shortlist" =
$mech->text_contains('Shortlisted');
};
+subtest "re-ordering shortlist on non shortlist page redirect to shortlist" => sub {
+ $user->user_planned_reports->remove();
+ my ($problem1) = $mech->create_problems_for_body(1, $body->id, 'New Problem');
+
+ $mech->get_ok($problem1->url);
+ my ($csrf) = $mech->content =~ /meta content="([^"]*)" name="csrf-token"/;
+
+ $mech->post_ok( '/my/planned/change', {
+ id => $problem1->id,
+ 'shortlist-up' => 1,
+ token => $csrf,
+ },
+ );
+
+ $mech->content_contains('Your shortlist');
+};
+
+subtest "shortlist with no action is forbidden" => sub {
+ $user->user_planned_reports->remove();
+ my ($problem1) = $mech->create_problems_for_body(1, $body->id, 'New Problem');
+
+ $mech->get_ok($problem1->url);
+ my ($csrf) = $mech->content =~ /meta content="([^"]*)" name="csrf-token"/;
+
+ my $result = $mech->post( '/my/planned/change', {
+ id => $problem1->id,
+ token => $csrf,
+ },
+ );
+
+ is $result->code, 403, '403 response if no action';
+};
+
+subtest "cannot remove non-existant problems from shortlist" => sub {
+ $user->user_planned_reports->remove();
+ my ($problem1) = $mech->create_problems_for_body(1, $body->id, 'New Problem');
+
+ $mech->get_ok($problem1->url);
+ my ($csrf) = $mech->content =~ /meta content="([^"]*)" name="csrf-token"/;
+
+ my $result = $mech->post( '/my/planned/change', {
+ id => 999,
+ 'shortlist-remove' => 1,
+ token => $csrf,
+ },
+ );
+
+ is $result->code, 404, 'removing missing report returns 404';
+};
+
+subtest "can remove problems from shortlist" => sub {
+ $user->user_planned_reports->remove();
+ my ($problem1, $problem2) = $mech->create_problems_for_body(2, $body->id, 'New Problem');
+
+ $mech->get_ok($problem1->url);
+ my ($csrf) = $mech->content =~ /meta content="([^"]*)" name="csrf-token"/;
+
+ $mech->post_ok( '/my/planned/change_multiple', {
+ 'ids[]' => [
+ $problem1->id,
+ $problem2->id,
+ ],
+ token => $csrf,
+ }
+ );
+
+ $mech->get_ok($problem1->url);
+ $mech->text_contains('Shortlisted');
+
+ ($csrf) = $mech->content =~ /meta content="([^"]*)" name="csrf-token"/;
+
+ $mech->post_ok( '/my/planned/change', {
+ id => $problem1->id,
+ 'shortlist-remove' => 1,
+ token => $csrf,
+ },
+ 'Removed problem from shortlist');
+
+ $mech->get_ok($problem1->url);
+ $mech->text_lacks('Shortlisted');
+ $mech->text_contains('Shortlist');
+
+ # check cases where problem has changed body due
+ # to e.g. change of category
+ $problem2->update({
+ bodies_str => $body2->id,
+ title => 'Other body problem',
+ });
+
+ $mech->get_ok('/my/planned');
+ $mech->text_contains('Other body problem');
+
+ ($csrf) = $mech->content =~ /meta content="([^"]*)" name="csrf-token"/;
+
+ $mech->post_ok( '/my/planned/change', {
+ id => $problem2->id,
+ 'shortlist-remove' => 1,
+ token => $csrf,
+ },
+ 'Removed problem for other body from shortlist');
+
+ $mech->get_ok('/my/planned');
+ $mech->text_lacks('Other body problem');
+};
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'oxfordshire' ],
+ BASE_URL => 'http://oxfordshire.fixmystreet.site',
+}, sub {
+ subtest "can remove problems not displayed in cobrand from shortlist" => sub {
+ $user->user_planned_reports->remove();
+ my ($problem1) = $mech->create_problems_for_body(2, $body->id, 'New Problem');
+
+ $mech->get_ok($problem1->url);
+ my ($csrf) = $mech->content =~ /meta content="([^"]*)" name="csrf-token"/;
+
+ $mech->post_ok( '/my/planned/change_multiple', {
+ 'ids[]' => [
+ $problem1->id,
+ ],
+ token => $csrf,
+ }
+ );
+
+ $mech->get_ok('/my/planned');
+ $mech->text_contains('New Problem');
+ $mech->content_contains('Remove from shortlist');
+
+ $problem1->update({
+ bodies_str => $body2->id,
+ });
+
+ $mech->get_ok('/my/planned');
+ $mech->text_contains('New Problem');
+ $mech->content_contains('Remove from shortlist');
+
+ ($csrf) = $mech->content =~ /meta content="([^"]*)" name="csrf-token"/;
+
+ $mech->post_ok( '/my/planned/change', {
+ id => $problem1->id,
+ 'shortlist-remove' => 1,
+ token => $csrf,
+ ajax => 1,
+ },
+ 'Removed problem not displayed in this cobrand');
+
+ $mech->get_ok('/my/planned');
+ $mech->text_lacks('New Problem', 'Problem no longer in shortlist');
+ };
+};
+
done_testing();
diff --git a/t/app/controller/report_as_other.t b/t/app/controller/report_as_other.t
index daa213e8c..91644e8ce 100644
--- a/t/app/controller/report_as_other.t
+++ b/t/app/controller/report_as_other.t
@@ -47,7 +47,7 @@ subtest "Body user, has permission to add report as another user" => sub {
detail => 'Test report details.',
category => 'Potholes',
name => 'Another User',
- email => 'another@example.net',
+ username => 'another@example.net',
);
is $report->name, 'Another User', 'report name is given name';
is $report->user->name, 'Another User', 'user name matches';
@@ -66,7 +66,7 @@ subtest "Body user, has permission to add report as another (existing) user" =>
detail => 'Test report details.',
category => 'Potholes',
name => 'Existing Yooser',
- email => 'existing@example.net',
+ username => 'existing@example.net',
);
is $report->name, 'Existing Yooser', 'report name is given name';
is $report->user->name, 'Existing User', 'user name remains same';
@@ -108,7 +108,7 @@ subtest "Body user, has permission to add update as another user" => sub {
form_as => 'another_user',
update => 'Test Update',
name => 'Another User',
- rznvy => 'another2@example.net',
+ username => 'another2@example.net',
);
is $update->name, 'Another User', 'update name is given name';
is $update->user->name, 'Another User', 'user name matches';
@@ -124,7 +124,7 @@ subtest "Body user, has permission to add update as another (existing) user" =>
form_as => 'another_user',
update => 'Test Update',
name => 'Existing Yooser',
- rznvy => 'existing@example.net',
+ username => 'existing@example.net',
);
is $update->name, 'Existing Yooser', 'update name is given name';
is $update->user->name, 'Existing User', 'user name remains same';
diff --git a/t/app/controller/report_display.t b/t/app/controller/report_display.t
index 4d73a5204..f0913fbd2 100644
--- a/t/app/controller/report_display.t
+++ b/t/app/controller/report_display.t
@@ -128,7 +128,7 @@ subtest "test a good report" => sub {
my %fields = (
name => '',
- rznvy => '',
+ username => '',
update => '',
add_alert => 1, # defaults to true
fixed => undef
diff --git a/t/app/controller/report_import.t b/t/app/controller/report_import.t
index 47113198e..e4a202db7 100644
--- a/t/app/controller/report_import.t
+++ b/t/app/controller/report_import.t
@@ -362,14 +362,12 @@ subtest "Submit a correct entry (with location) to cobrand" => sub {
photo2 => '',
photo3 => '',
phone => '',
- email => 'test-ll@example.com',
+ username => 'test-ll@example.com',
},
"check imported fields are shown"
or diag Dumper( $mech->visible_form_values ); use Data::Dumper;
- my $user =
- FixMyStreet::App->model('DB::User')
- ->find( { email => 'test-ll@example.com' } );
+ my $user = FixMyStreet::App->model('DB::User')->find( { email => 'test-ll@example.com' } );
ok $user, "Found a user";
my $report = $user->problems->first;
diff --git a/t/app/controller/report_inspect.t b/t/app/controller/report_inspect.t
index 5bbbdff79..239cc408b 100644
--- a/t/app/controller/report_inspect.t
+++ b/t/app/controller/report_inspect.t
@@ -11,10 +11,18 @@ my $rp = FixMyStreet::DB->resultset("ResponsePriority")->create({
body => $oxon,
name => 'High Priority',
});
+my $rp2 = FixMyStreet::DB->resultset("ResponsePriority")->create({
+ body => $oxon,
+ name => 'Low Priority',
+});
FixMyStreet::DB->resultset("ContactResponsePriority")->create({
contact => $contact,
response_priority => $rp,
});
+FixMyStreet::DB->resultset("ContactResponsePriority")->create({
+ contact => $contact3,
+ response_priority => $rp2,
+});
my $wodc = $mech->create_body_ok(2420, 'West Oxfordshire District Council');
$mech->create_contact_ok( body_id => $wodc->id, category => 'Horses', email => 'horses@example.net' );
@@ -116,7 +124,6 @@ FixMyStreet::override_config {
$mech->content_contains('Invalid location');
$mech->submit_form_ok({ button => 'save', with_fields => { latitude => 51.754926, longitude => -1.256179, include_update => undef } });
$mech->content_lacks('Invalid location');
- $user->user_body_permissions->search({ body_id => $oxon->id, permission_type => 'planned_reports' })->delete;
};
subtest "test duplicate reports are shown" => sub {
@@ -140,6 +147,71 @@ FixMyStreet::override_config {
$report2->update;
};
+ subtest "can mark a report as duplicate without supplying a duplicate and a public update" => sub {
+ my $old_state = $report->state;
+ $report->comments->delete_all;
+
+ $mech->get_ok("/report/$report_id");
+ $mech->submit_form_ok({ button => 'save', with_fields => { state => 'Duplicate', include_update => "0" } });
+
+ $mech->content_contains('provide a duplicate ID', "error message about missing duplicate id");
+ $report->discard_changes;
+ $report2->discard_changes;
+
+ is $report->state, $old_state, 'report not marked as duplicate';
+ is $report->comments->search({ problem_state => 'duplicate' })->count, 0, 'no update marking report as duplicate was left';
+
+ is $report->get_extra_metadata('duplicate_of'), undef;
+
+ $mech->submit_form_ok({ button => 'save', with_fields => { state => 'Duplicate', public_update => 'This is a duplicate', include_update => "1" } });
+ $mech->content_lacks('provide a duplicate ID', "no error message about missing duplicate id");
+ $report->discard_changes;
+ $report2->discard_changes;
+
+ is $report->state, 'duplicate', 'report marked as duplicate';
+ is $report->comments->search({ problem_state => 'duplicate' })->count, 1, 'update marking report as duplicate was left';
+ is $report->get_extra_metadata('duplicate_of'), undef;
+ is_deeply $report2->get_extra_metadata('duplicates'), undef;
+
+ $report->update({ state => $old_state });
+ };
+
+ subtest "can mark a report as duplicate without supplying a public update and a duplicate id" => sub {
+ my $old_state = $report->state;
+ $report->comments->delete_all;
+
+ $mech->get_ok("/report/$report_id");
+ $mech->submit_form_ok({ button => 'save', with_fields => { state => 'Duplicate', include_update => "0" } });
+
+ $mech->content_contains('provide a duplicate ID', "error message about missing duplicate id");
+ $report->discard_changes;
+ $report2->discard_changes;
+
+ is $report->state, $old_state, 'report not marked as duplicate';
+ is $report->comments->search({ problem_state => 'duplicate' })->count, 0, 'no update marking report as duplicate was left';
+
+ is $report->get_extra_metadata('duplicate_of'), undef;
+
+ $mech->submit_form_ok({ button => 'save', with_fields => { state => 'Duplicate', duplicate_of => $report2->id, include_update => "0" } });
+ $mech->content_lacks('provide a duplicate ID', "no error message about missing duplicate id");
+ $report->discard_changes;
+ $report2->discard_changes;
+
+ is $report->state, 'duplicate', 'report marked as duplicate';
+ is $report->comments->search({ problem_state => 'duplicate' })->count, 1, 'update marking report as duplicate was left';
+ is $report->get_extra_metadata('duplicate_of'), $report2->id;
+ is_deeply $report2->get_extra_metadata('duplicates'), [ $report->id ];
+
+ # Check that duplicate does not include shortlist add button (no form in form)
+ $mech->get_ok("/report/$report_id");
+ $mech->content_lacks('item-list__item__shortlist-add');
+
+ $report->set_extra_metadata('duplicate_of', undef);
+ $report->update({ state => $old_state });
+ $report2->set_extra_metadata('duplicates', undef);
+ $report2->update;
+ };
+
subtest "marking a report as a duplicate with update correctly sets update status" => sub {
my $old_state = $report->state;
$report->comments->delete_all;
@@ -172,6 +244,9 @@ FixMyStreet::override_config {
my $old_state = $report->state;
$report->comments->delete_all;
+ $mech->get_ok("/report/$report2_id/nearby.json");
+ $mech->content_lacks('Add to shortlist');
+
$mech->get_ok("/report/$report_id");
my $update_text = "This text was entered as an update by the user.";
$mech->submit_form_ok({ button => 'save', with_fields => {
@@ -184,6 +259,7 @@ FixMyStreet::override_config {
is $report->state, 'duplicate', 'report marked as duplicate';
is $report->comments->search({ problem_state => 'duplicate' })->count, 1, 'update marked report as duplicate';
+ $mech->get_ok("/report/$report_id"); # Get again as planned_reports permission means redirect to referer...
$mech->content_contains($update_text);
$mech->content_lacks("Thank you for your report. This problem has already been reported.");
@@ -191,7 +267,6 @@ FixMyStreet::override_config {
};
subtest "post-inspect redirect is to the right place if URL set" => sub {
- $user->user_body_permissions->create({ body => $oxon, permission_type => 'planned_reports' });
$mech->get_ok("/report/$report_id");
my $update_text = "This text was entered as an update by the user.";
$mech->submit_form_ok({ button => 'save', with_fields => {
@@ -202,11 +277,9 @@ FixMyStreet::override_config {
is $mech->res->code, 200, "got 200";
is $mech->res->previous->code, 302, "got 302 for redirect";
is $mech->uri->path, '/', 'redirected to front page';
- $user->user_body_permissions->search({ body_id => $oxon->id, permission_type => 'planned_reports' })->delete;
};
subtest "post-inspect redirect is to the right place if URL not set" => sub {
- $user->user_body_permissions->create({ body => $oxon, permission_type => 'planned_reports' });
$user->set_extra_metadata(categories => [ $contact->id ]);
$user->update;
$mech->get_ok("/report/$report_id");
@@ -223,7 +296,6 @@ FixMyStreet::override_config {
is $params{lat}, $report->latitude, "latitude param is correct";
is $params{lon}, $report->longitude, "longitude param is correct";
is $params{filter_category}, $contact->category, "categories param is correct";
- $user->user_body_permissions->search({ body_id => $oxon->id, permission_type => 'planned_reports' })->delete;
};
subtest "default response priorities display correctly" => sub {
@@ -254,15 +326,165 @@ FixMyStreet::override_config {
$mech->submit_form_ok({
button => 'save',
with_fields => {
- $test->{priority} ? (priority => 1) : (),
+ $test->{priority} ? (priority => $rp->id) : (),
$test->{category} ? (category => 'Cows') : (),
$test->{detailed} ? (detailed_information => 'Highland ones') : (),
}
});
};
}
+
+ subtest "check priority not set for category with no priorities" => sub {
+ $report->discard_changes;
+ $report->update({ category => 'Cows', response_priority_id => undef });
+ $report->discard_changes;
+ is $report->response_priority, undef, 'response priority not set';
+ $user->user_body_permissions->delete;
+ $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_edit_category' });
+ $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_edit_priority' });
+ $mech->get_ok("/report/$report_id");
+ $mech->submit_form_ok({
+ button => 'save',
+ with_fields => {
+ priority => $rp->id,
+ category => 'Sheep',
+ }
+ });
+
+ $report->discard_changes;
+ is $report->response_priority, undef, 'response priority not set';
+ };
+
+ subtest "check can set priority for category when changing from category with no priorities" => sub {
+ $report->discard_changes;
+ $report->update({ category => 'Sheep', response_priority_id => undef });
+ $report->discard_changes;
+ is $report->response_priority, undef, 'response priority not set';
+ $user->user_body_permissions->delete;
+ $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_edit_category' });
+ $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_edit_priority' });
+ $mech->get_ok("/report/$report_id");
+ $mech->submit_form_ok({
+ button => 'save',
+ with_fields => {
+ priority => $rp->id,
+ category => 'Cows',
+ }
+ });
+
+ $report->discard_changes;
+ is $report->response_priority->id, $rp->id, 'response priority set';
+ };
+
+ subtest "check can't set priority that isn't for a category" => sub {
+ $report->discard_changes;
+ $report->update({ category => 'Cows', response_priority_id => $rp->id });
+ $report->discard_changes;
+ is $report->response_priority->id, $rp->id, 'response priority set';
+ $user->user_body_permissions->delete;
+ $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_edit_category' });
+ $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_edit_priority' });
+ $mech->get_ok("/report/$report_id");
+ $mech->submit_form_ok({
+ button => 'save',
+ with_fields => {
+ priority => $rp2->id,
+ }
+ });
+
+ $report->discard_changes;
+ is $report->response_priority, undef, 'response priority set';
+ };
+
+ subtest "check nearest address display" => sub {
+ $mech->get_ok("/report/$report_id");
+ $mech->content_lacks('Nearest calculated address', 'No address displayed');
+
+ my $data = {
+ resourceSets => [ {
+ resources => [ {
+ address => {
+ addressLine => 'Constitution Hill',
+ locality => 'London',
+ }
+ } ],
+ } ],
+ };
+ $report->geocode($data);
+ $report->update;
+ $mech->get_ok("/report/$report_id");
+ $mech->content_lacks('Nearest calculated address', 'No address displayed');
+
+ $data = {
+ resourceSets => [ {
+ resources => [ {
+ name => 'Constitution Hill, London, SW1A',
+ address => {
+ addressLine => 'Constitution Hill',
+ locality => 'London',
+ }
+ } ],
+ } ],
+ };
+ $report->geocode($data);
+ $report->update;
+ $mech->get_ok("/report/$report_id");
+ $mech->content_contains('Nearest calculated address', 'Address displayed');
+ $mech->content_contains('Constitution Hill, London, SW1A', 'Correct address displayed');
+ }
};
+foreach my $test (
+ { cobrand => 'fixmystreet', limited => 0, desc => 'detailed_information has no max length' },
+ { cobrand => 'oxfordshire', limited => 1, desc => 'detailed_information has max length' },
+) {
+
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => $test->{cobrand},
+ }, sub {
+ subtest $test->{desc} => sub {
+ $user->user_body_permissions->delete;
+ $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_inspect' });
+ $mech->get_ok("/report/$report_id");
+ $mech->submit_form_ok({
+ button => 'save',
+ with_fields => {
+ include_update => 0,
+ detailed_information => 'XXX164XXX' . 'x' x (164-9)
+ }
+ });
+
+ $report->discard_changes;
+ like $report->get_extra_metadata('detailed_information'), qr/XXX164XXX/, 'detailed information saved';
+ $mech->content_lacks('limited to 164 characters', "164 charcters of detailed information ok");
+ $mech->content_contains('XXX164XXX', "Detailed information field contains submitted text");
+
+ $mech->submit_form_ok({
+ button => 'save',
+ with_fields => {
+ include_update => 0,
+ detailed_information => 'XXX165XXX' . 'x' x (164-8)
+ }
+ });
+ if ($test->{limited}) {
+ $mech->content_contains('164 characters maximum');
+ $mech->content_contains('limited to 164 characters', "165 charcters of detailed information not ok");
+ $mech->content_contains('XXX165XXX', "Detailed information field contains submitted text");
+
+ $report->discard_changes;
+ like $report->get_extra_metadata('detailed_information'), qr/XXX164XXX/, 'detailed information not saved';
+ } else {
+ $mech->content_lacks(' characters maximum');
+ $mech->content_lacks('limited to 164 characters', "165 charcters of detailed information ok");
+ $mech->content_contains('XXX165XXX', "Detailed information field contains submitted text");
+
+ $report->discard_changes;
+ like $report->get_extra_metadata('detailed_information'), qr/XXX165XXX/, 'detailed information saved';
+ }
+ };
+ };
+}
+
FixMyStreet::override_config {
ALLOWED_COBRANDS => 'oxfordshire',
}, sub {
@@ -320,6 +542,61 @@ FixMyStreet::override_config {
};
FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ ALLOWED_COBRANDS => 'fixmystreet',
+}, sub {
+ subtest "test category not updated if fail to include public update" => sub {
+ $mech->get_ok("/report/$report_id");
+ $mech->submit_form(button => 'save', with_fields => { category => 'Badgers' });
+
+ $report->discard_changes;
+ is $report->category, "Cows", "Report in correct category";
+ $mech->content_contains('Badgers" selected', 'Changed category still selected');
+ };
+
+ subtest "test invalid form maintains Category and priority" => sub {
+ $mech->get_ok("/report/$report_id");
+ my $expected_fields = {
+ state => 'action scheduled',
+ category => 'Cows',
+ public_update => '',
+ priority => $rp->id,
+ include_update => '1',
+ detailed_information => 'XXX164XXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
+ defect_type => '',
+ traffic_information => ''
+ };
+ my $values = $mech->visible_form_values('report_inspect_form');
+ is_deeply $values, $expected_fields, 'correct form fields present';
+
+ $mech->submit_form(button => 'save', with_fields => { category => 'Badgers', priority => $rp2->id });
+
+ $expected_fields->{category} = 'Badgers';
+ $expected_fields->{priority} = $rp2->id;
+
+ my $new_values = $mech->visible_form_values('report_inspect_form');
+ is_deeply $new_values, $expected_fields, 'correct form fields present';
+ };
+
+ subtest "test changing category and leaving an update only creates one comment" => sub {
+ $report->comments->delete;
+ $mech->get_ok("/report/$report_id");
+ $mech->submit_form(
+ button => 'save',
+ with_fields => {
+ category => 'Badgers',
+ include_update => 1,
+ public_update => 'This is a public update',
+ });
+
+ $report->discard_changes;
+ is $report->category, "Badgers", "Report in correct category";
+ is $report->comments->count, 1, "Only leaves one update";
+ like $report->comments->first->text, qr/Category changed.*Badgers/, 'update text included category change';
+ };
+};
+
+FixMyStreet::override_config {
ALLOWED_COBRANDS => [ 'oxfordshire', 'fixmystreet' ],
BASE_URL => 'http://fixmystreet.site',
}, sub {
diff --git a/t/app/controller/report_new.t b/t/app/controller/report_new.t
index ab6b5d78e..e0fe205bd 100644
--- a/t/app/controller/report_new.t
+++ b/t/app/controller/report_new.t
@@ -101,6 +101,7 @@ foreach my $test (
photo3 => '',
name => '',
may_show_name => '1',
+ username => '',
email => '',
phone => '',
password_sign_in => '',
@@ -127,6 +128,7 @@ foreach my $test (
photo3 => '',
name => '',
may_show_name => '1',
+ username => '',
email => '',
phone => '',
category => 'Something bad',
@@ -156,6 +158,7 @@ foreach my $test (
photo3 => '',
name => '',
may_show_name => '1',
+ username => '',
email => '',
phone => '',
category => 'Street lighting',
@@ -182,6 +185,7 @@ foreach my $test (
photo3 => '',
name => '',
may_show_name => undef,
+ username => '',
email => '',
phone => '',
category => 'Street lighting',
@@ -208,6 +212,7 @@ foreach my $test (
photo3 => '',
name => 'Bob Jones',
may_show_name => undef,
+ username => '',
email => '',
phone => '',
category => 'Street lighting',
@@ -233,6 +238,7 @@ foreach my $test (
photo3 => '',
name => 'Bob Jones',
may_show_name => '1',
+ username => '',
email => '',
phone => '',
category => 'Street lighting',
@@ -258,6 +264,7 @@ foreach my $test (
photo3 => '',
name => 'Bob Jones',
may_show_name => '1',
+ username => '',
email => '',
phone => '',
category => 'Street lighting',
@@ -283,6 +290,7 @@ foreach my $test (
photo3 => '',
name => 'DUDE',
may_show_name => '1',
+ username => '',
email => '',
phone => '',
category => 'Street lighting',
@@ -307,6 +315,7 @@ foreach my $test (
photo3 => '',
name => 'anonymous',
may_show_name => '1',
+ username => '',
email => '',
phone => '',
category => 'Street lighting',
@@ -331,14 +340,15 @@ foreach my $test (
photo3 => '',
name => 'Joe Smith',
may_show_name => '1',
- email => 'not an email',
+ username => 'not an email',
+ email => '',
phone => '',
category => 'Street lighting',
password_sign_in => '',
password_register => '',
remember_me => undef,
},
- changes => { email => 'notanemail', },
+ changes => { username => 'notanemail', email => 'notanemail' },
errors => [ 'Please enter a valid email', ],
},
{
@@ -352,6 +362,7 @@ foreach my $test (
photo3 => '',
name => '',
may_show_name => '1',
+ username => '',
email => '',
phone => '',
category => 'Street lighting',
@@ -379,7 +390,8 @@ foreach my $test (
photo3 => '',
name => ' Bob Jones ',
may_show_name => '1',
- email => ' BOB @ExAmplE.COM ',
+ username => ' BOB @ExAmplE.COM ',
+ email => '',
phone => '',
category => 'Street lighting',
password_sign_in => '',
@@ -388,6 +400,7 @@ foreach my $test (
},
changes => {
name => 'Bob Jones',
+ username => 'bob@example.com',
email => 'bob@example.com',
},
errors => [ 'Please enter a subject', 'Please enter some details', ],
@@ -403,6 +416,7 @@ foreach my $test (
photo3 => '',
name => 'Bob Jones',
may_show_name => '1',
+ username => 'bob@example.com',
email => 'bob@example.com',
phone => '',
category => 'Street lighting',
@@ -426,6 +440,7 @@ foreach my $test (
photo3 => '',
name => 'Bob Jones',
may_show_name => '1',
+ username => 'bob@example.com',
email => 'bob@example.com',
phone => '',
category => 'Street lighting',
@@ -449,6 +464,7 @@ foreach my $test (
photo3 => '',
name => 'Bob Jones',
may_show_name => '1',
+ username => 'bob@example.com',
email => 'bob@example.com',
phone => '',
category => 'Street lighting',
@@ -560,7 +576,7 @@ foreach my $test (
photo1 => '',
name => 'Joe Bloggs',
may_show_name => '1',
- email => 'test-1@example.com',
+ username => 'test-1@example.com',
phone => '07903 123 456',
category => 'Street lighting',
password_register => $test->{password} ? 'secret' : '',
@@ -674,7 +690,7 @@ subtest "test password errors for a user who is signing in as they report" => su
title => 'Test Report',
detail => 'Test report details.',
photo1 => '',
- email => 'test-2@example.com',
+ username => 'test-2@example.com',
password_sign_in => 'secret1',
category => 'Street lighting',
}
@@ -685,7 +701,7 @@ subtest "test password errors for a user who is signing in as they report" => su
# check that we got the errors expected
is_deeply $mech->page_errors, [
- "There was a problem with your email/password combination. If you cannot remember your password, or do not have one, please fill in the \x{2018}sign in by email\x{2019} section of the form.",
+ "There was a problem with your login information. If you cannot remember your password, or do not have one, please fill in the \x{2018}No\x{2019} section of the form.",
], "check there were errors";
};
@@ -726,7 +742,7 @@ subtest "test report creation for a user who is signing in as they report" => su
title => 'Test Report',
detail => 'Test report details.',
photo1 => '',
- email => 'test-2@example.com',
+ username => 'test-2@example.com',
password_sign_in => 'secret2',
category => 'Street lighting',
}
@@ -877,7 +893,7 @@ foreach my $test (
# Test that AJAX pages return the right data
$mech->get_ok(
- '/ajax?bbox=' . ($report->longitude - 0.01) . ',' . ($report->latitude - 0.01)
+ '/around?ajax=1&bbox=' . ($report->longitude - 0.01) . ',' . ($report->latitude - 0.01)
. ',' . ($report->longitude + 0.01) . ',' . ($report->latitude + 0.01)
);
$mech->content_contains( "Test Report at caf\xc3\xa9" );
@@ -947,7 +963,7 @@ subtest "test report creation for a category that is non public" => sub {
title => 'Test Report',
detail => 'Test report details.',
photo1 => '',
- email => 'test-2@example.com',
+ username => 'test-2@example.com',
name => 'Joe Bloggs',
category => 'Street lighting',
}
@@ -1040,6 +1056,51 @@ subtest "check that a lat/lon off coast leads to /around" => sub {
};
+subtest "check we load a partial report correctly" => sub {
+ my $user = FixMyStreet::App->model('DB::User')->find_or_create(
+ {
+ email => 'test-partial@example.com'
+ }
+ );
+
+ my $report = FixMyStreet::App->model('DB::Problem')->create( {
+ name => '',
+ postcode => '',
+ category => 'Street lighting',
+ title => 'Testing',
+ detail => "Testing Detail",
+ anonymous => 0,
+ state => 'partial',
+ lang => 'en-gb',
+ service => '',
+ areas => '',
+ used_map => 1,
+ latitude => '51.754926',
+ longitude => '-1.256179',
+ user_id => $user->id,
+ } );
+
+ my $report_id = $report->id;
+
+ my $token = FixMyStreet::App->model("DB::Token")
+ ->create( { scope => 'partial', data => $report->id } );
+
+ my $token_code = $token->token;
+
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ },
+ sub {
+ $mech->get("/L/$token_code");
+ is $mech->res->previous->code, 302, 'partial token page redirects';
+ is $mech->uri->path, "/report/new", "partial redirects to report page";
+ $mech->content_contains('Testing Detail');
+ };
+
+ $mech->delete_user($user);
+};
+
for my $test (
{
desc => 'user title not set if not bromley problem',
@@ -1135,7 +1196,7 @@ for my $test (
title => "Test Report",
detail => 'Test report details.',
photo1 => '',
- email => 'firstlast@example.com',
+ username => 'firstlast@example.com',
may_show_name => '1',
phone => '07903 123 456',
category => 'Trees',
@@ -1167,9 +1228,7 @@ for my $test (
# confirm token in order to update the user details
$mech->get_ok($url);
- my $user =
- FixMyStreet::App->model('DB::User')
- ->find( { email => 'firstlast@example.com' } );
+ my $user = FixMyStreet::App->model('DB::User')->find( { email => 'firstlast@example.com' } );
my $report = $user->problems->first;
ok $report, "Found the report";
@@ -1284,7 +1343,7 @@ subtest "test Hart" => sub {
$mech->submit_form_ok( { with_fields => { pc => 'GU51 4AE' } }, "submit location" );
$mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" );
my %optional_fields = $test->{confirm} ? () :
- ( email => $test_email, phone => '07903 123 456' );
+ ( username => $test_email, phone => '07903 123 456' );
# we do this as otherwise test::www::mechanize::catalyst
# goes to the value set in ->host above irregardless and
@@ -1424,7 +1483,7 @@ subtest "unresponsive body handling works" => sub {
detail => 'Test report details.',
photo1 => '',
name => 'Joe Bloggs',
- email => $test_email,
+ username => $test_email,
may_show_name => '1',
phone => '07903 123 456',
category => 'Trees',
@@ -1497,7 +1556,7 @@ subtest "unresponsive body handling works" => sub {
detail => 'Test report details.',
photo1 => '',
name => 'Joe Bloggs',
- email => $test_email,
+ username => $test_email,
may_show_name => '1',
phone => '07903 123 456',
category => 'Trees',
@@ -1618,7 +1677,7 @@ subtest "extra google analytics code displayed on email confirmation problem cre
title => "Test Report",
detail => 'Test report details.',
photo1 => '',
- email => 'firstlast@example.com',
+ username => 'firstlast@example.com',
name => 'Test User',
may_show_name => '1',
phone => '07903 123 456',
@@ -1639,9 +1698,7 @@ subtest "extra google analytics code displayed on email confirmation problem cre
$mech->get_ok($url);
# find the report
- my $user =
- FixMyStreet::App->model('DB::User')
- ->find( { email => 'firstlast@example.com' } );
+ my $user = FixMyStreet::App->model('DB::User')->find( { email => 'firstlast@example.com' } );
my $report = $user->problems->first;
ok $report, "Found the report";
diff --git a/t/app/controller/report_new_open311.t b/t/app/controller/report_new_open311.t
index 9a4a81182..0224e7e47 100644
--- a/t/app/controller/report_new_open311.t
+++ b/t/app/controller/report_new_open311.t
@@ -54,6 +54,7 @@ foreach my $test (
photo3 => '',
name => '',
may_show_name => '1',
+ username => '',
email => '',
phone => '',
category => 'Street lighting',
@@ -76,7 +77,7 @@ foreach my $test (
title => 'test',
detail => 'test detail',
name => 'Test User',
- email => 'testopen311@example.com',
+ username => 'testopen311@example.com',
category => 'Street lighting',
number => 27,
},
@@ -100,7 +101,7 @@ foreach my $test (
$mech->clear_emails_ok;
# check that the user does not exist
- my $test_email = $test->{submit_with}->{email};
+ my $test_email = $test->{submit_with}->{username};
my $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
if ( $user ) {
$user->problems->delete;
diff --git a/t/app/controller/report_new_text.t b/t/app/controller/report_new_text.t
new file mode 100644
index 000000000..734b9dbb4
--- /dev/null
+++ b/t/app/controller/report_new_text.t
@@ -0,0 +1,371 @@
+use FixMyStreet::TestMech;
+use t::Mock::Twilio;
+
+my $twilio = t::Mock::Twilio->new;
+LWP::Protocol::PSGI->register($twilio->to_psgi_app, host => 'api.twilio.com');
+
+# disable info logs for this test run
+FixMyStreet::App->log->disable('info');
+END { FixMyStreet::App->log->enable('info'); }
+
+my $mech = FixMyStreet::TestMech->new;
+
+my $body = $mech->create_body_ok(2651, 'City of Edinburgh Council');
+$mech->create_contact_ok( body_id => $body->id, category => 'Street lighting', email => 'highways@example.com' );
+$mech->create_contact_ok( body_id => $body->id, category => 'Trees', email => 'trees@example.com' );
+
+# test that phone number validation works okay
+foreach my $test (
+ {
+ msg => 'invalid number',
+ pc => 'EH1 1BB',
+ fields => {
+ username => '0121 4960000000', email => '', phone => '',
+ title => 'Title', detail => 'Detail', name => 'Bob Jones',
+ category => 'Street lighting',
+ may_show_name => '1', remember_me => undef,
+ photo1 => '', photo2 => '', photo3 => '',
+ password_register => '', password_sign_in => '',
+ },
+ changes => {
+ username => '01214960000000',
+ phone => '01214960000000',
+ },
+ errors => [ 'Please check your phone number is correct' ],
+ },
+ {
+ msg => 'landline number',
+ pc => 'EH1 1BB',
+ fields => {
+ username => '0121 4960000', email => '', phone => '',
+ title => 'Title', detail => 'Detail', name => 'Bob Jones',
+ category => 'Street lighting',
+ may_show_name => '1', remember_me => undef,
+ photo1 => '', photo2 => '', photo3 => '',
+ password_register => '', password_sign_in => '',
+ },
+ changes => {
+ username => '+44 121 496 0000',
+ phone => '+44 121 496 0000',
+ },
+ errors => [ 'Please enter a mobile number', ],
+ },
+ )
+{
+ subtest "check form errors where $test->{msg}" => sub {
+ $mech->get_ok('/around');
+
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ SMS_AUTHENTICATION => 1,
+ PHONE_COUNTRY => 'GB',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => $test->{pc} } },
+ "submit location" );
+ is_deeply $mech->page_errors, [], "no errors for pc '$test->{pc}'";
+
+ # click through to the report page
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, },
+ "follow 'skip this step' link" );
+
+ # submit the main form
+ $mech->submit_form_ok( { with_fields => $test->{fields} }, "submit form" );
+ };
+
+ # check that we got the errors expected
+ is_deeply [ sort @{$mech->page_errors} ], [ sort @{$test->{errors}} ], "check errors";
+
+ # check that fields have changed as expected
+ my $new_values = {
+ %{ $test->{fields} }, # values added to form
+ %{ $test->{changes} }, # changes we expect
+ };
+ is_deeply $mech->visible_form_values, $new_values,
+ "values correctly changed";
+ };
+}
+
+my $test_phone = '+61491570156';
+my $first_user;
+foreach my $test (
+ {
+ desc => 'does not have an account, does not set a password',
+ user => 0, password => 0,
+ },
+ {
+ desc => 'does not have an account, sets a password',
+ user => 0, password => 1,
+ },
+ {
+ desc => 'does have an account and is not signed in; does not sign in, does not set a password',
+ user => 1, password => 0,
+ },
+ {
+ desc => 'does have an account and is not signed in; does not sign in, sets a password',
+ user => 1, password => 1,
+ },
+) {
+ subtest "test report creation for a user who " . $test->{desc} => sub {
+ $mech->log_out_ok;
+
+ if ($test->{user}) {
+ my $user = FixMyStreet::App->model('DB::User')->find( { phone => $test_phone } );
+ ok $user, "test user does exist";
+ $user->problems->delete;
+ $user->name( 'Old Name' );
+ $user->password( 'old_password' );
+ $user->update;
+ } elsif (!$first_user) {
+ ok !FixMyStreet::App->model('DB::User')->find( { phone => $test_phone } ),
+ "test user does not exist";
+ $first_user = 1;
+ } else {
+ # Not first pass, so will exist, but want no user to start, so delete it.
+ $mech->delete_user($test_phone);
+ }
+
+ $mech->get_ok('/around');
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ SMS_AUTHENTICATION => 1,
+ PHONE_COUNTRY => 'GB',
+ TWILIO_ACCOUNT_SID => 'AC123',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB', } }, "submit location" );
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" );
+ $mech->submit_form_ok(
+ {
+ button => 'submit_register',
+ with_fields => {
+ title => 'Test Report', detail => 'Test report details.',
+ photo1 => '',
+ name => 'Joe Bloggs', may_show_name => '1',
+ username => $test_phone,
+ category => 'Street lighting',
+ password_register => $test->{password} ? 'secret' : '',
+ }
+ },
+ "submit good details"
+ );
+ };
+
+ is_deeply $mech->page_errors, [], "check there were no errors";
+
+ my $user = FixMyStreet::App->model('DB::User')->find( { phone => $test_phone } );
+ ok $user, "user found";
+ if ($test->{user}) {
+ is $user->name, 'Old Name', 'name unchanged';
+ ok $user->check_password('old_password'), 'password unchanged';
+ } else {
+ is $user->name, undef, 'name not yet set';
+ is $user->password, '', 'password not yet set for new user';
+ }
+
+ my $report = $user->problems->first;
+ ok $report, "Found the report";
+ is $report->state, 'unconfirmed', "report not confirmed";
+ is $report->bodies_str, $body->id;
+
+ $mech->submit_form_ok({ with_fields => { code => '00000' } });
+ $mech->content_contains('Try again');
+
+ my $code = $twilio->get_text_code;
+ $mech->submit_form_ok({ with_fields => { code => $code } });
+
+ $report->discard_changes;
+ is $report->state, 'confirmed', "Report is now confirmed";
+
+ $mech->get_ok( '/report/' . $report->id );
+
+ is $report->name, 'Joe Bloggs', 'name updated correctly';
+ if ($test->{password}) {
+ ok $report->user->check_password('secret'), 'password updated correctly';
+ } elsif ($test->{user}) {
+ ok $report->user->check_password('old_password'), 'password unchanged, as no new one given';
+ } else {
+ is $report->user->password, '', 'password still not set, as none given';
+ }
+
+ # check that the reporter has an alert
+ my $alert = FixMyStreet::App->model('DB::Alert')->find( {
+ user => $report->user,
+ alert_type => 'new_updates',
+ parameter => $report->id,
+ } );
+ ok $alert, "created new alert";
+
+ # user is created and logged in
+ $mech->logged_in_ok;
+
+ # cleanup
+ $mech->delete_user($user)
+ if $test->{user} && $test->{password};
+ };
+}
+
+# this test to make sure that we don't see spurious error messages about
+# the name being blank when there is a sign in error
+subtest "test password errors for a user who is signing in as they report" => sub {
+ $mech->log_out_ok;
+
+ my $user = $mech->create_user_ok($test_phone);
+ ok $user->update( {
+ name => 'Joe Bloggs',
+ email => 'joe@example.net',
+ password => 'secret2',
+ } ), "set user details";
+
+ $mech->get_ok('/around');
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ SMS_AUTHENTICATION => 1,
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB', } }, "submit location" );
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" );
+ $mech->submit_form_ok(
+ {
+ button => 'submit_sign_in',
+ with_fields => {
+ title => 'Test Report',
+ detail => 'Test report details.',
+ photo1 => '',
+ username => $test_phone,
+ password_sign_in => 'secret1',
+ category => 'Street lighting',
+ }
+ },
+ "submit with wrong password"
+ );
+ };
+
+ # check that we got the errors expected
+ is_deeply $mech->page_errors, [
+ "There was a problem with your login information. If you cannot remember your password, or do not have one, please fill in the \x{2018}No\x{2019} section of the form.",
+ ], "check there were errors";
+};
+
+subtest "test report creation for a user who is signing in as they report" => sub {
+ $mech->log_out_ok;
+ $mech->cookie_jar({});
+
+ my $user = $mech->create_user_ok($test_phone);
+
+ $mech->get_ok('/around');
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ SMS_AUTHENTICATION => 1,
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB', } }, "submit location" );
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" );
+ $mech->submit_form_ok(
+ {
+ button => 'submit_sign_in',
+ with_fields => {
+ title => 'Test Report',
+ detail => 'Test report details.',
+ photo1 => '',
+ username => $test_phone,
+ password_sign_in => 'secret2',
+ category => 'Street lighting',
+ }
+ },
+ "submit good details"
+ );
+
+ # check that we got the message expected
+ $mech->content_contains( 'You have successfully signed in; please check and confirm your details are accurate:' );
+
+ # Now submit with a name
+ $mech->submit_form_ok(
+ {
+ with_fields => {
+ name => 'Joe Bloggs',
+ }
+ },
+ "submit good details"
+ );
+ };
+
+ my $report = $user->problems->first;
+ ok $report, "Found the report";
+ $mech->content_contains('Thank you for reporting this issue');
+ is $report->bodies_str, $body->id;
+ is $report->state, 'confirmed', "report is now confirmed";
+ $mech->get_ok( '/report/' . $report->id );
+ my $alert = FixMyStreet::App->model('DB::Alert')->find( {
+ user => $report->user,
+ alert_type => 'new_updates',
+ parameter => $report->id,
+ } );
+ ok $alert, "created new alert";
+
+ $mech->logged_in_ok;
+};
+
+subtest "test report creation for a user who is logged in" => sub {
+ my $user = $mech->create_user_ok($test_phone);
+ $mech->get_ok('/around');
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB', } }, "submit location" );
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" );
+ is_deeply(
+ $mech->visible_form_values,
+ {
+ title => '',
+ detail => '',
+ may_show_name => '1',
+ name => 'Joe Bloggs',
+ email => 'joe@example.net',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ category => '-- Pick a category --',
+ },
+ "user's details prefilled"
+ );
+
+ $mech->submit_form_ok(
+ {
+ with_fields => {
+ title => "Test Report at café",
+ detail => 'Test report details.',
+ photo1 => '',
+ name => 'Joe Bloggs',
+ may_show_name => '1',
+ category => 'Street lighting',
+ }
+ },
+ "submit good details"
+ );
+ };
+
+ my $report = $user->problems->first;
+ ok $report, "Found the report";
+ is $report->bodies_str, $body->id;
+ $mech->content_contains('Thank you for reporting this issue');
+ is $report->state, 'confirmed', "report is now confirmed";
+ $mech->get_ok( '/report/' . $report->id );
+ my $alert = FixMyStreet::App->model('DB::Alert')->find( {
+ user => $report->user,
+ alert_type => 'new_updates',
+ parameter => $report->id,
+ } );
+ ok $alert, "created new alert";
+
+ $mech->logged_in_ok;
+
+ $mech->get_ok(
+ '/around?ajax=1&bbox=' . ($report->longitude - 0.01) . ',' . ($report->latitude - 0.01)
+ . ',' . ($report->longitude + 0.01) . ',' . ($report->latitude + 0.01)
+ );
+ $mech->content_contains( "Test Report at caf\xc3\xa9" );
+};
+
+done_testing();
diff --git a/t/app/controller/report_update_text.t b/t/app/controller/report_update_text.t
new file mode 100644
index 000000000..45b4e78c2
--- /dev/null
+++ b/t/app/controller/report_update_text.t
@@ -0,0 +1,307 @@
+use FixMyStreet::TestMech;
+use t::Mock::Twilio;
+
+my $twilio = t::Mock::Twilio->new;
+LWP::Protocol::PSGI->register($twilio->to_psgi_app, host => 'api.twilio.com');
+
+my $mech = FixMyStreet::TestMech->new;
+my $user = $mech->create_user_ok('test@example.com', name => 'Test User');
+my $user2 = $mech->create_user_ok('commenter@example.com', name => 'Commenter');
+my $body = $mech->create_body_ok(2504, 'Westminster City Council');
+
+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 => $body->id,
+ areas => ',105255,11806,11828,2247,2504,',
+ category => 'Other',
+ title => 'Test 2',
+ detail => 'Test 2 Detail',
+ used_map => 't',
+ name => 'Test User',
+ anonymous => 'f',
+ state => 'confirmed',
+ confirmed => $dt->ymd . ' ' . $dt->hms,
+ lang => 'en-gb',
+ service => '',
+ cobrand => 'default',
+ cobrand_data => '',
+ send_questionnaire => 't',
+ latitude => '51.5016605453401',
+ longitude => '-0.142497580865087',
+ user_id => $user->id,
+ }
+);
+my $report_id = $report->id;
+ok $report, "created test report - $report_id";
+
+my $comment = FixMyStreet::App->model('DB::Comment')->find_or_create( {
+ problem_id => $report_id,
+ user_id => $user2->id,
+ name => 'Other User',
+ mark_fixed => 'false',
+ text => 'This is some update text',
+ state => 'confirmed',
+ confirmed => $dt->ymd . ' ' . $dt->hms,
+ anonymous => 'f',
+});
+
+my $comment_id = $comment->id;
+ok $comment, "created test update - $comment_id";
+
+for my $test (
+ {
+ desc => 'Invalid phone',
+ fields => {
+ username => '01214960000000',
+ update => 'Update',
+ name => 'Name',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ fixed => undef,
+ add_alert => 1,
+ may_show_name => undef,
+ remember_me => undef,
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => {},
+ field_errors => [ 'Please check your phone number is correct' ]
+ },
+ {
+ desc => 'landline number',
+ fields => {
+ username => '01214960000',
+ update => 'Update',
+ name => 'Name',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ fixed => undef,
+ add_alert => 1,
+ may_show_name => undef,
+ remember_me => undef,
+ password_register => '',
+ password_sign_in => '',
+ },
+ changes => {
+ username => '+44 121 496 0000',
+ },
+ field_errors => [ 'Please enter a mobile number' ]
+ },
+ )
+{
+ subtest "submit an update - $test->{desc}" => sub {
+ $mech->get_ok("/report/$report_id");
+
+ FixMyStreet::override_config {
+ SMS_AUTHENTICATION => 1,
+ PHONE_COUNTRY => 'GB',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => $test->{fields} }, 'submit update' );
+ };
+
+ is_deeply $mech->page_errors, $test->{field_errors}, 'field errors';
+
+ my $values = {
+ %{ $test->{fields} },
+ %{ $test->{changes} },
+ };
+
+ is_deeply $mech->visible_form_values('updateForm'), $values, 'form changes';
+ };
+}
+
+my $test_phone = '+61491570156';
+for my $test (
+ {
+ desc => 'submit an update, unregistered, logged out',
+ form_values => {
+ submit_update => 1,
+ username => $test_phone,
+ update => 'Update from an unregistered user',
+ add_alert => undef,
+ name => 'Unreg User',
+ may_show_name => undef,
+ },
+ },
+ {
+ desc => 'submit an update, unregistered, logged out, sign up for alerts',
+ form_values => {
+ submit_update => 1,
+ username => $test_phone,
+ update => 'Update from an unregistered user',
+ add_alert => 1,
+ name => 'Unreg User',
+ may_show_name => undef,
+ },
+ },
+ {
+ desc => 'submit an update, registered, logged out, confirming by text',
+ registered => 1,
+ form_values => {
+ submit_update => 1,
+ username => $test_phone,
+ update => 'Update from a registered user',
+ add_alert => undef,
+ name => 'Reg User',
+ password_register => 'new_secret',
+ },
+ },
+) {
+ subtest $test->{desc} => sub {
+ $mech->log_out_ok();
+ my $user;
+ if ($test->{registered}) {
+ $user = $mech->create_user_ok( $test_phone );
+ $user->update( { name => 'Mr Reg', password => 'secret2' } );
+ }
+
+ $mech->get_ok("/report/$report_id");
+ FixMyStreet::override_config {
+ SMS_AUTHENTICATION => 1,
+ TWILIO_ACCOUNT_SID => 'AC123',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => $test->{form_values} }, 'submit update');
+ };
+ $mech->content_contains('Nearly done! Now check your phone');
+
+ if ($user) {
+ $user->discard_changes;
+ ok $user->check_password( 'secret2' ), 'password unchanged';
+ is $user->name, 'Mr Reg', 'name unchanged';
+ }
+
+ my ($token) = $mech->content =~ /name="token" value="([^"]*)"/;
+ $token = FixMyStreet::App->model('DB::Token')->find({
+ token => $token,
+ scope => 'comment'
+ });
+ ok $token, 'Token found in database';
+
+ my $update_id = $token->data->{id};
+ my $add_alerts = $token->data->{add_alert};
+ my $update = FixMyStreet::App->model('DB::Comment')->find( { id => $update_id } );
+
+ ok $update, 'found update in database';
+ is $update->state, 'unconfirmed', 'update unconfirmed';
+ my $details = $test->{form_values};
+ is $update->user->phone, $details->{username}, 'update phone';
+ is $update->user->phone_verified, 1;
+ is $update->text, $details->{update}, 'update text';
+ is $add_alerts, $details->{add_alert} ? 1 : 0, 'do not sign up for alerts';
+
+ my $code = $twilio->get_text_code;
+ $mech->submit_form_ok( { with_fields => { code => '00000' } });
+ $mech->content_contains('Try again');
+ $mech->submit_form_ok( { with_fields => { code => $code } });
+
+ $mech->content_contains("/report/$report_id#update_$update_id");
+
+ if ($user) {
+ $user->discard_changes;
+ ok $user->check_password( 'new_secret' ), 'password changed';
+ is $user->name, 'Reg User', 'name changed';
+ } else {
+ $user = FixMyStreet::App->model( 'DB::User' )->find( { phone => $details->{username} } );
+ ok $user, 'found user';
+ }
+
+ my $alert = FixMyStreet::App->model( 'DB::Alert' )->find(
+ { user => $user, alert_type => 'new_updates', confirmed => 1, }
+ );
+
+ ok $details->{add_alert} ? defined( $alert ) : !defined( $alert ), 'sign up for alerts';
+
+ $update->discard_changes;
+ is $update->state, 'confirmed', 'update confirmed';
+ $mech->delete_user( $user );
+ };
+}
+
+for my $test (
+ {
+ desc => 'submit an update for a registered user, signing in with wrong password',
+ form_values => {
+ submit_update => 1,
+ username => $test_phone,
+ update => 'Update from a user',
+ add_alert => undef,
+ password_sign_in => 'secret',
+ },
+ field_errors => [
+ "There was a problem with your login information. If you cannot remember your password, or do not have one, please fill in the \x{2018}No\x{2019} section of the form.",
+ 'Please enter your name', # FIXME Not really necessary error
+ ],
+ },
+ {
+ desc => 'submit an update for a registered user and sign in',
+ form_values => {
+ submit_update => 1,
+ username => $test_phone,
+ update => 'Update from a user',
+ add_alert => undef,
+ password_sign_in => 'secret2',
+ },
+ message => 'You have successfully signed in; please check and confirm your details are accurate:',
+ }
+) {
+ subtest $test->{desc} => sub {
+ # Set things up
+ my $user = $mech->create_user_ok( $test->{form_values}->{username} );
+ my $pw = 'secret2';
+ $user->update( { name => 'Mr Reg', password => $pw } );
+ $report->comments->delete;
+
+ $mech->log_out_ok();
+ $mech->clear_emails_ok();
+ $mech->get_ok("/report/$report_id");
+ FixMyStreet::override_config {
+ SMS_AUTHENTICATION => 1,
+ }, sub {
+ $mech->submit_form_ok(
+ {
+ button => 'submit_sign_in',
+ with_fields => $test->{form_values}
+ },
+ 'submit update'
+ );
+ };
+
+ $mech->content_contains($test->{message}) if $test->{message};
+
+ is_deeply $mech->page_errors, $test->{field_errors}, 'check there were errors'
+ if $test->{field_errors};
+
+ SKIP: {
+ skip( "Incorrect password", 4 ) unless $test->{form_values}{password_sign_in} eq $pw;
+
+ # Now submit with a name
+ $mech->submit_form_ok(
+ { with_fields => { name => 'Joe Bloggs', } },
+ "submit good details"
+ );
+
+ $mech->content_contains('Thank you for updating this issue');
+
+ my $update = $report->comments->first;
+ ok $update, 'found update';
+ is $update->text, $test->{form_values}->{update}, 'update text';
+ is $update->user->phone, $test->{form_values}->{username}, 'update user';
+ is $update->state, 'confirmed', 'update confirmed';
+ $mech->delete_user( $update->user );
+ }
+ };
+}
+
+done_testing();
diff --git a/t/app/controller/report_updates.t b/t/app/controller/report_updates.t
index 0526b2fd7..aefe77e47 100644
--- a/t/app/controller/report_updates.t
+++ b/t/app/controller/report_updates.t
@@ -196,7 +196,7 @@ for my $test (
{
desc => 'No email, no message',
fields => {
- rznvy => '',
+ username => '',
update => '',
name => '',
photo1 => '',
@@ -215,7 +215,7 @@ for my $test (
{
desc => 'Invalid email, no message',
fields => {
- rznvy => 'test',
+ username => 'test',
update => '',
name => '',
photo1 => '',
@@ -234,7 +234,7 @@ for my $test (
{
desc => 'email with spaces, no message',
fields => {
- rznvy => 'test @ example. com',
+ username => 'test @ example. com',
update => '',
name => '',
photo1 => '',
@@ -248,14 +248,14 @@ for my $test (
password_sign_in => '',
},
changes => {
- rznvy => 'test@example.com',
+ username => 'test@example.com',
},
field_errors => [ 'Please enter a message', 'Please enter your name' ]
},
{
desc => 'email with uppercase, no message',
fields => {
- rznvy => 'test@EXAMPLE.COM',
+ username => 'test@EXAMPLE.COM',
update => '',
name => '',
photo1 => '',
@@ -269,7 +269,7 @@ for my $test (
password_sign_in => '',
},
changes => {
- rznvy => 'test@example.com',
+ username => 'test@example.com',
},
field_errors => [ 'Please enter a message', 'Please enter your name' ]
},
@@ -297,7 +297,7 @@ for my $test (
desc => 'submit an update for a non registered user',
initial_values => {
name => '',
- rznvy => '',
+ username => '',
may_show_name => 1,
add_alert => 1,
photo1 => '',
@@ -311,7 +311,7 @@ for my $test (
},
form_values => {
submit_update => 1,
- rznvy => 'unregistered@example.com',
+ username => 'unregistered@example.com',
update => 'Update from an unregistered user',
add_alert => undef,
name => 'Unreg User',
@@ -323,7 +323,7 @@ for my $test (
desc => 'submit an update for a non registered user and sign up',
initial_values => {
name => '',
- rznvy => '',
+ username => '',
may_show_name => 1,
add_alert => 1,
photo1 => '',
@@ -337,7 +337,7 @@ for my $test (
},
form_values => {
submit_update => 1,
- rznvy => 'unregistered@example.com',
+ username => 'unregistered@example.com',
update => "update from an\r\n\r\nunregistered user",
add_alert => 1,
name => 'Unreg User',
@@ -395,14 +395,14 @@ for my $test (
ok $update, 'found update in database';
is $update->state, 'unconfirmed', 'update unconfirmed';
- is $update->user->email, $details->{rznvy}, 'update email';
+ is $update->user->email, $details->{username}, 'update email';
is $update->text, $details->{update}, 'update text';
is $add_alerts, $details->{add_alert} ? 1 : 0, 'do not sign up for alerts';
$mech->get_ok( $url );
$mech->content_contains("/report/$report_id#update_$update_id");
- my $unreg_user = FixMyStreet::App->model( 'DB::User' )->find( { email => $details->{rznvy} } );
+ my $unreg_user = FixMyStreet::App->model( 'DB::User' )->find( { email => $details->{username} } );
ok $unreg_user, 'found user';
@@ -427,7 +427,7 @@ for my $test (
desc => 'overriding email confirmation allows report confirmation with no email sent',
initial_values => {
name => '',
- rznvy => '',
+ username => '',
may_show_name => 1,
add_alert => 1,
photo1 => '',
@@ -441,7 +441,7 @@ for my $test (
},
form_values => {
submit_update => 1,
- rznvy => 'unregistered@example.com',
+ username => 'unregistered@example.com',
update => "update no email confirm",
add_alert => 1,
name => 'Unreg User',
@@ -493,10 +493,10 @@ for my $test (
ok $update, 'found update in database';
is $update->state, 'confirmed', 'update confirmed';
- is $update->user->email, $details->{rznvy}, 'update email';
+ is $update->user->email, $details->{username}, 'update email';
is $update->text, $details->{update}, 'update text';
- my $unreg_user = FixMyStreet::App->model( 'DB::User' )->find( { email => $details->{rznvy} } );
+ my $unreg_user = FixMyStreet::App->model( 'DB::User' )->find( { email => $details->{username} } );
ok $unreg_user, 'found user';
@@ -918,16 +918,96 @@ subtest 'check meta correct for second comment marking as reopened' => sub {
like $update_meta->[2], qr/Open/, 'update meta says reopened';
};
-subtest "check first comment with status change but no text is displayed" => sub {
- $user->from_body( $body->id );
- $user->update;
+subtest 'check meta correct for comment after mark_fixed with not problem_state' => sub {
+ $report->comments->delete;
+ my $comment = FixMyStreet::App->model('DB::Comment')->create(
+ {
+ user => $user,
+ problem_id => $report->id,
+ text => 'update text',
+ confirmed => DateTime->now( time_zone => 'local'),
+ problem_state => '',
+ anonymous => 0,
+ mark_open => 0,
+ mark_fixed => 1,
+ state => 'confirmed',
+ }
+ );
+
+ $mech->get_ok( "/report/" . $report->id );
+ my $update_meta = $mech->extract_update_metas;
+ like $update_meta->[0], qr/fixed/i, 'update meta says fixed';
+
+ $comment = FixMyStreet::App->model('DB::Comment')->create(
+ {
+ user => $user,
+ problem_id => $report->id,
+ text => 'update text',
+ confirmed => DateTime->now( time_zone => 'local' ) + DateTime::Duration->new( minutes => 1 ),
+ problem_state => 'fixed - user',
+ anonymous => 0,
+ mark_open => 0,
+ mark_fixed => 0,
+ state => 'confirmed',
+ }
+ );
+
+ $mech->get_ok( "/report/" . $report->id );
+ $update_meta = $mech->extract_update_metas;
+ unlike $update_meta->[2], qr/Fixed/i, 'update meta does not say fixed';
+};
+
+for my $test(
+ {
+ user => $user2,
+ name => $body->name,
+ body => $body,
+ superuser => 0,
+ desc =>"check first comment from body user with status change but no text is displayed"
+ },
+ {
+ user => $user2,
+ name => $body->name,
+ superuser => 0,
+ bodyuser => 1,
+ desc =>"check first comment from ex body user with status change but no text is displayed"
+ },
+ {
+ user => $user2,
+ name => $body->name,
+ body => $body,
+ superuser => 1,
+ desc =>"check first comment from body super user with status change but no text is displayed"
+ },
+ {
+ user => $user2,
+ name => 'an administrator',
+ superuser => 1,
+ desc =>"check first comment from super user with status change but no text is displayed"
+ }
+) {
+subtest $test->{desc} => sub {
+ my $extra = {};
+ if ($test->{body}) {
+ $extra->{is_body_user} = $test->{body}->id;
+ $user2->from_body( $test->{body}->id );
+ } else {
+ if ($test->{superuser}) {
+ $extra->{is_superuser} = 1;
+ } elsif ($test->{bodyuser}) {
+ $extra->{is_body_user} = $body->id;
+ }
+ $user2->from_body(undef);
+ }
+ $user2->is_superuser($test->{superuser});
+ $user2->update;
$report->comments->delete;
my $comment = FixMyStreet::App->model('DB::Comment')->create(
{
- user => $user,
- name => $user->from_body->name,
+ user => $test->{user},
+ name => $test->{name},
problem_id => $report->id,
text => '',
confirmed => DateTime->now( time_zone => 'local'),
@@ -936,17 +1016,30 @@ subtest "check first comment with status change but no text is displayed" => sub
mark_open => 0,
mark_fixed => 0,
state => 'confirmed',
+ extra => $extra,
}
);
$mech->log_in_ok( $user->email );
+
+ ok $user->user_body_permissions->search({
+ body_id => $body->id,
+ permission_type => 'view_body_contribute_details'
+ })->delete, 'Remove user view_body_contribute_details permissions';
+
$mech->get_ok("/report/$report_id");
my $update_meta = $mech->extract_update_metas;
like $update_meta->[1], qr/Updated by/, 'updated by meta if no text';
- unlike $update_meta->[1], qr/Test User/, 'commenter name not included';
+ unlike $update_meta->[1], qr/Commenter/, 'commenter name not included';
like $update_meta->[0], qr/investigating/i, 'update meta includes state change';
+ if ($test->{body} || $test->{bodyuser}) {
+ like $update_meta->[1], qr/Westminster/, 'body user update uses body name';
+ } elsif ($test->{superuser}) {
+ like $update_meta->[1], qr/an administrator/, 'superuser update says an administrator';
+ }
+
ok $user->user_body_permissions->create({
body => $body,
permission_type => 'view_body_contribute_details'
@@ -955,10 +1048,108 @@ subtest "check first comment with status change but no text is displayed" => sub
$mech->get_ok("/report/$report_id");
$update_meta = $mech->extract_update_metas;
like $update_meta->[1], qr/Updated by/, 'updated by meta if no text';
- like $update_meta->[1], qr/Test User/, 'commenter name included if user has view contribute permission';
+ like $update_meta->[1], qr/Commenter/, 'commenter name included if user has view contribute permission';
like $update_meta->[0], qr/investigating/i, 'update meta includes state change';
};
+}
+
+for my $test(
+ {
+ desc =>"check comment from super user hiding report is not displayed",
+ problem_state => 'hidden',
+ },
+ {
+ desc =>"check comment from super user unconfirming report is not displayed",
+ problem_state => 'unconfirmed',
+ }
+) {
+subtest $test->{desc} => sub {
+ my $extra = { is_superuser => 1 };
+ $user2->is_superuser(1);
+ $user2->update;
+
+ $report->comments->delete;
+
+ my $comment = FixMyStreet::App->model('DB::Comment')->create(
+ {
+ user => $user2,
+ name => 'an administrator',
+ problem_id => $report->id,
+ text => '',
+ confirmed => DateTime->now( time_zone => 'local'),
+ problem_state => $test->{problem_state},
+ anonymous => 0,
+ mark_open => 0,
+ mark_fixed => 0,
+ state => 'confirmed',
+ extra => $extra,
+ }
+ );
+ $mech->log_in_ok( $user->email );
+ $mech->get_ok("/report/$report_id");
+
+ my $update_meta = $mech->extract_update_metas;
+ is scalar(@$update_meta), 0, 'no comments on report';
+ };
+}
+
+for my $test(
+ {
+ desc =>"check comments from super user hiding and unhiding report are not displayed",
+ problem_states => [qw/hidden confirmed/],
+ comment_count => 0,
+ },
+ {
+ desc =>"check comment from super user unconfirming and confirming report are is not displayed",
+ problem_states => [qw/unconfirmed confirmed/],
+ comment_count => 0,
+ },
+ {
+ desc =>"check comment after unconfirming and confirming a report is displayed",
+ problem_states => [qw/unconfirmed confirmed investigating/],
+ comment_count => 2, # state change line + who updated line
+ },
+ {
+ desc =>"check comment after confirming a report after blank state is not displayed",
+ problem_states => ['unconfirmed', '', 'confirmed'],
+ comment_count => 0, # state change line + who updated line
+ },
+) {
+subtest $test->{desc} => sub {
+ my $extra = { is_superuser => 1 };
+ $user2->is_superuser(1);
+ $user2->update;
+
+ $report->comments->delete;
+
+ for my $state (@{$test->{problem_states}}) {
+ my $comment = FixMyStreet::App->model('DB::Comment')->create(
+ {
+ user => $user2,
+ name => 'an administrator',
+ problem_id => $report->id,
+ text => '',
+ confirmed => DateTime->now( time_zone => 'local'),
+ problem_state => $state,
+ anonymous => 0,
+ mark_open => 0,
+ mark_fixed => 0,
+ state => 'confirmed',
+ extra => $extra,
+ }
+ );
+ }
+ $mech->log_in_ok( $user->email );
+ $mech->get_ok("/report/$report_id");
+
+ my $update_meta = $mech->extract_update_metas;
+ is scalar(@$update_meta), $test->{comment_count}, 'expected number of comments on report';
+ };
+}
+$user2->is_superuser(0);
+$user2->from_body(undef);
+$user2->update;
$user->from_body(undef);
$user->update;
@@ -966,19 +1157,20 @@ $user->update;
$report->state('confirmed');
$report->bodies_str($body->id);
$report->update;
+$report->comments->delete;
for my $test (
{
desc => 'submit an update for a registered user, signing in with wrong password',
form_values => {
submit_update => 1,
- rznvy => 'registered@example.com',
+ username => 'registered@example.com',
update => 'Update from a user',
add_alert => undef,
password_sign_in => 'secret',
},
field_errors => [
- "There was a problem with your email/password combination. If you cannot remember your password, or do not have one, please fill in the \x{2018}sign in by email\x{2019} section of the form.",
+ "There was a problem with your login information. If you cannot remember your password, or do not have one, please fill in the \x{2018}No\x{2019} section of the form.",
'Please enter your name', # FIXME Not really necessary error
],
},
@@ -986,7 +1178,7 @@ for my $test (
desc => 'submit an update for a registered user and sign in',
form_values => {
submit_update => 1,
- rznvy => 'registered@example.com',
+ username => 'registered@example.com',
update => 'Update from a user',
add_alert => undef,
password_sign_in => 'secret2',
@@ -996,7 +1188,7 @@ for my $test (
) {
subtest $test->{desc} => sub {
# Set things up
- my $user = $mech->create_user_ok( $test->{form_values}->{rznvy} );
+ my $user = $mech->create_user_ok( $test->{form_values}->{username} );
my $pw = 'secret2';
$user->update( { name => 'Mr Reg', password => $pw } );
$report->comments->delete;
@@ -1036,7 +1228,7 @@ for my $test (
my $update = $report->comments->first;
ok $update, 'found update';
is $update->text, $test->{form_values}->{update}, 'update text';
- is $update->user->email, $test->{form_values}->{rznvy}, 'update user';
+ is $update->user->email, $test->{form_values}->{username}, 'update user';
is $update->state, 'confirmed', 'update confirmed';
$mech->delete_user( $update->user );
}
@@ -1053,7 +1245,7 @@ subtest 'submit an update for a registered user, creating update by email' => su
$mech->submit_form_ok( {
with_fields => {
submit_update => 1,
- rznvy => 'registered@example.com',
+ username => 'registered@example.com',
update => 'Update from a user',
add_alert => undef,
name => 'New Name',
@@ -1502,7 +1694,7 @@ for my $test (
fields => {
submit_update => 1,
name => 'Test User',
- rznvy => 'test@example.com',
+ username => 'test@example.com',
may_show_name => 1,
update => 'update from owner',
add_alert => undef,
@@ -1524,7 +1716,7 @@ for my $test (
submit_update => 1,
name => 'Test User',
may_show_name => 1,
- rznvy => 'test@example.com',
+ username => 'test@example.com',
update => 'update from owner',
add_alert => undef,
fixed => 1,
@@ -1589,7 +1781,7 @@ for my $test (
my $update = $report->comments->first;
ok $update, 'found update';
is $update->text, $results->{update}, 'update text';
- is $update->user->email, $test->{fields}->{rznvy}, 'update user';
+ is $update->user->email, $test->{fields}->{username}, 'update user';
is $update->state, 'unconfirmed', 'update confirmed';
is $update->anonymous, $test->{anonymous}, 'user anonymous';
diff --git a/t/app/controller/reports.t b/t/app/controller/reports.t
index f3958a0a5..76c920562 100644
--- a/t/app/controller/reports.t
+++ b/t/app/controller/reports.t
@@ -12,9 +12,6 @@ END {
ok( my $mech = FixMyStreet::TestMech->new, 'Created mech object' );
-# Run the cron script with empty database
-FixMyStreet::Script::UpdateAllReports::generate_dashboard();
-
$mech->create_body_ok(2514, 'Birmingham City Council');
my $body_edin_id = $mech->create_body_ok(2651, 'City of Edinburgh Council')->id;
my $body_west_id = $mech->create_body_ok(2504, 'Westminster City Council')->id;
@@ -99,10 +96,14 @@ $fife_problems[10]->update( {
});
# Run the cron script that makes the data for /reports so we don't get an error.
-FixMyStreet::Script::UpdateAllReports::generate_dashboard();
+my $data = FixMyStreet::Script::UpdateAllReports::generate_dashboard();
# check that we can get the page
-$mech->get_ok('/reports');
+FixMyStreet::override_config {
+ TEST_DASHBOARD_DATA => $data,
+}, sub {
+ $mech->get_ok('/reports');
+};
$mech->title_like(qr{Dashboard});
$mech->content_contains('Birmingham');
@@ -114,6 +115,18 @@ FixMyStreet::override_config {
MAPIT_URL => 'http://mapit.uk/',
}, sub {
$mech->submit_form_ok( { with_fields => { body => $body_edin_id } }, 'Submitted dropdown okay' );
+ is $mech->uri->path, '/reports/City+of+Edinburgh+Council';
+
+ subtest "test ward pages" => sub {
+ $mech->get_ok('/reports/Birmingham/Bad-Ward');
+ is $mech->uri->path, '/reports/Birmingham+City+Council';
+ $mech->get_ok('/reports/Birmingham/Aston');
+ is $mech->uri->path, '/reports/Birmingham+City+Council/Aston';
+ $mech->get_ok('/reports/Birmingham/Aston|Bournville');
+ is $mech->uri->path, '/reports/Birmingham+City+Council/Aston%7CBournville';
+ $mech->content_contains('Aston, Bournville');
+ };
+
$mech->get_ok('/reports/Westminster');
};
@@ -126,6 +139,7 @@ is scalar @$problems, 5, 'correct number of problems displayed';
FixMyStreet::override_config {
MAPIT_URL => 'http://mapit.uk/',
+ TEST_DASHBOARD_DATA => $data,
}, sub {
$mech->get_ok('/reports');
$mech->submit_form_ok({ with_fields => { body => $body_slash_id } }, 'Submitted dropdown okay');
@@ -187,13 +201,18 @@ is scalar @$problems, 4, 'only public problems are displayed';
$mech->content_lacks('All reports Test 3 for ' . $body_west_id, 'non public problem is not visible');
# No change to numbers if report is non-public
-$mech->get_ok('/reports');
+FixMyStreet::override_config {
+ TEST_DASHBOARD_DATA => $data,
+}, sub {
+ $mech->get_ok('/reports');
+};
$mech->content_contains('&quot;Apr&quot;,&quot;May&quot;,&quot;Jun&quot;,&quot;Jul&quot;');
$mech->content_contains('5,9,10,22');
subtest "test fiksgatami all reports page" => sub {
FixMyStreet::override_config {
ALLOWED_COBRANDS => [ 'fiksgatami' ],
+ TEST_DASHBOARD_DATA => $data, # Not relevant to what we're testing, just so page loads
}, sub {
$mech->create_body_ok(3, 'Oslo');
ok $mech->host("fiksgatami.no"), 'change host to fiksgatami';
diff --git a/t/app/controller/rss.t b/t/app/controller/rss.t
index 5ec7bfae7..171121eaa 100644
--- a/t/app/controller/rss.t
+++ b/t/app/controller/rss.t
@@ -1,3 +1,4 @@
+use open ':std', ':locale';
use FixMyStreet::TestMech;
use FixMyStreet::App;
@@ -18,7 +19,7 @@ my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( {
bodies_str => '2651',
areas => ',11808,135007,14419,134935,2651,20728,',
category => 'Street lighting',
- title => 'Testing',
+ title => '&Test’i<n>g \'☃"',
detail => 'Testing Detail',
used_map => 1,
name => $user1->name,
@@ -44,7 +45,7 @@ FixMyStreet::override_config {
}, sub {
$mech->get_ok("/rss/pc/EH11BB/2");
};
-$mech->content_contains( "Testing, 10th October" );
+$mech->content_contains( "&amp;Test’i&lt;n&gt;g &#39;☃&quot;, 10th October" );
$mech->content_lacks( 'Nearest road to the pin' );
is $mech->response->header('Access-Control-Allow-Origin'), '*';
@@ -118,7 +119,7 @@ FixMyStreet::override_config {
}, sub {
$mech->get_ok("/rss/pc/EH11BB/2");
};
-$mech->content_contains( "Testing, 10th October" );
+$mech->content_contains( "&amp;Test’i&lt;n&gt;g &#39;☃&quot;, 10th October" );
$mech->content_contains( '18 North Bridge, Edinburgh' );
$report->delete();
diff --git a/t/app/model/extra.t b/t/app/model/extra.t
index a5e3e3574..55accb086 100644
--- a/t/app/model/extra.t
+++ b/t/app/model/extra.t
@@ -101,6 +101,7 @@ subtest 'Default hash layout' => sub {
subtest 'Get named field values' => sub {
my $user = $db->resultset('User')->create({
email => 'test-moderation@example.com',
+ email_verified => 1,
name => 'Test User'
});
my $report = $db->resultset('Problem')->create(
diff --git a/t/app/model/photoset.t b/t/app/model/photoset.t
index 4aa5c8992..d171ba88b 100644
--- a/t/app/model/photoset.t
+++ b/t/app/model/photoset.t
@@ -12,9 +12,7 @@ my $UPLOAD_DIR = tempdir( CLEANUP => 1 );
my $db = FixMyStreet::DB->schema;
-my $user = $db->resultset('User')->find_or_create({
- name => 'Bob', email => 'bob@example.com',
-});
+my $user = $db->resultset('User')->find_or_create({ name => 'Bob', email => 'bob@example.com' });
FixMyStreet::override_config {
UPLOAD_DIR => $UPLOAD_DIR,