denny/ShinyCMS

View on GitHub
t/admin-controllers/controller_Admin-Users.t

Summary

Maintainability
Test Coverage
# ===================================================================
# File:        t/admin-controllers/controller_Admin-Users.t
# Project:    ShinyCMS
# Purpose:    Tests for user admin features
#
# Author:    Denny de la Haye <2019@denny.me>
# Copyright (c) 2009-2019 Denny de la Haye
#
# ShinyCMS is free software; you can redistribute it and/or modify it
# under the terms of either the GPL 2.0 or the Artistic License 2.0
# ===================================================================

use strict;
use warnings;

use Test::More;
use Test::WWW::Mechanize::Catalyst::WithContext;

use lib 't/support';
require 'login_helpers.pl';  ## no critic


my $admin = create_test_admin( 'test_admin_users', 'User Admin' );

my $schema = get_schema();

my $t = Test::WWW::Mechanize::Catalyst::WithContext->new( catalyst_app => 'ShinyCMS' );


# Try to fetch the admin area, expecting to fail and be asked to log in first
$t->get_ok(
    '/admin',
    'Try to fetch page in admin area'
);
$t->title_is(
    'Log In - ShinyCMS',
    'Admin area requires login'
);

# Submit admin login form
$t->submit_form_ok({
    form_id => 'login',
    fields => {
        username => $admin->username,
        password => $admin->username,
    }},
    'Submit login form'
);
$t->content_contains(
    'Logout',
    'Login attempt successful'
);
# Fetch the admin area again
$t->get_ok(
    '/admin',
    'Fetch admin area again'
);


# Add a new role
$t->follow_link_ok(
    { text => 'Add role' },
    'Follow link to add a new role'
);
$t->title_is(
    'Add Role - ShinyCMS',
    'Reached page for adding new roles'
);
$t->submit_form_ok({
    form_id => 'add_role',
    fields => {
        role => 'Test Role',
    }},
    'Submitted form to create new role'
);
$t->title_is(
    'Edit Role - ShinyCMS',
    'Redirected to edit page for new role'
);
$t->uri->path =~ m{/admin/users/role/(\d+)/edit};
my $role_id = $1;
$t->submit_form_ok({
    form_id => 'edit_role',
    fields => {
        role => 'Updated Test Role',
    }},
    'Submitted form to update role name'
);


# Add a new access group
$t->follow_link_ok(
    { text => 'Add access group' },
    'Follow link to add a new access group'
);
$t->title_is(
    'Add Access Group - ShinyCMS',
    'Reached page for adding new access groups'
);
$t->submit_form_ok({
    form_id => 'add_access',
    fields => {
        access => 'Test Group',
    }},
    'Submitted form to create new access group'
);
$t->title_is(
    'Edit Access Group - ShinyCMS',
    'Redirected to edit page for new access group'
);
$t->uri->path =~ m{/admin/users/access-group/(\d+)/edit};
my $access_id = $1;
$t->submit_form_ok({
    form_id => 'edit_access',
    fields => {
        access => 'Test Access Group',
    }},
    'Submitted form to update access group name'
);


# Add a new user
$t->follow_link_ok(
    { text => 'Add user' },
    'Follow link to add a new user'
);
$t->title_is(
    'Add User - ShinyCMS',
    'Reached page for adding new users'
);
$t->submit_form_ok({
    form_id => 'edit_user',
    fields => {
        username => 'test_username',
        password => 'test_password',
        email    => 'invalid@email',
    }},
    'Submitted form to create new user, with invalid email address'
);
$t->title_is(
    'Add User - ShinyCMS',
    'Redirected back to page for adding new users'
);
my $test_data_email = 'test_email@shinycms.org';
my $pic_file = 'root/static/cms-uploads/user-profile-pics/admin/space-invader.png';
$t->submit_form_ok({
    form_id => 'edit_user',
    fields => {
        username => 'test_username',
        password => 'test_password',
        email    => $test_data_email,
        profile_pic    => $pic_file,
        allow_comments => 'on',
    }},
    'Submitted form to create new user, with valid email address'
);
$t->title_is(
    'Edit User - ShinyCMS',
    'Redirected to edit page for new user'
);
my @inputs1 = $t->grep_inputs({ name => qr{^email$} });
ok(
    $inputs1[0]->value eq $test_data_email,
    'Verified that user was created'
);
$t->uri->path =~ m{/admin/users/user/(\d+)/edit};
my $user_id = $1;

# Update user details
$t->submit_form_ok({
    form_id => 'edit_user',
    fields => {
        allow_comments => undef,
        admin_notes    => 'User updated by test suite',
        date_group_1   => DateTime->now->ymd,
        time_group_1   => DateTime->now->hms,
        active         => undef,
    }},
    'Submitted form to update user notes and access, and remove discussion'
);
my @inputs2 = $t->grep_inputs({ name => qr{^admin_notes$} });
ok(
    $inputs2[0]->value eq 'User updated by test suite',
    'Verified that user was updated'
);

my $large_file = '/bin/bash';
$t->submit_form_ok({
    form_id => 'edit_user',
    fields => {
        profile_pic => $large_file,
    }},
    'Submitted form again, attempting to upload a large (>1MiB) profile pic'
);
$t->text_contains(
    'Profile pic must be less than ',
    'Got error message about file size'
);

$t->submit_form_ok({
    form_id => 'edit_user',
    fields => {
        'role_'.$role_id => 'on',
        active           => 'on',
        date_group_1     => 'never',
        profile_pic      => $pic_file,
    }},
    'Submit form to add role and profile pic, and set access to not expire'
);
$t->content_contains(
    'user-profile-pics/test_username/test_username.png',
    'Profile pic uploaded succsesfully'
);

# Add a new user with a clashing username
$t->follow_link_ok(
    { text => 'Add user' },
    'Follow link to add another new user'
);
$t->submit_form_ok({
    form_id => 'edit_user',
    fields => {
        username => 'test_username',
        password => 'test_password',
        email    => $test_data_email,
    }},
    'Submitted form to create new user with same username as existing user'
);
$t->title_is(
    'Add User - ShinyCMS',
    'Redirected back to Add User page'
);
$t->text_contains(
    'That username already exists',
    'Adding user with duplicate username failed'
);

# Fetch the list of users
$t->follow_link_ok(
    { text => 'List users' },
    'Click on link to view list of users in admin area'
);
$t->title_is(
    'List Users - ShinyCMS',
    'Reached user list in admin area'
);

# Search users
$t->submit_form_ok({
    form_id => 'search_users',
    fields => {
        query => 'test_admin_users',
    }},
    'Submitted form to search users'
);
$t->text_contains(
    'test_admin_users@example.com',
    'Search returned matching users'
);
$t->back;

# Change password
$t->follow_link_ok(
    { url_regex => qr{/admin/users/user/$user_id/change-password$} },
    "Click on link to change user's password"
);
$t->title_like(
    qr{Change Password for \w+ - ShinyCMS},
    'Reached page for changing user password'
);
$t->submit_form_ok({
    form_id => 'change_password',
    fields => {
        password_one => 'testing_password',
        password_two => 'different_password',
    }},
    'Submitted form to change password, with mismatched passwords'
);
$t->title_like(
    qr{Change Password for \w+ - ShinyCMS},
    'Redirected back to change password page'
);
$t->text_contains(
    'Passwords did not match',
    'Got error message about passwords not matching'
);
$t->submit_form_ok({
    form_id => 'change_password',
    fields => {
        password_one => 'testing_password',
        password_two => 'testing_password',
    }},
    'Submitted form to change password again, with matching passwords'
);
$t->title_is(
    'List Users - ShinyCMS',
    'Redirected back to user list'
);
$t->text_contains(
    'Password changed',
    'Verified that password was changed'
);


# ...


# Look at logins/IP logs for a user
$t->follow_link_ok(
    { text => 'List users' },
    'Click on link to load user list'
);
$t->follow_link_ok(
    { text => 'Logins' },
    "Click link to view file access logs for user 'admin'"
);
$t->title_is(
    'User Logins - ShinyCMS',
    'Reached list of login details for admin user'
);


# ...


# Look at file access logs for a user
# TODO: this is one of the few admin area tests that relies on the demo data being loaded
my $logs_user_id = $schema->resultset( 'FileAccess' )->first->user->id;
$t->follow_link_ok(
    { text => 'List users' },
    'Click on link to load user list again'
);
$t->follow_link_ok(
    { url_regex => qr{/admin/users/user/$logs_user_id/file-access-logs$} },
    "Go back to user list, click link to view file access logs for user #$user_id"
);
$t->title_like(
    qr{^Access logs for: [-\w]+ - ShinyCMS$},
    'Reached file access logs'
);


# Delete user (can't use submit_form_ok due to javascript confirmation)
$t->post_ok(
    '/admin/users/save',
    {
        user_id => $user_id,
        delete  => 'Delete'
    },
    'Submitted request to delete user'
);
# View list of users
$t->title_is(
    'List Users - ShinyCMS',
    'Reached list of users'
);
$t->content_lacks(
    $test_data_email,
    'Verified that user was deleted'
);

# Delete access group
$t->post_ok(
    "/admin/users/access-group/$access_id/save",
    {
        delete => 'Delete'
    },
    'Submitted request to delete access group'
);
$t->title_is(
    'Access Groups - ShinyCMS',
    'Reached list of access groups'
);
$t->content_lacks(
    'Test Access Group',
    'Verified that access group was deleted'
);

# Delete role
$t->post_ok(
    "/admin/users/role/$role_id/save",
    {
        delete => 'Delete'
    },
    'Submitted request to delete role'
);
$t->title_is(
    'Roles - ShinyCMS',
    'Reached list of roles'
);
$t->content_lacks(
    'Test Role',
    'Verified that role was deleted'
);


# Log in as the wrong sort of admin, and make sure we're blocked
my $poll_admin = create_test_admin( 'test_admin_users_poll_admin', 'Poll Admin' );
$t = login_test_admin( $poll_admin->username, $poll_admin->username )
    or die 'Failed to log in as Poll Admin';
$t->get_ok(
    '/admin/users',
    'Attempt to fetch user admin area as Poll Admin'
);
$t->title_unlike(
    qr{^.*User.* - ShinyCMS$},
    'Failed to reach user admin area without any appropriate roles enabled'
);


# Tidy up user accounts
remove_test_admin( $poll_admin );
remove_test_admin( $admin      );

system( 'rm -f root/static/cms-uploads/user-profile-pics/test_username/*.*' );
system( 'rmdir root/static/cms-uploads/user-profile-pics/test_username' );

done_testing();