@@ -200,6 +200,8 @@ private function assertSuccessSessionMessage(string $email): void
200
200
*/
201
201
public function testResetLinkSentAfterForgotPassword (): void
202
202
{
203
+ $ email = 'customer@example.com ' ;
204
+
203
205
// Getting and asserting actual default expiration period
204
206
$ defaultExpirationPeriod = 2 ;
205
207
$ actualExpirationPeriod = (int ) $ this ->scopeConfig ->getValue (
@@ -211,56 +213,66 @@ public function testResetLinkSentAfterForgotPassword(): void
211
213
$ actualExpirationPeriod
212
214
);
213
215
214
- // Updating expiration period
216
+ // Updating reset_link_expiration_period to 1 under customer configuration
215
217
$ this ->resourceConfig ->saveConfig (
216
218
'customer/password/reset_link_expiration_period ' ,
217
219
1 ,
218
220
ScopeConfigInterface::SCOPE_TYPE_DEFAULT ,
219
221
0
220
222
);
221
223
224
+ // Click forgot password link and assert mail received with reset password link
225
+ $ this ->clickForgotPasswordAndAssertResetLinkReceivedInMail ($ email );
226
+ }
227
+
228
+ /**
229
+ * @magentoConfigFixture current_store customer/captcha/enable 0
230
+ * @magentoConfigFixture current_store customer/password/min_time_between_password_reset_requests 0
231
+ * @magentoConfigFixture current_store customer/password/max_number_password_reset_requests 0
232
+ * @magentoDataFixture Magento/Customer/_files/customer.php
233
+ *
234
+ * @depends testResetLinkSentAfterForgotPassword
235
+ * @return void
236
+ * @throws NoSuchEntityException
237
+ * @throws AlreadyExistsException
238
+ * @throws AuthenticationException
239
+ * @throws LocalizedException
240
+ */
241
+ public function testResetLinkExpirationByTimeout (): void
242
+ {
243
+ $ this ->reinitableConfig ->reinit ();
222
244
$ email = 'customer@example.com ' ;
223
245
224
- $ this -> getRequest ()-> setPostValue ([ ' email ' => $ email ]);
225
- $ this ->getRequest ()-> setMethod (HttpRequest:: METHOD_POST );
246
+ // Generating random reset password token
247
+ $ rpData = $ this ->generateResetPasswordToken ( $ email );
226
248
227
- // Click on the forgot password
228
- $ this ->dispatch ('customer/account/forgotPasswordPost ' );
229
- $ this ->assertRedirect ($ this ->stringContains ('customer/account/ ' ));
230
- $ this ->assertSessionMessages (
231
- $ this ->equalTo (
232
- [
233
- "If there is an account associated with {$ email } you will receive an email with a link "
234
- . "to reset your password. "
235
- ]
236
- ),
237
- MessageInterface::TYPE_SUCCESS
238
- );
249
+ // Resetting request and clearing cookie message
250
+ $ this ->resetRequest ();
251
+ $ this ->clearCookieMessagesList ();
239
252
240
- $ sendMessage = $ this ->transportBuilderMock ->getSentMessage ()->getBody ()->getParts ()[0 ]->getRawContent ();
253
+ // Setting token and customer id to session
254
+ /** @var Session $customer */
255
+ $ session = Bootstrap::getObjectManager ()->get (Session::class);
256
+ $ session ->setRpToken ($ rpData ['token ' ]);
257
+ $ session ->setRpCustomerId ($ rpData ['customerId ' ]);
241
258
242
- $ this ->assertStringContainsString (
243
- 'There was recently a request to change the password for your account ' ,
244
- $ sendMessage
259
+ // Click on the reset password link and assert no expiration error message received
260
+ $ this ->clickResetPasswordLink ($ rpData ['token ' ], $ rpData ['customerId ' ]);
261
+ $ this ->assertSessionMessages (
262
+ $ this ->equalTo ([]),
263
+ MessageInterface::TYPE_ERROR
245
264
);
246
265
247
- /** @var CustomerRegistry $customerRegistry */
248
- $ customerRegistry = $ this ->_objectManager ->get (CustomerRegistry::class);
249
- $ customerData = $ customerRegistry ->retrieveByEmail ($ email );
250
- $ token = $ customerData ->getRpToken ();
251
- $ customerId = $ customerData ->getId ();
266
+ // Updating reset password created date
267
+ $ this ->updateResetPasswordCreatedDateAndTime ($ email , $ rpData ['customerId ' ]);
252
268
253
- // Asserting mail contains reset link
254
- $ this ->assertEquals (
255
- 1 ,
256
- Xpath::getElementsCountForXpath (
257
- sprintf (
258
- '//a[contains(@href, \'customer/account/createPassword/?id=%1$d&token=%2$s \')] ' ,
259
- $ customerId ,
260
- $ token
261
- ),
262
- $ sendMessage
263
- )
269
+ // Clicking on the reset password link
270
+ $ this ->clickResetPasswordLink ($ rpData ['token ' ], $ rpData ['customerId ' ]);
271
+
272
+ // Asserting failed message after link expire
273
+ $ this ->assertSessionMessages (
274
+ $ this ->equalTo (['Your password reset link has expired. ' ]),
275
+ MessageInterface::TYPE_ERROR
264
276
);
265
277
}
266
278
@@ -270,18 +282,50 @@ public function testResetLinkSentAfterForgotPassword(): void
270
282
* @magentoConfigFixture current_store customer/password/max_number_password_reset_requests 0
271
283
* @magentoDataFixture Magento/Customer/_files/customer.php
272
284
*
273
- * @depends testResetLinkSentAfterForgotPassword
285
+ * @depends testResetLinkExpirationByTimeout
274
286
* @return void
275
287
* @throws NoSuchEntityException
276
- * @throws \Magento\Framework\Exception\ AlreadyExistsException
277
- * @throws \Magento\Framework\Exception\ AuthenticationException
278
- * @throws \Magento\Framework\Exception\ LocalizedException
288
+ * @throws AlreadyExistsException
289
+ * @throws AuthenticationException
290
+ * @throws LocalizedException
279
291
*/
280
- public function testResetLinkExpirationByTimeout (): void
292
+ public function testExpiredResetPasswordLinkAfterForgotPassword (): void
281
293
{
282
- $ this ->reinitableConfig ->reinit ();
283
294
$ email = 'customer@example.com ' ;
284
295
296
+ // Click forgot password link and assert mail received with reset password link
297
+ $ this ->clickForgotPasswordAndAssertResetLinkReceivedInMail ($ email );
298
+
299
+ // Generating random reset password token
300
+ $ rpData = $ this ->generateResetPasswordToken ($ email );
301
+
302
+ // Resetting request and clearing cookie message
303
+ $ this ->resetRequest ();
304
+ $ this ->clearCookieMessagesList ();
305
+
306
+ // Updating reset password created date
307
+ $ this ->updateResetPasswordCreatedDateAndTime ($ email , $ rpData ['customerId ' ]);
308
+
309
+ // Clicking on the reset password link
310
+ $ this ->clickResetPasswordLink ($ rpData ['token ' ], $ rpData ['customerId ' ]);
311
+
312
+ // Asserting failed message after link expire
313
+ $ this ->assertSessionMessages (
314
+ $ this ->equalTo (['Your password reset link has expired. ' ]),
315
+ MessageInterface::TYPE_ERROR
316
+ );
317
+ }
318
+
319
+ /**
320
+ * @param string $email
321
+ * @return array
322
+ * @throws AlreadyExistsException
323
+ * @throws AuthenticationException
324
+ * @throws LocalizedException
325
+ * @throws NoSuchEntityException
326
+ */
327
+ private function generateResetPasswordToken ($ email ): array
328
+ {
285
329
/** @var CustomerRegistry $customerRegistry */
286
330
$ customerRegistry = $ this ->_objectManager ->get (CustomerRegistry::class);
287
331
$ customerData = $ customerRegistry ->retrieveByEmail ($ email );
@@ -292,44 +336,100 @@ public function testResetLinkExpirationByTimeout(): void
292
336
293
337
$ customerId = $ customerData ->getId ();
294
338
295
- $ this ->resetRequest ();
296
- $ this ->clearCookieMessagesList ();
297
-
298
- /** @var Session $customer */
299
- $ session = Bootstrap::getObjectManager ()->get (Session::class);
300
- $ session ->setRpToken ($ token );
301
- $ session ->setRpCustomerId ($ customerId );
302
-
303
- // Click on the reset password link
304
- $ this ->getRequest ()->setParam ('token ' , $ token )->setParam ('id ' , $ customerId );
305
- $ this ->dispatch ('customer/account/createPassword ' );
306
- $ this ->assertSessionMessages (
307
- $ this ->equalTo ([]),
308
- MessageInterface::TYPE_ERROR
309
- );
339
+ return [
340
+ 'token ' => $ token ,
341
+ 'customerId ' => $ customerId
342
+ ];
343
+ }
310
344
345
+ /**
346
+ * @param string $email
347
+ * @param int $customerId
348
+ * @return void
349
+ * @throws AlreadyExistsException
350
+ * @throws NoSuchEntityException
351
+ */
352
+ private function updateResetPasswordCreatedDateAndTime ($ email , $ customerId ): void
353
+ {
311
354
$ rpTokenCreatedAt = $ this ->dateTimeFactory ->create ()
312
355
->sub (\DateInterval::createFromDateString ('2 hour ' ))
313
356
->format (DateTime::DATETIME_PHP_FORMAT );
314
357
315
- // Updating reTokenCreatedAt field
358
+ /** @var CustomerRegistry $customerRegistry */
359
+ $ customerRegistry = $ this ->_objectManager ->get (CustomerRegistry::class);
360
+ $ customerData = $ customerRegistry ->retrieveByEmail ($ email );
316
361
$ customerSecure = $ customerRegistry ->retrieveSecureData ($ customerId );
317
362
$ customerSecure ->setRpTokenCreatedAt ($ rpTokenCreatedAt );
318
363
$ this ->customerResource ->save ($ customerData );
364
+ }
319
365
366
+ /**
367
+ * @param string $token
368
+ * @param int $customerId
369
+ * @return void
370
+ */
371
+ private function clickResetPasswordLink ($ token , $ customerId ): void
372
+ {
320
373
$ this ->getRequest ()->setParam ('token ' , $ token )->setParam ('id ' , $ customerId );
321
374
$ this ->getRequest ()->setMethod (HttpRequest::METHOD_GET );
322
375
$ this ->dispatch ('customer/account/createPassword ' );
376
+ }
323
377
324
- // Asserting failed message after link expire
378
+ /**
379
+ * @param string $email
380
+ * @return void
381
+ * @throws NoSuchEntityException
382
+ */
383
+ private function clickForgotPasswordAndAssertResetLinkReceivedInMail ($ email ): void
384
+ {
385
+ $ this ->getRequest ()->setPostValue (['email ' => $ email ]);
386
+ $ this ->getRequest ()->setMethod (HttpRequest::METHOD_POST );
387
+
388
+ // Click on the forgot password link
389
+ $ this ->dispatch ('customer/account/forgotPasswordPost ' );
390
+ $ this ->assertRedirect ($ this ->stringContains ('customer/account/ ' ));
391
+
392
+ // Asserting the success message after forgot password
325
393
$ this ->assertSessionMessages (
326
- $ this ->equalTo (['Your password reset link has expired. ' ]),
327
- MessageInterface::TYPE_ERROR
394
+ $ this ->equalTo (
395
+ [
396
+ "If there is an account associated with {$ email } you will receive an email with a link "
397
+ . "to reset your password. "
398
+ ]
399
+ ),
400
+ MessageInterface::TYPE_SUCCESS
401
+ );
402
+
403
+ // Asserting mail received after forgot password
404
+ $ sendMessage = $ this ->transportBuilderMock ->getSentMessage ()->getBody ()->getParts ()[0 ]->getRawContent ();
405
+ $ this ->assertStringContainsString (
406
+ 'There was recently a request to change the password for your account ' ,
407
+ $ sendMessage
408
+ );
409
+
410
+ // Getting reset password token and customer id from the database
411
+ /** @var CustomerRegistry $customerRegistry */
412
+ $ customerRegistry = $ this ->_objectManager ->get (CustomerRegistry::class);
413
+ $ customerData = $ customerRegistry ->retrieveByEmail ($ email );
414
+ $ token = $ customerData ->getRpToken ();
415
+ $ customerId = $ customerData ->getId ();
416
+
417
+ // Asserting mail contains reset link
418
+ $ this ->assertEquals (
419
+ 1 ,
420
+ Xpath::getElementsCountForXpath (
421
+ sprintf (
422
+ '//a[contains(@href, \'customer/account/createPassword/?id=%1$d&token=%2$s \')] ' ,
423
+ $ customerId ,
424
+ $ token
425
+ ),
426
+ $ sendMessage
427
+ )
328
428
);
329
429
}
330
430
331
431
/**
332
- * @inheritDoc
432
+ * @return void
333
433
*/
334
434
protected function resetRequest (): void
335
435
{
0 commit comments