From 27eaf777a5f9bd0bc7a87ebaf44a3e30885753c8 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Wed, 7 Aug 2019 00:15:54 +0200 Subject: [PATCH] add tests for compoment extension --- .../Component/d3_totp_UserComponent.php | 42 +- .../Component/d3_totp_UserComponentTest.php | 507 ++++++++++++++++++ 2 files changed, 541 insertions(+), 8 deletions(-) create mode 100644 src/tests/unit/Modules/Application/Component/d3_totp_UserComponentTest.php diff --git a/src/Modules/Application/Component/d3_totp_UserComponent.php b/src/Modules/Application/Component/d3_totp_UserComponent.php index e741c36..8244951 100644 --- a/src/Modules/Application/Component/d3_totp_UserComponent.php +++ b/src/Modules/Application/Component/d3_totp_UserComponent.php @@ -21,6 +21,8 @@ use Doctrine\DBAL\DBALException; use OxidEsales\Eshop\Application\Model\User; use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException; use OxidEsales\Eshop\Core\Registry; +use OxidEsales\Eshop\Core\Session; +use OxidEsales\Eshop\Core\UtilsView; class d3_totp_UserComponent extends d3_totp_UserComponent_parent { @@ -36,7 +38,7 @@ class d3_totp_UserComponent extends d3_totp_UserComponent_parent $oUser = $this->getUser(); if ($oUser && $oUser->getId()) { - $totp = oxNew(d3totp::class); + $totp = $this->d3GetTotpObject(); $totp->loadByUserId($oUser->getId()); if ($totp->isActive() @@ -58,6 +60,14 @@ class d3_totp_UserComponent extends d3_totp_UserComponent_parent } } + /** + * @return d3totp + */ + public function d3GetTotpObject() + { + return oxNew(d3totp::class); + } + /** * @throws DBALException * @throws DatabaseConnectionException @@ -70,7 +80,7 @@ class d3_totp_UserComponent extends d3_totp_UserComponent_parent $oUser = oxNew(User::class); $oUser->load($sUserId); - $totp = oxNew(d3totp::class); + $totp = $this->d3GetTotpObject(); $totp->loadByUserId($sUserId); try { @@ -81,12 +91,20 @@ class d3_totp_UserComponent extends d3_totp_UserComponent_parent return false; } } catch (d3totp_wrongOtpException $oEx) { - Registry::getUtilsView()->addErrorToDisplay($oEx, false, false, "", 'd3totplogin'); + $this->d3GetUtilsView()->addErrorToDisplay($oEx, false, false, "", 'd3totplogin'); } return 'd3totplogin'; } + /** + * @return UtilsView + */ + public function d3GetUtilsView() + { + return Registry::getUtilsView(); + } + public function cancelTotpLogin() { $this->d3TotpClearSessionVariables(); @@ -125,8 +143,8 @@ class d3_totp_UserComponent extends d3_totp_UserComponent_parent */ public function d3TotpRelogin(User $oUser, $sTotp) { - Registry::getSession()->setVariable(d3totp::TOTP_SESSION_VARNAME, $sTotp); - Registry::getSession()->setVariable('usr', $oUser->getId()); + $this->d3GetSession()->setVariable(d3totp::TOTP_SESSION_VARNAME, $sTotp); + $this->d3GetSession()->setVariable('usr', $oUser->getId()); $this->setUser(null); $this->setLoginStatus(USER_LOGIN_SUCCESS); $this->_afterLogin($oUser); @@ -134,8 +152,16 @@ class d3_totp_UserComponent extends d3_totp_UserComponent_parent public function d3TotpClearSessionVariables() { - Registry::getSession()->deleteVariable(d3totp::TOTP_SESSION_CURRENTCLASS); - Registry::getSession()->deleteVariable(d3totp::TOTP_SESSION_CURRENTUSER); - Registry::getSession()->deleteVariable(d3totp::TOTP_SESSION_NAVFORMPARAMS); + $this->d3GetSession()->deleteVariable(d3totp::TOTP_SESSION_CURRENTCLASS); + $this->d3GetSession()->deleteVariable(d3totp::TOTP_SESSION_CURRENTUSER); + $this->d3GetSession()->deleteVariable(d3totp::TOTP_SESSION_NAVFORMPARAMS); + } + + /** + * @return Session + */ + public function d3GetSession() + { + return Registry::getSession(); } } \ No newline at end of file diff --git a/src/tests/unit/Modules/Application/Component/d3_totp_UserComponentTest.php b/src/tests/unit/Modules/Application/Component/d3_totp_UserComponentTest.php new file mode 100644 index 0000000..6d746cb --- /dev/null +++ b/src/tests/unit/Modules/Application/Component/d3_totp_UserComponentTest.php @@ -0,0 +1,507 @@ + + * @link http://www.oxidmodule.com + */ + +namespace D3\Totp\tests\unit\Modules\Application\Component; + +use D3\Totp\Application\Model\d3totp; +use D3\Totp\Application\Model\Exceptions\d3totp_wrongOtpException; +use D3\Totp\Modules\Application\Component\d3_totp_UserComponent; +use D3\Totp\tests\unit\d3TotpUnitTestCase; +use OxidEsales\Eshop\Application\Component\UserComponent; +use OxidEsales\Eshop\Application\Model\User; +use OxidEsales\Eshop\Core\Controller\BaseController; +use OxidEsales\Eshop\Core\Registry; +use OxidEsales\Eshop\Core\Session; +use OxidEsales\Eshop\Core\UtilsView; +use PHPUnit_Framework_MockObject_MockObject; +use ReflectionException; + +class d3_totp_UserComponentTest extends d3TotpUnitTestCase +{ + /** @var d3_totp_UserComponent */ + protected $_oController; + + /** + * setup basic requirements + */ + public function setUp() + { + parent::setUp(); + + $this->_oController = oxNew(UserComponent::class); + + Registry::getSession()->setVariable(d3totp::TOTP_SESSION_VARNAME, false); + } + + public function tearDown() + { + parent::tearDown(); + + unset($this->_oController); + } + + /** + * @test + * @throws ReflectionException + */ + public function login_noredirectFailsIfNoUserLoggedIn() + { + $oUser = false; + + /** @var BaseController|PHPUnit_Framework_MockObject_MockObject $oParentMock */ + $oParentMock = $this->getMock(BaseController::class, array( + 'isEnabledPrivateSales', + )); + $oParentMock->method('isEnabledPrivateSales')->willReturn(false); + + /** @var d3totp|PHPUnit_Framework_MockObject_MockObject $oTotpMock */ + $oTotpMock = $this->getMock(d3totp::class, array( + 'isActive', + )); + $oTotpMock->expects($this->never())->method('isActive')->willReturn(false); + + /** @var UserComponent|PHPUnit_Framework_MockObject_MockObject $oControllerMock */ + $oControllerMock = $this->getMock(UserComponent::class, array( + 'getUser', + 'd3GetTotpObject', + 'getParent' + )); + $oControllerMock->method('getUser')->willReturn($oUser); + $oControllerMock->method('d3GetTotpObject')->willReturn($oTotpMock); + $oControllerMock->method('getParent')->willReturn($oParentMock); + + $this->_oController = $oControllerMock; + + $this->callMethod($this->_oController, 'login_noredirect'); + } + + /** + * @test + * @throws ReflectionException + */ + public function login_noredirectFailTotpNotActive() + { + /** @var User|PHPUnit_Framework_MockObject_MockObject $oUserMock */ + $oUserMock = $this->getMock(User::class, array( + 'logout', + 'getId', + )); + $oUserMock->expects($this->never())->method('logout')->willReturn(false); + $oUserMock->method('getId')->willReturn('foo'); + + /** @var BaseController|PHPUnit_Framework_MockObject_MockObject $oParentMock */ + $oParentMock = $this->getMock(BaseController::class, array( + 'isEnabledPrivateSales', + )); + $oParentMock->method('isEnabledPrivateSales')->willReturn(false); + + /** @var d3totp|PHPUnit_Framework_MockObject_MockObject $oTotpMock */ + $oTotpMock = $this->getMock(d3totp::class, array( + 'isActive', + )); + $oTotpMock->expects($this->once())->method('isActive')->willReturn(false); + + /** @var UserComponent|PHPUnit_Framework_MockObject_MockObject $oControllerMock */ + $oControllerMock = $this->getMock(UserComponent::class, array( + 'getUser', + 'd3GetTotpObject', + 'getParent' + )); + $oControllerMock->method('getUser')->willReturn($oUserMock); + $oControllerMock->method('d3GetTotpObject')->willReturn($oTotpMock); + $oControllerMock->method('getParent')->willReturn($oParentMock); + + $this->_oController = $oControllerMock; + + $this->callMethod($this->_oController, 'login_noredirect'); + } + + /** + * @test + * @throws ReflectionException + */ + public function login_noredirectPass() + { + /** @var User|PHPUnit_Framework_MockObject_MockObject $oUserMock */ + $oUserMock = $this->getMock(User::class, array( + 'logout', + 'getId', + )); + $oUserMock->expects($this->once())->method('logout')->willReturn(false); + $oUserMock->method('getId')->willReturn('foo'); + + /** @var BaseController|PHPUnit_Framework_MockObject_MockObject $oParentMock */ + $oParentMock = $this->getMock(BaseController::class, array( + 'isEnabledPrivateSales', + )); + $oParentMock->method('isEnabledPrivateSales')->willReturn(false); + + /** @var d3totp|PHPUnit_Framework_MockObject_MockObject $oTotpMock */ + $oTotpMock = $this->getMock(d3totp::class, array( + 'isActive', + )); + $oTotpMock->expects($this->once())->method('isActive')->willReturn(true); + + /** @var UserComponent|PHPUnit_Framework_MockObject_MockObject $oControllerMock */ + $oControllerMock = $this->getMock(UserComponent::class, array( + 'getUser', + 'd3GetTotpObject', + 'getParent' + )); + $oControllerMock->method('getUser')->willReturn($oUserMock); + $oControllerMock->method('d3GetTotpObject')->willReturn($oTotpMock); + $oControllerMock->method('getParent')->willReturn($oParentMock); + + $this->_oController = $oControllerMock; + + $this->assertSame( + 'd3totplogin', + $this->callMethod($this->_oController, 'login_noredirect') + ); + } + + /** + * @test + * @throws ReflectionException + */ + public function d3GetTotpObjectReturnsRightInstance() + { + $this->assertInstanceOf( + d3totp::class, + $this->callMethod($this->_oController, 'd3GetTotpObject') + ); + } + + /** + * @test + * @throws ReflectionException + */ + public function checkTotploginNoTotpLogin() + { + /** @var UserComponent|PHPUnit_Framework_MockObject_MockObject $oControllerMock */ + $oControllerMock = $this->getMock(UserComponent::class, array( + 'isNoTotpOrNoLogin', + 'hasValidTotp', + 'd3TotpRelogin' + )); + $oControllerMock->method('isNoTotpOrNoLogin')->willReturn(true); + $oControllerMock->expects($this->never())->method('hasValidTotp')->willReturn(false); + $oControllerMock->expects($this->never())->method('d3TotpRelogin')->willReturn(false); + + $this->_oController = $oControllerMock; + + $this->assertSame( + 'd3totplogin', + $this->callMethod($this->_oController, 'checkTotplogin') + ); + } + + /** + * @test + * @throws ReflectionException + */ + public function checkTotploginUnvalidTotp() + { + /** @var UtilsView|PHPUnit_Framework_MockObject_MockObject $oUtilsViewMock */ + $oUtilsViewMock = $this->getMock(UtilsView::class, array( + 'addErrorToDisplay', + )); + $oUtilsViewMock->expects($this->atLeast(1))->method('addErrorToDisplay')->willReturn(true); + + /** @var UserComponent|PHPUnit_Framework_MockObject_MockObject $oControllerMock */ + $oControllerMock = $this->getMock(UserComponent::class, array( + 'isNoTotpOrNoLogin', + 'hasValidTotp', + 'd3TotpRelogin', + 'd3GetUtilsView' + )); + $oControllerMock->method('isNoTotpOrNoLogin')->willReturn(false); + $oControllerMock->expects($this->once())->method('hasValidTotp')->willThrowException(oxNew(d3totp_wrongOtpException::class)); + $oControllerMock->expects($this->never())->method('d3TotpRelogin')->willReturn(false); + $oControllerMock->method('d3GetUtilsView')->willReturn($oUtilsViewMock); + + $this->_oController = $oControllerMock; + + $this->assertSame( + 'd3totplogin', + $this->callMethod($this->_oController, 'checkTotplogin') + ); + } + + /** + * @test + * @throws ReflectionException + */ + public function checkTotploginValidTotp() + { + /** @var UtilsView|PHPUnit_Framework_MockObject_MockObject $oUtilsViewMock */ + $oUtilsViewMock = $this->getMock(UtilsView::class, array( + 'addErrorToDisplay', + )); + $oUtilsViewMock->expects($this->never())->method('addErrorToDisplay')->willReturn(true); + + /** @var UserComponent|PHPUnit_Framework_MockObject_MockObject $oControllerMock */ + $oControllerMock = $this->getMock(UserComponent::class, array( + 'isNoTotpOrNoLogin', + 'hasValidTotp', + 'd3TotpRelogin', + 'd3GetUtilsView' + )); + $oControllerMock->method('isNoTotpOrNoLogin')->willReturn(false); + $oControllerMock->expects($this->once())->method('hasValidTotp')->willReturn(true); + $oControllerMock->expects($this->once())->method('d3TotpRelogin')->willReturn(true); + $oControllerMock->method('d3GetUtilsView')->willReturn($oUtilsViewMock); + + $this->_oController = $oControllerMock; + + $this->assertFalse( + $this->callMethod($this->_oController, 'checkTotplogin') + ); + } + + /** + * @test + * @throws ReflectionException + */ + public function d3GetUtilsViewReturnsRightInstance() + { + $this->assertInstanceOf( + UtilsView::class, + $this->callMethod($this->_oController, 'd3GetUtilsView') + ); + } + + /** + * @test + * @throws ReflectionException + */ + public function canCancelTotpLogin() + { + /** @var UserComponent|PHPUnit_Framework_MockObject_MockObject $oControllerMock */ + $oControllerMock = $this->getMock(UserComponent::class, array( + 'd3TotpClearSessionVariables', + )); + $oControllerMock->expects($this->once())->method('d3TotpClearSessionVariables')->willReturn(false); + + $this->_oController = $oControllerMock; + + $this->callMethod($this->_oController, 'cancelTotpLogin'); + } + + /** + * @test + * @throws ReflectionException + */ + public function isNoTotpOrNoLoginTrueNoSessionVariable() + { + Registry::getSession()->setVariable(d3totp::TOTP_SESSION_CURRENTUSER, false); + + /** @var d3totp|PHPUnit_Framework_MockObject_MockObject $oTotpMock */ + $oTotpMock = $this->getMock(d3totp::class, array( + 'isActive', + )); + $oTotpMock->method('isActive')->willReturn(true); + + $this->assertTrue( + $this->callMethod($this->_oController, 'isNoTotpOrNoLogin', array($oTotpMock)) + ); + } + + /** + * @test + * @throws ReflectionException + */ + public function isNoTotpOrNoLoginTrueTotpNotActive() + { + Registry::getSession()->setVariable(d3totp::TOTP_SESSION_CURRENTUSER, true); + + /** @var d3totp|PHPUnit_Framework_MockObject_MockObject $oTotpMock */ + $oTotpMock = $this->getMock(d3totp::class, array( + 'isActive', + )); + $oTotpMock->method('isActive')->willReturn(false); + + $this->assertTrue( + $this->callMethod($this->_oController, 'isNoTotpOrNoLogin', array($oTotpMock)) + ); + } + + /** + * @test + * @throws ReflectionException + */ + public function isNoTotpOrNoLoginFalse() + { + Registry::getSession()->setVariable(d3totp::TOTP_SESSION_CURRENTUSER, true); + + /** @var d3totp|PHPUnit_Framework_MockObject_MockObject $oTotpMock */ + $oTotpMock = $this->getMock(d3totp::class, array( + 'isActive', + )); + $oTotpMock->method('isActive')->willReturn(true); + + $this->assertFalse( + $this->callMethod($this->_oController, 'isNoTotpOrNoLogin', array($oTotpMock)) + ); + } + + /** + * @test + * @throws ReflectionException + */ + public function hasValidTotpTrueSessionVarname() + { + Registry::getSession()->setVariable(d3totp::TOTP_SESSION_VARNAME, true); + + /** @var d3totp|PHPUnit_Framework_MockObject_MockObject $oTotpMock */ + $oTotpMock = $this->getMock(d3totp::class, array( + 'verify', + )); + $oTotpMock->method('verify')->willReturn(false); + + $this->assertTrue( + $this->callMethod($this->_oController, 'hasValidTotp', array('123456', $oTotpMock)) + ); + } + + /** + * @test + * @throws ReflectionException + */ + public function hasValidTotpTrueValidTotp() + { + Registry::getSession()->setVariable(d3totp::TOTP_SESSION_VARNAME, false); + + /** @var d3totp|PHPUnit_Framework_MockObject_MockObject $oTotpMock */ + $oTotpMock = $this->getMock(d3totp::class, array( + 'verify', + )); + $oTotpMock->method('verify')->willReturn(true); + + $this->assertTrue( + $this->callMethod($this->_oController, 'hasValidTotp', array('123456', $oTotpMock)) + ); + } + + /** + * @test + * @throws ReflectionException + */ + public function hasValidTotpFalseMissingTotp() + { + Registry::getSession()->setVariable(d3totp::TOTP_SESSION_VARNAME, false); + + /** @var d3totp|PHPUnit_Framework_MockObject_MockObject $oTotpMock */ + $oTotpMock = $this->getMock(d3totp::class, array( + 'verify', + )); + $oTotpMock->method('verify')->willReturn(true); + + $this->assertFalse( + $this->callMethod($this->_oController, 'hasValidTotp', array(null, $oTotpMock)) + ); + } + + /** + * @test + * @throws ReflectionException + */ + public function hasValidTotpFalseUnverifiedTotp() + { + Registry::getSession()->setVariable(d3totp::TOTP_SESSION_VARNAME, false); + + /** @var d3totp|PHPUnit_Framework_MockObject_MockObject $oTotpMock */ + $oTotpMock = $this->getMock(d3totp::class, array( + 'verify', + )); + $oTotpMock->method('verify')->willReturn(false); + + $this->assertFalse( + $this->callMethod($this->_oController, 'hasValidTotp', array('123456', $oTotpMock)) + ); + } + + /** + * @test + * @throws ReflectionException + */ + public function d3TotpReloginPass() + { + /** @var Session|PHPUnit_Framework_MockObject_MockObject $oSessionMock */ + $oSessionMock = $this->getMock(Session::class, array( + 'setVariable', + )); + $oSessionMock->expects($this->atLeast(2))->method('setVariable')->willReturn(false); + + /** @var User|PHPUnit_Framework_MockObject_MockObject $oUserMock */ + $oUserMock = $this->getMock(User::class, array( + 'getId', + )); + $oUserMock->method('getId')->willReturn('foo'); + + /** @var UserComponent|PHPUnit_Framework_MockObject_MockObject $oControllerMock */ + $oControllerMock = $this->getMock(UserComponent::class, array( + 'd3GetSession', + 'setUser', + 'setLoginStatus', + '_afterLogin', + )); + $oControllerMock->method('d3GetSession')->willReturn($oSessionMock); + $oControllerMock->expects($this->once())->method('setUser')->willReturn(false); + $oControllerMock->expects($this->once())->method('setLoginStatus')->willReturn(false); + $oControllerMock->expects($this->once())->method('_afterLogin')->willReturn(false); + + $this->_oController = $oControllerMock; + + $this->callMethod($this->_oController, 'd3TotpRelogin', array($oUserMock, '123456')); + } + + /** + * @test + * @throws ReflectionException + */ + public function d3TotpClearSessionVariablesPass() + { + /** @var Session|PHPUnit_Framework_MockObject_MockObject $oSessionMock */ + $oSessionMock = $this->getMock(Session::class, array( + 'deleteVariable', + )); + $oSessionMock->expects($this->atLeast(3))->method('deleteVariable')->willReturn(false); + + /** @var UserComponent|PHPUnit_Framework_MockObject_MockObject $oControllerMock */ + $oControllerMock = $this->getMock(UserComponent::class, array( + 'd3GetSession', + )); + $oControllerMock->method('d3GetSession')->willReturn($oSessionMock); + + $this->_oController = $oControllerMock; + + $this->callMethod($this->_oController, 'd3TotpClearSessionVariables'); + } + + /** + * @test + * @throws ReflectionException + */ + public function d3GetSessionReturnsRightInstance() + { + $this->assertInstanceOf( + Session::class, + $this->callMethod($this->_oController, 'd3GetSession') + ); + } +} \ No newline at end of file