2 // This file is part of Moodle - http://moodle.org/
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
18 * Unit tests for login lib.
21 * @copyright 2017 Juan Leyva
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 defined('MOODLE_INTERNAL') ||
die();
28 require_once($CFG->dirroot
. '/login/lib.php');
34 * @copyright 2017 Juan Leyva
35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37 class core_login_lib_testcase
extends advanced_testcase
{
39 public function test_core_login_process_password_reset_one_time_without_username_protection() {
42 $this->resetAfterTest();
43 $CFG->protectusernames
= 0;
44 $user = $this->getDataGenerator()->create_user(array('auth' => 'manual'));
46 $sink = $this->redirectEmails();
48 list($status, $notice, $url) = core_login_process_password_reset($user->username
, null);
49 $this->assertSame('emailresetconfirmsent', $status);
50 $emails = $sink->get_messages();
51 $this->assertCount(1, $emails);
52 $email = reset($emails);
53 $this->assertSame($user->email
, $email->to
);
54 $this->assertNotEmpty($email->header
);
55 $this->assertNotEmpty($email->body
);
56 $this->assertRegExp('/A password reset was requested for your account/', $email->body
);
60 public function test_core_login_process_password_reset_two_consecutive_times_without_username_protection() {
63 $this->resetAfterTest();
64 $CFG->protectusernames
= 0;
65 $user = $this->getDataGenerator()->create_user(array('auth' => 'manual'));
67 $sink = $this->redirectEmails();
69 list($status, $notice, $url) = core_login_process_password_reset($user->username
, null);
70 $this->assertSame('emailresetconfirmsent', $status);
71 // Request for a second time.
72 list($status, $notice, $url) = core_login_process_password_reset($user->username
, null);
73 $this->assertSame('emailresetconfirmsent', $status);
74 $emails = $sink->get_messages();
75 $this->assertCount(2, $emails); // Two emails sent (one per each request).
76 $email = array_pop($emails);
77 $this->assertSame($user->email
, $email->to
);
78 $this->assertNotEmpty($email->header
);
79 $this->assertNotEmpty($email->body
);
80 $this->assertRegExp('/A password reset was requested for your account/', $email->body
);
84 public function test_core_login_process_password_reset_three_consecutive_times_without_username_protection() {
87 $this->resetAfterTest();
88 $CFG->protectusernames
= 0;
89 $user = $this->getDataGenerator()->create_user(array('auth' => 'manual'));
91 $sink = $this->redirectEmails();
93 list($status, $notice, $url) = core_login_process_password_reset($user->username
, null);
94 $this->assertSame('emailresetconfirmsent', $status);
95 // Request for a second time.
96 list($status, $notice, $url) = core_login_process_password_reset($user->username
, null);
97 $this->assertSame('emailresetconfirmsent', $status);
99 list($status, $notice, $url) = core_login_process_password_reset($user->username
, null);
100 $this->assertSame('emailalreadysent', $status);
101 $emails = $sink->get_messages();
102 $this->assertCount(2, $emails); // Third time email is not sent.
105 public function test_core_login_process_password_reset_one_time_with_username_protection() {
108 $this->resetAfterTest();
109 $CFG->protectusernames
= 1;
110 $user = $this->getDataGenerator()->create_user(array('auth' => 'manual'));
112 $sink = $this->redirectEmails();
114 list($status, $notice, $url) = core_login_process_password_reset($user->username
, null);
115 $this->assertSame('emailpasswordconfirmmaybesent', $status); // Generic message not giving clues.
116 $emails = $sink->get_messages();
117 $this->assertCount(1, $emails);
118 $email = reset($emails);
119 $this->assertSame($user->email
, $email->to
);
120 $this->assertNotEmpty($email->header
);
121 $this->assertNotEmpty($email->body
);
122 $this->assertRegExp('/A password reset was requested for your account/', $email->body
);
126 public function test_core_login_process_password_reset_with_preexisting_expired_request_without_username_protection() {
129 $this->resetAfterTest();
130 $CFG->protectusernames
= 0;
131 $user = $this->getDataGenerator()->create_user(array('auth' => 'manual'));
133 $sink = $this->redirectEmails();
135 list($status, $notice, $url) = core_login_process_password_reset($user->username
, null);
136 $this->assertSame('emailresetconfirmsent', $status);
138 list($status, $notice, $url) = core_login_process_password_reset($user->username
, null);
139 $this->assertSame('emailresetconfirmsent', $status);
141 $resetrequests = $DB->get_records('user_password_resets');
142 $request = reset($resetrequests);
143 $request->timerequested
= time() - YEARSECS
;
144 $DB->update_record('user_password_resets', $request);
146 // Request again - third time - but it shuld be expired so we should get an email.
147 list($status, $notice, $url) = core_login_process_password_reset($user->username
, null);
148 $this->assertSame('emailresetconfirmsent', $status);
149 $emails = $sink->get_messages();
150 $this->assertCount(3, $emails); // Normal process, the previous request was deleted.
151 $email = reset($emails);
152 $this->assertSame($user->email
, $email->to
);
153 $this->assertNotEmpty($email->header
);
154 $this->assertNotEmpty($email->body
);
155 $this->assertRegExp('/A password reset was requested for your account/', $email->body
);
159 public function test_core_login_process_password_reset_disabled_auth() {
160 $this->resetAfterTest();
161 $user = $this->getDataGenerator()->create_user(array('auth' => 'oauth2'));
163 $sink = $this->redirectEmails();
165 core_login_process_password_reset($user->username
, null);
166 $emails = $sink->get_messages();
167 $this->assertCount(1, $emails);
168 $email = reset($emails);
169 $this->assertSame($user->email
, $email->to
);
170 $this->assertNotEmpty($email->header
);
171 $this->assertNotEmpty($email->body
);
172 $this->assertRegExp('/Unfortunately your account on this site is disabled/', $email->body
);
176 public function test_core_login_process_password_reset_auth_not_supporting_email_reset() {
179 $this->resetAfterTest();
180 $CFG->auth
= $CFG->auth
. ',mnet';
181 $user = $this->getDataGenerator()->create_user(array('auth' => 'mnet'));
183 $sink = $this->redirectEmails();
185 core_login_process_password_reset($user->username
, null);
186 $emails = $sink->get_messages();
187 $this->assertCount(1, $emails);
188 $email = reset($emails);
189 $this->assertSame($user->email
, $email->to
);
190 $this->assertNotEmpty($email->header
);
191 $this->assertNotEmpty($email->body
);
192 $this->assertRegExp('/Unfortunately passwords cannot be reset on this site/', $email->body
);
196 public function test_core_login_process_password_reset_missing_parameters() {
197 $this->expectException('moodle_exception');
198 $this->expectExceptionMessage(get_string('cannotmailconfirm', 'error'));
199 core_login_process_password_reset(null, null);
202 public function test_core_login_process_password_reset_invalid_username_with_username_protection() {
204 $this->resetAfterTest();
205 $CFG->protectusernames
= 1;
206 list($status, $notice, $url) = core_login_process_password_reset('72347234nasdfasdf/Ds', null);
207 $this->assertEquals('emailpasswordconfirmmaybesent', $status);
210 public function test_core_login_process_password_reset_invalid_username_without_username_protection() {
212 $this->resetAfterTest();
213 $CFG->protectusernames
= 0;
214 list($status, $notice, $url) = core_login_process_password_reset('72347234nasdfasdf/Ds', null);
215 $this->assertEquals('emailpasswordconfirmnotsent', $status);
218 public function test_core_login_process_password_reset_invalid_email_without_username_protection() {
220 $this->resetAfterTest();
221 $CFG->protectusernames
= 0;
222 list($status, $notice, $url) = core_login_process_password_reset(null, 'fakeemail@nofd.zdy');
223 $this->assertEquals('emailpasswordconfirmnotsent', $status);