77
88namespace Magento \User \Controller \Adminhtml ;
99
10+ use Magento \Framework \App \Config \Storage \WriterInterface ;
1011use Magento \Framework \Exception \LocalizedException ;
1112use Magento \Framework \Mail \EmailMessage ;
13+ use Magento \Framework \Message \MessageInterface ;
1214use Magento \Store \Model \Store ;
1315use Magento \TestFramework \Fixture \Config as Config ;
1416use Magento \TestFramework \Fixture \DataFixture ;
1517use Magento \TestFramework \Fixture \DataFixtureStorage ;
1618use Magento \TestFramework \Fixture \DataFixtureStorageManager ;
19+ use Magento \TestFramework \Fixture \DbIsolation ;
20+ use Magento \TestFramework \Helper \Bootstrap ;
1721use Magento \TestFramework \Mail \Template \TransportBuilderMock ;
1822use Magento \TestFramework \TestCase \AbstractBackendController ;
1923use Magento \User \Model \User as UserModel ;
24+ use Magento \User \Model \UserFactory ;
2025use Magento \User \Test \Fixture \User as UserDataFixture ;
2126
2227/**
2328 * Test class for user reset password email
24- *
29+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2530 * @magentoAppArea adminhtml
2631 */
2732class UserResetPasswordEmailTest extends AbstractBackendController
@@ -36,6 +41,16 @@ class UserResetPasswordEmailTest extends AbstractBackendController
3641 */
3742 protected $ userModel ;
3843
44+ /**
45+ * @var UserFactory
46+ */
47+ private $ userFactory ;
48+
49+ /**
50+ * @var WriterInterface
51+ */
52+ private $ configWriter ;
53+
3954 /**
4055 * @throws LocalizedException
4156 */
@@ -44,6 +59,8 @@ protected function setUp(): void
4459 parent ::setUp ();
4560 $ this ->fixtures = DataFixtureStorageManager::getStorage ();
4661 $ this ->userModel = $ this ->_objectManager ->create (UserModel::class);
62+ $ this ->userFactory = \Magento \TestFramework \Helper \Bootstrap::getObjectManager ()->create (UserFactory::class);
63+ $ this ->configWriter = $ this ->_objectManager ->get (WriterInterface::class);
4764 }
4865
4966 #[
@@ -74,4 +91,75 @@ private function getResetPasswordUri(EmailMessage $message): string
7491 $ urlString = trim ($ match [0 ][0 ], $ store ->getBaseUrl ('web ' ));
7592 return substr ($ urlString , 0 , strpos ($ urlString , "/key " ));
7693 }
94+
95+ /**
96+ * @return void
97+ * @throws LocalizedException
98+ */
99+ #[
100+ DbIsolation(false ),
101+ Config(
102+ 'admin/security/min_time_between_password_reset_requests ' ,
103+ '0 ' ,
104+ 'store '
105+ ),
106+ DataFixture(UserDataFixture::class, ['role_id ' => 1 ], 'user ' )
107+ ]
108+ public function testEnablePasswordChangeFrequencyLimit (): void
109+ {
110+ // Load admin user
111+ $ user = $ this ->fixtures ->get ('user ' );
112+ $ username = $ user ->getDataByKey ('username ' );
113+ $ adminEmail = $ user ->getDataByKey ('email ' );
114+
115+ // login admin
116+ $ adminUser = $ this ->userFactory ->create ();
117+ $ adminUser ->login ($ username , \Magento \TestFramework \Bootstrap::ADMIN_PASSWORD );
118+
119+ // Resetting password multiple times
120+ for ($ i = 0 ; $ i < 5 ; $ i ++) {
121+ $ this ->getRequest ()->setPostValue ('email ' , $ adminEmail );
122+ $ this ->dispatch ('backend/admin/auth/forgotpassword ' );
123+ }
124+
125+ /** @var TransportBuilderMock $transportMock */
126+ $ transportMock = Bootstrap::getObjectManager ()->get (
127+ TransportBuilderMock::class
128+ );
129+ $ sendMessage = $ transportMock ->getSentMessage ()->getBody ()->getParts ()[0 ]->getRawContent ();
130+
131+ $ this ->assertStringContainsString (
132+ 'There was recently a request to change the password for your account ' ,
133+ $ sendMessage
134+ );
135+
136+ // Setting the limit to greater than 0
137+ $ this ->configWriter ->save ('admin/security/min_time_between_password_reset_requests ' , 2 );
138+
139+ // Resetting password multiple times
140+ for ($ i = 0 ; $ i < 5 ; $ i ++) {
141+ $ this ->getRequest ()->setPostValue ('email ' , $ adminEmail );
142+ $ this ->dispatch ('backend/admin/auth/forgotpassword ' );
143+ }
144+
145+ $ this ->assertSessionMessages (
146+ $ this ->equalTo (
147+ ['We received too many requests for password resets. '
148+ . ' Please wait and try again later or contact hello@example.com. ' ]
149+ ),
150+ MessageInterface::TYPE_ERROR
151+ );
152+
153+ // Wait for 2 minutes before resetting password
154+ sleep (120 );
155+
156+ $ this ->getRequest ()->setPostValue ('email ' , $ adminEmail );
157+ $ this ->dispatch ('backend/admin/auth/forgotpassword ' );
158+
159+ $ sendMessage = $ transportMock ->getSentMessage ()->getBody ()->getParts ()[0 ]->getRawContent ();
160+ $ this ->assertStringContainsString (
161+ 'There was recently a request to change the password for your account ' ,
162+ $ sendMessage
163+ );
164+ }
77165}
0 commit comments