Skip to content

Commit def1c57

Browse files
committed
OXDEV-9243 Add tests for honeypot and image captcha
1 parent 6fac086 commit def1c57

5 files changed

Lines changed: 235 additions & 4 deletions

File tree

tests/Codeception/Acceptance/HoneyPotCaptchaCest.php

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
use Codeception\Util\Fixtures;
1313
use OxidEsales\Codeception\Module\Translation\Translator;
14+
use OxidEsales\Codeception\Page\Account\UserLogin;
15+
use OxidEsales\Codeception\Page\Account\UserPasswordReminder;
1416
use OxidEsales\Codeception\Page\DataObject\ContactData;
1517
use OxidEsales\SecurityModule\Tests\Codeception\Support\AcceptanceTester;
1618

@@ -20,7 +22,13 @@
2022
*/
2123
class HoneyPotCaptchaCest extends BaseCest
2224
{
23-
private string $honeyPotInput = "lastname_confirm";
25+
private string $honeyPotInput = 'lastname_confirm';
26+
private string $loginForm = 'main.content form[name="login"]';
27+
private string $loginBoxForm = 'header form[name="login"]';
28+
private string $newsletterForm = 'main.content form.needs-validation';
29+
private string $contactForm = 'main.content form.needs-validation';
30+
private string $registerForm = 'main.content form[name="order"]';
31+
private string $forgotPwdForm = 'main.content form[name="forgotpwd"]';
2432

2533
public function _before(AcceptanceTester $I): void
2634
{
@@ -34,7 +42,9 @@ public function testHoneyPotCaptchaOnRegistrationPage(AcceptanceTester $I): void
3442
$registrationPage = $homePage->openUserRegistrationPage();
3543
$userData = $this->getNewUserData();
3644
$this->fillRegistrationForm($I, $userData);
37-
$I->executeJS("document.querySelector('input[name=\"$this->honeyPotInput\"]').value = 'some value';");
45+
$I->executeJS(
46+
"document.querySelector('$this->registerForm input[name=\"$this->honeyPotInput\"]').value = 'some value';"
47+
);
3848
$I->retryClick($registrationPage->saveFormButton);
3949

4050
$I->see(Translator::translate('FORM_VALIDATION_FAILED'));
@@ -49,7 +59,9 @@ public function testHoneyPotCaptchaOnContactPage(AcceptanceTester $I): void
4959
$contactData = new ContactData();
5060
$contactData->setEmail($userData['userLoginName']);
5161
$contactPage->fillInContactData($contactData);
52-
$I->executeJS("document.querySelector('input[name=\"$this->honeyPotInput\"]').value = 'some value';");
62+
$I->executeJS(
63+
"document.querySelector('$this->contactForm input[name=\"$this->honeyPotInput\"]').value = 'some value';"
64+
);
5365
$contactPage->sendContactData();
5466

5567
$I->see(Translator::translate('FORM_VALIDATION_FAILED'));
@@ -62,12 +74,65 @@ public function testHoneyPotCaptchaOnNewsletterPage(AcceptanceTester $I): void
6274

6375
$homePage = $I->openShop();
6476
$newsletterPage = $homePage->subscribeForNewsletter($userData['userLoginName']);
65-
$I->executeJS("document.querySelector('input[name=\"$this->honeyPotInput\"]').value = 'some value';");
77+
$I->executeJS(
78+
"document.querySelector('$this->newsletterForm input[name=\"$this->honeyPotInput\"]').value = 'some value';"
79+
);
6680
$newsletterPage->subscribe();
6781

6882
$I->see(Translator::translate('FORM_VALIDATION_FAILED'));
6983
}
7084

85+
public function testHoneyPotCaptchaOnLoginPage(AcceptanceTester $I): void
86+
{
87+
$userData = Fixtures::get('existingUser');
88+
89+
$userLoginPage = new UserLogin($I);
90+
$I->amOnPage($userLoginPage->URL);
91+
$I->see(Translator::translate('LOGIN'));
92+
93+
$I->executeJS(
94+
"document.querySelector('$this->loginForm input[name=\"$this->honeyPotInput\"]').value = 'some value';"
95+
);
96+
$userLoginPage->loginWithError($userData['userLoginName'], $userData['userPassword']);
97+
98+
$I->see(Translator::translate('FORM_VALIDATION_FAILED'));
99+
}
100+
101+
public function testHoneyPotCaptchaOnLoginBox(AcceptanceTester $I): void
102+
{
103+
104+
$userData = Fixtures::get('existingUser');
105+
106+
$homePage = $I->openShop();
107+
$accountMenu = $homePage->openAccountMenu();
108+
$I->waitForText(Translator::translate('FORGOT_PASSWORD'));
109+
$I->retryFillField($accountMenu->userLoginName, $userData['userLoginName']);
110+
$I->retryFillField($accountMenu->userLoginPassword, $userData['userPassword']);
111+
$I->executeJS(
112+
"document.querySelector('$this->loginBoxForm input[name=\"$this->honeyPotInput\"]').value = 'some value';"
113+
);
114+
$I->retryClick($accountMenu->userLoginButton);
115+
$I->waitForPageLoad();
116+
117+
$I->see(Translator::translate('FORM_VALIDATION_FAILED'));
118+
}
119+
120+
public function testHoneyPotCaptchaOnForgotPasswordPage(AcceptanceTester $I): void
121+
{
122+
123+
$userData = Fixtures::get('existingUser');
124+
125+
$forgotPwdPage = new UserPasswordReminder($I);
126+
$I->amOnPage($forgotPwdPage->URL);
127+
128+
$I->executeJS(
129+
"document.querySelector('$this->forgotPwdForm input[name=\"$this->honeyPotInput\"]').value = 'some value';"
130+
);
131+
$forgotPwdPage->resetPassword($userData['userLoginName']);
132+
133+
$I->see(Translator::translate('FORM_VALIDATION_FAILED'));
134+
}
135+
71136
private function fillRegistrationForm(AcceptanceTester $I, array $userData)
72137
{
73138
foreach ($userData['inputFields'] as $key => $value) {

tests/Codeception/Acceptance/ImageCaptchaVisibilityCest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Codeception\Util\Fixtures;
1414
use OxidEsales\Codeception\Module\Translation\Translator;
1515
use OxidEsales\Codeception\Page\Account\UserLogin;
16+
use OxidEsales\Codeception\Page\Account\UserPasswordReminder;
1617
use OxidEsales\SecurityModule\Tests\Codeception\Support\AcceptanceTester;
1718

1819
/**
@@ -92,6 +93,19 @@ public function testCaptchaImageOnLoginBox(AcceptanceTester $I, Example $example
9293
$this->checkVisibility($I, $example['visibility']);
9394
}
9495

96+
/**
97+
* @dataProvider captchaDataProvider
98+
*/
99+
public function testCaptchaImageOnForgotPasswordPage(AcceptanceTester $I, Example $example): void
100+
{
101+
$this->setCaptchaState($example['enabled']);
102+
103+
$forgotPwdPage = new UserPasswordReminder($I);
104+
$I->amOnPage($forgotPwdPage->URL);
105+
106+
$this->checkVisibility($I, $example['visibility']);
107+
}
108+
95109
private function checkVisibility(AcceptanceTester $I, bool $visible)
96110
{
97111
if ($visible) {
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
<?php
2+
3+
/**
4+
* Copyright © OXID eSales AG. All rights reserved.
5+
* See LICENSE file for license details.
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
namespace OxidEsales\SecurityModule\Tests\Integration\Captcha\Shop;
11+
12+
use OxidEsales\Eshop\Application\Controller\ForgotPasswordController;
13+
use OxidEsales\Eshop\Core\Registry;
14+
use OxidEsales\Eshop\Core\Request;
15+
use OxidEsales\Eshop\Core\UtilsView;
16+
use OxidEsales\EshopCommunity\Core\Di\ContainerFacade;
17+
use OxidEsales\EshopCommunity\Tests\Integration\IntegrationTestCase;
18+
use OxidEsales\SecurityModule\Captcha\Service\ModuleSettingsServiceInterface;
19+
20+
class ForgotPasswordControllerTest extends IntegrationTestCase
21+
{
22+
protected UtilsView $utilsViewMock;
23+
protected Request $requestMock;
24+
25+
public function setUp(): void
26+
{
27+
parent::setUp();
28+
29+
$moduleSettings = ContainerFacade::get(ModuleSettingsServiceInterface::class);
30+
$moduleSettings->saveIsCaptchaEnabled(true);
31+
32+
$this->utilsViewMock = $this->getMockBuilder(UtilsView::class)
33+
->disableOriginalConstructor()
34+
->onlyMethods(['addErrorToDisplay'])
35+
->getMock();
36+
37+
$this->requestMock = $this->getMockBuilder(Request::class)
38+
->disableOriginalConstructor()
39+
->onlyMethods(['getRequestParameter'])
40+
->getMock();
41+
42+
Registry::set(UtilsView::class, $this->utilsViewMock);
43+
Registry::set(Request::class, $this->requestMock);
44+
Registry::getSession()->setVariable('captcha', 'valid_captcha');
45+
Registry::getSession()->setVariable('captcha_expiration', time() + 60);
46+
}
47+
48+
public function testForgotPasswordWithValidCaptcha()
49+
{
50+
$this->requestMock
51+
->method('getRequestParameter')
52+
->willReturnCallback(function ($param) {
53+
if ($param === 'captcha') {
54+
return 'valid_captcha';
55+
}
56+
return '';
57+
});
58+
59+
$this->utilsViewMock
60+
->expects($this->any())
61+
->method('addErrorToDisplay')
62+
->willReturnCallback(function ($message) {
63+
$this->assertNotEquals('ERROR_INVALID_CAPTCHA', $message);
64+
});
65+
66+
$subject = oxNew(ForgotPasswordController::class);
67+
$subject->forgotPassword();
68+
}
69+
70+
public function testForgotPasswordWithInvalidCaptcha()
71+
{
72+
$this->requestMock
73+
->method('getRequestParameter')
74+
->with('captcha')
75+
->willReturn('invalid_captcha');
76+
77+
$this->utilsViewMock
78+
->expects($this->once())
79+
->method('addErrorToDisplay')
80+
->with('ERROR_INVALID_CAPTCHA');
81+
82+
$subject = oxNew(ForgotPasswordController::class);
83+
$subject->forgotPassword();
84+
}
85+
86+
public function testForgotPasswordWithInvalidHoneyPotCaptcha()
87+
{
88+
$this->requestMock
89+
->method('getRequestParameter')
90+
->willReturnCallback(function ($param) {
91+
if ($param === 'captcha') {
92+
return 'valid_captcha';
93+
}
94+
if ($param === 'lastname_confirm') {
95+
return 'some-text';
96+
}
97+
return '';
98+
});
99+
100+
$this->utilsViewMock
101+
->expects($this->once())
102+
->method('addErrorToDisplay')
103+
->with('FORM_VALIDATION_FAILED');
104+
105+
$subject = oxNew(ForgotPasswordController::class);
106+
$subject->forgotPassword();
107+
}
108+
109+
public function testForgotPasswordWithEmptyCaptcha()
110+
{
111+
$this->requestMock
112+
->method('getRequestParameter')
113+
->with('captcha')
114+
->willReturn('');
115+
116+
$this->utilsViewMock
117+
->expects($this->once())
118+
->method('addErrorToDisplay')
119+
->with('ERROR_EMPTY_CAPTCHA');
120+
121+
$subject = oxNew(ForgotPasswordController::class);
122+
$subject->forgotPassword();
123+
}
124+
}

tests/Integration/Captcha/Shop/NewsletterControllerTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,27 @@ public function testSendWithEmptyCaptcha()
101101
$subject = oxNew(NewsletterController::class);
102102
$subject->send();
103103
}
104+
105+
public function testSendWithInvalidHoneyPotCaptcha()
106+
{
107+
$this->requestMock
108+
->method('getRequestParameter')
109+
->willReturnCallback(function ($param) {
110+
if ($param === 'captcha') {
111+
return 'valid_captcha';
112+
}
113+
if ($param === 'lastname_confirm') {
114+
return 'some-text';
115+
}
116+
return '';
117+
});
118+
119+
$this->utilsViewMock
120+
->expects($this->once())
121+
->method('addErrorToDisplay')
122+
->with('FORM_VALIDATION_FAILED');
123+
124+
$subject = oxNew(NewsletterController::class);
125+
$subject->send();
126+
}
104127
}

tests/PhpStan/phpstan-bootstrap.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,8 @@ class_alias(
2626
\OxidEsales\Eshop\Application\Controller\NewsletterController::class,
2727
\OxidEsales\SecurityModule\Captcha\Shop\NewsletterController_parent::class
2828
);
29+
30+
class_alias(
31+
\OxidEsales\Eshop\Application\Controller\ForgotPasswordController::class,
32+
\OxidEsales\SecurityModule\Captcha\Shop\ForgotPasswordController_parent::class
33+
);

0 commit comments

Comments
 (0)