use FixMyStreet::TestMech; my $mech = FixMyStreet::TestMech->new; my $user = $mech->create_user_ok('test@example.com', name => 'Test User'); my $superuser = $mech->create_user_ok('superuser@example.com', name => 'Super User', is_superuser => 1); my $oxfordshire = $mech->create_body_ok(2237, 'Oxfordshire County Council'); my $haringey = $mech->create_body_ok(2509, 'Haringey Borough Council'); my $southend = $mech->create_body_ok(2607, 'Southend-on-Sea Borough Council'); $mech->log_in_ok( $superuser->email ); subtest 'search abuse' => sub { my $abuse = FixMyStreet::App->model('DB::Abuse')->find_or_create( { email => $user->email } ); $mech->get_ok( '/admin/users?search=example' ); $mech->content_like(qr{test\@example.com.*\s*.*?\s*User in abuse table}s); }; subtest 'remove user from abuse list from edit user page' => sub { $mech->get_ok( '/admin/user_edit/' . $user->id ); $mech->content_contains('User in abuse table'); $mech->click_ok('unban'); my $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $user->email } ); ok !$abuse, 'record removed from abuse table'; }; subtest 'remove user with phone account from abuse list from edit user page' => sub { my $abuse_user = $mech->create_user_ok('01234 456789'); my $abuse = FixMyStreet::App->model('DB::Abuse')->find_or_create( { email => $abuse_user->phone } ); $mech->get_ok( '/admin/user_edit/' . $abuse_user->id ); $mech->content_contains('User in abuse table'); my $abuse_found = FixMyStreet::App->model('DB::Abuse')->find( { email => $abuse_user->phone } ); ok $abuse_found, 'user in abuse table'; $mech->click_ok('unban'); $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $user->phone } ); ok !$abuse, 'record removed from abuse table'; }; subtest 'no option to remove user already in abuse list' => sub { my $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $user->email } ); $abuse->delete if $abuse; $mech->get_ok( '/admin/user_edit/' . $user->id ); $mech->content_lacks('User in abuse table'); }; subtest 'show flagged entries' => sub { $user->flagged( 1 ); $user->update; $mech->get_ok('/admin/flagged'); $mech->content_contains( $user->email ); $user->flagged( 0 ); $user->update; }; subtest 'user search' => sub { $mech->get_ok('/admin/users'); $mech->get_ok('/admin/users?search=' . $user->name); $mech->content_contains( $user->name); my $u_id = $user->id; $mech->content_like( qr{user_edit/$u_id">Edit} ); $mech->get_ok('/admin/users?search=' . $user->email); $mech->content_like( qr{user_edit/$u_id">Edit} ); $user->from_body($haringey->id); $user->update; $mech->get_ok('/admin/users?search=' . $haringey->id ); $mech->content_contains('Haringey'); }; subtest 'search does not show user from another council' => sub { FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'oxfordshire' ], }, sub { $mech->get_ok('/admin/users'); $mech->get_ok('/admin/users?search=' . $user->name); $mech->content_contains( "Searching found no users." ); $mech->get_ok('/admin/users?search=' . $user->email); $mech->content_contains( "Searching found no users." ); }; }; subtest 'user_edit does not show user from another council' => sub { FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'oxfordshire' ], }, sub { $mech->get('/admin/user_edit/' . $user->id); ok !$mech->res->is_success(), "want a bad response"; is $mech->res->code, 404, "got 404"; }; }; for my $test ( { desc => 'add user - blank form', fields => { email => '', email_verified => 0, phone => '', phone_verified => 0, }, error => ['Please verify at least one of email/phone', 'Please enter a name'], }, { desc => 'add user - blank, verify phone', fields => { email => '', email_verified => 0, phone => '', phone_verified => 1, }, error => ['Please enter a valid email or phone number', 'Please enter a name'], }, { desc => 'add user - bad email', fields => { name => 'Norman', email => 'bademail', email_verified => 0, phone => '', phone_verified => 0, }, error => ['Please enter a valid email'], }, { desc => 'add user - bad phone', fields => { name => 'Norman', phone => '01214960000000', phone_verified => 1, }, error => ['Please check your phone number is correct'], }, { desc => 'add user - landline', fields => { name => 'Norman Name', phone => '+441214960000', phone_verified => 1, }, error => ['Please enter a mobile number'], }, { desc => 'add user - good details', fields => { name => 'Norman Name', phone => '+61491570156', phone_verified => 1, }, }, ) { subtest $test->{desc} => sub { $mech->get_ok('/admin/users'); $mech->submit_form_ok( { with_fields => $test->{fields} } ); if ($test->{error}) { $mech->content_contains($_) for @{$test->{error}}; } else { $mech->content_contains('Updated'); } }; } my %default_perms = ( "permissions[moderate]" => undef, "permissions[planned_reports]" => undef, "permissions[report_mark_private]" => undef, "permissions[report_edit]" => undef, "permissions[report_edit_category]" => undef, "permissions[report_edit_priority]" => undef, "permissions[report_inspect]" => undef, "permissions[report_instruct]" => undef, "permissions[contribute_as_another_user]" => undef, "permissions[contribute_as_anonymous_user]" => undef, "permissions[contribute_as_body]" => undef, "permissions[view_body_contribute_details]" => undef, "permissions[user_edit]" => undef, "permissions[user_manage_permissions]" => undef, "permissions[user_assign_body]" => undef, "permissions[user_assign_areas]" => undef, "permissions[template_edit]" => undef, "permissions[responsepriority_edit]" => undef, "permissions[category_edit]" => undef, trusted_bodies => undef, ); # Start this section with user having no name # Regression test for mysociety/fixmystreetforcouncils#250 $user->update({ name => '' }); FixMyStreet::override_config { MAPIT_URL => 'http://mapit.uk/', }, sub { for my $test ( { desc => 'edit user name', fields => { name => '', email => 'test@example.com', email_verified => 1, body => $haringey->id, phone => '', phone_verified => undef, flagged => undef, is_superuser => undef, area_id => '', %default_perms, }, changes => { name => 'Changed User', }, log_count => 1, log_entries => [qw/edit/], }, { desc => 'edit user email', fields => { name => 'Changed User', email => 'test@example.com', email_verified => 1, body => $haringey->id, phone => '', phone_verified => undef, flagged => undef, is_superuser => undef, area_id => '', %default_perms, }, changes => { email => 'changed@example.com', }, log_count => 2, log_entries => [qw/edit edit/], }, { desc => 'edit user body', fields => { name => 'Changed User', email => 'changed@example.com', email_verified => 1, body => $haringey->id, phone => '', phone_verified => undef, flagged => undef, is_superuser => undef, area_id => '', %default_perms, }, changes => { body => $southend->id, }, log_count => 3, log_entries => [qw/edit edit edit/], }, { desc => 'edit user flagged', fields => { name => 'Changed User', email => 'changed@example.com', email_verified => 1, body => $southend->id, phone => '', phone_verified => undef, flagged => undef, is_superuser => undef, area_id => '', %default_perms, }, changes => { flagged => 'on', }, log_count => 4, log_entries => [qw/edit edit edit edit/], }, { desc => 'edit user remove flagged', fields => { name => 'Changed User', email => 'changed@example.com', email_verified => 1, body => $southend->id, phone => '', phone_verified => undef, flagged => 'on', is_superuser => undef, area_id => '', %default_perms, }, changes => { flagged => undef, }, log_count => 4, log_entries => [qw/edit edit edit edit/], }, { desc => 'edit user add is_superuser', fields => { name => 'Changed User', email => 'changed@example.com', email_verified => 1, body => $southend->id, phone => '', phone_verified => undef, flagged => undef, is_superuser => undef, area_id => '', %default_perms, }, changes => { is_superuser => 'on', }, removed => [ keys %default_perms, ], log_count => 5, log_entries => [qw/edit edit edit edit edit/], }, { desc => 'edit user remove is_superuser', fields => { name => 'Changed User', email => 'changed@example.com', email_verified => 1, body => $southend->id, phone => '', phone_verified => undef, flagged => undef, is_superuser => 'on', area_id => '', }, changes => { is_superuser => undef, }, added => { %default_perms, }, log_count => 5, log_entries => [qw/edit edit edit edit edit/], }, ) { subtest $test->{desc} => sub { $mech->get_ok( '/admin/user_edit/' . $user->id ); my $visible = $mech->visible_form_values; is_deeply $visible, $test->{fields}, 'expected user'; my $expected = { %{ $test->{fields} }, %{ $test->{changes} } }; $mech->submit_form_ok( { with_fields => $expected } ); # Some actions cause visible fields to be added/removed foreach my $x (@{ $test->{removed} }) { delete $expected->{$x}; } if ( $test->{added} ) { $expected = { %$expected, %{ $test->{added} } }; } $visible = $mech->visible_form_values; is_deeply $visible, $expected, 'user updated'; $mech->content_contains( 'Updated!' ); }; } }; FixMyStreet::override_config { MAPIT_URL => 'http://mapit.uk/', SMS_AUTHENTICATION => 1, }, sub { subtest "Test edit user add verified phone" => sub { $mech->get_ok( '/admin/user_edit/' . $user->id ); $mech->submit_form_ok( { with_fields => { phone => '+61491570157', phone_verified => 1, } } ); $mech->content_contains( 'Updated!' ); }; subtest "Test changing user to an existing one" => sub { my $existing_user = $mech->create_user_ok('existing@example.com', name => 'Existing User'); $mech->create_problems_for_body(2, 2514, 'Title', { user => $existing_user }); my $count = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id })->count; $mech->get_ok( '/admin/user_edit/' . $user->id ); $mech->submit_form_ok( { with_fields => { email => 'existing@example.com' } }, 'submit email change' ); is $mech->uri->path, '/admin/user_edit/' . $existing_user->id, 'redirected'; my $p = FixMyStreet::DB->resultset('Problem')->search({ user_id => $existing_user->id })->count; is $p, $count + 2, 'reports merged'; }; }; $user = $mech->create_user_ok('test@example.com', name => 'Test User'); subtest "Send login email from admin" => sub { $mech->email_count_is(0); $mech->get_ok( '/admin/user_edit/' . $user->id ); $mech->submit_form_ok( { button => 'send_login_email' }, "send login email form submitted" ); my $email = $mech->get_email; ok $email, "got an email"; is $email->header('Subject'), "Your FixMyStreet account details", "subject is correct"; is $email->header('To'), $user->email, "to is correct"; my $link = $mech->get_link_from_email($email); my $mech2 = FixMyStreet::TestMech->new; $mech2->not_logged_in_ok; $mech2->get_ok($link); $mech2->logged_in_ok; $mech2->log_out_ok; $mech->clear_emails_ok; }; subtest "Send login email from admin for unverified email" => sub { $user->update( { email_verified => 0 } ); $mech->email_count_is(0); $mech->get_ok( '/admin/user_edit/' . $user->id ); $mech->submit_form_ok( { button => 'send_login_email' }, "send login email form submitted" ); my $email = $mech->get_email; ok $email, "got an email"; is $email->header('Subject'), "Your FixMyStreet account details", "subject is correct"; is $email->header('To'), 'test@example.com', "to is correct"; my $link = $mech->get_link_from_email($email); my $mech2 = FixMyStreet::TestMech->new; $mech2->not_logged_in_ok; $mech2->get_ok($link); $mech2->logged_in_ok; my $test_user = FixMyStreet::DB->resultset('User')->search({ email => $user->email }, { order_by => [ { -desc => 'id' } ] } ); $user->discard_changes; is $test_user->count, 1, "only one user"; is $test_user->first->id, $user->id, "User is same"; ok $user->email_verified, 'email is verified now'; $mech2->log_out_ok; $user->update( { email_verified => 1 } ); }; subtest "Anonymizing user from admin" => sub { $mech->create_problems_for_body(4, 2237, 'Title'); my $count_p = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id })->count; my $count_u = FixMyStreet::DB->resultset('Comment')->search({ user_id => $user->id })->count; $mech->get_ok( '/admin/user_edit/' . $user->id ); $mech->submit_form_ok({ button => 'anon_everywhere' }); my $c = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id, anonymous => 1 })->count; is $c, $count_p; $c = FixMyStreet::DB->resultset('Comment')->search({ user_id => $user->id, anonymous => 1 })->count; is $c, $count_u; }; subtest "Hiding user's reports from admin" => sub { my $count_p = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id })->count; my $count_u = FixMyStreet::DB->resultset('Comment')->search({ user_id => $user->id })->count; $mech->get_ok( '/admin/user_edit/' . $user->id ); $mech->submit_form_ok({ button => 'hide_everywhere' }); my $c = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id, state => 'hidden' })->count; is $c, $count_p; $c = FixMyStreet::DB->resultset('Comment')->search({ user_id => $user->id, state => 'hidden' })->count; is $c, $count_u; }; subtest "Logging user out" => sub { my $mech2 = FixMyStreet::TestMech->new; $mech2->log_in_ok($user->email); $mech2->logged_in_ok; $mech->get_ok( '/admin/user_edit/' . $user->id ); $mech->submit_form_ok({ button => 'logout_everywhere' }, 'Logging user out'); $mech2->not_logged_in_ok; }; subtest "Removing account from admin" => sub { $mech->create_problems_for_body(4, 2237, 'Title'); my $count_p = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id })->count; my $count_u = FixMyStreet::DB->resultset('Comment')->search({ user_id => $user->id })->count; $mech->get_ok( '/admin/user_edit/' . $user->id ); $mech->submit_form_ok({ button => 'remove_account' }, 'Removing account'); my $c = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id, anonymous => 1, name => '' })->count; is $c, $count_p, 'All reports anon/nameless'; $c = FixMyStreet::DB->resultset('Comment')->search({ user_id => $user->id, anonymous => 1, name => '' })->count; is $c, $count_u, 'All updates anon/nameless'; $user->discard_changes; is $user->name, '', 'Name gone'; is $user->password, '', 'Password gone'; is $user->email, 'removed-' . $user->id . '@example.org', 'Email gone' }; subtest "can view list of user's alerts" => sub { $mech->get_ok( '/admin/user_edit/' . $user->id ); $mech->content_lacks("User's alerts", 'no list of alerts'); $mech->create_problems_for_body(1, 2514, 'Title', { user => $user }); my $p = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id })->first; my $alert = FixMyStreet::DB->resultset('Alert')->find_or_create({ user_id => $user->id, alert_type => 'new_updates', parameter => $p->id }); $mech->get_ok( '/admin/user_edit/' . $user->id ); $mech->content_contains("User's alerts", 'has list of alerts'); $mech->content_contains($alert->id, 'lists alert'); }; subtest "can edit list of user's alerts" => sub { $mech->get_ok( '/admin/user_edit/' . $user->id ); my $alert = FixMyStreet::DB->resultset('Alert')->search({ user_id => $user->id, alert_type => 'new_updates', })->first; $mech->content_like(qr[${\$alert->id}\s*new_updates]m, 'alert on page'); $mech->submit_form_ok( { with_fields => { 'edit_alert[' . $alert->id . ']' => 'disable' } }, 'disabling alert'); $alert->discard_changes; ok $alert->whendisabled, 'alert disabled'; $mech->submit_form_ok( { with_fields => { 'edit_alert[' . $alert->id . ']' => 'enable' } }, 'enabling alert'); $alert->discard_changes; is $alert->whendisabled, undef, 'alert enabled'; $mech->submit_form_ok( { with_fields => { 'edit_alert[' . $alert->id . ']' => 'delete', } }, 'deleting alert'); $mech->content_unlike(qr[${\$alert->id}\s*new_updates]m, 'alert not on page'); is $user->alerts->count, 0, 'alert deleted'; }; subtest "View timeline" => sub { $mech->get_ok('/admin/timeline'); }; done_testing();