add first integration test

This commit is contained in:
Daniel Seifert 2022-11-07 16:00:53 +01:00 committed by Daniel Seifert
parent 215e0dcd36
commit eae7291120
Signed by: DanielS
GPG Key ID: 6A513E13AEE66170
10 changed files with 442 additions and 9 deletions

4
.gitignore vendored
View File

@ -1 +1,3 @@
.idea
.idea
src/tests/.phpunit.result.cache
src/tests/reports/

View File

@ -20,15 +20,8 @@ use D3\Webauthn\Application\Model\WebauthnConf;
use D3\Webauthn\Modules\Application\Model\d3_User_Webauthn;
use Doctrine\DBAL\Driver\Exception as DoctrineException;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Query\QueryBuilder;
use OxidEsales\Eshop\Application\Model\User;
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
use OxidEsales\Eshop\Core\Registry;
use OxidEsales\Eshop\Core\Session;
use OxidEsales\Eshop\Core\UtilsView;
use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory;
use OxidEsales\EshopCommunity\Internal\Framework\Database\QueryBuilderFactoryInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

View File

@ -111,6 +111,6 @@ class d3_User_Webauthn extends d3_User_Webauthn_parent
)
)->setMaxResults(1);
return $qb->execute()->fetchOne();
return $qb->execute()->fetchOne() ?: null;
}
}

View File

@ -59,6 +59,10 @@ class Events
*/
public static function onActivate()
{
if (defined('OXID_PHP_UNIT')) {
return;
}
self::setupModule();
self::regenerateViews();

52
src/tests/README.md Normal file
View File

@ -0,0 +1,52 @@
# D3 Webauthn / FIDO2 Tests
## Requirements
Both unit and acceptance tests require OXID Testing Library installed.
See https://github.com/OXID-eSales/testing_library.
### Configuration
Please install the packages listed in the composer.json in "require-dev". Unfortunately Composer does not provide an automatic installation.
Here is an example of Testing Library configuration file `oxideshop/test_config.yml`
```
# This file is auto-generated during the composer install
mandatory_parameters:
shop_path: /var/www/oxideshop/source
shop_tests_path: /var/www/oxideshop/tests
partial_module_paths: d3/oxwebauthn
optional_parameters:
shop_url: null
shop_serial: ''
enable_varnish: false
is_subshop: false
install_shop: false
remote_server_dir: null
shop_setup_path: null
restore_shop_after_tests_suite: false
test_database_name: null
restore_after_acceptance_tests: false
restore_after_unit_tests: false
tmp_path: /tmp/oxid_test_library/
database_restoration_class: DatabaseRestorer
activate_all_modules: false
run_tests_for_shop: false
run_tests_for_modules: true
screen_shots_path: null
screen_shots_url: null
browser_name: firefox
selenium_server_ip: 127.0.0.1
selenium_server_port: '4444'
additional_test_paths: null
```
## Unit Tests
To execute unit tests run the following:
```
cd /var/www/oxideshop/
PHPBIN=/usr/bin/php7.4 ./vendor/bin/runtests
```

View File

@ -0,0 +1,37 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
// Include totp test config
namespace D3\Webauthn\tests;
use D3\ModCfg\Tests\additional_abstract;
use OxidEsales\Eshop\Core\Exception\StandardException;
include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'd3webauthn_config.php');
class additional extends additional_abstract
{
/**
* additional constructor.
* @throws StandardException
*/
public function __construct()
{
if (D3WEBAUTHN_REQUIRE_MODCFG) {
$this->reactivateModCfg();
}
}
}
oxNew(additional::class);

View File

@ -0,0 +1,14 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
const D3WEBAUTHN_REQUIRE_MODCFG = false;

View File

@ -0,0 +1,173 @@
<?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.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
* @link https://www.oxidmodule.com
*/
namespace D3\Webauthn\tests\integration;
use D3\ModCfg\Application\Model\DependencyInjectionContainer\d3DicHandler;
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
use Exception;
use OxidEsales\Eshop\Application\Model\Article;
use OxidEsales\Eshop\Application\Model\User;
use OxidEsales\Eshop\Core\Model\BaseModel;
abstract class integrationTestCase extends d3ModCfgUnitTestCase
{
/**
* Set up fixture.
*/
public function setUp(): void
{
d3DicHandler::getUncompiledInstance();
parent::setUp();
$this->createTestData();
}
/**
* Tear down fixture.
*/
public function tearDown(): void
{
$this->cleanTestData();
parent::tearDown();
d3DicHandler::removeInstance();
}
abstract public function createTestData();
abstract public function cleanTestData();
/**
* @param $sClass
* @param $sId
* @param array $aFields
* @throws Exception
*/
public function createObject($sClass, $sId, $aFields = [], $blAdmin = false)
{
/** @var BaseModel $oObject */
$oObject = oxNew($sClass);
$oObject->setAdminMode($blAdmin);
if ($oObject->exists($sId)) {
$oObject->delete($sId);
}
$oObject->setId($sId);
$oObject->assign($aFields);
$oObject->save();
}
/**
* @param $sTableName
* @param $sId
* @param array $aFields
* @throws Exception
*/
public function createBaseModelObject($sTableName, $sId, $aFields = [])
{
/** @var BaseModel $oObject */
$oObject = oxNew(BaseModel::class);
$oObject->init($sTableName);
$oObject->setId($sId);
$oObject->assign($aFields);
$oObject->save();
}
/**
* @param $sId
* @param array $aFields
* @throws Exception
*/
public function createArticle($sId, $aFields = [])
{
$this->createObject(
Article::class,
$sId,
array_merge(
['oxprice' => 0],
$aFields
)
);
}
/**
* @param $sId
* @param array $aFields
* @throws Exception
*/
public function createUser($sId, $aFields = [], $blAdmin = false)
{
$this->createObject(
User::class,
$sId,
array_merge(['oxusername' => $sId], $aFields),
$blAdmin
);
}
/**
* @param $sClass
* @param $sId
*/
public function deleteObject($sClass, $sId)
{
try {
/** @var BaseModel $oObject */
$oObject = d3GetModCfgDIC()->get($sClass);
if (method_exists($oObject, 'setRights')) {
$oObject->setRights(null);
}
if ($oObject->exists($sId)) {
$oObject->delete($sId);
}
} catch (Exception $ex) {
}
}
/**
* @param $sTableName
* @param $sId
*/
public function deleteBaseModelObject($sTableName, $sId)
{
try {
/** @var BaseModel $oObject */
$oObject = oxNew(BaseModel::class);
$oObject->init($sTableName);
if (method_exists($oObject, 'setRights')) {
$oObject->setRights(null);
}
if ($oObject->exists($sId)) {
$oObject->delete($sId);
}
} catch (Exception $ex) {
}
}
/**
* @param $sId
*/
public function deleteUser($sId)
{
$this->deleteObject(User::class, $sId);
}
}

View File

@ -0,0 +1,129 @@
<?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\Webauthn\tests\integration;
use OxidEsales\Eshop\Application\Controller\Admin\LoginController;
use OxidEsales\Eshop\Application\Model\User;
use OxidEsales\Eshop\Core\DatabaseProvider;
use OxidEsales\Eshop\Core\Registry;
class passwordAdminAuthTest extends integrationTestCase
{
protected $userList = [
'1' => 'userId1',
'2' => 'userId2',
'3' => 'userId3',
'4' => 'userId4',
];
public function createTestData()
{
$admin = DatabaseProvider::getDb()->getOne('SELECT oxid FROM oxuser WHERE oxrights = "malladmin"');
Registry::getSession()->setVariable('auth', $admin);
$this->createUser(
$this->userList['1'],
[
'oxactive' => 1,
'oxrights' => 'user',
'oxshopid' => 1,
'oxusername' => 'noadmin@user.localhost',
'oxpassword' => '$2y$10$QErMJNHQCoN03tfCUQDRfOvbwvqfzwWw1iI/7bC49fKQrPKoDdnaK', // 123456
'oxstreet' => __CLASS__
],
true
);
$this->createUser(
$this->userList['2'],
[
'oxactive' => 1,
'oxrights' => 'malladmin',
'oxshopid' => 1,
'oxusername' => 'admin@user.localhost',
'oxpassword' => '$2y$10$QErMJNHQCoN03tfCUQDRfOvbwvqfzwWw1iI/7bC49fKQrPKoDdnaK', // 123456
'oxstreet' => __CLASS__
],
true
);
$this->createUser(
$this->userList['3'],
[
'oxactive' => 1,
'oxrights' => 'malladmin',
'oxshopid' => 2,
'oxusername' => 'wrongshop@user.localhost',
'oxpassword' => '$2y$10$QErMJNHQCoN03tfCUQDRfOvbwvqfzwWw1iI/7bC49fKQrPKoDdnaK', // 123456
'oxstreet' => __CLASS__
],
true
);
$this->createUser(
$this->userList['4'],
[
'oxactive' => 0,
'oxrights' => 'malladmin',
'oxshopid' => 1,
'oxusername' => 'inactive@user.localhost',
'oxpassword' => '$2y$10$QErMJNHQCoN03tfCUQDRfOvbwvqfzwWw1iI/7bC49fKQrPKoDdnaK', // 123456
'oxstreet' => __CLASS__
],
true
);
}
public function cleanTestData()
{
$this->deleteUser($this->userList[1]);
$this->deleteUser($this->userList[2]);
$this->deleteUser($this->userList[3]);
$this->deleteUser($this->userList[4]);
}
/**
* @test
* @dataProvider passwordLoginDataProvider
*/
public function testCantLoginBecauseOfNotExistingAccount($username, $password, $expected)
{
$_POST['user'] = $username;
$_POST['pwd'] = $password;
/** @var LoginController $login */
$login = oxNew(LoginController::class);
$this->assertSame(
$expected,
$login->checklogin()
);
}
/**
* @return array[]
*/
public function passwordLoginDataProvider(): array
{
return [
'not existing account' => ['unknown@user.localhost', '123456', null],
'missing password' => ['admin@user.localhost', 'null', null],
'inactive account' => ['inactive@user.localhost', '123456', null],
'no backend account' => ['noadmin@user.localhost', '123456', null],
'wrong shop account' => ['wrongshop@user.localhost', '123456', 'admin_start'],
'account ok' => ['admin@user.localhost', '123456', 'admin_start'],
];
}
}

29
src/tests/phpunit.xml Normal file
View File

@ -0,0 +1,29 @@
<phpunit backupGlobals="true"
backupStaticAttributes="false"
cacheTokens="true"
colors="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="false"
convertWarningsToExceptions="true"
forceCoversAnnotation="false"
processIsolation="false"
stopOnError="false"
stopOnFailure="false"
stopOnIncomplete="false"
stopOnSkipped="false"
verbose="false">
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">../Application</directory>
<directory suffix=".php">../Modules</directory>
<directory suffix=".php">../Setup</directory>
<exclude>
<directory suffix=".php">../Application/views</directory>
<directory suffix=".php">../Application/translations</directory>
</exclude>
</whitelist>
</filter>
<logging>
<log type="junit" target="reports/logfile.xml"/>
</logging>
</phpunit>