1414use OxidEsales \Eshop \Core \Exception \UserException ;
1515use OxidEsales \Eshop \Core \Registry ;
1616use OxidEsales \Eshop \Core \Request ;
17- use OxidEsales \EshopCommunity \Tests \Integration \IntegrationTestCase ;
17+ use OxidEsales \Eshop \Core \Utils ;
18+ use OxidEsales \EshopCommunity \Core \Di \ContainerFacade ;
19+ use OxidEsales \EshopCommunity \Internal \Framework \Module \Facade \ModuleSettingServiceInterface ;
20+ use OxidEsales \SecurityModule \Authentication \TwoFactorAuth \Service \AuthorizeService ;
21+ use OxidEsales \SecurityModule \Authentication \TwoFactorAuth \Service \ModuleSettingsService ;
22+ use OxidEsales \SecurityModule \Captcha \Service \ModuleSettingsServiceInterface as CaptchaSettingsServiceInterface ;
23+ use OxidEsales \SecurityModule \Core \Module ;
24+ use OxidEsales \SecurityModule \Tests \Integration \IntegrationTestCase ;
1825
1926class UserTest extends IntegrationTestCase
2027{
28+ // Fixture users from tests/Fixtures/testdata_ce.sql (password: useruser)
29+ private const OTP_USER_NAME = 'user@oxid-esales.com ' ;
30+ private const OTP_USER_PASSWORD = 'useruser ' ;
31+
2132 protected Request $ requestMock ;
2233
2334 public function setUp (): void
@@ -34,6 +45,12 @@ public function setUp(): void
3445 Registry::getSession ()->setVariable ('captcha_expiration ' , time () + 60 );
3546 }
3647
48+ public function tearDown (): void
49+ {
50+ $ this ->disableTwoFactorAuth ();
51+ parent ::tearDown ();
52+ }
53+
3754 public function testCheckValuesWithInvalidCaptcha ()
3855 {
3956 $ this ->requestMock
@@ -100,20 +117,107 @@ public function testLoginWithEmptyCaptcha()
100117 $ subject ->login ('' , '' );
101118 }
102119
103- public function testLoginWithOtpEnabledAndInvalidPasswordThrows (): void
120+ public function testLoginWithOTPEnabledAndValidCredentialsReturnsFalse (): void
104121 {
105- $ this ->requestMock
106- ->method ('getRequestParameter ' )
107- ->willReturnCallback (function ($ param ) {
108- if ($ param === 'captcha ' ) {
109- return 'valid_captcha ' ;
110- }
111- return null ;
112- });
122+ $ this ->disableCaptcha ();
123+ $ this ->enableTwoFactorAuth ();
124+
125+ $ utilsMock = $ this ->createMock (Utils::class);
126+ $ utilsMock ->expects ($ this ->once ())->method ('redirect ' );
127+ Registry::set (Utils::class, $ utilsMock );
128+
129+ $ subject = oxNew (User::class);
130+ $ result = $ subject ->login (self ::OTP_USER_NAME , self ::OTP_USER_PASSWORD );
131+
132+ $ this ->assertFalse ($ result );
133+ $ this ->assertEquals (
134+ self ::OTP_USER_NAME ,
135+ Registry::getSession ()->getVariable (AuthorizeService::USER_SESSION_KEY )
136+ );
137+ }
138+
139+ public function testLoginWithOTPEnabledAndInvalidCredentialsThrowsException (): void
140+ {
141+ $ this ->disableCaptcha ();
142+ $ this ->enableTwoFactorAuth ();
143+
144+ $ this ->expectException (UserException::class);
145+ $ this ->expectExceptionMessage ('ERROR_MESSAGE_USER_NOVALIDLOGIN ' );
146+
147+ $ subject = oxNew (User::class);
148+ $ subject ->login (self ::OTP_USER_NAME , uniqid ());
149+ }
150+
151+ public function testLoginWithOTPEnabledAndNonExistentUserThrowsException (): void
152+ {
153+ $ this ->disableCaptcha ();
154+ $ this ->enableTwoFactorAuth ();
113155
114156 $ this ->expectException (UserException::class);
157+ $ this ->expectExceptionMessage ('ERROR_MESSAGE_USER_NOVALIDLOGIN ' );
158+
159+ $ subject = oxNew (User::class);
160+ $ subject ->login ('nonexistent@test.com ' , 'anypassword ' );
161+ }
162+
163+ public function testLoginWithOTPDisabledCallsParentLogin (): void
164+ {
165+ $ this ->disableCaptcha ();
166+ $ this ->disableTwoFactorAuth ();
115167
116168 $ subject = oxNew (User::class);
117- $ subject ->login (uniqid (), uniqid ());
169+ $ result = $ subject ->login (self ::OTP_USER_NAME , self ::OTP_USER_PASSWORD );
170+
171+ $ this ->assertTrue ($ result );
172+ $ this ->assertNull (
173+ Registry::getSession ()->getVariable (AuthorizeService::USER_SESSION_KEY )
174+ );
175+ }
176+
177+ public function testLoginWithOTPEnabledStoresUserInSession (): void
178+ {
179+ $ this ->disableCaptcha ();
180+ $ this ->enableTwoFactorAuth ();
181+
182+ $ utilsMock = $ this ->createMock (Utils::class);
183+ $ utilsMock ->method ('redirect ' );
184+ Registry::set (Utils::class, $ utilsMock );
185+
186+ $ subject = oxNew (User::class);
187+ $ subject ->login (self ::OTP_USER_NAME , self ::OTP_USER_PASSWORD );
188+
189+ $ sessionUserName = Registry::getSession ()->getVariable (AuthorizeService::USER_SESSION_KEY );
190+ $ this ->assertEquals (self ::OTP_USER_NAME , $ sessionUserName );
191+ }
192+
193+ private function enableTwoFactorAuth (): void
194+ {
195+ $ moduleSettingService = ContainerFacade::get (ModuleSettingServiceInterface::class);
196+ $ moduleSettingService ->saveBoolean (
197+ ModuleSettingsService::ACTIVE ,
198+ true ,
199+ Module::MODULE_ID
200+ );
201+ $ moduleSettingService ->saveString (
202+ ModuleSettingsService::TWO_FACTOR_TYPE ,
203+ 'otp ' ,
204+ Module::MODULE_ID
205+ );
206+ }
207+
208+ private function disableTwoFactorAuth (): void
209+ {
210+ $ moduleSettingService = ContainerFacade::get (ModuleSettingServiceInterface::class);
211+ $ moduleSettingService ->saveBoolean (
212+ ModuleSettingsService::ACTIVE ,
213+ false ,
214+ Module::MODULE_ID
215+ );
216+ }
217+
218+ private function disableCaptcha (): void
219+ {
220+ $ captchaSettings = ContainerFacade::get (CaptchaSettingsServiceInterface::class);
221+ $ captchaSettings ->saveIsCaptchaEnabled (false );
118222 }
119223}
0 commit comments