285 lines
12 KiB
PHP
285 lines
12 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace ElixirAudit\Tests\SeleniumTests\App\PubUsers;
|
|
|
|
use BRSystems\Core\Library\cGoogle2FA\cGoogle2FA;
|
|
use DOMDocument;
|
|
use DOMXPath;
|
|
use Facebook\WebDriver\WebDriverBy;
|
|
use ElixirAudit\Tests\BasePhpUnitSeleniumCase;
|
|
use ElixirAudit\Tests\DataSetup\Constants\siteAccounts;
|
|
use ElixirAudit\Tests\DataSetup\Constants\siteLanguages;
|
|
use ElixirAudit\Tests\DataSetup\Constants\siteUsers;
|
|
use ElixirAudit\Tests\DataSetup\Traits\App\pubUsersTrait;
|
|
|
|
class pubUserPwdResetTest extends BasePhpUnitSeleniumCase
|
|
{
|
|
use pubUsersTrait;
|
|
|
|
const url = [
|
|
siteLanguages::LANG_LV => [
|
|
'url' => 'paroles-atgusana',
|
|
'header' => 'Paroles atgūšana',
|
|
|
|
'exists' => ['#user_data', 'button.btn.btn-block'],
|
|
'text-exists' => [
|
|
'Paroles atgūšana', 'Atpakaļ uz autentifikāciju',
|
|
'Lūdzu ievadiet lietotāja e-pastu vai lietotājvārdu, kuram vēlieties atgūt paroli.'
|
|
],
|
|
|
|
'inv-user' => 'Lietotājs nav atrasts vai ir bloķēts!',
|
|
|
|
'fill-field' => 'Lūdzu aizpildiet lauku!',
|
|
'fill-email' => 'Ievadīta nekorekta e-pasta adrese!',
|
|
|
|
'email-sent' => 'E-pasts tika nosūtīts',
|
|
'email-sent-error' => 'Lietotājs nav atrasts vai ir bloķēts!',
|
|
|
|
'linksToTexts' => [
|
|
'/ienakt-gramatvedibas-sistema' => [
|
|
'wait_id' => 'user_login',
|
|
'text' => 'Ienākt grāmatvedības sistēmā',
|
|
'text_selector' => 'div#form > .relative > p.font-20.semi-font'
|
|
],
|
|
],
|
|
|
|
'email-a' => 'Atjaunot paroli',
|
|
'email-subject' => 'Konts - Paroles atjaunošana',
|
|
'email-expected-body' => [
|
|
'Labdien', 'Esam saņēmuši pieprasījumu atjaunot nozaudētu ZUTENIS konta paroli.',
|
|
'Zemāk jūs atradīsit pagaidu ģenerētu paroli, kas būs derīga 2 stundas.',
|
|
'Pagaidu parole', 'Paroli var arī atjaunot, noklikšķinot uz pogas',
|
|
'Ar cieņu', 'Nepieciešama palīdzība?', 'info@zutenis.lv',
|
|
'Jūs saņēmāt šo e-pastu, jo šī e-pasta adrese ir reģistrēta www.ZUTENIS.lv'
|
|
],
|
|
'header-3pwd' => 'Mainīt lietotāja paroli',
|
|
'pwd-change-error' => [
|
|
'Lietotāja paroles atgūšana neizdevās!',
|
|
'Lūdzu, mēģiniet vēlreiz atiestatīt paroli',
|
|
'lūdzu, sazinieties ar atbalsta dienestu!',
|
|
],
|
|
]
|
|
];
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$this->reloadDbTables(['mod_users']);
|
|
}
|
|
|
|
public function testPwdReset(): void
|
|
{
|
|
$loginData = $this->getLoginCredentialsByType(siteUsers::loginAppSelfEmployed);
|
|
|
|
foreach (self::url as $lang => $pageData) {
|
|
$this->url($pageData['url']);
|
|
$this->elementWait('user_data');
|
|
|
|
// Test error containing fields
|
|
$this->webDriver->executeScript('$("#user_data").focus().blur();');
|
|
$this->webDriver->action()->moveToElement($this->byId('user_data'))->perform();
|
|
$this->elementWait('#user_data + div.errMsg', self::CSS_SELECTOR);
|
|
$this->assertEquals($pageData['fill-field'], $this->byCssSelector('#user_data + div.errMsg')->getText());
|
|
|
|
$this->webDriver->executeScript('$("#user_data").focus().val("test").blur();');
|
|
$this->webDriver->action()->moveToElement($this->byId('user_data'))->perform();
|
|
$this->elementWait('#user_data + div.errMsg', self::CSS_SELECTOR);
|
|
$this->assertEquals($pageData['fill-email'], $this->byCssSelector('#user_data + div.errMsg')->getText());
|
|
|
|
|
|
// Input invalid login data
|
|
$this->byId("user_data")->clear()->sendKeys('test.test@gmail.com');
|
|
$this->byCssSelector("form#passRecovery_cnt button.btn.btn-block")->click();
|
|
$this->elementWait('div.status_error', self::CSS_SELECTOR);
|
|
$this->assertEquals($pageData['email-sent-error'], $this->byCssSelector('div.status_error')->getText());
|
|
|
|
$this->byId("user_data")->clear()->sendKeys($loginData['email']);
|
|
$this->byCssSelector("form#passRecovery_cnt button.btn.btn-block")->click();
|
|
$this->elementWait('div.status_ok', self::CSS_SELECTOR);
|
|
$this->assertEquals($pageData['email-sent'], $this->byCssSelector('div.status_ok')->getText());
|
|
|
|
|
|
// Fetch email from MailHog
|
|
$messages = $this->awaitEmailFromMailHog(
|
|
$loginData['email'],
|
|
$pageData['email-subject'],
|
|
60 * 5
|
|
);
|
|
|
|
// Validate mail content
|
|
$this->assertEquals($pageData['email-subject'], $this->emailHtmlDecode($messages->subject));
|
|
$this->assertExpected($pageData['email-expected-body'], $this->emailHtmlDecode($messages->body));
|
|
|
|
// Preserve user password reset db data state
|
|
$loginData['data'] = $this->cDb->_querySelectRow(
|
|
'mod_users', ['user_password', 'user_pwdtime', 'user_newpwd'], ['id' => $loginData['id']]);
|
|
|
|
|
|
// Get password reset url from mail
|
|
$doc = new DOMDocument();
|
|
$doc->loadHTML($messages->body);
|
|
|
|
$xpath = new DOMXpath($doc);
|
|
$activationUrl = $xpath->query("//a[contains(., '{$pageData['email-a']}')]")
|
|
->item(0)->attributes->item(0)->nodeValue;
|
|
$tempPassword = $xpath->query("//b[@id='pass']")->item(0)->nodeValue;
|
|
|
|
|
|
// Test password change from link case 1
|
|
//------------------------------------------------------------
|
|
$this->userPassRecoveryForm($activationUrl, $lang, $pageData, $loginData);
|
|
$this->logout();
|
|
|
|
|
|
// Test password change from link case 2 - error activation case
|
|
//------------------------------------------------------------
|
|
$this->url($activationUrl, true);
|
|
$this->elementWait('div#form div.status_error', self::CSS_SELECTOR);
|
|
$this->assertExpected($pageData['pwd-change-error'], $this->byCssSelector('div#form div.status_error')->getText());
|
|
|
|
|
|
// Test password change from link case 3 - manual password input login form
|
|
//------------------------------------------------------------
|
|
$this->url($loginData['url']);
|
|
$this->elementWait('user_login');
|
|
|
|
// Reset user db state to previous before password change
|
|
$this->cDb->_queryUpdate('mod_users', $loginData['data'], ['id' => $loginData['id']]);
|
|
|
|
// Input login data
|
|
$this->byId("user_login")->sendKeys($loginData['user']);
|
|
$this->byId("user_password")->sendKeys($tempPassword);
|
|
$this->byCssSelector("form#frm_input div#agree_to_terms")->click();
|
|
$this->byCssSelector("form#frm_input button.btn.btn-block")->click();
|
|
|
|
// Change password
|
|
$this->userPassRecoveryForm(null, $lang, $pageData, $loginData);
|
|
$this->logout();
|
|
|
|
|
|
// Test password change from link case 4 - no 2fa security - manual password input login form
|
|
//------------------------------------------------------------
|
|
$this->url($loginData['url']);
|
|
$this->elementWait('user_login');
|
|
|
|
// Reset user db state to previous before password change
|
|
$loginData['data']['user_2fa_secret_enabled'] = '';
|
|
$this->cDb->_queryUpdate('mod_users', $loginData['data'], ['id' => $loginData['id']]);
|
|
|
|
// Input login data
|
|
$this->byId("user_login")->sendKeys($loginData['user']);
|
|
$this->byId("user_password")->sendKeys($tempPassword);
|
|
$this->byCssSelector("form#frm_input div#agree_to_terms")->click();
|
|
$this->byCssSelector("form#frm_input button.btn.btn-block")->click();
|
|
|
|
// Change password
|
|
$this->userPassRecoveryForm(null, $lang, $pageData, $loginData, false);
|
|
$this->elementWait('#restricted-access a.logout', self::CSS_SELECTOR);
|
|
// Logout
|
|
$this->byCssSelector("#restricted-access a.logout")->click();
|
|
|
|
|
|
// Test password change from link case 5 - no 2fa security
|
|
//------------------------------------------------------------
|
|
// Reset user db state to previous before password change
|
|
$this->cDb->_queryUpdate('mod_users', $loginData['data'], ['id' => $loginData['id']]);
|
|
|
|
$this->userPassRecoveryForm($activationUrl, $lang, $pageData, $loginData, false);
|
|
$this->elementWait('#restricted-access a.logout', self::CSS_SELECTOR);
|
|
// Logout
|
|
$this->byCssSelector("#restricted-access a.logout")->click();
|
|
$this->reloadDbTables(['mod_users']);
|
|
}
|
|
}
|
|
|
|
public function userPassRecoveryForm(
|
|
string $url = null, string $lang = siteLanguages::LANG_LV,
|
|
array $pageData = [], array $loginData = [], bool $has2FASecurityEnabled = true
|
|
): void
|
|
{
|
|
// Activate account
|
|
if (!is_null($url)) {
|
|
$this->url($url, true);
|
|
}
|
|
|
|
if ($has2FASecurityEnabled) {
|
|
// Wait for 2FA activation request
|
|
$this->elementWait('frm_2fa_input');
|
|
|
|
// Validate 2fa code from google
|
|
$oGoogle2FA = new cGoogle2FA();
|
|
$next2FACode = $oGoogle2FA->getGoogleAuthCode($loginData['2fa']);
|
|
|
|
foreach (str_split($next2FACode) as $i => $char) {
|
|
$this->byCssSelector("input.code2fa[tabindex='" . ++$i . "']")->clear()->sendKeys($char);
|
|
}
|
|
}
|
|
|
|
// Check are we in right place
|
|
$this->elementWait('pwd_cnt');
|
|
$this->assertEquals($pageData['header-3pwd'], $this->byCssSelector('div.container .relative > p.font-20')->getText());
|
|
|
|
// Test password change
|
|
$this->fillAndSubmitPasswordChangeForm([
|
|
'newPass' => 'testmynewpassword12!@'
|
|
]);
|
|
|
|
$this->awaitAndSelectAccount(siteAccounts::ACCOUNT_SELF_EMPLOYED);
|
|
|
|
// Validate dashboard welcome messages
|
|
if ($has2FASecurityEnabled) {
|
|
$this->elementWait("#drop_cnt > .doc > .form-data div.container.dashboard-cnt", self::CSS_SELECTOR);
|
|
$this->assertExpected(pubUserLoginForcePwdChangeTest::url[$lang]['welcome-msg'], $this->byTagName('body')->getText());
|
|
}
|
|
|
|
$this->awaitAndAcceptCookies();
|
|
}
|
|
|
|
public function testLoginPageRedirectLinks(): void
|
|
{
|
|
foreach (self::url as $lang => $pageData) {
|
|
|
|
$this->url($pageData['url']);
|
|
$this->elementWait('user_data');
|
|
|
|
// Test pages clicks
|
|
$pagesToVisit = [];
|
|
$links = $this->webDriver->findElements(WebDriverBy::cssSelector('#passRecovery_cnt > a.link'));
|
|
foreach ($links as $link) {
|
|
$pagesToVisit[] = $link->getAttribute('href');
|
|
}
|
|
|
|
foreach ($pagesToVisit as $href) {
|
|
if (isset($pageData['linksToTexts'][$href])) {
|
|
$this->url($this->normalizeUrl($href));
|
|
sleep(2);
|
|
|
|
// Element Wait fails for some unknown reason
|
|
if (isset($pageData['linksToTexts'][$href]['wait_id']))
|
|
$this->elementWait($pageData['linksToTexts'][$href]['wait_id']);
|
|
elseif (isset($pageData['linksToTexts'][$href]['wait_tag']))
|
|
$this->elementWait($pageData['linksToTexts'][$href]['wait_tag'], self::TAG_NAME);
|
|
|
|
$this->assertEquals($pageData['linksToTexts'][$href]['text'], $this->byCssSelector($pageData['linksToTexts'][$href]['text_selector'])->getText());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public function testPwdResetPageLoaded(): void
|
|
{
|
|
foreach (self::url as $lang => $pageData) {
|
|
$this->url($pageData['url']);
|
|
$this->elementWait('user_data');
|
|
|
|
foreach ($pageData['exists'] as $selectorToFind) {
|
|
$this->assertTrue($this->elementExists($selectorToFind, self::CSS_SELECTOR));
|
|
}
|
|
|
|
$this->assertExpected($pageData['text-exists'], $this->byTagName('body')->getText());
|
|
}
|
|
}
|
|
}
|