7
7
8
8
namespace Magento \Customer \Controller ;
9
9
10
+ use Magento \Config \Model \ResourceModel \Config as CoreConfig ;
11
+ use Magento \Customer \Api \CustomerRepositoryInterface ;
12
+ use Magento \Customer \Model \CustomerRegistry ;
13
+ use Magento \Framework \App \Config \ScopeConfigInterface ;
10
14
use Magento \Framework \App \Request \Http as HttpRequest ;
15
+ use Magento \Framework \Exception \LocalizedException ;
11
16
use Magento \Framework \Message \MessageInterface ;
12
17
use Magento \Framework \ObjectManagerInterface ;
18
+ use Magento \Framework \Serialize \Serializer \Json ;
19
+ use Magento \Framework \Stdlib \CookieManagerInterface ;
13
20
use Magento \TestFramework \Helper \Bootstrap ;
14
21
use Magento \TestFramework \Mail \Template \TransportBuilderMock ;
15
22
use Magento \TestFramework \TestCase \AbstractController ;
23
+ use Magento \Theme \Controller \Result \MessagePlugin ;
16
24
17
25
/**
18
26
* Class checks password forgot scenarios
19
27
*
20
28
* @see \Magento\Customer\Controller\Account\ForgotPasswordPost
21
29
* @magentoDbIsolation enabled
30
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
22
31
*/
23
32
class ForgotPasswordPostTest extends AbstractController
24
33
{
@@ -28,6 +37,21 @@ class ForgotPasswordPostTest extends AbstractController
28
37
/** @var TransportBuilderMock */
29
38
private $ transportBuilderMock ;
30
39
40
+ /**
41
+ * @var CustomerRepositoryInterface
42
+ */
43
+ private $ customerRepository ;
44
+
45
+ /**
46
+ * @var CoreConfig
47
+ */
48
+ protected $ resourceConfig ;
49
+
50
+ /**
51
+ * @var ScopeConfigInterface
52
+ */
53
+ private $ scopeConfig ;
54
+
31
55
/**
32
56
* @inheritdoc
33
57
*/
@@ -37,6 +61,8 @@ protected function setUp(): void
37
61
38
62
$ this ->objectManager = Bootstrap::getObjectManager ();
39
63
$ this ->transportBuilderMock = $ this ->objectManager ->get (TransportBuilderMock::class);
64
+ $ this ->resourceConfig = $ this ->_objectManager ->get (CoreConfig::class);
65
+ $ this ->scopeConfig = Bootstrap::getObjectManager ()->get (ScopeConfigInterface::class);
40
66
}
41
67
42
68
/**
@@ -134,4 +160,84 @@ private function assertSuccessSessionMessage(string $email): void
134
160
);
135
161
$ this ->assertSessionMessages ($ this ->equalTo ([$ message ]), MessageInterface::TYPE_SUCCESS );
136
162
}
163
+
164
+ /**
165
+ * @magentoDbIsolation disabled
166
+ * @magentoConfigFixture current_store customer/password/min_time_between_password_reset_requests 0
167
+ * @magentoConfigFixture current_store customer/captcha/enable 0
168
+ * @magentoDataFixture Magento/Customer/_files/customer.php
169
+ * @return void
170
+ * @throws LocalizedException
171
+ */
172
+ public function testEnablePasswordChangeFrequencyLimitForCustomer (): void
173
+ {
174
+ $ email = 'customer@example.com ' ;
175
+
176
+ // Resetting password multiple times
177
+ for ($ i = 0 ; $ i < 5 ; $ i ++) {
178
+ $ this ->getRequest ()->setPostValue (['email ' => $ email ]);
179
+ $ this ->getRequest ()->setMethod (HttpRequest::METHOD_POST );
180
+ $ this ->dispatch ('customer/account/forgotPasswordPost ' );
181
+ }
182
+
183
+ // Asserting mail received after forgot password
184
+ $ sendMessage = $ this ->transportBuilderMock ->getSentMessage ()->getBody ()->getParts ()[0 ]->getRawContent ();
185
+ $ this ->assertStringContainsString (
186
+ 'There was recently a request to change the password for your account ' ,
187
+ $ sendMessage
188
+ );
189
+
190
+ // Updating the limit to greater than 0
191
+ $ this ->resourceConfig ->saveConfig (
192
+ 'customer/password/min_time_between_password_reset_requests ' ,
193
+ 2 ,
194
+ ScopeConfigInterface::SCOPE_TYPE_DEFAULT ,
195
+ 0
196
+ );
197
+
198
+ // Resetting password multiple times
199
+ for ($ i = 0 ; $ i < 5 ; $ i ++) {
200
+ $ this ->clearCookieMessagesList ();
201
+ $ this ->getRequest ()->setPostValue ('email ' , $ email );
202
+ $ this ->dispatch ('customer/account/forgotPasswordPost ' );
203
+ }
204
+
205
+ // Asserting the error message
206
+ $ this ->assertSessionMessages (
207
+ $ this ->equalTo (
208
+ ['We received too many requests for password resets. '
209
+ . ' Please wait and try again later or contact hello@example.com. ' ]
210
+ ),
211
+ MessageInterface::TYPE_ERROR
212
+ );
213
+
214
+ // Wait for 2 minutes before resetting password
215
+ sleep (120 );
216
+
217
+ // Clicking on the forgot password link
218
+ $ this ->getRequest ()->setPostValue ('email ' , $ email );
219
+ $ this ->dispatch ('customer/account/forgotPasswordPost ' );
220
+
221
+ // Asserting mail received after forgot password
222
+ $ sendMessage = $ this ->transportBuilderMock ->getSentMessage ()->getBody ()->getParts ()[0 ]->getRawContent ();
223
+ $ this ->assertStringContainsString (
224
+ 'There was recently a request to change the password for your account ' ,
225
+ $ sendMessage
226
+ );
227
+ }
228
+
229
+ /**
230
+ * Clear cookie messages list.
231
+ *
232
+ * @return void
233
+ */
234
+ private function clearCookieMessagesList (): void
235
+ {
236
+ $ cookieManager = $ this ->_objectManager ->get (CookieManagerInterface::class);
237
+ $ jsonSerializer = $ this ->_objectManager ->get (Json::class);
238
+ $ cookieManager ->setPublicCookie (
239
+ MessagePlugin::MESSAGES_COOKIES_NAME ,
240
+ $ jsonSerializer ->serialize ([])
241
+ );
242
+ }
137
243
}
0 commit comments