From e80182f5e4a05fe1bd5e2f983f4443cab52006fc Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Fri, 9 Dec 2022 22:23:32 +0100 Subject: [PATCH] add further tests --- src/Application/Model/WebauthnAfterLogin.php | 39 ++- src/Application/Model/WebauthnErrors.php | 7 +- .../Model/WebauthnAfterLoginTest.php | 228 ++++++++++++++++++ .../Application/Model/WebauthnErrorsTest.php | 133 ++++++++++ 4 files changed, 392 insertions(+), 15 deletions(-) create mode 100644 src/tests/unit/Application/Model/WebauthnAfterLoginTest.php create mode 100644 src/tests/unit/Application/Model/WebauthnErrorsTest.php diff --git a/src/Application/Model/WebauthnAfterLogin.php b/src/Application/Model/WebauthnAfterLogin.php index c26d8fe..dbe420d 100644 --- a/src/Application/Model/WebauthnAfterLogin.php +++ b/src/Application/Model/WebauthnAfterLogin.php @@ -16,28 +16,36 @@ declare(strict_types=1); namespace D3\Webauthn\Application\Model; use D3\TestingTools\Production\IsMockable; -use OxidEsales\Eshop\Core\Registry; +use OxidEsales\Eshop\Core\Language; +use OxidEsales\Eshop\Core\Request; +use OxidEsales\Eshop\Core\Session; use OxidEsales\Eshop\Core\UtilsServer; class WebauthnAfterLogin { use IsMockable; - public function setDisplayProfile() + /** + * @return void + */ + public function setDisplayProfile(): void { - $sProfile = Registry::getRequest()->getRequestEscapedParameter('profile') ?: - Registry::getSession()->getVariable(WebauthnConf::WEBAUTHN_ADMIN_PROFILE); + $session = $this->d3GetMockableRegistryObject(Session::class); - Registry::getSession()->deleteVariable(WebauthnConf::WEBAUTHN_ADMIN_PROFILE); + $sProfile = $this->d3GetMockableRegistryObject(Request::class) + ->getRequestEscapedParameter('profile') ?: + $session->getVariable(WebauthnConf::WEBAUTHN_ADMIN_PROFILE); + + $session->deleteVariable(WebauthnConf::WEBAUTHN_ADMIN_PROFILE); $myUtilsServer = $this->d3GetMockableRegistryObject(UtilsServer::class); if (isset($sProfile)) { - $aProfiles = Registry::getSession()->getVariable("aAdminProfiles"); + $aProfiles = $session->getVariable("aAdminProfiles"); if ($aProfiles && isset($aProfiles[$sProfile])) { // setting cookie to store last locally used profile $myUtilsServer->setOxCookie("oxidadminprofile", $sProfile . "@" . implode("@", $aProfiles[$sProfile]), time() + 31536000); - Registry::getSession()->setVariable("profile", $aProfiles[$sProfile]); + $session->setVariable("profile", $aProfiles[$sProfile]); } } else { //deleting cookie info, as setting profile to default @@ -48,21 +56,26 @@ class WebauthnAfterLogin /** * @return void */ - public function changeLanguage() + public function changeLanguage(): void { $myUtilsServer = $this->d3GetMockableRegistryObject(UtilsServer::class); + $session = $this->d3GetMockableRegistryObject(Session::class); + // languages - $iLang = Registry::getRequest()->getRequestEscapedParameter('chlanguage') ?: - Registry::getSession()->getVariable(WebauthnConf::WEBAUTHN_ADMIN_CHLANGUAGE); + $iLang = $this->d3GetMockableRegistryObject(Request::class) + ->getRequestEscapedParameter('chlanguage') ?: + $session->getVariable(WebauthnConf::WEBAUTHN_ADMIN_CHLANGUAGE); - Registry::getSession()->deleteVariable(WebauthnConf::WEBAUTHN_ADMIN_CHLANGUAGE); + $session->deleteVariable(WebauthnConf::WEBAUTHN_ADMIN_CHLANGUAGE); + + $language = $this->d3GetMockableRegistryObject(Language::class); + $aLanguages = $language->getAdminTplLanguageArray(); - $aLanguages = Registry::getLang()->getAdminTplLanguageArray(); if (!isset($aLanguages[$iLang])) { $iLang = key($aLanguages); } $myUtilsServer->setOxCookie("oxidadminlanguage", $aLanguages[$iLang]->abbr, time() + 31536000); - Registry::getLang()->setTplLanguage($iLang); + $language->setTplLanguage($iLang); } } \ No newline at end of file diff --git a/src/Application/Model/WebauthnErrors.php b/src/Application/Model/WebauthnErrors.php index 2a7cfcb..aa133a8 100644 --- a/src/Application/Model/WebauthnErrors.php +++ b/src/Application/Model/WebauthnErrors.php @@ -15,10 +15,13 @@ declare(strict_types=1); namespace D3\Webauthn\Application\Model; -use OxidEsales\Eshop\Core\Registry; +use D3\TestingTools\Production\IsMockable; +use OxidEsales\Eshop\Core\Language; class WebauthnErrors { + use IsMockable; + public const INVALIDSTATE = 'invalidstateerror'; public const NOTALLWED = 'notallowederror'; public const ABORT = 'aborterror'; @@ -35,7 +38,7 @@ class WebauthnErrors */ public function translateError($msg, $type = null): string { - $lang = Registry::getLang(); + $lang = $this->d3GetMockableRegistryObject(Language::class); $type = $type ? '_'.$type : null; switch ($this->getErrIdFromMessage($msg)) { diff --git a/src/tests/unit/Application/Model/WebauthnAfterLoginTest.php b/src/tests/unit/Application/Model/WebauthnAfterLoginTest.php new file mode 100644 index 0000000..34fc078 --- /dev/null +++ b/src/tests/unit/Application/Model/WebauthnAfterLoginTest.php @@ -0,0 +1,228 @@ + + * @link https://www.oxidmodule.com + */ + +declare(strict_types=1); + +namespace D3\Webauthn\tests\unit\Application\Model; + +use D3\TestingTools\Development\CanAccessRestricted; +use D3\Webauthn\Application\Model\WebauthnAfterLogin; +use D3\Webauthn\Application\Model\WebauthnConf; +use OxidEsales\Eshop\Core\Language; +use OxidEsales\Eshop\Core\Registry; +use OxidEsales\Eshop\Core\Request; +use OxidEsales\Eshop\Core\Session; +use OxidEsales\Eshop\Core\UtilsServer; +use OxidEsales\TestingLibrary\UnitTestCase; +use PHPUnit\Framework\MockObject\MockObject; +use ReflectionException; + +class WebauthnAfterLoginTest extends UnitTestCase +{ + use CanAccessRestricted; + + /** + * @test + * @param $requestProfile + * @param $sessionProfile + * @param $setProfileCookie + * @param $setSessionVar + * @return void + * @throws ReflectionException + * @dataProvider canSetDisplayProfileDataProvider + * @covers \D3\Webauthn\Application\Model\WebauthnAfterLogin::setDisplayProfile + */ + public function canSetDisplayProfile($requestProfile, $sessionProfile, $setProfileCookie, $setSessionVar) + { + /** @var UtilsServer|MockObject $utilsServerMock */ + $utilsServerMock = $this->getMockBuilder(UtilsServer::class) + ->onlyMethods(['setOxCookie']) + ->getMock(); + $utilsServerMock->expects($this->exactly((int) $setProfileCookie))->method('setOxCookie')->with( + $this->identicalTo('oxidadminprofile'), + $this->logicalOr($this->identicalTo('1@prof@No1'), $this->identicalTo('')) + ); + + /** @var Request|MockObject $requestMock */ + $requestMock = $this->getMockBuilder(Request::class) + ->onlyMethods(['getRequestEscapedParameter']) + ->getMock(); + $requestMock->method('getRequestEscapedParameter')->willReturn($requestProfile); + + /** @var Session|MockObject $sessionMock */ + $sessionMock = $this->getMockBuilder(Session::class) + ->onlyMethods(['getVariable', 'deleteVariable', 'setVariable']) + ->getMock(); + $sessionMock->method('getVariable')->willReturnMap([ + [WebauthnConf::WEBAUTHN_ADMIN_PROFILE, $sessionProfile], + ['aAdminProfiles', [['prof','No0'], ['prof', 'No1'], ['prof','No2']]] + ]); + $sessionMock->expects($this->once())->method('deleteVariable'); + $sessionMock->expects($this->exactly((int) $setSessionVar))->method('setVariable'); + + /** @var WebauthnAfterLogin|MockObject $sut */ + $sut = $this->getMockBuilder(WebauthnAfterLogin::class) + ->onlyMethods(['d3GetMockableRegistryObject']) + ->getMock(); + $sut->method('d3GetMockableRegistryObject')->willReturnCallback( + function () use ($sessionMock, $requestMock, $utilsServerMock) { + $args = func_get_args(); + switch ($args[0]) { + case Session::class: + return $sessionMock; + case Request::class: + return $requestMock; + case UtilsServer::class: + return $utilsServerMock; + default: + return Registry::get($args[0]); + } + } + ); + + $this->callMethod( + $sut, + 'setDisplayProfile' + ); + } + + /** + * @return array[] + */ + public function canSetDisplayProfileDataProvider(): array + { + return [ + 'valid request profile' => [1, null, true, true], + 'invalid request profile' => ['23', null, false, false], + 'valid session profile' => [null, 1, true, true], + 'invalid session profile' => [null, '23', false, false], + 'no profile selected' => [null, null, true, false], + ]; + } + + /** + * @test + * @param $requestLang + * @param $sessionLang + * @param $expectedLang + * @return void + * @throws ReflectionException + * @dataProvider canChangeLanguageDataProvider + * @covers \D3\Webauthn\Application\Model\WebauthnAfterLogin::changeLanguage + */ + public function canChangeLanguage($requestLang, $sessionLang, $expectedLang, $expectedAbbr) + { + /** @var Language|MockObject $languageMock */ + $languageMock = $this->getMockBuilder(Language::class) + ->onlyMethods(['getAdminTplLanguageArray', 'setTplLanguage']) + ->getMock(); + $languageMock->method('getAdminTplLanguageArray')->willReturn( + $this->getConfiguredLanguageStub() + ); + $languageMock->expects($this->once())->method('setTplLanguage') + ->with($this->identicalTo($expectedLang)); + + /** @var UtilsServer|MockObject $utilsServerMock */ + $utilsServerMock = $this->getMockBuilder(UtilsServer::class) + ->onlyMethods(['setOxCookie']) + ->getMock(); + $utilsServerMock->expects($this->once())->method('setOxCookie')->with( + $this->identicalTo('oxidadminlanguage'), + $this->identicalTo($expectedAbbr) + ); + + /** @var Request|MockObject $requestMock */ + $requestMock = $this->getMockBuilder(Request::class) + ->onlyMethods(['getRequestEscapedParameter']) + ->getMock(); + $requestMock->method('getRequestEscapedParameter')->willReturn($requestLang); + + /** @var Session|MockObject $sessionMock */ + $sessionMock = $this->getMockBuilder(Session::class) + ->onlyMethods(['getVariable', 'deleteVariable']) + ->getMock(); + $sessionMock->method('getVariable')->willReturnMap([ + [WebauthnConf::WEBAUTHN_ADMIN_CHLANGUAGE, $sessionLang], + ]); + $sessionMock->expects($this->once())->method('deleteVariable'); + + /** @var WebauthnAfterLogin|MockObject $sut */ + $sut = $this->getMockBuilder(WebauthnAfterLogin::class) + ->onlyMethods(['d3GetMockableRegistryObject']) + ->getMock(); + $sut->method('d3GetMockableRegistryObject')->willReturnCallback( + function () use ($sessionMock, $requestMock, $utilsServerMock, $languageMock) { + $args = func_get_args(); + switch ($args[0]) { + case Session::class: + return $sessionMock; + case Request::class: + return $requestMock; + case UtilsServer::class: + return $utilsServerMock; + case Language::class: + return $languageMock; + default: + return Registry::get($args[0]); + } + } + ); + + $this->callMethod( + $sut, + 'changeLanguage' + ); + } + + /** + * @return array + */ + public function getConfiguredLanguageStub(): array + { + $de_1 = oxNew(\stdClass::class); + $de_1->id = 0; + $de_1->oxid = 'de'; + $de_1->abbr = 'de'; + $de_1->name = 'Deutsch'; + $de_1->active = '1'; + $de_1->sort = '1'; + $de_1->selected = 0; + + $en_2 = oxNew(\stdClass::class); + $en_2->id = 1; + $en_2->oxid = 'en'; + $en_2->abbr = 'en'; + $en_2->name = 'English'; + $en_2->active = '1'; + $en_2->sort = '2'; + $en_2->selected = 0; + return [ + $de_1, + $en_2 + ]; + } + + /** + * @return array[] + */ + public function canChangeLanguageDataProvider(): array + { + return [ + 'valid request language' => [1, null, 1, 'en'], + 'invalid request language' => [25, null, 0, 'de'], + 'valid session language' => [null, 1, 1, 'en'], + 'invalid session language' => [null, 25, 0, 'de'], + 'no selected language' => [null, null, 0, 'de'], + ]; + } +} \ No newline at end of file diff --git a/src/tests/unit/Application/Model/WebauthnErrorsTest.php b/src/tests/unit/Application/Model/WebauthnErrorsTest.php new file mode 100644 index 0000000..220d5fe --- /dev/null +++ b/src/tests/unit/Application/Model/WebauthnErrorsTest.php @@ -0,0 +1,133 @@ + + * @link https://www.oxidmodule.com + */ + +declare(strict_types=1); + +namespace D3\Webauthn\tests\unit\Application\Model; + +use D3\TestingTools\Development\CanAccessRestricted; +use D3\Webauthn\Application\Model\WebauthnErrors; +use OxidEsales\Eshop\Core\Language; +use OxidEsales\Eshop\Core\Registry; +use OxidEsales\TestingLibrary\UnitTestCase; +use PHPUnit\Framework\MockObject\MockObject; +use ReflectionException; + +class WebauthnErrorsTest extends UnitTestCase +{ + use CanAccessRestricted; + + /** + * @test + * @param $errId + * @param $message + * @param $expectedTranslationIdPart + * @return void + * @throws ReflectionException + * @dataProvider canTranslateErrorDataProvider + * @covers \D3\Webauthn\Application\Model\WebauthnErrors::translateError + */ + public function canTranslateError($errId, $message, $expectedTranslationIdPart) + { + /** @var Language|MockObject $languageMock */ + $languageMock = $this->getMockBuilder(Language::class) + ->onlyMethods(['translateString']) + ->getMock(); + $languageMock->expects($this->once())->method('translateString')->with( + $this->callback( + function ($value) use ($expectedTranslationIdPart) { + return (bool) strstr($value, $expectedTranslationIdPart); + } + ) + )->willReturn('translated'); + + /** @var WebauthnErrors|MockObject $sut */ + $sut = $this->getMockBuilder(WebauthnErrors::class) + ->onlyMethods(['d3GetMockableRegistryObject', 'getErrIdFromMessage']) + ->getMock(); + $sut->method('d3GetMockableRegistryObject')->willReturnCallback( + function () use ($languageMock) { + $args = func_get_args(); + switch ($args[0]) { + case Language::class: + return $languageMock; + default: + return Registry::get($args[0]); + } + } + ); + $sut->method('getErrIdFromMessage')->willReturn($errId); + + $this->assertSame( + 'translated', + $this->callMethod( + $sut, + 'translateError', + [$message] + ) + ); + } + + /** + * @return array + */ + public function canTranslateErrorDataProvider(): array + { + return [ + 'invalid state' => [WebauthnErrors::INVALIDSTATE, 'myMsg', 'INVALIDSTATE'], + 'not allowed' => [WebauthnErrors::NOTALLWED, 'myMsg', 'NOTALLOWED'], + 'abort' => [WebauthnErrors::ABORT, 'myMsg', 'ABORT'], + 'constraint' => [WebauthnErrors::CONSTRAINT, 'myMsg', 'CONSTRAINT'], + 'not supported' => [WebauthnErrors::NOTSUPPORTED, 'myMsg', 'NOTSUPPORTED'], + 'unknown' => [WebauthnErrors::UNKNOWN, 'myMsg', 'UNKNOWN'], + 'no pubkey sppt'=> [WebauthnErrors::NOPUBKEYSUPPORT, 'myMsg', 'NOPUBKEYSUPPORT'], + 'unsecure' => ['other', strtoupper(WebauthnErrors::UNSECURECONNECTION), strtoupper(WebauthnErrors::UNSECURECONNECTION)], + 'other' => ['other', 'other', 'TECHNICALERROR'], + ]; + } + + /** + * @test + * @param $message + * @param $expected + * @return void + * @throws ReflectionException + * @dataProvider canGetErrIdFromMessageDataProvider + * @covers \D3\Webauthn\Application\Model\WebauthnErrors::getErrIdFromMessage + */ + public function canGetErrIdFromMessage($message, $expected) + { + /** @var WebauthnErrors $sut */ + $sut = oxNew(WebauthnErrors::class); + + $this->assertSame( + $expected, + $this->callMethod( + $sut, + 'getErrIdFromMessage', + [$message] + ) + ); + } + + /** + * @return array[] + */ + public function canGetErrIdFromMessageDataProvider(): array + { + return [ + 'with colon' => [' My Text With : Colon', 'my text with'], + 'without colon' => [' My Text With Colon', 'my text with colon'] + ]; + } +} \ No newline at end of file