7
7
8
8
namespace Magento \User \Controller \Adminhtml ;
9
9
10
+ use Magento \Framework \App \Area ;
11
+ use Magento \Framework \App \Config \ReinitableConfigInterface ;
12
+ use Magento \Framework \App \Config \ScopeConfigInterface ;
10
13
use Magento \Framework \Exception \LocalizedException ;
11
14
use Magento \Framework \Mail \EmailMessage ;
15
+ use Magento \Framework \Message \MessageInterface ;
12
16
use Magento \Store \Model \Store ;
17
+ use Magento \TestFramework \Fixture \AppArea ;
13
18
use Magento \TestFramework \Fixture \Config as Config ;
14
19
use Magento \TestFramework \Fixture \DataFixture ;
15
20
use Magento \TestFramework \Fixture \DataFixtureStorage ;
16
21
use Magento \TestFramework \Fixture \DataFixtureStorageManager ;
22
+ use Magento \TestFramework \Fixture \DbIsolation ;
23
+ use Magento \TestFramework \Helper \Bootstrap ;
17
24
use Magento \TestFramework \Mail \Template \TransportBuilderMock ;
18
25
use Magento \TestFramework \TestCase \AbstractBackendController ;
19
26
use Magento \User \Model \User as UserModel ;
27
+ use Magento \User \Model \UserFactory ;
20
28
use Magento \User \Test \Fixture \User as UserDataFixture ;
29
+ use Magento \Framework \App \ResourceConnection ;
30
+ use Magento \Config \Model \ResourceModel \Config as CoreConfig ;
21
31
22
32
/**
23
33
* Test class for user reset password email
24
- *
34
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
25
35
* @magentoAppArea adminhtml
26
36
*/
27
37
class UserResetPasswordEmailTest extends AbstractBackendController
@@ -36,6 +46,26 @@ class UserResetPasswordEmailTest extends AbstractBackendController
36
46
*/
37
47
protected $ userModel ;
38
48
49
+ /**
50
+ * @var UserFactory
51
+ */
52
+ private $ userFactory ;
53
+
54
+ /**
55
+ * @var ResourceConnection
56
+ */
57
+ private $ resourceConnection ;
58
+
59
+ /**
60
+ * @var ReinitableConfigInterface
61
+ */
62
+ private $ reinitableConfig ;
63
+
64
+ /**
65
+ * @var CoreConfig
66
+ */
67
+ protected $ resourceConfig ;
68
+
39
69
/**
40
70
* @throws LocalizedException
41
71
*/
@@ -44,6 +74,10 @@ protected function setUp(): void
44
74
parent ::setUp ();
45
75
$ this ->fixtures = DataFixtureStorageManager::getStorage ();
46
76
$ this ->userModel = $ this ->_objectManager ->create (UserModel::class);
77
+ $ this ->userFactory = \Magento \TestFramework \Helper \Bootstrap::getObjectManager ()->create (UserFactory::class);
78
+ $ this ->resourceConnection = $ this ->_objectManager ->get (ResourceConnection::class);
79
+ $ this ->reinitableConfig = $ this ->_objectManager ->get (ReinitableConfigInterface::class);
80
+ $ this ->resourceConfig = $ this ->_objectManager ->get (CoreConfig::class);
47
81
}
48
82
49
83
#[
@@ -74,4 +108,120 @@ private function getResetPasswordUri(EmailMessage $message): string
74
108
$ urlString = trim ($ match [0 ][0 ], $ store ->getBaseUrl ('web ' ));
75
109
return substr ($ urlString , 0 , strpos ($ urlString , "/key " ));
76
110
}
111
+
112
+ /**
113
+ * @return void
114
+ * @throws LocalizedException
115
+ */
116
+ #[
117
+ AppArea('adminhtml ' ),
118
+ DbIsolation(false ),
119
+ DataFixture(UserDataFixture::class, ['role_id ' => 1 ], 'user ' )
120
+ ]
121
+ public function testLimitNumberOfResetRequestPerHourByEmail (): void
122
+ {
123
+ // Load admin user
124
+ $ user = $ this ->fixtures ->get ('user ' );
125
+ $ username = $ user ->getDataByKey ('username ' );
126
+ $ adminEmail = $ user ->getDataByKey ('email ' );
127
+
128
+ // login admin
129
+ $ adminUser = $ this ->userFactory ->create ();
130
+ $ adminUser ->login ($ username , \Magento \TestFramework \Bootstrap::ADMIN_PASSWORD );
131
+
132
+ // Setting Password Reset Protection Type By Email
133
+ $ this ->resourceConfig ->saveConfig (
134
+ 'admin/security/password_reset_protection_type ' ,
135
+ 3 ,
136
+ ScopeConfigInterface::SCOPE_TYPE_DEFAULT ,
137
+ 0
138
+ );
139
+
140
+ // Setting Max Number of Password Reset Requests 0
141
+ $ this ->resourceConfig ->saveConfig (
142
+ 'admin/security/max_number_password_reset_requests ' ,
143
+ 0 ,
144
+ ScopeConfigInterface::SCOPE_TYPE_DEFAULT ,
145
+ 0
146
+ );
147
+
148
+ // Setting Min Time Between Password Reset Requests 0
149
+ $ this ->resourceConfig ->saveConfig (
150
+ 'admin/security/min_time_between_password_reset_requests ' ,
151
+ 0 ,
152
+ ScopeConfigInterface::SCOPE_TYPE_DEFAULT ,
153
+ 0
154
+ );
155
+ $ this ->reinitableConfig ->reinit ();
156
+
157
+ // Resetting Password
158
+ $ this ->resetPassword ($ adminEmail );
159
+
160
+ /** @var TransportBuilderMock $transportMock */
161
+ $ transportMock = Bootstrap::getObjectManager ()->get (
162
+ TransportBuilderMock::class
163
+ );
164
+ $ sendMessage = $ transportMock ->getSentMessage ()->getBody ()->getParts ()[0 ]->getRawContent ();
165
+
166
+ $ this ->assertStringContainsString (
167
+ 'There was recently a request to change the password for your account ' ,
168
+ $ sendMessage
169
+ );
170
+
171
+ $ this ->assertSessionMessages (
172
+ $ this ->equalTo ([]),
173
+ MessageInterface::TYPE_ERROR
174
+ );
175
+
176
+ // Setting Max Number of Password Reset Requests greater than 0
177
+ $ this ->resourceConfig ->saveConfig (
178
+ 'admin/security/max_number_password_reset_requests ' ,
179
+ 2 ,
180
+ ScopeConfigInterface::SCOPE_TYPE_DEFAULT ,
181
+ 0
182
+ );
183
+ $ this ->reinitableConfig ->reinit ();
184
+
185
+ $ this ->resetPassword ($ adminEmail );
186
+ $ this ->assertSessionMessages (
187
+ $ this ->equalTo ([]),
188
+ MessageInterface::TYPE_ERROR
189
+ );
190
+
191
+ // Resetting password multiple times
192
+ for ($ i = 0 ; $ i < 2 ; $ i ++) {
193
+ $ this ->resetPassword ($ adminEmail );
194
+ $ this ->assertSessionMessages (
195
+ $ this ->equalTo (
196
+ ['We received too many requests for password resets. '
197
+ . ' Please wait and try again later or contact hello@example.com. ' ]
198
+ ),
199
+ MessageInterface::TYPE_ERROR
200
+ );
201
+ }
202
+
203
+ // Clearing the table password_reset_request_event
204
+ $ connection = $ this ->resourceConnection ->getConnection ();
205
+ $ tableName = $ this ->resourceConnection ->getTableName ('password_reset_request_event ' );
206
+ $ connection ->truncateTable ($ tableName );
207
+
208
+ $ this ->assertEquals (0 , $ connection ->fetchOne ("SELECT COUNT(*) FROM $ tableName " ));
209
+
210
+ $ this ->resetPassword ($ adminEmail );
211
+ $ sendMessage = $ transportMock ->getSentMessage ()->getBody ()->getParts ()[0 ]->getRawContent ();
212
+ $ this ->assertStringContainsString (
213
+ 'There was recently a request to change the password for your account ' ,
214
+ $ sendMessage
215
+ );
216
+ }
217
+
218
+ /**
219
+ * @param $adminEmail
220
+ * @return void
221
+ */
222
+ private function resetPassword ($ adminEmail ): void
223
+ {
224
+ $ this ->getRequest ()->setPostValue ('email ' , $ adminEmail );
225
+ $ this ->dispatch ('backend/admin/auth/forgotpassword ' );
226
+ }
77
227
}
0 commit comments