UserPasswordResetTest.php 6.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

/**
 * @file
 * Definition of Drupal\user\Tests\UserPasswordResetTest.
 */

namespace Drupal\user\Tests;

use Drupal\simpletest\WebTestBase;

/**
 * Tests resetting a user password.
 */
class UserPasswordResetTest extends WebTestBase {
16
17
18
  /**
   * The user object to test password resetting.
   *
19
   * @var \Drupal\user\UserInterface
20
21
   */
  protected $account;
22
23
24
25
26
27
28
29
30

  public static function getInfo() {
    return array(
      'name' => 'Reset password',
      'description' => 'Ensure that password reset methods work as expected.',
      'group' => 'User',
    );
  }

31
32
33
  public function setUp() {
    parent::setUp();

34
35
    // Create a user.
    $account = $this->drupalCreateUser();
36
37

    // Activate user by logging in.
38
    $this->drupalLogin($account);
39

40
    $this->account = user_load($account->id());
41
    $this->drupalLogout();
42
43
44
45
46

    // Set the last login time that is used to generate the one-time link so
    // that it is definitely over a second ago.
    $account->login = REQUEST_TIME - mt_rand(10, 100000);
    db_update('users')
47
      ->fields(array('login' => $account->getLastLoginTime()))
48
      ->condition('uid', $account->id())
49
      ->execute();
50
51
52
  }

  /**
53
   * Tests password reset functionality.
54
   */
55
56
57
58
59
  function testUserPasswordReset() {
    // Try to reset the password for an invalid account.
    $this->drupalGet('user/password');

    $edit = array('name' => $this->randomName(32));
60
    $this->drupalPostForm(NULL, $edit, t('E-mail new password'));
61
62

    $this->assertText(t('Sorry, @name is not recognized as a username or an e-mail address.', array('@name' => $edit['name'])), 'Validation error message shown when trying to request password for invalid account.');
63
    $this->assertEqual(count($this->drupalGetMails(array('id' => 'user_password_reset'))), 0, 'No e-mail was sent when requesting a password for an invalid account.');
64
65

    // Reset the password by username via the password reset page.
66
    $edit['name'] = $this->account->getUsername();
67
    $this->drupalPostForm(NULL, $edit, t('E-mail new password'));
68
69

     // Verify that the user was sent an e-mail.
70
    $this->assertMail('to', $this->account->getEmail(), 'Password e-mail sent to user.');
71
    $subject = t('Replacement login information for @username at @site', array('@username' => $this->account->getUsername(), '@site' => \Drupal::config('system.site')->get('name')));
72
73
74
75
76
77
    $this->assertMail('subject', $subject, 'Password reset e-mail subject is correct.');

    $resetURL = $this->getResetURL();
    $this->drupalGet($resetURL);

    // Check the one-time login page.
78
    $this->assertText($this->account->getUsername(), 'One-time login page contains the correct username.');
79
80
81
    $this->assertText(t('This login can be used only once.'), 'Found warning about one-time login.');

    // Check successful login.
82
    $this->drupalPostForm(NULL, NULL, t('Log in'));
83
    $this->assertLink(t('Log out'));
84
    $this->assertTitle(t('@name | @site', array('@name' => $this->account->getUsername(), '@site' => \Drupal::config('system.site')->get('name'))), 'Logged in using password reset link.');
85

86
87
88
89
90
91
92
93
94
95
    // Change the forgotten password.
    $password = user_password();
    $edit = array('pass[pass1]' => $password, 'pass[pass2]' => $password);
    $this->drupalPostForm(NULL, $edit, t('Save'));
    $this->assertText(t('The changes have been saved.'), 'Forgotten password changed.');

    // Verify that the password reset session has been destroyed.
    $this->drupalPostForm(NULL, $edit, t('Save'));
    $this->assertText(t('Your current password is missing or incorrect; it\'s required to change the Password.'), 'Password needed to make profile changes.');

96
    // Log out, and try to log in again using the same one-time link.
97
    $this->drupalLogout();
98
99
100
101
102
103
104
    $this->drupalGet($resetURL);
    $this->assertText(t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.'), 'One-time link is no longer valid.');

    // Request a new password again, this time using the e-mail address.
    $this->drupalGet('user/password');
    // Count email messages before to compare with after.
    $before = count($this->drupalGetMails(array('id' => 'user_password_reset')));
105
    $edit = array('name' => $this->account->getEmail());
106
    $this->drupalPostForm(NULL, $edit, t('E-mail new password'));
107
    $this->assertTrue( count($this->drupalGetMails(array('id' => 'user_password_reset'))) === $before + 1, 'E-mail sent when requesting password reset using e-mail address.');
108

109
    // Create a password reset link as if the request time was 60 seconds older than the allowed limit.
110
    $timeout = \Drupal::config('user.settings')->get('password_reset_timeout');
111
    $bogus_timestamp = REQUEST_TIME - $timeout - 60;
112
    $_uid = $this->account->id();
113
    $this->drupalGet("user/reset/$_uid/$bogus_timestamp/" . user_pass_rehash($this->account->getPassword(), $bogus_timestamp, $this->account->getLastLoginTime()));
114
115
    $this->assertText(t('You have tried to use a one-time login link that has expired. Please request a new one using the form below.'), 'Expired password reset request rejected.');
  }
116
117
118
119
120
121
122
123
124
125
126
127
128

  /**
   * Retrieves password reset e-mail and extracts the login link.
   */
  public function getResetURL() {
    // Assume the most recent email.
    $_emails = $this->drupalGetMails();
    $email = end($_emails);
    $urls = array();
    preg_match('#.+user/reset/.+#', $email['body'], $urls);

    return $urls[0];
  }
129

130
131
132
  /**
   * Prefill the text box on incorrect login via link to password reset page.
   */
133
134
135
136
137
138
  public function testUserResetPasswordTextboxFilled() {
    $this->drupalGet('user/login');
    $edit = array(
      'name' => $this->randomName(),
      'pass' => $this->randomName(),
    );
139
    $this->drupalPostForm('user', $edit, t('Log in'));
140
141
142
143
144
145
    $this->assertRaw(t('Sorry, unrecognized username or password. <a href="@password">Have you forgotten your password?</a>',
      array('@password' => url('user/password', array('query' => array('name' => $edit['name']))))));
    unset($edit['pass']);
    $this->drupalGet('user/password', array('query' => array('name' => $edit['name'])));
    $this->assertFieldByName('name', $edit['name'], 'User name found.');
  }
146
}