t('User registration'), 'description' => t('Registers a user, fails login, resets password, successfully logs in with the one time password, changes password, logs out, successfully logs in with the new password, visits profile page.'), 'group' => t('User') ); } /** * Registers a user, fails login, resets password, successfully logs in with the one time password, * changes password, logs out, successfully logs in with the new password, visits profile page. * * Assumes that the profile module is disabled. */ function testUserRegistration() { // Set user registration to "Visitors can create accounts and no administrator approval is required." variable_set('user_register', 1); // Enable user configurable timezone, and set the default timezone to +1 hour (or +3600 seconds). variable_set('configurable_timezones', 1); variable_set('date_default_timezone', 3600); $edit = array(); $edit['name'] = $name = $this->randomName(); $edit['mail'] = $mail = $edit['name'] . '@example.com'; $this->drupalPost('user/register', $edit, t('Create new account')); $this->assertText(t('Your password and further instructions have been sent to your e-mail address.'), t('User registered successfully.')); // Check database for created user. $user = user_load($edit); $this->assertTrue($user, t('User found in database.')); $this->assertTrue($user->uid > 0, t('User has valid user id.')); // Check user fields. $this->assertEqual($user->name, $name, t('Username matches.')); $this->assertEqual($user->mail, $mail, t('E-mail address matches.')); $this->assertEqual($user->theme, '', t('Correct theme field.')); $this->assertEqual($user->signature, '', t('Correct signature field.')); $this->assertTrue(($user->created > REQUEST_TIME - 20 ), t('Correct creation time.')); $this->assertEqual($user->status, variable_get('user_register', 1) == 1 ? 1 : 0, t('Correct status field.')); $this->assertEqual($user->timezone, variable_get('date_default_timezone', NULL), t('Correct timezone field.')); $this->assertEqual($user->language, '', t('Correct language field.')); $this->assertEqual($user->picture, '', t('Correct picture field.')); $this->assertEqual($user->init, $mail, t('Correct init field.')); // Attempt to login with incorrect password. $edit = array(); $edit['name'] = $name; $edit['pass'] = 'foo'; $this->drupalPost('user', $edit, t('Log in')); $this->assertText(t('Sorry, unrecognized username or password. Have you forgotten your password?'), t('Invalid login attempt failed.')); // Login using password reset page. $url = user_pass_reset_url($user); sleep(1); // TODO Find better way. $this->drupalGet($url); $this->assertText(t('This login can be used only once.'), t('Login can be used only once.')); $this->drupalPost(NULL, NULL, t('Log in')); $this->assertText(t('You have just used your one-time login link. It is no longer necessary to use this link to login. Please change your password.'), t('This link is no longer valid.')); // Change user password. $new_pass = user_password(); $edit = array(); $edit['pass[pass1]'] = $new_pass; $edit['pass[pass2]'] = $new_pass; $this->drupalPost(NULL, $edit, t('Save')); $this->assertText(t('The changes have been saved.'), t('Password changed to @password', array('@password' => $new_pass))); // Make sure password changes are present in database. require_once DRUPAL_ROOT . '/' . variable_get('password_inc', 'includes/password.inc'); $user = user_load(array('uid' => $user->uid)); $this->assertTrue(user_check_password($new_pass, $user), t('Correct password in database.')); // Logout of user account. $this->clickLink(t('Log out')); $this->assertNoText($user->name, t('Logged out.')); // Login user. $edit = array(); $edit['name'] = $user->name; $edit['pass'] = $new_pass; $this->drupalPost('user', $edit, t('Log in')); $this->assertText(t('Log out'), t('Logged in.')); $this->assertText($user->name, t('[logged in] Username found.')); $this->assertNoText(t('Sorry. Unrecognized username or password.'), t('[logged in] No message for unrecognized username or password.')); $this->assertNoText(t('User login'), t('[logged in] No user login form present.')); $this->drupalGet('user'); $this->assertText($user->name, t('[user auth] Not login page.')); $this->assertText(t('View'), t('[user auth] Found view tab on the profile page.')); $this->assertText(t('Edit'), t('[user auth] Found edit tab on the profile page.')); } } class UserValidationTestCase extends DrupalWebTestCase { /** * Implementation of getInfo(). */ function getInfo() { return array( 'name' => t('Username/e-mail validation'), 'description' => t('Verify that username/email validity checks behave as designed.'), 'group' => t('User') ); } // Username validation. function testUsernames() { $test_cases = array( // '' => array('', 'assert'), 'foo' => array('Valid username', 'assertNull'), 'FOO' => array('Valid username', 'assertNull'), 'Foo O\'Bar' => array('Valid username', 'assertNull'), 'foo@bar' => array('Valid username', 'assertNull'), 'foo@example.com' => array('Valid username', 'assertNull'), 'foo@-example.com' => array('Valid username', 'assertNull'), // invalid domains are allowed in usernames 'þòøÇߪř€' => array('Valid username', 'assertNull'), 'ᚠᛇᚻ᛫ᛒᛦᚦ' => array('Valid UTF8 username', 'assertNull'), // runes ' foo' => array('Invalid username that starts with a space', 'assertNotNull'), 'foo ' => array('Invalid username that ends with a space', 'assertNotNull'), 'foo bar' => array('Invalid username that contains 2 spaces \'  \'', 'assertNotNull'), '' => array('Invalid empty username', 'assertNotNull'), 'foo/' => array('Invalid username containing invalid chars', 'assertNotNull'), 'foo' . chr(0) . 'bar' => array('Invalid username containing chr(0)', 'assertNotNull'), // NULL 'foo' . chr(13) . 'bar' => array('Invalid username containing chr(13)', 'assertNotNull'), // CR str_repeat('x', USERNAME_MAX_LENGTH + 1) => array('Invalid excessively long username', 'assertNotNull'), ); foreach ($test_cases as $name => $test_case) { list($description, $test) = $test_case; $result = user_validate_name($name); $this->$test($result, $description . ' ('. $name . ')'); } } // Mail validation. More extensive tests can be found at common.test function testMailAddresses() { $test_cases = array( // '' => array('', 'assert'), '' => array('Empty mail address', 'assertNotNull'), 'foo' => array('Invalid mail address', 'assertNotNull'), 'foo@example.com' => array('Valid mail address', 'assertNull'), ); foreach ($test_cases as $name => $test_case) { list($description, $test) = $test_case; $result = user_validate_mail($name); $this->$test($result, $description . ' (' . $name . ')'); } } } class UserDeleteTestCase extends DrupalWebTestCase { /** * Implementation of getInfo(). */ function getInfo() { return array( 'name' => t('User delete'), 'description' => t('Registers a user and deletes it.'), 'group' => t('User') ); } /** * Registers a user and deletes it. */ function testUserRegistration() { // Set user registration to "Visitors can create accounts and no administrator approval is required." variable_set('user_register', 1); $edit = array(); $edit['name'] = $this->randomName(); $edit['mail'] = $edit['name'] . '@example.com'; $this->drupalPost('user/register', $edit, t('Create new account')); $this->assertText(t('Your password and further instructions have been sent to your e-mail address.'), t('User registered successfully.')); $user = user_load($edit); // Create admin user to delete registered user. $admin_user = $this->drupalCreateUser(array('administer users')); $this->drupalLogin($admin_user); // Delete user. $this->drupalGet('user/' . $user->uid . '/edit'); $this->drupalPost(NULL, NULL, t('Delete')); $this->assertRaw(t('Are you sure you want to delete the account %name?', array('%name' => $user->name)), t('[confirm deletion] Asks for confirmation.')); $this->assertText(t('All submissions made by this user will be attributed to the anonymous account. This action cannot be undone.'), t('[confirm deletion] Inform that all submissions will be attributed to anonymouse account.')); // Confirm deletion. $this->drupalPost(NULL, NULL, t('Delete')); $this->assertRaw(t('%name has been deleted.', array('%name' => $user->name)), t('User deleted')); $this->assertFalse(user_load($edit), t('User is not found in the database')); } } class UserPictureTestCase extends DrupalWebTestCase { protected $user; protected $_directory_test; function getInfo() { return array( 'name' => t('Upload user picture'), 'description' => t('Assure that dimension check, extension check and image scaling work as designed.'), 'group' => t('User') ); } function setUp() { parent::setUp(); // Enable user pictures. variable_set('user_pictures', 1); $this->user = $this->drupalCreateUser(); // Test if directories specified in settings exist in filesystem. $file_dir = file_directory_path(); $file_check = file_check_directory($file_dir, FILE_CREATE_DIRECTORY, 'file_directory_path'); $picture_dir = variable_get('user_picture_path', 'pictures'); $picture_path = $file_dir .'/'.$picture_dir; $pic_check = file_check_directory($picture_path, FILE_CREATE_DIRECTORY, 'user_picture_path'); $this->_directory_test = is_writable($picture_path); $this->assertTrue($this->_directory_test, "The directory $picture_path doesn't exist or is not writable. Further tests won't be made."); } function testNoPicture() { $this->drupalLogin($this->user); // Try to upload a file that is not an image for the user picture. $not_an_image = current($this->drupalGetTestFiles('html')); $this->saveUserPicture($not_an_image); $this->assertRaw(t('Only JPEG, PNG and GIF images are allowed.'), t('Non-image files are not accepted.')); } /** * Do the test: * GD Toolkit is installed * Picture has invalid dimension * * results: The image should be uploaded because ImageGDToolkit resizes the picture */ function testWithGDinvalidDimension() { if ($this->_directory_test) if (image_get_toolkit()) { $this->drupalLogin($this->user); $image = current($this->drupalGetTestFiles('image')); $info = image_get_info($image->filename); // Set new variables: invalid dimensions, valid filesize (0 = no limit). $test_dim = ($info['width'] - 10) . 'x' . ($info['height'] - 10); variable_set('user_picture_dimensions', $test_dim); variable_set('user_picture_file_size', 0); $pic_path = $this->saveUserPicture($image); // Check that the image was resized and is being displayed on the // user's profile page. $text = t('The image was resized to fit within the maximum allowed dimensions of %dimensions pixels.', array('%dimensions' => $test_dim)); $this->assertRaw($text, t('Image was resized.')); $this->assertRaw(file_create_url($pic_path), t("Image is displayed in user's profile page")); // Check if file is located in proper directory. $this->assertTrue(is_file($pic_path), t("File is located in proper directory")); } } /** * Do the test: * GD Toolkit is installed * Picture has invalid size * * results: The image should be uploaded because ImageGDToolkit resizes the picture */ function testWithGDinvalidSize() { if ($this->_directory_test) if (image_get_toolkit()) { $this->drupalLogin($this->user); $image = current($this->drupalGetTestFiles('image')); $info = image_get_info($image->filename); // Set new variables: valid dimensions, invalid filesize. $test_dim = ($info['width'] + 10) . 'x' . ($info['height'] + 10); $test_size = 1; variable_set('user_picture_dimensions', $test_dim); variable_set('user_picture_file_size', $test_size); $pic_path = $this->saveUserPicture($image); // Test that the upload failed and that the correct reason was cited. $text = t('The specified file %filename could not be uploaded.', array('%filename' => $image->basename)); $this->assertRaw($text, t('Upload failed.')); $text = t('The file is %filesize exceeding the maximum file size of %maxsize.', array('%filesize' => format_size(filesize($image->filename)), '%maxsize' => format_size($test_size * 1024))); $this->assertRaw($text, t('File size cited as reason for failure.')); // Check if file is not uploaded. $this->assertFalse(is_file($pic_path), t('File was not uploaded.')); } } /** * Do the test: * GD Toolkit is not installed * Picture has invalid size * * results: The image shouldn't be uploaded */ function testWithoutGDinvalidDimension() { if ($this->_directory_test) if (!image_get_toolkit()) { $this->drupalLogin($this->user); $image = current($this->drupalGetTestFiles('image')); $info = image_get_info($image->filename); // Set new variables: invalid dimensions, valid filesize (0 = no limit). $test_dim = ($info['width'] - 10) . 'x' . ($info['height'] - 10); variable_set('user_picture_dimensions', $test_dim); variable_set('user_picture_file_size', 0); $pic_path = $this->saveUserPicture($image); // Test that the upload failed and that the correct reason was cited. $text = t('The specified file %filename could not be uploaded.', array('%filename' => $image->basename)); $this->assertRaw($text, t('Upload failed.')); $text = t('The image is too large; the maximum dimensions are %dimensions pixels.', array('%dimensions' => $test_dim)); $this->assertRaw($text, t('Checking response on invalid image (dimensions).')); // Check if file is not uploaded. $this->assertFalse(is_file($pic_path), t('File was not uploaded.')); } } /** * Do the test: * GD Toolkit is not installed * Picture has invalid size * * results: The image shouldn't be uploaded */ function testWithoutGDinvalidSize() { if ($this->_directory_test) if (!image_get_toolkit()) { $this->drupalLogin($this->user); $image = current($this->drupalGetTestFiles('image')); $info = image_get_info($image->filename); // Set new variables: valid dimensions, invalid filesize. $test_dim = ($info['width'] + 10) . 'x' . ($info['height'] + 10); $test_size = 1; variable_set('user_picture_dimensions', $test_dim); variable_set('user_picture_file_size', $test_size); $pic_path = $this->saveUserPicture($image); // Test that the upload failed and that the correct reason was cited. $text = t('The specified file %filename could not be uploaded.', array('%filename' => $image->basename)); $this->assertRaw($text, t('Upload failed.')); $text = t('The file is %filesize exceeding the maximum file size of %maxsize.', array('%filesize' => format_size(filesize($image->filename)), '%maxsize' => format_size($test_size * 1024))); $this->assertRaw($text, t('File size cited as reason for failure.')); // Check if file is not uploaded. $this->assertFalse(is_file($pic_path), t('File was not uploaded.')); } } /** * Do the test: * Picture is valid (proper size and dimension) * * results: The image should be uploaded */ function testPictureIsValid() { if ($this->_directory_test) { $this->drupalLogin($this->user); $image = current($this->drupalGetTestFiles('image')); $info = image_get_info($image->filename); // Set new variables: valid dimensions, valid filesize (0 = no limit). $test_dim = ($info['width'] + 10) . 'x' . ($info['height'] + 10); variable_set('user_picture_dimensions', $test_dim); variable_set('user_picture_file_size', 0); $pic_path = $this->saveUserPicture($image); // check if image is displayed in user's profile page $this->assertRaw($pic_path, t("Image is displayed in user's profile page")); // check if file is located in proper directory $this->assertTrue(is_file($pic_path), t('File is located in proper directory')); } } function saveUserPicture($image) { $edit = array('files[picture_upload]' => realpath($image->filename)); $this->drupalPost('user/' . $this->user->uid.'/edit', $edit, t('Save')); $img_info = image_get_info($image->filename); $picture_dir = variable_get('user_picture_path', 'pictures'); $pic_path = file_directory_path() . '/' . $picture_dir . '/picture-' . $this->user->uid . '.' . $img_info['extension']; return $pic_path; } } class UserPermissionsTestCase extends DrupalWebTestCase { protected $admin_user; protected $rid; /** * Implementation of getInfo(). */ function getInfo() { return array( 'name' => t('Role permissions'), 'description' => t('Verify that role permissions can be added and removed via the permissions page.'), 'group' => t('User') ); } function setUp() { parent::setUp(); $this->admin_user = $this->drupalCreateUser(array('administer permissions', 'access user profiles')); // Find the new role ID - it must be the maximum. $all_rids = array_keys($this->admin_user->roles); sort($all_rids); $this->rid = array_pop($all_rids); } /** * Change user permissions and check user_access(). */ function testUserPermissionChanges() { $this->drupalLogin($this->admin_user); $rid = $this->rid; $account = $this->admin_user; // Add a permission. $this->assertFalse(user_access('administer nodes', $account, TRUE), t('User does not have "administer nodes" permission.')); $edit = array(); $edit[$rid . '[administer nodes]'] = TRUE; $this->drupalPost('admin/user/permissions', $edit, t('Save permissions')); $this->assertText(t('The changes have been saved.'), t('Successful save message displayed.')); $this->assertTrue(user_access('administer nodes', $account, TRUE), t('User now has "administer nodes" permission.')); // Remove a permission. $this->assertTrue(user_access('access user profiles', $account, TRUE), t('User has "access user profiles" permission.')); $edit = array(); $edit[$rid . '[access user profiles]'] = FALSE; $this->drupalPost('admin/user/permissions', $edit, t('Save permissions')); $this->assertText(t('The changes have been saved.'), t('Successful save message displayed.')); $this->assertFalse(user_access('access user profiles', $account, TRUE), t('User no longer has "access user profiles" permission.')); } } class UserAdminTestCase extends DrupalWebTestCase { /** * Implementation of getInfo(). */ function getInfo() { return array( 'name' => t('User admininstration'), 'description' => t('Test user admininstration page functionality.'), 'group' => t('User') ); } /** * Registers a user and deletes it. */ function testUserAdmin() { $user_a = $this->drupalCreateUser(array()); $user_b = $this->drupalCreateUser(array('administer taxonomy')); $user_c = $this->drupalCreateUser(array('administer taxonomy')); // Create admin user to delete registered user. $admin_user = $this->drupalCreateUser(array('administer users')); $this->drupalLogin($admin_user); $this->drupalGet('admin/user/user'); $this->assertText($user_a->name, t('Found user A on admin users page')); $this->assertText($user_b->name, t('Found user B on admin users page')); $this->assertText($user_c->name, t('Found user C on admin users page')); $this->assertText($admin_user->name, t('Found Admin user on admin users page')); // Filter the users by permission 'administer taxonomy'. $edit = array(); $edit['filter'] = 'permission'; $edit['permission'] = 'administer taxonomy'; $this->drupalPost('admin/user/user', $edit, t('Filter')); // Check if the correct users show up. $this->assertNoText($user_a->name, t('User A not on filtered by perm admin users page')); $this->assertText($user_b->name, t('Found user B on filtered by perm admin users page')); $this->assertText($user_c->name, t('Found user C on filtered by perm admin users page')); // Test blocking of a user. $account = user_load(array('name' => $user_b->name)); $this->assertEqual($account->status, 1, 'User B not blocked'); $edit = array(); $edit['operation'] = 'block'; $edit['accounts['. $account->uid .']'] = TRUE; $this->drupalPost('admin/user/user', $edit, t('Update')); $account = user_load(array('name' => $user_b->name)); $this->assertEqual($account->status, 0, 'User B blocked'); } } /** * Test user autocompletion. */ class UserAutocompleteTestCase extends DrupalWebTestCase { /** * Implementation of getInfo(). */ function getInfo() { return array( 'name' => t('User autocompletion'), 'description' => t('Test user autocompletion functionality.'), 'group' => t('User') ); } /** * Implementation of setUp(). */ function setUp() { parent::setUp(); // Set up two users with different permissions to test access. $this->unprivileged_user = $this->drupalCreateUser(); $this->privileged_user = $this->drupalCreateUser(array('access user profiles')); } /** * Tests access to user autocompletion and verify the correct results. */ function testUserAutocomplete() { // Check access from unprivileged user, should be denied. $this->drupalLogin($this->unprivileged_user); $this->drupalGet('user/autocomplete/' . $this->unprivileged_user->name[0]); $this->assertResponse(403, t('Autocompletion access denied to user without permission.')); // Check access from privileged user. $this->drupalLogout(); $this->drupalLogin($this->privileged_user); $this->drupalGet('user/autocomplete/' . $this->unprivileged_user->name[0]); $this->assertResponse(200, t('Autocompletion access allowed.')); // Using first letter of the user's name, make sure the user's full name is in the results. $this->assertRaw($this->unprivileged_user->name, t('User name found in autocompletion results.')); } }