Index: modules/node/node.module =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.module,v retrieving revision 1.1008 diff -u -p -r1.1008 node.module --- modules/node/node.module 31 Dec 2008 12:02:22 -0000 1.1008 +++ modules/node/node.module 2 Jan 2009 01:17:08 -0000 @@ -1478,9 +1478,24 @@ function node_ranking() { /** * Implementation of hook_user_delete(). */ -function node_user_delete(&$edit, &$user) { - db_query('UPDATE {node} SET uid = 0 WHERE uid = %d', $user->uid); - db_query('UPDATE {node_revision} SET uid = 0 WHERE uid = %d', $user->uid); +function node_user_delete(&$edit, &$account, $method) { + switch ($method) { + case USER_REMOVAL_BLOCK_UNPUBLISH: + db_update('node')->fields(array('status' => 0))->condition('uid', $account->uid)->execute(); + break; + + case USER_REMOVAL_ANONYMIZE: + db_update('node')->fields(array('uid' => 0))->condition('uid', $account->uid)->execute(); + db_update('node_revision')->fields(array('uid' => 0))->condition('uid', $account->uid)->execute(); + db_delete('history')->condition('uid', $account->uid)->execute(); + break; + + case USER_REMOVAL_DELETE: + db_delete('node')->condition('uid', $account->uid)->execute(); + db_delete('node_revision')->condition('uid', $account->uid)->execute(); + db_delete('history')->condition('uid', $account->uid)->execute(); + break; + } } /** Index: modules/user/user.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.admin.inc,v retrieving revision 1.33 diff -u -p -r1.33 user.admin.inc --- modules/user/user.admin.inc 16 Nov 2008 15:10:49 -0000 1.33 +++ modules/user/user.admin.inc 2 Jan 2009 02:29:40 -0000 @@ -235,6 +235,19 @@ function user_admin_settings() { $form['registration']['user_email_verification'] = array('#type' => 'checkbox', '#title' => t('Require e-mail verification when a visitor creates an account'), '#default_value' => variable_get('user_email_verification', TRUE), '#description' => t('If this box is checked, new users will be required to validate their e-mail address prior to logging into the site, and will be assigned a system-generated password. With it unchecked, users will be logged in immediately upon registering, and may select their own passwords during registration.')); $form['registration']['user_registration_help'] = array('#type' => 'textarea', '#title' => t('User registration guidelines'), '#default_value' => variable_get('user_registration_help', ''), '#description' => t('This text is displayed at the top of the user registration form and is useful for helping or instructing your users.')); + // User removal settings. + $form['removal'] = array( + '#type' => 'fieldset', + '#title' => t('User removal settings'), + ); + $form['removal']['user_removal_method'] = array( + '#type' => 'radios', + '#title' => t('Default account removal method'), + '#default_value' => variable_get('user_removal_method', USER_REMOVAL_BLOCK), + '#options' => user_removal_methods(), + '#description' => t('The default user account removal method applies to all users who choose to remove their accounts. Laws for certain countries, services, and audiences may require one of the listed options. Users with the %select-removal-method or %administer-users permissions are able to override the default method.', array('%select-removal-method' => t('Select removal method for own account'), '%administer-users' => t('Administer users'), '@permissions-url' => url('admin/user/permissions'))), + ); + // User e-mail settings. $form['email'] = array( '#type' => 'fieldset', @@ -243,7 +256,7 @@ function user_admin_settings() { ); // These email tokens are shared for all settings, so just define // the list once to help ensure they stay in sync. - $email_token_help = t('Available variables are:') . ' !username, !site, !password, !uri, !uri_brief, !mailto, !date, !login_uri, !edit_uri, !login_url.'; + $email_token_help = t('Available variables are:') . ' !username, !site, !password, !uri, !uri_brief, !mailto, !date, !login_uri, !edit_uri, !login_url, !remove_url.'; $form['email']['admin_created'] = array( '#type' => 'fieldset', @@ -375,6 +388,26 @@ function user_admin_settings() { '#rows' => 3, ); + $form['email']['removal'] = array( + '#type' => 'fieldset', + '#title' => t('Account removal email'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + '#description' => t('Customize e-mail messages sent to users when they attempt to remove their accounts.') . ' ' . $email_token_help, + ); + $form['email']['removal']['user_mail_removal_subject'] = array( + '#type' => 'textfield', + '#title' => t('Subject'), + '#default_value' => _user_mail_text('removal_subject'), + '#maxlength' => 180, + ); + $form['email']['removal']['user_mail_removal_body'] = array( + '#type' => 'textarea', + '#title' => t('Body'), + '#default_value' => _user_mail_text('removal_body'), + '#rows' => 3, + ); + $form['email']['deleted'] = array( '#type' => 'fieldset', '#title' => t('Account deleted email'), @@ -486,6 +519,66 @@ function user_admin_settings() { } /** + * Helper function to return user account removal methods. + * + * @param $account + * (optional) The user account to remove. + * @param $method + * (optional) The account removal method to use. + * @return + * If no argument is passed in, all account removal options are returned. If + * $account and optionally $method are passed, an array containing 'question' + * and 'description' for a confirmation form is returned. + * + * @see user_admin_settings() + * @see user_confirm_delete() + */ +function user_removal_methods($account = NULL, $method = NULL) { + global $user; + + if (!isset($account)) { + return array( + USER_REMOVAL_BLOCK => t('Disable user account and keep all contents.'), + USER_REMOVAL_BLOCK_UNPUBLISH => t('Disable user account and unpublish all contents.'), + USER_REMOVAL_ANONYMIZE => t('Remove user account and anonymize all contents.'), + USER_REMOVAL_DELETE => t('Remove user account and remove all contents.'), + ); + } + if (!isset($method)) { + return array( + 'question' => ($account->uid == $user->uid ? t('Are you sure you want to remove your account?') : t('Are you sure you want to remove the account %name?', array('%name' => $account->name))), + 'description' => t('Please select the account removal method above.'), + ); + } + switch ($method) { + case USER_REMOVAL_BLOCK: + default: + return array( + 'question' => ($account->uid == $user->uid ? t('Are you sure you want to disable your account?') : t('Are you sure you want to disable the account %name?', array('%name' => $account->name))), + 'description' => '', + ); + + case USER_REMOVAL_BLOCK_UNPUBLISH: + return array( + 'question' => ($account->uid == $user->uid ? t('Are you sure you want to disable your account?') : t('Are you sure you want to disable the account %name?', array('%name' => $account->name))), + 'description' => ($account->uid == $user->uid ? t('All your submissions will be unpublished.') : t('All submissions made by this user will be unpublished.')), + ); + + case USER_REMOVAL_ANONYMIZE: + return array( + 'question' => ($account->uid == $user->uid ? t('Are you sure you want to remove your account?') : t('Are you sure you want to remove the account %name?', array('%name' => $account->name))), + 'description' => ($account->uid == $user->uid ? t('All your submissions will be anonymized.') : t('All submissions made by this user will be attributed to the anonymous account.')), + ); + + case USER_REMOVAL_DELETE: + return array( + 'question' => ($account->uid == $user->uid ? t('Are you sure you want to remove your account?') : t('Are you sure you want to remove the account %name?', array('%name' => $account->name))), + 'description' => ($account->uid == $user->uid ? t('All your submissions will be deleted.') : t('All submissions made by this user will be deleted.')), + ); + } +} + +/** * Menu callback: administer permissions. * * @ingroup forms Index: modules/user/user.install =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.install,v retrieving revision 1.15 diff -u -p -r1.15 user.install --- modules/user/user.install 20 Nov 2008 06:56:17 -0000 1.15 +++ modules/user/user.install 1 Jan 2009 21:04:19 -0000 @@ -360,6 +360,19 @@ function user_update_7002(&$sandbox) { } /** + * Set default method for removing user accounts. + * + * Prior 7.x, users were not able to remove their accounts. When administrators + * deleted an account, all contents were assigned to uid 0 (Anonymous). + */ +function user_update_7003() { + $ret = array(); + require_once DRUPAL_ROOT . drupal_get_path('module', 'user') . '/user.admin.inc'; + variable_set('user_removal_method', USER_REMOVAL_ANONYMIZE); + return $ret; +} + +/** * @} End of "defgroup user-updates-6.x-to-7.x" * The next series of updates should start at 8000. */ Index: modules/user/user.module =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.module,v retrieving revision 1.951 diff -u -p -r1.951 user.module --- modules/user/user.module 30 Dec 2008 16:43:20 -0000 1.951 +++ modules/user/user.module 2 Jan 2009 04:50:13 -0000 @@ -17,6 +17,27 @@ define('USERNAME_MAX_LENGTH', 60); define('EMAIL_MAX_LENGTH', 64); /** + * User removal method: Disable user account and keep all contents. + */ +define('USER_REMOVAL_BLOCK', 0); + +/** + * User removal method: Disable user account and unpublish all contents. + */ +define('USER_REMOVAL_BLOCK_UNPUBLISH', 1); + +/** + * User removal method: Remove user account and anonymize all contents. + */ +define('USER_REMOVAL_ANONYMIZE', 2); + +/** + * User removal method: Remove user account and remove all contents. + */ +define('USER_REMOVAL_DELETE', 3); + + +/** * Invokes hook_user() in every module. * * We cannot use module_invoke() for this, because the arguments need to @@ -587,6 +608,14 @@ function user_perm() { 'title' => t('Change own username'), 'description' => t('Select a different username.'), ), + 'remove own account' => array( + 'title' => t('Remove or disable own account'), + 'description' => t('Remove or disable own user account and anonymize, unpublish or remove own submissions depending on the configured user settings.', array('@user-settings-url' => url('admin/user/settings'))), + ), + 'select account removal method' => array( + 'title' => t('Select removal method for own account'), + 'description' => t('Select the method for removing own user account.'), + ), ); } @@ -948,6 +977,13 @@ function user_edit_access($account) { return (($GLOBALS['user']->uid == $account->uid) || user_access('administer users')) && $account->uid > 0; } +/** + * Menu access callback; limit access to user delete/remove pages. + */ +function user_delete_access($account) { + return ((($GLOBALS['user']->uid == $account->uid) && user_access('remove own account')) || user_access('administer users')) && $account->uid > 0; +} + function user_load_self($arg) { $arg[1] = user_load($GLOBALS['user']->uid); return $arg; @@ -1086,8 +1122,17 @@ function user_menu() { 'title' => 'Delete', 'page callback' => 'drupal_get_form', 'page arguments' => array('user_confirm_delete', 1), - 'access callback' => 'user_access', - 'access arguments' => array('administer users'), + 'access callback' => 'user_delete_access', + 'access arguments' => array(1), + 'type' => MENU_CALLBACK, + ); + + $items['user/%user/remove'] = array( + 'title' => 'Account removal', + 'page callback' => 'user_remove', + 'page arguments' => array(1, 3, 4, 5), + 'access callback' => 'user_delete_access', + 'access arguments' => array(1), 'type' => MENU_CALLBACK, ); @@ -1445,6 +1490,19 @@ function user_pass_reset_url($account) { return url("user/reset/$account->uid/$timestamp/" . user_pass_rehash($account->pass, $timestamp, $account->login), array('absolute' => TRUE)); } +/** + * Generate a URL to confirm a user account removal. + * + * @see user_mail_tokens() + */ +function user_remove_url($account) { + if (!isset($account->user_removal_method)) { + $account->user_removal_method = variable_get('user_removal_method', USER_REMOVAL_BLOCK); + } + $timestamp = REQUEST_TIME; + return url("user/$account->uid/remove/$timestamp/{$account->user_removal_method}/" . user_pass_rehash($account->pass, $timestamp, $account->login), array('absolute' => TRUE)); +} + function user_pass_rehash($password, $timestamp, $login) { return md5($timestamp . $password . $login); } @@ -1597,19 +1655,48 @@ function _user_edit_submit($account, &$e /** * Delete a user. * - * @param $edit An array of submitted form values. - * @param $uid The user ID of the user to delete. + * @param $edit + * An array of submitted form values. + * @param $uid + * The user ID of the user to delete. + * @param $method + * The account removal method to use. */ -function user_delete($edit, $uid) { +function user_delete($edit, $uid, $method) { $account = user_load(array('uid' => $uid)); + + if (!$account) { + drupal_set_message(t('The user id %id does not exist.', array('%id' => $uid)), 'error'); + watchdog('user', 'Attempted to delete non-existing user id: %id.', array('%id' => $uid), WATCHDOG_ERROR); + return; + } + drupal_session_destroy_uid($uid); - _user_mail_notify('status_deleted', $account); - module_invoke_all('user_delete', $edit, $account); - db_query('DELETE FROM {users} WHERE uid = %d', $uid); - db_query('DELETE FROM {users_roles} WHERE uid = %d', $uid); - db_query('DELETE FROM {authmap} WHERE uid = %d', $uid); - $variables = array('%name' => $account->name, '%email' => '<' . $account->mail . '>'); - watchdog('user', 'Deleted user: %name %email.', $variables, WATCHDOG_NOTICE); + // @todo hook_user_delete is misleading for USER_REMOVAL_BLOCK* cases. + module_invoke_all('user_delete', $edit, $account, $method); + + switch ($method) { + case USER_REMOVAL_BLOCK: + case USER_REMOVAL_BLOCK_UNPUBLISH: + default: + db_update('users')->fields(array('status' => 0))->condition('uid', $uid)->execute(); + drupal_set_message(t('%name has been disabled.', array('%name' => $account->name))); + break; + + case USER_REMOVAL_ANONYMIZE: + case USER_REMOVAL_DELETE: + // Do not send account deleted notification if option was checked. + if (empty($edit['user_skip_mails'])) { + _user_mail_notify('status_deleted', $account); + } + db_delete('users')->condition('uid', $uid)->execute(); + db_delete('users_roles')->condition('uid', $uid)->execute(); + db_delete('authmap')->condition('uid', $uid)->execute(); + drupal_set_message(t('%name has been deleted.', array('%name' => $account->name))); + $variables = array('%name' => $account->name, '%email' => '<' . $account->mail . '>'); + watchdog('user', 'Deleted user: %name %email.', $variables, WATCHDOG_NOTICE); + break; + } } /** @@ -1682,6 +1769,20 @@ function _user_mail_text($key, $language return t('Account details for !username at !site (blocked)', $variables, $langcode); case 'status_blocked_body': return t("!username,\n\nYour account on !site has been blocked.", $variables, $langcode); + + case 'removal_subject': + return t('Account details for !username at !site (deleted)', $variables, $langcode); + case 'removal_body': + return t("!username, + +A request to remove your account has been made at !site. + +You may now remove your account on !uri_brief by clicking this link or copying and pasting it into your browser: + +!remove_url + +This link expires in one day and nothing will happen if it is not used.", $variables, $langcode); + case 'status_deleted_subject': return t('Account details for !username at !site (deleted)', $variables, $langcode); case 'status_deleted_body': @@ -1875,7 +1976,19 @@ function user_multiple_delete_confirm(&$ $user = db_result(db_query('SELECT name FROM {users} WHERE uid = %d', $uid)); $form['accounts'][$uid] = array('#type' => 'hidden', '#value' => $uid, '#prefix' => '
  • ', '#suffix' => check_plain($user) . "
  • \n"); } + $form['operation'] = array('#type' => 'hidden', '#value' => 'delete'); + $form['user_removal_method'] = array( + '#type' => 'radios', + '#title' => t('Account removal method'), + '#default_value' => variable_get('user_removal_method', USER_REMOVAL_BLOCK), + '#options' => user_removal_methods(), + ); + $form['user_skip_mails'] = array( + '#type' => 'checkbox', + '#title' => t('Do not send account deletion notification mails.'), + '#default_value' => FALSE, + ); return confirm_form($form, t('Are you sure you want to delete these users?'), @@ -1886,9 +1999,8 @@ function user_multiple_delete_confirm(&$ function user_multiple_delete_confirm_submit($form, &$form_state) { if ($form_state['values']['confirm']) { foreach ($form_state['values']['accounts'] as $uid => $value) { - user_delete($form_state['values'], $uid); + user_delete($form_state['values'], $uid, $form_state['values']['user_removal_method']); } - drupal_set_message(t('The users have been deleted.')); } $form_state['redirect'] = 'admin/user/user'; return; @@ -2085,6 +2197,7 @@ function user_mail_tokens($account, $lan '!username' => $account->name, '!site' => variable_get('site_name', 'Drupal'), '!login_url' => user_pass_reset_url($account), + '!remove_url' => user_remove_url($account), '!uri' => $base_url, '!uri_brief' => preg_replace('!^https?://!', '', $base_url), '!mailto' => $account->mail, Index: modules/user/user.pages.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.pages.inc,v retrieving revision 1.25 diff -u -p -r1.25 user.pages.inc --- modules/user/user.pages.inc 30 Dec 2008 16:43:20 -0000 1.25 +++ modules/user/user.pages.inc 2 Jan 2009 05:17:21 -0000 @@ -231,6 +231,7 @@ function user_edit($account, $category = * @see user_edit_delete_submit() */ function user_profile_form($form_state, $account, $category = 'account') { + global $user; $edit = (empty($form_state['values'])) ? (array)$account : $form_state['values']; @@ -238,7 +239,7 @@ function user_profile_form($form_state, $form['_category'] = array('#type' => 'value', '#value' => $category); $form['_account'] = array('#type' => 'value', '#value' => $account); $form['submit'] = array('#type' => 'submit', '#value' => t('Save'), '#weight' => 30); - if (user_access('administer users')) { + if (($account->uid == $user->uid && user_access('remove own account')) || user_access('administer users')) { $form['delete'] = array( '#type' => 'submit', '#value' => t('Delete'), @@ -301,13 +302,44 @@ function user_edit_delete_submit($form, * @see user_confirm_delete_submit() */ function user_confirm_delete(&$form_state, $account) { + global $user; $form['_account'] = array('#type' => 'value', '#value' => $account); + // Display account removal method selection, if allowed. + module_load_include('inc', 'user', 'user.admin'); + $default_method = variable_get('user_removal_method', USER_REMOVAL_BLOCK); + + if (user_access('select account removal method') || user_access('administer users')) { + extract(user_removal_methods($account)); + $form['user_removal_method'] = array( + '#type' => 'radios', + '#title' => t('Account removal method'), + '#default_value' => $default_method, + '#options' => user_removal_methods(), + '#required' => TRUE, + ); + } + else { + extract(user_removal_methods($account, $default_method)); + $form['user_removal_method'] = array('#type' => 'value', '#value' => $default_method); + } + + // Allow user account administrators to skip account removal confirmation and + // account deletion notification mails, as long as they do not attempt to + // remove their own accounts. + if (user_access('administer users') && $account->uid != $user->uid) { + $form['user_skip_mails'] = array( + '#type' => 'checkbox', + '#title' => t('Do not send account removal confirmation and account deletion notification e-mails.'), + '#default_value' => FALSE, + ); + } + return confirm_form($form, - t('Are you sure you want to delete the account %name?', array('%name' => $account->name)), + $question, 'user/' . $account->uid, - t('All submissions made by this user will be attributed to the anonymous account. This action cannot be undone.'), + $description . ' ' . t('This action cannot be undone.'), t('Delete'), t('Cancel')); } @@ -315,11 +347,56 @@ function user_confirm_delete(&$form_stat * Submit function for the confirm form for user deletion. */ function user_confirm_delete_submit($form, &$form_state) { - user_delete($form_state['values'], $form_state['values']['_account']->uid); - drupal_set_message(t('%name has been deleted.', array('%name' => $form_state['values']['_account']->name))); + global $user; + $account = $form_state['values']['_account']; - if (!isset($_REQUEST['destination'])) { - $form_state['redirect'] = 'admin/user/user'; + // Invoke user removal immediately, if the current user has administrative + // privileges; no confirmation/notification mails will be sent. + if (user_access('administer users') && !empty($form_state['values']['user_skip_mails'])) { + user_delete($form_state['values'], $account->uid, $form_state['values']['user_removal_method']); + + if (!isset($_REQUEST['destination'])) { + $form_state['redirect'] = 'admin/user/user'; + } + } + else { + // Store removal method in $account for user_remove_url(). + $account->user_removal_method = $form_state['values']['user_removal_method']; + _user_mail_notify('removal', $account); + drupal_set_message(t('An account removal confirmation request has been sent to your e-mail address.')); + + if (!isset($_REQUEST['destination'])) { + $form_state['redirect'] = "user/$account->uid"; + } + } +} + +/** + * Menu callback; Remove a user account through email confirmation. + * + * @see user_confirm_delete() + * @see user_remove_url() + */ +function user_remove($account, $timestamp, $method, $hashed_pass) { + // Time out in seconds until removal URL expires; 24 hours = 86400 seconds. + $timeout = 86400; + $current = REQUEST_TIME; + + // Basic validation of arguments. + if (!empty($timestamp) && !empty($hashed_pass)) { + // Validate expiration and hashed password/login. + if ($timestamp <= $current && $current - $timestamp < $timeout && $account->uid && /*$timestamp >= $account->login &&*/ $hashed_pass == user_pass_rehash($account->pass, $timestamp, $account->login)) { + $edit = array(); + user_delete($edit, $account->uid, $method); + drupal_goto(''); + } + else { + drupal_set_message(t('You have tried to use a one-time account removal link that has expired. Please request a new one using the form below.')); + drupal_goto("user/$account->uid/delete"); + } + } + else { + drupal_access_denied(); } } Index: modules/user/user.test =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.test,v retrieving revision 1.24 diff -u -p -r1.24 user.test --- modules/user/user.test 30 Dec 2008 16:43:20 -0000 1.24 +++ modules/user/user.test 2 Jan 2009 05:14:53 -0000 @@ -155,41 +155,80 @@ class UserValidationTestCase extends Dru class UserDeleteTestCase extends DrupalWebTestCase { function getInfo() { return array( - 'name' => t('User delete'), - 'description' => t('Registers a user and deletes it.'), + 'name' => t('User registration and removal'), + 'description' => t('Register users and deletes them.'), 'group' => t('User') ); } /** - * Registers a user and deletes it. + * Register a user. */ function testUserRegistration() { // Set user registration to "Visitors can create accounts and no administrator approval is required." variable_set('user_register', 1); + // Register user. $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.')); + $this->assertTrue(user_load($edit), t('User is found in the database')); + } - $user = user_load($edit); + /** + * Delete a user's account. + */ + function testUserDeletion() { + // Set user removal method to "Remove user account and anonymize all contents." + variable_set('user_removal_method', USER_REMOVAL_ANONYMIZE); - // Create admin user to delete registered user. + // Create a user. + $user = $this->drupalCreateUser(array('remove own account')); + $this->drupalLogin($user); + + // Attempt to delete user. + $this->drupalGet('user/' . $user->uid . '/edit'); + $this->drupalPost(NULL, NULL, t('Delete')); + $this->assertText(t('Are you sure you want to remove your account?'), t('[confirm deletion] Asks for confirmation.')); + $this->assertText(t('All submissions you made will be anonymized. This action cannot be undone.'), t('[confirm deletion] Inform that all submissions will be attributed to anonymous account.')); + + // Confirm deletion. + $this->drupalPost(NULL, NULL, t('Delete')); + $timestamp = REQUEST_TIME; + $this->assertText(t('An account removal confirmation request has been sent to your e-mail address.'), t('Account removal request mailed message displayed')); + + // Confirm removal request. + $this->drupalGet("user/$user->uid/remove/$timestamp/" . USER_REMOVAL_ANONYMIZE . '/' . user_pass_rehash($user->pass, $timestamp, $user->login)); + $this->assertRaw(t('%name has been deleted.', array('%name' => $user->name)), t('User deleted')); + $this->assertFalse(user_load(array('uid' => $user->uid)), t('User is not found in the database')); + } + + /** + * Create an administrative user and delete another user. + */ + function testUserDeletionByAdmin() { + // Set user removal method to "Remove user account and anonymize all contents." + variable_set('user_removal_method', USER_REMOVAL_ANONYMIZE); + + // Create a regular user. + $user = $this->drupalCreateUser(array()); + + // Create admin user to delete regular 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 anonymous account.')); + $this->assertRaw(t('Are you sure you want to remove the account %name?', array('%name' => $user->name)), t('[confirm deletion] Asks for confirmation.')); + $this->assertText(t('Please select the account removal method above. This action cannot be undone.'), t('[confirm deletion] Allows to select account removal method.')); // Confirm deletion. - $this->drupalPost(NULL, NULL, t('Delete')); + $this->drupalPost(NULL, array('user_skip_mails' => TRUE), 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')); + $this->assertFalse(user_load(array('uid' => $user->uid)), t('User is not found in the database')); } }