add migrations
Cette révision appartient à :
Parent
028fc05d54
révision
462bb34447
|
@ -63,12 +63,14 @@ and its requirements.
|
|||
|
||||
The Flow and Wave themes are supported by default. Other themes may require customisation.
|
||||
|
||||
## Module installation
|
||||
## Module installation / update
|
||||
|
||||
Open a command line interface and navigate to the shop root directory (parent of source and vendor). Execute the following command. Adapt the paths to your environment.
|
||||
Open a command line interface and navigate to the shop root directory (parent of source and vendor). Execute the following commands. Adapt the paths to your environment.
|
||||
|
||||
```bash
|
||||
php composer require d3/oxid-twofactor-passwordless:^1.0
|
||||
composer require d3/oxid-twofactor-passwordless:^1.0
|
||||
|
||||
./vendor/bin/oe-eshop-db_migrate migrations:migrate d3webauthn
|
||||
```
|
||||
|
||||
If a reference to an unsuitable package `symfony/process` is shown, this must be changed. To do this, please add the switch `-W` to the above command (`... require -W ...`).
|
||||
|
|
|
@ -63,12 +63,14 @@ und dessen Anforderungen.
|
|||
|
||||
Im Standard wird das Flow- und Wave-Theme unterstützt. Andere Themes können Anpassungen erfordern.
|
||||
|
||||
## Modulinstallation
|
||||
## Modulinstallation / -update
|
||||
|
||||
Öffnen Sie eine Kommandozeile und navigieren Sie zum Stammverzeichnis des Shops (Elternverzeichnis von source und vendor). Führen Sie den folgenden Befehl aus. Passen Sie die Pfadangaben an Ihre Installationsumgebung an.
|
||||
Öffnen Sie eine Kommandozeile und navigieren Sie zum Stammverzeichnis des Shops (Elternverzeichnis von source und vendor). Führen Sie die folgenden Befehle aus. Passen Sie die Pfadangaben an Ihre Installationsumgebung an.
|
||||
|
||||
```bash
|
||||
php composer require d3/oxid-twofactor-passwordless:^1.0
|
||||
composer require d3/oxid-twofactor-passwordless:^1.0
|
||||
|
||||
./vendor/bin/oe-eshop-db_migrate migrations:migrate d3webauthn
|
||||
```
|
||||
|
||||
Wird ein Hinweis auf ein unpassendes Paket "symfony/process" gezeigt, muss dieses geändert werden. Fügen Sie dazu in den oben genannten Befehl bitte den Schalter `-W` ein (`... require -W ...`).
|
||||
|
|
|
@ -55,7 +55,8 @@
|
|||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"D3\\Webauthn\\": "../../../source/modules/d3/oxwebauthn"
|
||||
"D3\\Webauthn\\": "../../../source/modules/d3/oxwebauthn",
|
||||
"D3\\Webauthn\\Migrations\\": "../../../source/modules/d3/oxwebauthn/migration/data"
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
|
|
|
@ -19,7 +19,7 @@ use Assert\Assert;
|
|||
use Assert\AssertionFailedException;
|
||||
use Assert\InvalidArgumentException;
|
||||
use D3\TestingTools\Production\IsMockable;
|
||||
use D3\Webauthn\Setup\Actions;
|
||||
use D3\Webauthn\Migrations\Version20230209212939;
|
||||
use DateTime;
|
||||
use Doctrine\DBAL\Driver\Exception as DoctrineDriverException;
|
||||
use Doctrine\DBAL\Exception as DoctrineException;
|
||||
|
@ -76,7 +76,7 @@ class PublicKeyCredential extends BaseModel
|
|||
|
||||
Assert::that($encodedCID)
|
||||
->maxLength(
|
||||
Actions::FIELDLENGTH_CREDID,
|
||||
Version20230209212939::FIELDLENGTH_CREDID,
|
||||
'the credentialId (%3$d) does not fit into the database field (%2$d)'
|
||||
);
|
||||
|
||||
|
@ -126,7 +126,7 @@ class PublicKeyCredential extends BaseModel
|
|||
|
||||
Assert::that($encodedCredential)
|
||||
->maxLength(
|
||||
Actions::FIELDLENGTH_CREDENTIAL,
|
||||
Version20230209212939::FIELDLENGTH_CREDENTIAL,
|
||||
'the credential source (%3$d) does not fit into the database field (%2$d)',
|
||||
);
|
||||
|
||||
|
|
|
@ -110,10 +110,10 @@ class WebauthnLogin
|
|||
{
|
||||
/** @var UtilsView $myUtilsView */
|
||||
$myUtilsView = d3GetOxidDIC()->get('d3ox.webauthn.'.UtilsView::class);
|
||||
/** @var d3_User_Webauthn $user */
|
||||
$user = d3GetOxidDIC()->get('d3ox.webauthn.'.User::class);
|
||||
|
||||
try {
|
||||
/** @var d3_User_Webauthn $user */
|
||||
$user = d3GetOxidDIC()->get('d3ox.webauthn.'.User::class);
|
||||
$userId = $this->getUserId();
|
||||
|
||||
$this->handleErrorMessage();
|
||||
|
@ -158,10 +158,10 @@ class WebauthnLogin
|
|||
{
|
||||
/** @var UtilsView $myUtilsView */
|
||||
$myUtilsView = d3GetOxidDIC()->get('d3ox.webauthn.'.UtilsView::class);
|
||||
/** @var d3_User_Webauthn $user */
|
||||
$user = d3GetOxidDIC()->get('d3ox.webauthn.'.User::class);
|
||||
|
||||
try {
|
||||
/** @var d3_User_Webauthn $user */
|
||||
$user = d3GetOxidDIC()->get('d3ox.webauthn.'.User::class);
|
||||
$userId = $this->getUserId();
|
||||
|
||||
$this->handleErrorMessage();
|
||||
|
@ -195,8 +195,6 @@ class WebauthnLogin
|
|||
|
||||
$user->logout();
|
||||
$oStr = Str::getStr();
|
||||
d3GetOxidDIC()->get('d3ox.webauthn.'.Config::class)->getActiveView()
|
||||
->addTplParam('user', $oStr->htmlspecialchars($userId));
|
||||
d3GetOxidDIC()->get('d3ox.webauthn.'.Config::class)->getActiveView()
|
||||
->addTplParam('profile', $oStr->htmlspecialchars($selectedProfile));
|
||||
|
||||
|
|
|
@ -135,4 +135,11 @@ services:
|
|||
- 'getDb'
|
||||
arguments:
|
||||
- 2
|
||||
shared: true
|
||||
shared: true
|
||||
|
||||
d3ox.webauthn.OxidEsales\DoctrineMigrationWrapper\MigrationsBuilder:
|
||||
class: 'OxidEsales\DoctrineMigrationWrapper\MigrationsBuilder'
|
||||
factory: 'oxNew'
|
||||
arguments:
|
||||
- 'OxidEsales\DoctrineMigrationWrapper\MigrationsBuilder'
|
||||
shared: false
|
|
@ -18,12 +18,10 @@ namespace D3\Webauthn\Setup;
|
|||
use D3\TestingTools\Production\IsMockable;
|
||||
use Doctrine\DBAL\Driver\Exception as DoctrineDriverException;
|
||||
use Exception;
|
||||
use OxidEsales\DoctrineMigrationWrapper\MigrationsBuilder;
|
||||
use OxidEsales\Eshop\Application\Controller\FrontendController;
|
||||
use OxidEsales\Eshop\Core\Config;
|
||||
use OxidEsales\Eshop\Core\Database\Adapter\DatabaseInterface;
|
||||
use OxidEsales\Eshop\Core\DbMetaDataHandler;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
|
||||
use OxidEsales\Eshop\Core\SeoEncoder;
|
||||
use OxidEsales\Eshop\Core\Utils;
|
||||
use OxidEsales\Eshop\Core\UtilsView;
|
||||
|
@ -39,93 +37,17 @@ use Psr\Log\LoggerInterface;
|
|||
class Actions
|
||||
{
|
||||
use IsMockable;
|
||||
public const FIELDLENGTH_CREDID = 512;
|
||||
public const FIELDLENGTH_CREDENTIAL = 2000;
|
||||
|
||||
public $seo_de = 'sicherheitsschluessel';
|
||||
public $seo_en = 'en/key-authentication';
|
||||
public $stdClassName = 'd3_account_webauthn';
|
||||
|
||||
/**
|
||||
* SQL statement, that will be executed only at the first time of module installation.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $createCredentialSql =
|
||||
"CREATE TABLE `d3wa_usercredentials` (
|
||||
`OXID` char(32) NOT NULL,
|
||||
`OXUSERID` char(32) NOT NULL,
|
||||
`OXSHOPID` int(11) NOT NULL,
|
||||
`NAME` varchar(100) NOT NULL,
|
||||
`CREDENTIALID` varchar(".self::FIELDLENGTH_CREDID.") NOT NULL,
|
||||
`CREDENTIAL` varchar(".self::FIELDLENGTH_CREDENTIAL.") NOT NULL,
|
||||
`OXTIMESTAMP` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||
PRIMARY KEY (`OXID`),
|
||||
KEY `CREDENTIALID_IDX` (`CREDENTIALID`),
|
||||
KEY `SHOPUSER_IDX` (`OXUSERID`,`OXSHOPID`) USING BTREE
|
||||
) ENGINE=InnoDB COMMENT='WebAuthn Credentials';";
|
||||
|
||||
/**
|
||||
* Execute the sql at the first time of the module installation.
|
||||
* @return void
|
||||
* @throws DatabaseConnectionException
|
||||
* @throws DatabaseErrorException
|
||||
*/
|
||||
public function setupModule()
|
||||
public function runModuleMigrations()
|
||||
{
|
||||
if (!$this->tableExists('d3wa_usercredentials')) {
|
||||
$this->executeSQL($this->createCredentialSql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if table exists
|
||||
*
|
||||
* @param string $sTableName table name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function tableExists(string $sTableName): bool
|
||||
{
|
||||
$oDbMetaDataHandler = d3GetOxidDIC()->get('d3ox.webauthn.'.DbMetaDataHandler::class);
|
||||
return $oDbMetaDataHandler->tableExists($sTableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DatabaseInterface|null
|
||||
* @throws DatabaseConnectionException
|
||||
*/
|
||||
protected function d3GetDb(): ?DatabaseInterface
|
||||
{
|
||||
/** @var DatabaseInterface $db */
|
||||
$db = d3GetOxidDIC()->get('d3ox.webauthn.'.DatabaseInterface::class.'.assoc');
|
||||
return $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes given sql statement.
|
||||
*
|
||||
* @param string $sSQL Sql to execute.
|
||||
* @throws DatabaseConnectionException
|
||||
* @throws DatabaseErrorException
|
||||
*/
|
||||
public function executeSQL(string $sSQL)
|
||||
{
|
||||
$this->d3GetDb()->execute($sSQL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if field exists in table
|
||||
*
|
||||
* @param string $sFieldName field name
|
||||
* @param string $sTableName table name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function fieldExists(string $sFieldName, string $sTableName): bool
|
||||
{
|
||||
$oDbMetaDataHandler = d3GetOxidDIC()->get('d3ox.webauthn.'.DbMetaDataHandler::class);
|
||||
return $oDbMetaDataHandler->fieldExists($sFieldName, $sTableName);
|
||||
/** @var MigrationsBuilder $migrationsBuilder */
|
||||
$migrationsBuilder = d3GetOxidDIC()->get('d3ox.webauthn.'.MigrationsBuilder::class);
|
||||
$migrations = $migrationsBuilder->build();
|
||||
$migrations->execute('migrations:migrate', 'd3webauthn');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -34,7 +34,7 @@ class Events
|
|||
}
|
||||
|
||||
$actions = oxNew(Actions::class);
|
||||
$actions->setupModule();
|
||||
$actions->runModuleMigrations();
|
||||
$actions->regenerateViews();
|
||||
$actions->clearCache();
|
||||
$actions->seoUrl();
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
<?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
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\Webauthn\Migrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\DBAL\Types\DateTimeType;
|
||||
use Doctrine\DBAL\Types\IntegerType;
|
||||
use Doctrine\DBAL\Types\StringType;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
final class Version20230209212939 extends AbstractMigration
|
||||
{
|
||||
public const FIELDLENGTH_CREDID = 512;
|
||||
public const FIELDLENGTH_CREDENTIAL = 2000;
|
||||
|
||||
public function getDescription() : string
|
||||
{
|
||||
return 'create credential database table';
|
||||
}
|
||||
|
||||
public function up(Schema $schema) : void
|
||||
{
|
||||
$this->connection->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
|
||||
|
||||
$table = !$schema->hasTable('d3wa_usercredentials') ?
|
||||
$schema->createTable('d3wa_usercredentials') :
|
||||
$schema->getTable('d3wa_usercredentials');
|
||||
|
||||
if (!$table->hasColumn('OXID')) {
|
||||
$table->addColumn('OXID', (new StringType())->getName())
|
||||
->setLength(32)
|
||||
->setFixed(true)
|
||||
->setNotnull(true);
|
||||
}
|
||||
|
||||
if (!$table->hasColumn('OXUSERID')) {
|
||||
$table->addColumn('OXUSERID', (new StringType())->getName())
|
||||
->setLength(32)
|
||||
->setFixed(true)
|
||||
->setNotnull(true);
|
||||
}
|
||||
|
||||
if (!$table->hasColumn('OXSHOPID')) {
|
||||
$table->addColumn('OXSHOPID', (new IntegerType())->getName())
|
||||
->setLength(11)
|
||||
->setNotnull(true);
|
||||
}
|
||||
|
||||
if (!$table->hasColumn('NAME')) {
|
||||
$table->addColumn('NAME', (new StringType())->getName())
|
||||
->setLength(100)
|
||||
->setFixed(false)
|
||||
->setNotnull(true);
|
||||
}
|
||||
|
||||
if (!$table->hasColumn('CREDENTIALID')) {
|
||||
$table->addColumn('CREDENTIALID', (new StringType())->getName())
|
||||
->setLength(self::FIELDLENGTH_CREDID)
|
||||
->setFixed(false)
|
||||
->setNotnull(true);
|
||||
}
|
||||
|
||||
if (!$table->hasColumn('CREDENTIAL')) {
|
||||
$table->addColumn('CREDENTIAL', (new StringType())->getName())
|
||||
->setLength(self::FIELDLENGTH_CREDENTIAL)
|
||||
->setFixed(false)
|
||||
->setNotnull(true);
|
||||
}
|
||||
|
||||
if (!$table->hasColumn('OXTIMESTAMP')) {
|
||||
$table->addColumn('OXTIMESTAMP', (new DateTimeType())->getName())
|
||||
->setType(new DateTimeType())
|
||||
->setNotnull(true)
|
||||
// can't set default value via default method
|
||||
->setColumnDefinition('timestamp DEFAULT CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP');
|
||||
}
|
||||
|
||||
if (!$table->hasPrimaryKey()) {
|
||||
$table->setPrimaryKey(['OXID']);
|
||||
}
|
||||
|
||||
if (!$table->hasIndex('SHOPUSER_IDX')) {
|
||||
$table->addIndex(['OXUSERID', 'OXSHOPID'], 'SHOPUSER_IDX');
|
||||
}
|
||||
|
||||
if (!$table->hasIndex('CREDENTIALID_IDX')) {
|
||||
$table->addIndex(['CREDENTIALID'], 'CREDENTIALID_IDX');
|
||||
}
|
||||
|
||||
$table->setComment('WebAuthn Credentials');
|
||||
}
|
||||
|
||||
public function down(Schema $schema) : void
|
||||
{
|
||||
if ($schema->hasTable('d3wa_usercredentials')) {
|
||||
$schema->dropTable('d3wa_usercredentials');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
name: D3 Twofactor Passwordless
|
||||
migrations_namespace: D3\Webauthn\Migrations
|
||||
table_name: d3wa_migrations
|
||||
migrations_directory: data
|
|
@ -15,6 +15,7 @@
|
|||
<filter>
|
||||
<whitelist processUncoveredFilesFromWhitelist="true">
|
||||
<directory suffix=".php">../Application</directory>
|
||||
<directory suffix=".php">../migration</directory>
|
||||
<directory suffix=".php">../Modules</directory>
|
||||
<directory suffix=".php">../Setup</directory>
|
||||
<exclude>
|
||||
|
|
|
@ -19,9 +19,9 @@ use D3\TestingTools\Development\CanAccessRestricted;
|
|||
use D3\Webauthn\Setup\Actions;
|
||||
use D3\Webauthn\tests\unit\WAUnitTestCase;
|
||||
use Exception;
|
||||
use OxidEsales\DoctrineMigrationWrapper\Migrations;
|
||||
use OxidEsales\DoctrineMigrationWrapper\MigrationsBuilder;
|
||||
use OxidEsales\Eshop\Application\Controller\FrontendController;
|
||||
use OxidEsales\Eshop\Core\Database\Adapter\DatabaseInterface;
|
||||
use OxidEsales\Eshop\Core\Database\Adapter\Doctrine\Database;
|
||||
use OxidEsales\Eshop\Core\DbMetaDataHandler;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
use OxidEsales\Eshop\Core\SeoEncoder;
|
||||
|
@ -45,141 +45,35 @@ class ActionsTest extends WAUnitTestCase
|
|||
|
||||
/**
|
||||
* @test
|
||||
* @param $tableExist
|
||||
* @param $expectedInvocation
|
||||
* @return void
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\Webauthn\Setup\Actions::setupModule
|
||||
* @dataProvider canSetupModuleDataProvider
|
||||
* @covers \D3\Webauthn\Setup\Actions::runModuleMigrations()
|
||||
*/
|
||||
public function canSetupModule($tableExist, $expectedInvocation)
|
||||
public function canRunModuleMigrations()
|
||||
{
|
||||
/** @var Actions|MockObject $sut */
|
||||
$sut = $this->getMockBuilder(Actions::class)
|
||||
->onlyMethods(['tableExists', 'executeSQL'])
|
||||
->getMock();
|
||||
$sut->method('tableExists')->willReturn($tableExist);
|
||||
$sut->expects($expectedInvocation)->method('executeSQL')->willReturn(true);
|
||||
|
||||
$this->callMethod(
|
||||
$sut,
|
||||
'setupModule'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
*/
|
||||
public function canSetupModuleDataProvider(): array
|
||||
{
|
||||
return [
|
||||
'table exist' => [true, $this->never()],
|
||||
'table not exist' => [false, $this->once()],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @return void
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\Webauthn\Setup\Actions::tableExists
|
||||
*/
|
||||
public function canCheckTableExists()
|
||||
{
|
||||
$expected = true;
|
||||
|
||||
/** @var DbMetaDataHandler|MockObject $DbMetaDataMock */
|
||||
$DbMetaDataMock = $this->getMockBuilder(DbMetaDataHandler::class)
|
||||
->onlyMethods(['tableExists'])
|
||||
->getMock();
|
||||
$DbMetaDataMock->expects($this->once())->method('tableExists')->willReturn($expected);
|
||||
d3GetOxidDIC()->set('d3ox.webauthn.'.DbMetaDataHandler::class, $DbMetaDataMock);
|
||||
|
||||
/** @var Actions $sut */
|
||||
$sut = oxNew(Actions::class);
|
||||
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$this->callMethod(
|
||||
$sut,
|
||||
'tableExists',
|
||||
['testTable']
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @return void
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\Webauthn\Setup\Actions::d3GetDb
|
||||
*/
|
||||
public function d3GetDbReturnsRightInstance()
|
||||
{
|
||||
$sut = oxNew(Actions::class);
|
||||
|
||||
$this->assertInstanceOf(
|
||||
DatabaseInterface::class,
|
||||
$this->callMethod(
|
||||
$sut,
|
||||
'd3GetDb'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @return void
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\Webauthn\Setup\Actions::executeSQL
|
||||
*/
|
||||
public function canExecuteSQL()
|
||||
{
|
||||
/** @var Database|MockObject $dbMock */
|
||||
$dbMock = $this->getMockBuilder(Database::class)
|
||||
/** @var Migrations|MockObject $migrationMock */
|
||||
$migrationMock = $this->getMockBuilder(Migrations::class)
|
||||
->onlyMethods(['execute'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$dbMock->expects($this->once())->method('execute');
|
||||
|
||||
$sut = $this->getMockBuilder(Actions::class)
|
||||
->onlyMethods(['d3GetDb'])
|
||||
->getMock();
|
||||
$sut->method('d3GetDb')->willReturn($dbMock);
|
||||
|
||||
$this->callMethod(
|
||||
$sut,
|
||||
'executeSQL',
|
||||
['query']
|
||||
$migrationMock->expects($this->atLeastOnce())->method('execute')->with(
|
||||
$this->identicalTo('migrations:migrate'),
|
||||
$this->identicalTo('d3webauthn')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @return void
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\Webauthn\Setup\Actions::fieldExists
|
||||
*/
|
||||
public function canCheckFieldExists()
|
||||
{
|
||||
$expected = true;
|
||||
|
||||
/** @var DbMetaDataHandler|MockObject $DbMetaDataMock */
|
||||
$DbMetaDataMock = $this->getMockBuilder(DbMetaDataHandler::class)
|
||||
->onlyMethods(['fieldExists'])
|
||||
/** @var MigrationsBuilder|MockObject $migrationsBuilderMock */
|
||||
$migrationsBuilderMock = $this->getMockBuilder(MigrationsBuilder::class)
|
||||
->onlyMethods(['build'])
|
||||
->getMock();
|
||||
$DbMetaDataMock->expects($this->once())->method('fieldExists')->willReturn($expected);
|
||||
d3GetOxidDIC()->set('d3ox.webauthn.'.DbMetaDataHandler::class, $DbMetaDataMock);
|
||||
$migrationsBuilderMock->method('build')->willReturn($migrationMock);
|
||||
d3GetOxidDIC()->set('d3ox.webauthn.'.MigrationsBuilder::class, $migrationsBuilderMock);
|
||||
|
||||
/** @var Actions $sut */
|
||||
$sut = oxNew(Actions::class);
|
||||
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$this->callMethod(
|
||||
$sut,
|
||||
'fieldExists',
|
||||
['testField', 'testTable']
|
||||
)
|
||||
$this->callMethod(
|
||||
$sut,
|
||||
'runModuleMigrations'
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,303 @@
|
|||
<?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
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace D3\Webauthn\tests\unit\migration\data;
|
||||
|
||||
use D3\TestingTools\Development\CanAccessRestricted;
|
||||
use D3\Webauthn\Migrations\Version20230209212939;
|
||||
use D3\Webauthn\tests\unit\WAUnitTestCase;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\DBAL\Platforms\MySQL57Platform;
|
||||
use Doctrine\DBAL\Schema\AbstractSchemaManager;
|
||||
use Doctrine\DBAL\Schema\Column;
|
||||
use Doctrine\DBAL\Schema\MySqlSchemaManager;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
use Doctrine\Migrations\Configuration\Configuration;
|
||||
use Doctrine\Migrations\Version\Version;
|
||||
use Generator;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use ReflectionException;
|
||||
|
||||
class Version20230209212939Test extends WAUnitTestCase
|
||||
{
|
||||
use CanAccessRestricted;
|
||||
|
||||
/** @var Version20230209212939 */
|
||||
protected $sut;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp(); // TODO: Change the autogenerated stub
|
||||
|
||||
/** @var AbstractPlatform|MockObject $databasePlatformMock */
|
||||
$databasePlatformMock = $this->getMockBuilder(MySQL57Platform::class)
|
||||
->getMock();
|
||||
|
||||
/** @var AbstractSchemaManager|MockObject $schemaManagerMock */
|
||||
$schemaManagerMock = $this->getMockBuilder(MySqlSchemaManager::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
/** @var Connection|MockObject $connectionMock */
|
||||
$connectionMock = $this->getMockBuilder(Connection::class)
|
||||
->disableOriginalConstructor()
|
||||
->onlyMethods(['getDatabasePlatform', 'getSchemaManager'])
|
||||
->getMock();
|
||||
$connectionMock->method('getDatabasePlatform')->willReturn($databasePlatformMock);
|
||||
$connectionMock->method('getSchemaManager')->willReturn($schemaManagerMock);
|
||||
|
||||
/** @var Configuration|MockObject $configurationMock */
|
||||
$configurationMock = $this->getMockBuilder(Configuration::class)
|
||||
->disableOriginalConstructor()
|
||||
->onlyMethods(['getConnection'])
|
||||
->getMock();
|
||||
$configurationMock->method('getConnection')->willReturn($connectionMock);
|
||||
|
||||
/** @var Version|MockObject $versionMock */
|
||||
$versionMock = $this->getMockBuilder(Version::class)
|
||||
->onlyMethods(['getConfiguration'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$versionMock->method('getConfiguration')->willReturn($configurationMock);
|
||||
|
||||
$this->sut = oxNew(Version20230209212939::class, $versionMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @return void
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\Webauthn\Migrations\Version20230209212939::getDescription
|
||||
*/
|
||||
public function canGetDescription()
|
||||
{
|
||||
$this->assertIsString(
|
||||
$this->callMethod(
|
||||
$this->sut,
|
||||
'getDescription'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @return void
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\Webauthn\Migrations\Version20230209212939::up
|
||||
* @dataProvider canUpTableDataProvider
|
||||
*/
|
||||
public function canUpTable($tableExist, $invocationCount)
|
||||
{
|
||||
/** @var Table|MockObject $tableMock */
|
||||
$tableMock = $this->getMockBuilder(Table::class)
|
||||
->onlyMethods(['hasColumn', 'hasPrimaryKey', 'hasIndex'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$tableMock->method('hasColumn')->willReturn(true);
|
||||
$tableMock->method('hasPrimaryKey')->willReturn(true);
|
||||
$tableMock->method('hasIndex')->willReturn(true);
|
||||
|
||||
/** @var Schema|MockObject $schemaMock */
|
||||
$schemaMock = $this->getMockBuilder(Schema::class)
|
||||
->onlyMethods(['hasTable', 'createTable', 'getTable'])
|
||||
->getMock();
|
||||
$schemaMock->method('hasTable')->willReturn($tableExist);
|
||||
$schemaMock->expects($invocationCount)->method('createTable')->willReturn($tableMock);
|
||||
$schemaMock->method('getTable')->willReturn($tableMock);
|
||||
|
||||
$this->callMethod(
|
||||
$this->sut,
|
||||
'up',
|
||||
[$schemaMock]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Generator
|
||||
*/
|
||||
public function canUpTableDataProvider(): Generator
|
||||
{
|
||||
yield 'table not exist' => [false, $this->once()];
|
||||
yield 'table exist' => [true, $this->never()];
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @return void
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\Webauthn\Migrations\Version20230209212939::up
|
||||
* @dataProvider canUpColumnDataProvider
|
||||
*/
|
||||
public function canUpColumn($columnExist, $invocationCount)
|
||||
{
|
||||
/** @var Column|MockObject $columnMock */
|
||||
$columnMock = $this->getMockBuilder(Column::class)
|
||||
->onlyMethods(['setLength'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$columnMock->method('setLength')->willReturnSelf();
|
||||
|
||||
/** @var Table|MockObject $tableMock */
|
||||
$tableMock = $this->getMockBuilder(Table::class)
|
||||
->onlyMethods(['hasColumn', 'addColumn', 'hasPrimaryKey', 'hasIndex'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$tableMock->method('hasColumn')->willReturn($columnExist);
|
||||
$tableMock->expects($invocationCount)->method('addColumn')->willReturn($columnMock);
|
||||
$tableMock->method('hasPrimaryKey')->willReturn(true);
|
||||
$tableMock->method('hasIndex')->willReturn(true);
|
||||
|
||||
/** @var Schema|MockObject $schemaMock */
|
||||
$schemaMock = $this->getMockBuilder(Schema::class)
|
||||
->onlyMethods(['hasTable', 'getTable'])
|
||||
->getMock();
|
||||
$schemaMock->method('hasTable')->willReturn(true);
|
||||
$schemaMock->method('getTable')->willReturn($tableMock);
|
||||
|
||||
$this->callMethod(
|
||||
$this->sut,
|
||||
'up',
|
||||
[$schemaMock]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Generator
|
||||
*/
|
||||
public function canUpColumnDataProvider(): Generator
|
||||
{
|
||||
yield 'column not exist' => [false, $this->atLeast(7)];
|
||||
yield 'column exist' => [true, $this->never()];
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @return void
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\Webauthn\Migrations\Version20230209212939::up
|
||||
* @dataProvider canUpPrimaryKeyDataProvider
|
||||
*/
|
||||
public function canUpPrimaryKey($pKeyExist, $invocationCount)
|
||||
{
|
||||
/** @var Table|MockObject $tableMock */
|
||||
$tableMock = $this->getMockBuilder(Table::class)
|
||||
->onlyMethods(['hasColumn', 'addColumn', 'hasPrimaryKey', 'hasIndex', 'setPrimaryKey'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$tableMock->method('hasColumn')->willReturn(true);
|
||||
$tableMock->method('hasPrimaryKey')->willReturn($pKeyExist);
|
||||
$tableMock->method('hasIndex')->willReturn(true);
|
||||
$tableMock->expects($invocationCount)->method('setPrimaryKey');
|
||||
|
||||
/** @var Schema|MockObject $schemaMock */
|
||||
$schemaMock = $this->getMockBuilder(Schema::class)
|
||||
->onlyMethods(['hasTable', 'getTable'])
|
||||
->getMock();
|
||||
$schemaMock->method('hasTable')->willReturn(true);
|
||||
$schemaMock->method('getTable')->willReturn($tableMock);
|
||||
|
||||
$this->callMethod(
|
||||
$this->sut,
|
||||
'up',
|
||||
[$schemaMock]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Generator
|
||||
*/
|
||||
public function canUpPrimaryKeyDataProvider(): Generator
|
||||
{
|
||||
yield 'pk not exist' => [false, $this->once()];
|
||||
yield 'pk exist' => [true, $this->never()];
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @return void
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\Webauthn\Migrations\Version20230209212939::up
|
||||
* @dataProvider canUpIndexDataProvider
|
||||
*/
|
||||
public function canUpIndex($indexExist, $invocationCount)
|
||||
{
|
||||
/** @var Table|MockObject $tableMock */
|
||||
$tableMock = $this->getMockBuilder(Table::class)
|
||||
->onlyMethods(['hasColumn', 'addColumn', 'hasPrimaryKey', 'hasIndex', 'addIndex', 'setComment'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$tableMock->method('hasColumn')->willReturn(true);
|
||||
$tableMock->method('hasPrimaryKey')->willReturn(true);
|
||||
$tableMock->method('hasIndex')->willReturn($indexExist);
|
||||
$tableMock->expects($invocationCount)->method('addIndex');
|
||||
$tableMock->expects($this->once())->method('setComment');
|
||||
|
||||
/** @var Schema|MockObject $schemaMock */
|
||||
$schemaMock = $this->getMockBuilder(Schema::class)
|
||||
->onlyMethods(['hasTable', 'getTable'])
|
||||
->getMock();
|
||||
$schemaMock->method('hasTable')->willReturn(true);
|
||||
$schemaMock->method('getTable')->willReturn($tableMock);
|
||||
|
||||
$this->callMethod(
|
||||
$this->sut,
|
||||
'up',
|
||||
[$schemaMock]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Generator
|
||||
*/
|
||||
public function canUpIndexDataProvider(): Generator
|
||||
{
|
||||
yield 'index not exist' => [false, $this->atLeast(2)];
|
||||
yield 'index exist' => [true, $this->never()];
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @return void
|
||||
* @throws ReflectionException
|
||||
* @covers \D3\Webauthn\Migrations\Version20230209212939::down
|
||||
* @dataProvider canDownTableDataProvider
|
||||
*/
|
||||
public function canDownTable($tableExist, $invocationCount)
|
||||
{
|
||||
/** @var Schema|MockObject $schemaMock */
|
||||
$schemaMock = $this->getMockBuilder(Schema::class)
|
||||
->onlyMethods(['hasTable', 'dropTable'])
|
||||
->getMock();
|
||||
$schemaMock->method('hasTable')->willReturn($tableExist);
|
||||
$schemaMock->expects($invocationCount)->method('dropTable');
|
||||
|
||||
$this->callMethod(
|
||||
$this->sut,
|
||||
'down',
|
||||
[$schemaMock]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Generator
|
||||
*/
|
||||
public function canDownTableDataProvider(): Generator
|
||||
{
|
||||
yield 'table exist' => [true, $this->once()];
|
||||
yield 'table not exist' => [false, $this->never()];
|
||||
}
|
||||
}
|
Chargement…
Référencer dans un nouveau ticket