add test for totp login controller

This commit is contained in:
Daniel Seifert 2019-08-05 22:59:26 +02:00
parent d20322867d
commit ff9f1722af
6 changed files with 307 additions and 7 deletions

View File

@ -20,6 +20,7 @@ use D3\Totp\Application\Model\d3totp;
use OxidEsales\Eshop\Application\Controller\FrontendController;
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
use OxidEsales\Eshop\Core\Registry;
use OxidEsales\Eshop\Core\Utils;
class d3totplogin extends FrontendController
{
@ -30,8 +31,10 @@ class d3totplogin extends FrontendController
if (Registry::getSession()->hasVariable(d3totp::TOTP_SESSION_VARNAME) ||
false == Registry::getSession()->hasVariable(d3totp::TOTP_SESSION_CURRENTUSER)
) {
Registry::getUtils()->redirect('index.php?cl=start', true, 302);
exit;
$this->getUtils()->redirect('index.php?cl=start', true, 302);
if (false == defined('OXID_PHP_UNIT')) {
exit;
}
}
$this->addTplParam('navFormParams', Registry::getSession()->getVariable(d3totp::TOTP_SESSION_NAVFORMPARAMS));
@ -39,13 +42,21 @@ class d3totplogin extends FrontendController
return parent::render();
}
/**
* @return Utils
*/
public function getUtils()
{
return Registry::getUtils();
}
/**
* @return string|void
* @throws DatabaseConnectionException
*/
public function getBackupCodeCountMessage()
{
$oBackupCodeList = oxNew(d3backupcodelist::class);
$oBackupCodeList = $this->getBackupCodeListObject();
$iCount = $oBackupCodeList->getAvailableCodeCount(Registry::getSession()->getVariable(d3totp::TOTP_SESSION_CURRENTUSER));
if ($iCount < 4) {
@ -58,6 +69,14 @@ class d3totplogin extends FrontendController
return;
}
/**
* @return d3backupcodelist
*/
public function getBackupCodeListObject()
{
return oxNew(d3backupcodelist::class);
}
public function getPreviousClass()
{
return Registry::getSession()->getVariable(d3totp::TOTP_SESSION_CURRENTCLASS);

View File

@ -44,7 +44,7 @@ $aLang = [
'D3_TOTP_BACKUPCODES' => 'Backupcodes',
'D3_TOTP_BACKUPCODES_DESC' => 'Mit diesen Backupcodes können Sie sich anmelden, wenn die Generierung des Einmalpasswortes nicht möglich ist (z.B. Gerät verloren oder neu installiert). Sie können dann die Einstellungen zur Verwendung der 2-Faktor-Authentisierung ändern oder einen neuen Zugang erstellen. Speichern Sie sich diese Codes bitte in diesem Moment sicher ab. Nach Verlassen dieser Seite können diese Codes nicht erneut angezeigt werden.',
'D3_TOTP_AVAILBACKUPCODECOUNT' => 'noch %1$s Backupcodes verfügbar',
'D3_TOTP_AVAILBACKUPCODECOUNT' => 'noch %1$s Backupcode(s) verfügbar',
'D3_TOTP_AVAILBACKUPCODECOUNT_DESC' => 'Um neue Backupcodes zu erstellen, löschen Sie die bestehende Registrierung und legen diese bitte neu an.',
'D3_TOTP_ACCOUNT_SAVE' => 'Einstellungen übernehmen',

View File

@ -44,7 +44,7 @@ $aLang = [
'D3_TOTP_BACKUPCODES' => 'backup codes',
'D3_TOTP_BACKUPCODES_DESC' => 'You can use these backup codes to log on if it is not possible to generate the one-time password (e.g. device lost or newly installed). You can then change the settings to use 2-factor authentication or create a new account. Please save these codes securely at this moment. After leaving this page, these codes cannot be displayed again.',
'D3_TOTP_AVAILBACKUPCODECOUNT' => 'still %1$s backup codes available',
'D3_TOTP_AVAILBACKUPCODECOUNT' => 'still %1$s backup code(s) available',
'D3_TOTP_AVAILBACKUPCODECOUNT_DESC' => 'To create new backup codes, delete the existing registry and create a new one.',
'D3_TOTP_ACCOUNT_SAVE' => 'Confirm settings',

View File

@ -42,7 +42,7 @@ $aLang = [
'D3_TOTP_BACKUPCODES' => 'Backupcodes',
'D3_TOTP_BACKUPCODES_DESC' => 'Mit diesen Backupcodes können Sie sich anmelden, wenn die Generierung des Einmalpasswortes nicht möglich ist (z.B. Gerät verloren oder neu installiert). Sie können dann die Einstellungen zur Verwendung der 2-Faktor-Authentisierung ändern oder einen neuen Zugang erstellen. Speichern Sie sich diese Codes bitte in diesem Moment sicher ab. Nach Verlassen dieser Seite können diese Codes nicht erneut angezeigt werden.',
'D3_TOTP_AVAILBACKUPCODECOUNT' => 'noch %1$s Backupcodes verfügbar',
'D3_TOTP_AVAILBACKUPCODECOUNT' => 'noch %1$s Backupcode(s) verfügbar',
'D3_TOTP_AVAILBACKUPCODECOUNT_DESC' => 'Um neue Backupcodes zu erstellen, löschen Sie die bestehende Registrierung und legen diese bitte neu an.',
'D3_TOTP_SAVE' => 'Speichern',

View File

@ -42,7 +42,7 @@ $aLang = [
'D3_TOTP_BACKUPCODES' => 'backup codes',
'D3_TOTP_BACKUPCODES_DESC' => 'You can use these backup codes to log on if it is not possible to generate the one-time password (e.g. device lost or newly installed). You can then change the settings to use 2-factor authentication or create a new 2FA login. Please save these codes safely at this moment. After leaving this page, these codes cannot be displayed again.',
'D3_TOTP_AVAILBACKUPCODECOUNT' => '%1$s backup codes still available',
'D3_TOTP_AVAILBACKUPCODECOUNT' => '%1$s backup code(s) still available',
'D3_TOTP_AVAILBACKUPCODECOUNT_DESC' => 'To create new backup codes, delete the existing registry and create a new one.',
'D3_TOTP_SAVE' => 'Save',

View File

@ -0,0 +1,281 @@
<?php
/**
* This Software is the property of Data Development and is protected
* by copyright law - it is NOT Freeware.
*
* Any unauthorized use of this software without a valid license
* is a violation of the license agreement and will be prosecuted by
* civil and criminal law.
*
* http://www.shopmodule.com
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
* @link http://www.oxidmodule.com
*/
namespace D3\Totp\tests\unit\Application\Controller;
use D3\Totp\Application\Controller\d3totplogin;
use D3\Totp\Application\Model\d3backupcodelist;
use D3\Totp\Application\Model\d3totp;
use D3\Totp\tests\unit\d3TotpUnitTestCase;
use Doctrine\DBAL\DBALException;
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
use OxidEsales\Eshop\Core\Registry;
use OxidEsales\Eshop\Core\Utils;
use PHPUnit_Framework_MockObject_MockObject;
use ReflectionException;
class d3totploginTest extends d3TotpUnitTestCase
{
/** @var d3totplogin */
protected $_oController;
/**
* setup basic requirements
* @throws DBALException
* @throws DatabaseConnectionException
* @throws DatabaseErrorException
*/
public function setUp()
{
parent::setUp();
$this->_oController = oxNew(d3totplogin::class);
Registry::getSession()->deleteVariable(d3totp::TOTP_SESSION_CURRENTUSER);
Registry::getSession()->deleteVariable(d3totp::TOTP_SESSION_CURRENTCLASS);
}
public function tearDown()
{
parent::tearDown();
unset($this->_oController);
}
/**
* @test
* @throws ReflectionException
*/
public function renderRedirectIfNoTotp()
{
/** @var Utils|PHPUnit_Framework_MockObject_MockObject $oUtilsMock */
$oUtilsMock = $this->getMock(Utils::class, array(
'redirect'
));
$oUtilsMock->expects($this->once())->method('redirect')->willReturn(true);
/** @var d3totplogin|PHPUnit_Framework_MockObject_MockObject $oControllerMock */
$oControllerMock = $this->getMock(d3totplogin::class, array(
'getUtils'
));
$oControllerMock->method('getUtils')->willReturn($oUtilsMock);
$this->_oController = $oControllerMock;
$this->callMethod($this->_oController, 'render');
}
/**
* @test
* @throws ReflectionException
*/
public function renderDontRedirect()
{
Registry::getSession()->setVariable(d3totp::TOTP_SESSION_CURRENTUSER, 'foo');
/** @var Utils|PHPUnit_Framework_MockObject_MockObject $oUtilsMock */
$oUtilsMock = $this->getMock(Utils::class, array(
'redirect'
));
$oUtilsMock->expects($this->never())->method('redirect')->willReturn(true);
/** @var d3totplogin|PHPUnit_Framework_MockObject_MockObject $oControllerMock */
$oControllerMock = $this->getMock(d3totplogin::class, array(
'getUtils'
));
$oControllerMock->method('getUtils')->willReturn($oUtilsMock);
$this->_oController = $oControllerMock;
$this->assertSame(
'd3totplogin.tpl',
$this->callMethod($this->_oController, 'render')
);
}
/**
* @test
* @throws ReflectionException
*/
public function getUtilsReturnsRightInstance()
{
$this->assertInstanceOf(
Utils::class,
$this->callMethod($this->_oController, 'getUtils')
);
}
/**
* @test
* @throws ReflectionException
*/
public function getBackupCodeCountMessageReturnMessage()
{
/** @var d3backupcodelist|PHPUnit_Framework_MockObject_MockObject $oBackupCodesListMock */
$oBackupCodesListMock = $this->getMock(d3backupcodelist::class, array(
'getAvailableCodeCount'
));
$oBackupCodesListMock->method('getAvailableCodeCount')->willReturn(1);
/** @var d3totplogin|PHPUnit_Framework_MockObject_MockObject $oControllerMock */
$oControllerMock = $this->getMock(d3totplogin::class, array(
'getBackupCodeListObject'
));
$oControllerMock->method('getBackupCodeListObject')->willReturn($oBackupCodesListMock);
$this->_oController = $oControllerMock;
$this->assertGreaterThan(
0,
strpos(
$this->callMethod($this->_oController, 'getBackupCodeCountMessage'),
' 1 '
)
);
}
/**
* @test
* @throws ReflectionException
*/
public function getBackupCodeCountMessageReturnNoMessage()
{
/** @var d3backupcodelist|PHPUnit_Framework_MockObject_MockObject $oBackupCodesListMock */
$oBackupCodesListMock = $this->getMock(d3backupcodelist::class, array(
'getAvailableCodeCount'
));
$oBackupCodesListMock->method('getAvailableCodeCount')->willReturn(1234);
/** @var d3totplogin|PHPUnit_Framework_MockObject_MockObject $oControllerMock */
$oControllerMock = $this->getMock(d3totplogin::class, array(
'getBackupCodeListObject'
));
$oControllerMock->method('getBackupCodeListObject')->willReturn($oBackupCodesListMock);
$this->_oController = $oControllerMock;
$this->assertEmpty(
$this->callMethod($this->_oController, 'getBackupCodeCountMessage')
);
}
/**
* @test
* @throws ReflectionException
*/
public function getBackupCodeListObjectReturnsRightInstance()
{
$this->assertInstanceOf(
d3backupcodelist::class,
$this->callMethod($this->_oController, 'getBackupCodeListObject')
);
}
/**
* @test
* @throws ReflectionException
*/
public function canGetPreviousClass()
{
$className = "testClass";
Registry::getSession()->setVariable(d3totp::TOTP_SESSION_CURRENTCLASS, $className);
$this->assertSame(
$className,
$this->callMethod($this->_oController, 'getPreviousClass')
);
}
/**
* @test
* @throws ReflectionException
*/
public function orderClassIsOrderStep()
{
Registry::getSession()->setVariable(d3totp::TOTP_SESSION_CURRENTCLASS, 'order');
$this->assertTrue(
$this->callMethod(
$this->_oController,
'previousClassIsOrderStep'
)
);
}
/**
* @test
* @throws ReflectionException
*/
public function startClassIsNoOrderStep()
{
Registry::getSession()->setVariable(d3totp::TOTP_SESSION_CURRENTCLASS, 'start');
$this->assertFalse(
$this->callMethod(
$this->_oController,
'previousClassIsOrderStep'
)
);
}
/**
* @test
* @throws ReflectionException
*/
public function getIsOrderStepIsSameLikeOrderClass()
{
Registry::getSession()->setVariable(d3totp::TOTP_SESSION_CURRENTCLASS, 'order');
$this->assertTrue(
$this->callMethod(
$this->_oController,
'getIsOrderStep'
)
);
}
/**
* @test
* @throws ReflectionException
*/
public function getIsOrderStepIsSameLikeStartClass()
{
Registry::getSession()->setVariable(d3totp::TOTP_SESSION_CURRENTCLASS, 'start');
$this->assertFalse(
$this->callMethod(
$this->_oController,
'getIsOrderStep'
)
);
}
/**
* @test
* @throws ReflectionException
*/
public function canGetBreadCrumb()
{
$aBreadCrumb = $this->callMethod($this->_oController, 'getBreadCrumb');
$this->assertInternalType('string', $aBreadCrumb[0]['title']);
$this->assertTrue(strlen($aBreadCrumb[0]['title']) > 1);
$this->assertInternalType('string', $aBreadCrumb[0]['link']);
$this->assertTrue(strlen($aBreadCrumb[0]['link']) > 1);
}
}