You are here

password_policy.test in Password Policy 6

Same filename and directory in other branches
  1. 5 tests/password_policy.test
  2. 7 tests/password_policy.test

Unit tests for Password policy module.

File

tests/password_policy.test
View source
<?php

/**
 * @file
 * Unit tests for Password policy module.
 */
class PasswordPolicyTestCase extends DrupalWebTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Password constraints',
      'description' => 'Test password constraints.',
      'group' => 'Password Policy',
    );
  }
  public function setUp() {
    if (defined('USER_LOAD_PHPASS_PATCHED')) {
      parent::setUp('password_policy', 'phpass');
    }
    else {
      parent::setUp('password_policy');
    }
  }
  function testUppercaseConstraint() {
    module_load_include('inc', 'password_policy', 'constraints/constraint_uppercase');
    $constraint = 2;
    $uid = 0;
    $pass = 'Abc';
    $result = password_policy_constraint_uppercase_validate($pass, $constraint, $uid);
    $this
      ->assertFalse($result, 'One uppercase letter in the uppercase constraint with param 2');
    $pass = 'ABc';
    $result = password_policy_constraint_uppercase_validate($pass, $constraint, $uid);
    $this
      ->assertTrue($result, 'Two uppercase letters in the uppercase constraint with param 2');
    $pass = 'ABC';
    $result = password_policy_constraint_uppercase_validate($pass, $constraint, $uid);
    $this
      ->assertTrue($result, 'Three uppercase letters in the uppercase constraint with param 2');
  }
  function testLowercaseConstraint() {
    module_load_include('inc', 'password_policy', 'constraints/constraint_lowercase');
    $constraint = 2;
    $uid = 0;
    $pass = 'Abc';
    $result = password_policy_constraint_lowercase_validate($pass, $constraint, $uid);
    $this
      ->assertTrue($result, 'One uppercase letter in the lowercase constraint with param 2');
    $pass = 'ABc';
    $result = password_policy_constraint_lowercase_validate($pass, $constraint, $uid);
    $this
      ->assertFalse($result, 'Two uppercase letters in the lowercase constraint with param 2');
    $pass = 'ABC';
    $result = password_policy_constraint_lowercase_validate($pass, $constraint, $uid);
    $this
      ->assertFalse($result, 'Three uppercase letters in the lowercase constraint with param 2');
  }
  function testLetterConstraint() {
    module_load_include('inc', 'password_policy', 'constraints/constraint_letter');
    $constraint = 2;
    $uid = 0;
    $pass = 'a12';
    $result = password_policy_constraint_letter_validate($pass, $constraint, $uid);
    $this
      ->assertFalse($result, 'One lowercase letter in the letter constraint with param 2');
    $pass = 'aB1';
    $result = password_policy_constraint_letter_validate($pass, $constraint, $uid);
    $this
      ->assertTrue($result, 'One lowercase and one uppercase letter in the letter constraint with param 2');
    $pass = 'abC';
    $result = password_policy_constraint_letter_validate($pass, $constraint, $uid);
    $this
      ->assertTrue($result, 'Two lowercase and one uppercase letter in the letter constraint with param 2');
  }
  function testDigitConstraint() {
    module_load_include('inc', 'password_policy', 'constraints/constraint_digit');
    $constraint = 2;
    $uid = 0;
    $pass = '1ab';
    $result = password_policy_constraint_digit_validate($pass, $constraint, $uid);
    $this
      ->assertFalse($result, 'One digit in the digit constraint with param 2');
    $pass = '12a';
    $result = password_policy_constraint_digit_validate($pass, $constraint, $uid);
    $this
      ->assertTrue($result, 'Two digits in the digit constraint with param 2');
    $pass = '123';
    $result = password_policy_constraint_digit_validate($pass, $constraint, $uid);
    $this
      ->assertTrue($result, 'Three digits in the digit constraint with param 2');
  }
  function testLengthConstraint() {
    module_load_include('inc', 'password_policy', 'constraints/constraint_length');
    $constraint = 6;
    $uid = 0;
    $pass = 'abcde';
    $result = password_policy_constraint_length_validate($pass, $constraint, $uid);
    $this
      ->assertFalse($result, 'Five characters password in the length constraint with param 6');
    $pass = 'abcdef';
    $result = password_policy_constraint_length_validate($pass, $constraint, $uid);
    $this
      ->assertTrue($result, 'Six characters password in the length constraint with param 6');
    $pass = 'abcdefg';
    $result = password_policy_constraint_length_validate($pass, $constraint, $uid);
    $this
      ->assertTrue($result, 'Seven characters password in the length constraint with param 6');
  }
  function testAlphanumericConstraint() {
    module_load_include('inc', 'password_policy', 'constraints/constraint_alphanumeric');
    $constraint = 2;
    $uid = 0;
    $pass = '1$%';
    $result = password_policy_constraint_alphanumeric_validate($pass, $constraint, $uid);
    $this
      ->assertFalse($result, 'One digit and no letter in the alphanumeric constraint with param 2');
    $pass = '1a#';
    $result = password_policy_constraint_alphanumeric_validate($pass, $constraint, $uid);
    $this
      ->assertTrue($result, 'One digit and one letter in the alphanumeric constraint with param 2');
    $pass = '1ab';
    $result = password_policy_constraint_alphanumeric_validate($pass, $constraint, $uid);
    $this
      ->assertTrue($result, 'One digit ant two letters in the alphanumeric constraint with param 2');
  }
  function testPunctuationConstraint() {
    module_load_include('inc', 'password_policy', 'constraints/constraint_punctuation');
    $constraint = 2;
    $uid = 0;
    $pass = '%1a';
    $result = password_policy_constraint_punctuation_validate($pass, $constraint, $uid);
    $this
      ->assertFalse($result, 'One punctuation character in the punctuation constraint with param 2');
    $pass = '%^a';
    $result = password_policy_constraint_punctuation_validate($pass, $constraint, $uid);
    $this
      ->assertTrue($result, 'Two punctuation character in the punctuation constraint with param 2');
    $pass = '%^&';
    $result = password_policy_constraint_punctuation_validate($pass, $constraint, $uid);
    $this
      ->assertTrue($result, 'Three punctuation character in the punctuation constraint with param 2');
  }
  function testComplexityConstraint() {
    module_load_include('inc', 'password_policy', 'constraints/constraint_complexity');
    $constraint = 2;
    $uid = 0;
    $pass = 'abc';
    $result = password_policy_constraint_complexity_validate($pass, $constraint, $uid);
    $this
      ->assertFalse($result, 'Three letters in the type constraint with param 2');
    $pass = 'a1c';
    $result = password_policy_constraint_complexity_validate($pass, $constraint, $uid);
    $this
      ->assertTrue($result, 'Two letters and one digit in the type constraint with param 2');
    $pass = 'a1&';
    $result = password_policy_constraint_complexity_validate($pass, $constraint, $uid);
    $this
      ->assertTrue($result, 'One letter, one digit and one punctuation in the type constraint with param 2');
  }
  function testUsernameConstraint() {
    module_load_include('inc', 'password_policy', 'constraints/constraint_username');
    $constraint = 2;
    $user = $this
      ->drupalCreateUser();
    $name = $this
      ->randomName();
    $result = password_policy_constraint_username_validate($name, $constraint, $user->uid);
    $this
      ->assertTrue($result, 'Random string in the username constraint');
    $result = password_policy_constraint_username_validate($user->name, $constraint, $user->uid);
    $this
      ->assertFalse($result, 'Username in the username constraint');
    $result = password_policy_constraint_username_validate('foo' . $user->name . 'bar', $constraint, $user->uid);
    $this
      ->assertFalse($result, 'String containing username in the username constraint');
  }
  function testHistoryConstraint() {
    module_load_include('inc', 'password_policy', 'constraints/constraint_history');

    // Log in
    $user = $this
      ->drupalCreateUser(array(
      'administer site configuration',
    ));
    $this
      ->drupalLogin($user);

    // Create a policy
    $policy_name = $this
      ->randomName();
    $edit = array(
      'name' => $policy_name,
      'constraint_history' => t('2'),
      'roles[2]' => '2',
    );
    $this
      ->drupalPost('admin/settings/password_policy/add', $edit, t('Create'));
    $this
      ->assertText('Policy ' . $policy_name . ' has been created.', 'Policy ' . $policy_name . ' has been created');

    // Enable newly created policy
    $pid = db_result(db_query('SELECT pid FROM {password_policy} WHERE name="%s"', $policy_name));
    $constraints = unserialize(db_result(db_query('SELECT policy FROM {password_policy} WHERE pid=%d', $pid)));
    $this
      ->assertTrue($constraints['history'] == 2, t('Verified history constraint set.'));
    $edit = array(
      "enabled[{$pid}]" => $pid,
    );
    $this
      ->drupalPost('admin/settings/password_policy/list', $edit, t('Save changes'));
    $this
      ->assertText(t('The changes have been saved.'), t('Form submitted successfully.'));
    $enabled = db_result(db_query('SELECT enabled FROM {password_policy} WHERE pid=%d', $pid));
    $this
      ->assertTrue($enabled == 1, t('Policy enabled.'));

    // Change password
    $pass1 = "aaaaaa";
    $edit = array(
      'pass[pass1]' => $pass1,
      'pass[pass2]' => $pass1,
    );
    $this
      ->drupalPost("user/{$user->uid}/edit", $edit, t('Save'));
    $this
      ->assertText(t('The changes have been saved.'), t("1st password change: {$pass1}"));

    // Change password second time
    $pass2 = "bbbbbb";
    $edit = array(
      'pass[pass1]' => $pass1,
      'pass[pass2]' => $pass1,
    );
    $this
      ->drupalPost("user/{$user->uid}/edit", $edit, t('Save'));
    $this
      ->assertText(t('Your password has not met the following requirement(s):'), t("2nd password change should fail: {$pass1}"));

    // Try changing password with the first one
    $edit = array(
      'pass[pass1]' => $pass2,
      'pass[pass2]' => $pass2,
    );
    $this
      ->drupalPost("user/{$user->uid}/edit", $edit, t('Save'));
    $this
      ->assertText(t('The changes have been saved.'), t("3rd password change should pass: {$pass2}"));

    // Change password again
    $pass3 = "cccccc";
    $edit = array(
      'pass[pass1]' => $pass3,
      'pass[pass2]' => $pass3,
    );
    $this
      ->drupalPost("user/{$user->uid}/edit", $edit, t('Save'));
    $this
      ->assertText(t('The changes have been saved.'), t("4th password change should pass: {$pass3}"));

    // Delete test policy
    $this
      ->drupalPost('admin/settings/password_policy/delete/' . $pid, array(), t('Delete'));
    $this
      ->assertText('Password policy ' . $policy_name . ' was deleted.', 'Default password policy ' . $policy_name . 'was deleted');
  }
  function testDigitPlacementConstraint() {
    module_load_include('inc', 'password_policy', 'constraints/constraint_digit_placement');
    $constraint = 0;
    $uid = 0;
    $pass = 'ILove2Password';
    $result = password_policy_constraint_digit_placement_validate($pass, $constraint, $uid);
    $this
      ->assertTrue($result, 'One numeric character in the digit placement constraint with param 0');
    $pass = 'ILovePassword2';
    $result = password_policy_constraint_digit_placement_validate($pass, $constraint, $uid);
    $this
      ->assertTrue($result, 'One numeric character in the digit placement constraint with param 0');
    $constraint = 1;
    $pass = 'ILove2Password';
    $result = password_policy_constraint_digit_placement_validate($pass, $constraint, $uid);
    $this
      ->assertTrue($result, 'One numeric character in the digit placement constraint with param 1');
    $pass = 'ILovePassword2';
    $result = password_policy_constraint_digit_placement_validate($pass, $constraint, $uid);
    $this
      ->assertTrue($result, 'One numeric character in the digit placement constraint with param 1');
    $constraint = 2;
    $pass = 'ILove2Password';
    $result = password_policy_constraint_digit_placement_validate($pass, $constraint, $uid);
    $this
      ->assertTrue($result, 'One numeric character in the digit placement constraint with param 2');
    $pass = 'ILovePassword2';
    $result = password_policy_constraint_digit_placement_validate($pass, $constraint, $uid);
    $this
      ->assertFalse($result, 'One numeric character in the digit placement constraint with param 2');
    $pass = '1LovePassword';
    $result = password_policy_constraint_digit_placement_validate($pass, $constraint, $uid);
    $this
      ->assertFalse($result, 'One numeric character in the digit placement constraint with param 2');
    $pass = '1LovePassword2';
    $result = password_policy_constraint_digit_placement_validate($pass, $constraint, $uid);
    $this
      ->assertTrue($result, 'One numeric character in the digit placement constraint with param 2');
    $pass = 'ILove2Password3';
    $result = password_policy_constraint_digit_placement_validate($pass, $constraint, $uid);
    $this
      ->assertTrue($result, 'One numeric character in the digit placement constraint with param 2');
  }

}
class PasswordPolicyForcePasswordChangeTestCase extends DrupalWebTestCase {
  protected $admin_user;
  public static function getInfo() {
    return array(
      'name' => 'Forced password changes',
      'description' => 'Test forced password changes for single user, role, and all new users.',
      'group' => 'Password Policy',
    );
  }
  public function setUp() {
    if (defined('USER_LOAD_PHPASS_PATCHED')) {
      parent::setUp('password_policy', 'phpass');
    }
    else {
      parent::setUp('password_policy');
    }
  }

  // test permissions
  public function testPerms() {

    // no perms
    $user = $this
      ->drupalCreateUser();
    $this
      ->drupalLogin($user);
    $this
      ->drupalGet('admin/settings/password_policy/password_change');
    $this
      ->assertResponse('403', t('Acces should be denied.'));
    $this
      ->drupalLogout();

    // with perms
    $user = $this
      ->drupalCreateUser(array(
      'force password change',
    ));
    $this
      ->drupalLogin($user);
    $this
      ->drupalGet('admin/settings/password_policy/password_change');
    $this
      ->assertResponse('200', t('Access should be granted.'));
    $this
      ->drupalLogout();
  }

  // test form elements
  public function testForms() {

    // test admin form
    $user = $this
      ->drupalCreateUser(array(
      'force password change',
      'administer users',
    ));
    $this
      ->drupalLogin($user);
    $this
      ->drupalGet('admin/settings/password_policy/password_change');
    $this
      ->assertFieldByName('password_policy_new_login_change', '', t('Found first time login change checkbox.'));
    $this
      ->assertFieldByName('password_policy_force_change_roles[2]', '', t('Found roles checkboxes.'));
    $this
      ->assertFieldById('edit-submit', '', t('Found submit button.'));

    // test user edit form with perms
    $this
      ->drupalGet("user/{$user->uid}/edit");
    $this
      ->assertFieldByName('force_password_change', '', 'Force password change checkbox is visible to admin.');
    $this
      ->drupalLogout();

    // test user edit form without perms
    $user = $this
      ->drupalCreateUser();
    $this
      ->drupalLogin($user);
    $this
      ->drupalGet("user/{$user->uid}/edit");
    $this
      ->assertNoFieldByName('force_password_change', '', 'Force password change checkbox is hidden for normal users.');
    $this
      ->drupalLogout();
  }

  // test single user password change
  public function testSingleUser() {
    $admin = $this
      ->drupalCreateUser(array(
      'force password change',
      'administer users',
    ));
    $user = $this
      ->drupalCreateUser();
    $this
      ->drupalLogin($admin);
    $edit = array(
      'force_password_change' => TRUE,
    );
    $this
      ->drupalPost("user/{$user->uid}/edit", $edit, t('Save'));
    $this
      ->assertRaw(t('!user will be required to change their password the next time they log in.', array(
      '!user' => $user->name,
    )), t('User flagged for password change.'));
    $force_change = db_result(db_query('SELECT force_change FROM {password_policy_force_change} WHERE uid=%d', $user->uid));
    $this
      ->assertTrue($force_change == 1, t('Force change flag set to %d for %s.', array(
      '%d' => $force_change,
      '%s' => $user->name,
    )));

    //confirm admin can edit user account without changing password
    $edit = array(
      'name' => $user->name,
      'mail' => $user->mail,
      'force_password_change' => TRUE,
    );
    $this
      ->drupalPost("user/{$user->uid}/edit", $edit, t('Save'));
    $force_change = db_result(db_query('SELECT force_change FROM {password_policy_force_change} WHERE uid=%d', $user->uid));
    $this
      ->assertTrue($force_change == 1, t('User force change flag set in database:%s.', array(
      '%s' => $force_change,
    )));
    $this
      ->assertNoRaw(t('Your password has expired. You must change your password to proceed on the site.'), t('Admin can edit user account without changing password.'));
    $this
      ->drupalLogout();

    // verify user is forced to change password
    $this
      ->drupalLogin($user);
    $this
      ->assertFieldByName('mail', '', t('User redirected correctly.'));

    // marginal
    $this
      ->assertRaw(t('Your password has expired. You must change your password to proceed on the site.'), t('User presented with error instructing them to change their password.'));

    // attempt to change password
    $edit = array(
      'mail' => $user->mail,
      'pass[pass1]' => 'random_string',
      'pass[pass2]' => 'random_string',
    );
    $this
      ->drupalPost("user/{$user->uid}/edit", $edit, t('Save'));
    $this
      ->assertRaw(t('The changes have been saved.'), t('Password change successful.'));

    // verify user not prompted to change password a 2nd time
    $this
      ->drupalGet('node');
    $this
      ->assertNoFieldByName('mail', '', t('User not forced to change password a 2nd time.'));
    $this
      ->drupalLogout();
  }

  // test role-based password change
  public function testRoleChange() {
    $admin = $this
      ->drupalCreateUser(array(
      'administer users',
      'force password change',
    ));
    $user1 = $this
      ->drupalCreateUser();
    $user2 = $this
      ->drupalCreateUser();
    $this
      ->drupalLogin($admin);
    $edit = array(
      'password_policy_force_change_roles[2]' => 2,
    );
    $this
      ->drupalPost('admin/settings/password_policy/password_change', $edit, t('Submit'));
    $this
      ->assertText(t('Users in the following roles will be required to immediately change their password: authenticated user'), t('Authenticated users role selected.'));
    $this
      ->assertTrue($admin->uid != 1, t("Admin uid not 1: {$admin->uid}"));
    $this
      ->assertRaw(t('Your password has expired. You must change your password to proceed on the site.'), t('Admin (not uid 1) correctly forced to change password.'));

    // test db flags for individual users
    $entry_1 = db_result(db_query('SELECT uid FROM {password_policy_force_change} WHERE uid=%d', $user1->uid));
    $this
      ->assertTrue($entry_1 == $user1->uid, t("Entry created in password_policy_force_change for user {$user1->uid}."));
    $flag_1 = db_result(db_query('SELECT force_change FROM {password_policy_force_change} WHERE uid=%d', $user1->uid));
    $this
      ->assertTrue($flag_1 == 1, t("User {$user1->uid} flagged: {$flag_1}."));
    $this
      ->drupalLogout();

    //test individual users
    $this
      ->drupalLogin($user1);
    $this
      ->drupalGet('node');
    $this
      ->assertRaw(t('Your password has expired. You must change your password to proceed on the site.'), t('First test user forced to change password.'));
    $this
      ->drupalLogout();

    //test 2nd user
    $this
      ->drupalLogin($user2);
    $this
      ->assertRaw(t('Your password has expired. You must change your password to proceed on the site.'), t('Second test user forced to change password.'));
    $this
      ->drupalLogout();
  }

  //test new user change
  public function testNewUserChange() {
    $admin = $this
      ->drupalCreateUser(array(
      'administer users',
      'force password change',
    ));
    $this
      ->drupalLogin($admin);
    $edit = array(
      'password_policy_new_login_change' => TRUE,
    );
    $this
      ->drupalPost('admin/settings/password_policy/password_change', $edit, t('Submit'));
    $this
      ->assertRaw(t('New users will be required to change their password on first-time login.'), t('New users required to change password on 1st login.'));
    $this
      ->drupalLogout();
    $user = $this
      ->drupalCreateUser();
    $this
      ->drupalLogin($user);
    $this
      ->drupalGet('node');
    $this
      ->assertRaw(t('Your password has expired. You must change your password to proceed on the site.'), t('New user forced to change password.'));
  }

  //test admin forcing their own account to reset
  public function testSelfChange() {
    $admin = $this
      ->drupalCreateUser(array(
      'administer users',
      'force password change',
    ));
    $this
      ->drupalLogin($admin);
    $this
      ->assertNoRaw(t('Your password has expired. You must change your password to proceed on the site.'), t('Admin should not be prompted to change password yet.'));
    $edit = array(
      'force_password_change' => TRUE,
    );
    $this
      ->drupalPost("user/{$admin->uid}/edit", $edit, t('Save'));
    $this
      ->assertRaw(t('The changes have been saved.'), t('Admin has queued account for password change.'));
    $this
      ->assertNoRaw(t('Your password has expired. You must change your password to proceed on the site.'), t('Admin not initially prompted to change password.'));
    $this
      ->drupalGet('node');
    $this
      ->assertRaw(t('Your password has expired. You must change your password to proceed on the site.'), t('Admin forced to change password once they try to leave account page.'));
    $edit = array(
      'mail' => $admin->mail,
      'pass[pass1]' => 'fpcR@nd0m!',
      'pass[pass2]' => 'fpcR@nd0m!',
    );
    $this
      ->drupalPost("user/{$admin->uid}/edit", $edit, t('Save'));
    $this
      ->assertRaw(t('The changes have been saved.'), t('Admin changed password.'));
    $this
      ->drupalGet('node');
    $this
      ->assertNoRaw(t('Your password has expired. You must change your password to proceed on the site.'), t('Not prompted to change password a 2nd time.'));
  }

  /**
   * Test unforcing a password change.
   */
  public function testUnforceChange() {
    $admin = $this
      ->drupalCreateUser(array(
      'force password change',
      'administer users',
    ));
    $user = $this
      ->drupalCreateUser();
    $this
      ->drupalLogin($admin);

    // Force a password change.
    $edit = array(
      'force_password_change' => TRUE,
    );
    $this
      ->drupalPost("user/{$user->uid}/edit", $edit, t('Save'));
    $this
      ->assertRaw(t('!user will be required to change their password the next time they log in.', array(
      '!user' => $user->name,
    )), t('User flagged for password change.'));

    // Unforce the password change.
    $edit = array(
      'force_password_change' => FALSE,
    );
    $this
      ->drupalPost("user/{$user->uid}/edit", $edit, t('Save'));
    $force_change = db_result(db_query('SELECT force_change FROM {password_policy_force_change} WHERE uid=%d', $user->uid));
    $this
      ->assertTrue($force_change == 0, t('Force change flag set to %d for %s.', array(
      '%d' => $force_change,
      '%s' => $user->name,
    )));
  }

}

Classes

Namesort descending Description
PasswordPolicyForcePasswordChangeTestCase
PasswordPolicyTestCase @file Unit tests for Password policy module.