Skip to content

Commit 2c94f55

Browse files
akaashakaash
authored andcommitted
ACQE-5019 | Integration Testing - Reset link expiration by timeout
1 parent d9d3d9b commit 2c94f55

File tree

1 file changed

+210
-0
lines changed

1 file changed

+210
-0
lines changed

dev/tests/integration/testsuite/Magento/Customer/Controller/ForgotPasswordPostTest.php

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,29 @@
77

88
namespace Magento\Customer\Controller;
99

10+
use Magento\Config\Model\ResourceModel\Config as CoreConfig;
11+
use Magento\Customer\Model\CustomerRegistry;
12+
use Magento\Customer\Model\ResourceModel\Customer as CustomerResource;
13+
use Magento\Customer\Model\Session;
14+
use Magento\Framework\App\Config\ReinitableConfigInterface;
15+
use Magento\Framework\App\Config\ScopeConfigInterface;
16+
use Magento\Framework\App\Http;
1017
use Magento\Framework\App\Request\Http as HttpRequest;
18+
use Magento\Framework\Exception\NoSuchEntityException;
19+
use Magento\Framework\Intl\DateTimeFactory;
20+
use Magento\Framework\Math\Random;
1121
use Magento\Framework\Message\MessageInterface;
1222
use Magento\Framework\ObjectManagerInterface;
23+
use Magento\Framework\Serialize\Serializer\Json;
24+
use Magento\Framework\Stdlib\CookieManagerInterface;
25+
use Magento\Framework\Stdlib\DateTime;
1326
use Magento\TestFramework\Helper\Bootstrap;
27+
use Magento\TestFramework\Helper\Xpath;
1428
use Magento\TestFramework\Mail\Template\TransportBuilderMock;
29+
use Magento\TestFramework\Request;
1530
use Magento\TestFramework\TestCase\AbstractController;
31+
use Magento\Framework\Api\SearchCriteriaBuilder;
32+
use Magento\Theme\Controller\Result\MessagePlugin;
1633

1734
/**
1835
* Class checks password forgot scenarios
@@ -28,6 +45,36 @@ class ForgotPasswordPostTest extends AbstractController
2845
/** @var TransportBuilderMock */
2946
private $transportBuilderMock;
3047

48+
/**
49+
* @var CoreConfig
50+
*/
51+
protected $resourceConfig;
52+
53+
/**
54+
* @var ReinitableConfigInterface
55+
*/
56+
private $reinitableConfig;
57+
58+
/**
59+
* @var ScopeConfigInterface
60+
*/
61+
private $scopeConfig;
62+
63+
/**
64+
* @var DateTimeFactory
65+
*/
66+
private $dateTimeFactory;
67+
68+
/**
69+
* @var CustomerResource
70+
*/
71+
private $customerResource;
72+
73+
/**
74+
* @var Random
75+
*/
76+
private $random;
77+
3178
/**
3279
* @inheritdoc
3380
*/
@@ -37,6 +84,12 @@ protected function setUp(): void
3784

3885
$this->objectManager = Bootstrap::getObjectManager();
3986
$this->transportBuilderMock = $this->objectManager->get(TransportBuilderMock::class);
87+
$this->resourceConfig = $this->_objectManager->get(CoreConfig::class);
88+
$this->reinitableConfig = $this->_objectManager->get(ReinitableConfigInterface::class);
89+
$this->scopeConfig = Bootstrap::getObjectManager()->get(ScopeConfigInterface::class);
90+
$this->dateTimeFactory = $this->objectManager->get(DateTimeFactory::class);
91+
$this->customerResource = $this->objectManager->get(CustomerResource::class);
92+
$this->random = $this->objectManager->get(Random::class);
4093
}
4194

4295
/**
@@ -134,4 +187,161 @@ private function assertSuccessSessionMessage(string $email): void
134187
);
135188
$this->assertSessionMessages($this->equalTo([$message]), MessageInterface::TYPE_SUCCESS);
136189
}
190+
191+
/**
192+
* @magentoConfigFixture current_store customer/captcha/enable 0
193+
* @magentoConfigFixture current_store customer/password/min_time_between_password_reset_requests 0
194+
* @magentoConfigFixture current_store customer/password/max_number_password_reset_requests 0
195+
* @magentoDataFixture Magento/Customer/_files/customer.php
196+
*
197+
* @return void
198+
* @throws NoSuchEntityException
199+
*/
200+
public function testResetLinkSentAfterForgotPassword(): void
201+
{
202+
$defaultExpirationPeriod = 2;
203+
$actualExpirationPeriod = (int) $this->scopeConfig->getValue(
204+
'customer/password/reset_link_expiration_period',
205+
\Magento\Store\Model\ScopeInterface::SCOPE_WEBSITE
206+
);
207+
$this->assertEquals(
208+
$defaultExpirationPeriod,
209+
$actualExpirationPeriod
210+
);
211+
212+
$this->resourceConfig->saveConfig(
213+
'customer/password/reset_link_expiration_period',
214+
1,
215+
ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
216+
0
217+
);
218+
219+
$email = 'customer@example.com';
220+
221+
$this->getRequest()->setPostValue(['email' => $email]);
222+
$this->getRequest()->setMethod(HttpRequest::METHOD_POST);
223+
224+
$this->dispatch('customer/account/forgotPasswordPost');
225+
$this->assertRedirect($this->stringContains('customer/account/'));
226+
$this->assertSessionMessages(
227+
$this->equalTo(
228+
[
229+
"If there is an account associated with {$email} you will receive an email with a link "
230+
. "to reset your password."
231+
]
232+
),
233+
MessageInterface::TYPE_SUCCESS
234+
);
235+
236+
$sendMessage = $this->transportBuilderMock->getSentMessage()->getBody()->getParts()[0]->getRawContent();
237+
238+
$this->assertStringContainsString(
239+
'There was recently a request to change the password for your account',
240+
$sendMessage
241+
);
242+
243+
/** @var CustomerRegistry $customerRegistry */
244+
$customerRegistry = $this->_objectManager->get(CustomerRegistry::class);
245+
$customerData = $customerRegistry->retrieveByEmail($email);
246+
$token = $customerData->getRpToken();
247+
$customerId = $customerData->getId();
248+
249+
$this->assertEquals(
250+
1,
251+
Xpath::getElementsCountForXpath(
252+
sprintf(
253+
'//a[contains(@href, \'customer/account/createPassword/?id=%1$d&token=%2$s\')]',
254+
$customerId,
255+
$token
256+
),
257+
$sendMessage
258+
)
259+
);
260+
}
261+
262+
/**
263+
* @magentoConfigFixture current_store customer/captcha/enable 0
264+
* @magentoConfigFixture current_store customer/password/min_time_between_password_reset_requests 0
265+
* @magentoConfigFixture current_store customer/password/max_number_password_reset_requests 0
266+
* @magentoDataFixture Magento/Customer/_files/customer.php
267+
*
268+
* @depends testResetLinkSentAfterForgotPassword
269+
* @return void
270+
* @throws NoSuchEntityException
271+
* @throws \Magento\Framework\Exception\AlreadyExistsException
272+
* @throws \Magento\Framework\Exception\AuthenticationException
273+
* @throws \Magento\Framework\Exception\LocalizedException
274+
*/
275+
public function testResetLinkExpirationByTimeout(): void
276+
{
277+
$this->reinitableConfig->reinit();
278+
$email = 'customer@example.com';
279+
280+
/** @var CustomerRegistry $customerRegistry */
281+
$customerRegistry = $this->_objectManager->get(CustomerRegistry::class);
282+
$customerData = $customerRegistry->retrieveByEmail($email);
283+
$token = $this->random->getUniqueHash();
284+
$customerData->changeResetPasswordLinkToken($token);
285+
$customerData->setData('confirmation', 'confirmation');
286+
$customerData->save();
287+
288+
$customerId = $customerData->getId();
289+
290+
$this->resetRequest();
291+
$this->clearCookieMessagesList();
292+
293+
/** @var Session $customer */
294+
$session = Bootstrap::getObjectManager()->get(Session::class);
295+
$session->setRpToken($token);
296+
$session->setRpCustomerId($customerId);
297+
298+
$this->getRequest()->setParam('token', $token)->setParam('id', $customerId);
299+
$this->dispatch('customer/account/createPassword');
300+
$this->assertSessionMessages(
301+
$this->equalTo([]),
302+
MessageInterface::TYPE_ERROR
303+
);
304+
305+
$rpTokenCreatedAt = $this->dateTimeFactory->create()
306+
->sub(\DateInterval::createFromDateString('2 hour'))
307+
->format(DateTime::DATETIME_PHP_FORMAT);
308+
309+
$customerSecure = $customerRegistry->retrieveSecureData($customerId);
310+
$customerSecure->setRpTokenCreatedAt($rpTokenCreatedAt);
311+
$this->customerResource->save($customerData);
312+
313+
$this->getRequest()->setParam('token', $token)->setParam('id', $customerId);
314+
$this->getRequest()->setMethod(HttpRequest::METHOD_GET);
315+
$this->dispatch('customer/account/createPassword');
316+
317+
$this->assertSessionMessages(
318+
$this->equalTo(['Your password reset link has expired.']),
319+
MessageInterface::TYPE_ERROR
320+
);
321+
}
322+
323+
/**
324+
* @inheritDoc
325+
*/
326+
protected function resetRequest(): void
327+
{
328+
$this->_objectManager->removeSharedInstance(Http::class);
329+
$this->_objectManager->removeSharedInstance(Request::class);
330+
parent::resetRequest();
331+
}
332+
333+
/**
334+
* Clear cookie messages list.
335+
*
336+
* @return void
337+
*/
338+
private function clearCookieMessagesList(): void
339+
{
340+
$cookieManager = $this->_objectManager->get(CookieManagerInterface::class);
341+
$jsonSerializer = $this->_objectManager->get(Json::class);
342+
$cookieManager->setPublicCookie(
343+
MessagePlugin::MESSAGES_COOKIES_NAME,
344+
$jsonSerializer->serialize([])
345+
);
346+
}
137347
}

0 commit comments

Comments
 (0)