From 1251095eb366b055e91dc2e5979a8715f787f9aa Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Sun, 29 Sep 2024 23:28:35 +0200 Subject: [PATCH] add tests --- Application/Model/d3backupcode.php | 4 +- .../Admin/d3_totp_LoginController.php | 1 + Setup/Actions.php | 59 ++- .../Controller/Admin/d3force_2faTest.php | 17 + .../Controller/Admin/d3user_totpTest.php | 24 ++ .../Controller/d3_account_totpTest.php | 32 ++ .../Application/Model/d3backupcodeTest.php | 41 +- .../Model/d3backupcodelistTest.php | 17 + Tests/Unit/Application/Model/d3totpTest.php | 35 ++ Tests/Unit/Application/TranslationTest.php | 31 ++ .../Component/d3_totp_UserComponentTest.php | 64 +++ .../Application/Model/d3_totp_userTest.php | 26 ++ Tests/Unit/Modules/Core/d3_totp_utilsTest.php | 17 + Tests/Unit/Setup/ActionsTest.php | 387 ++++++++++++++++++ Tests/phpunit.xml | 1 + 15 files changed, 732 insertions(+), 24 deletions(-) create mode 100644 Tests/Unit/Application/TranslationTest.php create mode 100644 Tests/Unit/Setup/ActionsTest.php diff --git a/Application/Model/d3backupcode.php b/Application/Model/d3backupcode.php index 1158041..9cf3c8d 100644 --- a/Application/Model/d3backupcode.php +++ b/Application/Model/d3backupcode.php @@ -80,11 +80,11 @@ class d3backupcode extends BaseModel $user = $this->getUser(); if ($user instanceof User) { - return $this->getUser(); + return $user; } /** @var d3_totp_user $oUser */ - $oUser = oxNew(User::class); + $oUser = $this->d3TotpGetUserObject(); $sUserId = $oUser->d3TotpGetCurrentUser(); $oUser->load($sUserId); return $oUser; diff --git a/Modules/Application/Controller/Admin/d3_totp_LoginController.php b/Modules/Application/Controller/Admin/d3_totp_LoginController.php index bdd41bf..bdaed4b 100644 --- a/Modules/Application/Controller/Admin/d3_totp_LoginController.php +++ b/Modules/Application/Controller/Admin/d3_totp_LoginController.php @@ -59,6 +59,7 @@ class d3_totp_LoginController extends d3_totp_LoginController_parent /** * mockable parent method + * @codeCoverageIgnore */ protected function parent__checklogin() { diff --git a/Setup/Actions.php b/Setup/Actions.php index 0d271b4..8e80e21 100644 --- a/Setup/Actions.php +++ b/Setup/Actions.php @@ -27,7 +27,7 @@ use OxidEsales\Eshop\Core\Utils; use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory; use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; -use Psr\Container\NotFoundExceptionInterface; +use Psr\Log\LoggerInterface; class Actions { @@ -41,27 +41,49 @@ class Actions 'd3_account_totp', ]; + /** + * @return MigrationsBuilder + */ + protected function getMigrationsBuilder(): MigrationsBuilder + { + return oxNew(MigrationsBuilder::class); + } + /** * @throws Exception */ public function runModuleMigrations(): void { - /** @var MigrationsBuilder $migrationsBuilder */ - $migrationsBuilder = oxNew(MigrationsBuilder::class); + $migrationsBuilder = $this->getMigrationsBuilder(); $migrations = $migrationsBuilder->build(); $migrations->execute('migrations:migrate', 'd3totp'); } + protected function getDbMetaDataHandler(): DbMetaDataHandler + { + return oxNew(DbMetaDataHandler::class); + } + /** * Regenerate views for changed tables * @throws Exception */ public function regenerateViews(): void { - $oDbMetaDataHandler = oxNew(DbMetaDataHandler::class); + $oDbMetaDataHandler = $this->getDbMetaDataHandler(); $oDbMetaDataHandler->updateViews(); } + protected function getUtils(): Utils + { + return oxNew(Utils::class); + } + + protected function getLogger(): LoggerInterface + { + return Registry::getLogger(); + } + /** * clear cache * @throws Exception @@ -72,9 +94,9 @@ class Actions /** @var ShopTemplateCacheServiceBridge $templateCacheService */ $templateCacheService = $this->getDIContainer()->get(ShopTemplateCacheServiceBridgeInterface::class); $templateCacheService->invalidateCache(Registry::getConfig()->getShopId()); - $oUtils = oxNew(Utils::class); + $oUtils = $this->getUtils(); $oUtils->resetLanguageCache(); - } catch (ContainerExceptionInterface|NotFoundExceptionInterface $e) { + } catch (ContainerExceptionInterface $e) { Registry::getLogger()->error($e->getMessage(), [$this]); Registry::getUtilsView()->addErrorToDisplay($e->getMessage()); } @@ -86,24 +108,25 @@ class Actions public function seoUrl(): void { try { - if (!$this->hasSeoUrls()) { - $this->createSeoUrls(); + $seoEncoder = oxNew(SeoEncoder::class); + if (!$this->hasSeoUrls($seoEncoder)) { + $this->createSeoUrls($seoEncoder); } } catch (Exception $e) { - Registry::getLogger()->error($e->getMessage(), [$this]); + $this->getLogger()->error($e->getMessage(), [$this]); Registry::getUtilsView()->addErrorToDisplay('error wile creating SEO URLs: ' . $e->getMessage()); } } /** + * @param SeoEncoder $seoEncoder * @return bool - * @throws Exception */ - public function hasSeoUrls(): bool + public function hasSeoUrls(SeoEncoder $seoEncoder): bool { foreach ($this->stdClassName as $item) { foreach ([0, 1] as $lang) { - if (false === $this->hasSeoUrl($item, $lang)) { + if (false === $this->hasSeoUrl($seoEncoder, $item, $lang)) { return false; } } @@ -112,27 +135,25 @@ class Actions return true; } - protected function hasSeoUrl(string $item, int $langId): bool + protected function hasSeoUrl(SeoEncoder $seoEncoder, string $item, int $langId): bool { - $seoEncoder = oxNew(SeoEncoder::class); $seoUrl = $seoEncoder->getStaticUrl( oxNew(FrontendController::class)->getViewConfig()->getSelfLink() . "cl=" . $item, $langId ); - return (bool)strlen($seoUrl); } /** + * @param SeoEncoder $seoEncoder * @return void */ - public function createSeoUrls(): void + public function createSeoUrls(SeoEncoder $seoEncoder): void { foreach (array_keys($this->stdClassName) as $id) { - $seoEncoder = oxNew(SeoEncoder::class); $objectid = md5(strtolower(Registry::getConfig()->getShopId() . 'index.php?cl=' . $this->stdClassName[$id])); - if (!$this->hasSeoUrl($this->stdClassName[$id], 0)) { + if (!$this->hasSeoUrl($seoEncoder, $this->stdClassName[$id], 0)) { $seoEncoder->addSeoEntry( $objectid, Registry::getConfig()->getShopId(), @@ -143,7 +164,7 @@ class Actions false ); } - if (!$this->hasSeoUrl($this->stdClassName[$id], 1)) { + if (!$this->hasSeoUrl($seoEncoder, $this->stdClassName[$id], 1)) { $seoEncoder->addSeoEntry( $objectid, Registry::getConfig()->getShopId(), diff --git a/Tests/Unit/Application/Controller/Admin/d3force_2faTest.php b/Tests/Unit/Application/Controller/Admin/d3force_2faTest.php index 174c5bb..62310b2 100644 --- a/Tests/Unit/Application/Controller/Admin/d3force_2faTest.php +++ b/Tests/Unit/Application/Controller/Admin/d3force_2faTest.php @@ -127,4 +127,21 @@ class d3force_2faTest extends d3user_totpTest ) ); } + + /** + * @test + * @return void + * @throws ReflectionException + * @covers \D3\Totp\Application\Controller\Admin\d3force_2fa::getModuleConfiguration + */ + public function canGetModuleConfiguration() + { + $this->assertInstanceOf( + ModuleConfiguration::class, + $this->callMethod( + $this->_oController, + 'getModuleConfiguration' + ) + ); + } } diff --git a/Tests/Unit/Application/Controller/Admin/d3user_totpTest.php b/Tests/Unit/Application/Controller/Admin/d3user_totpTest.php index 15933a5..b1f3ea2 100644 --- a/Tests/Unit/Application/Controller/Admin/d3user_totpTest.php +++ b/Tests/Unit/Application/Controller/Admin/d3user_totpTest.php @@ -552,4 +552,28 @@ class d3user_totpTest extends d3TotpUnitTestCase $this->callMethod($this->_oController, 'getAvailableBackupCodeCount') ); } + + /** + * @test + * @return void + * @throws ReflectionException + * @covers \D3\Totp\Application\Controller\Admin\d3user_totp::getCurrentUserId + */ + public function canGetCurrentUserId(): void + { + /** @var d3user_totp|MockObject $oControllerMock */ + $oControllerMock = $this->d3getMockBuilder(d3user_totp::class) + ->onlyMethods([ + 'getEditObjectId' + ]) + ->getMock(); + $oControllerMock->expects($this->once())->method('getEditObjectId')->willReturn('foo'); + + $this->_oController = $oControllerMock; + + $this->callMethod( + $this->_oController, + 'getCurrentUserId' + ); + } } diff --git a/Tests/Unit/Application/Controller/d3_account_totpTest.php b/Tests/Unit/Application/Controller/d3_account_totpTest.php index b450040..73765db 100644 --- a/Tests/Unit/Application/Controller/d3_account_totpTest.php +++ b/Tests/Unit/Application/Controller/d3_account_totpTest.php @@ -421,4 +421,36 @@ class d3_account_totpTest extends d3TotpUnitTestCase ) ); } + + /** + * @test + * @return void + * @throws ReflectionException + * @covers \D3\Totp\Application\Controller\d3_account_totp::getCurrentUserId + */ + public function canGetCurrentUserId(): void + { + $userMock = $this->d3getMockBuilder(User::class) + ->onlyMethods(['getId']) + ->getMock(); + $userMock->expects($this->once())->method('getId')->willReturn('foo'); + + /** @var d3_account_totp|MockObject $oControllerMock */ + $oControllerMock = $this->d3getMockBuilder(d3_account_totp::class) + ->onlyMethods([ + 'getUser' + ]) + ->getMock(); + $oControllerMock->expects($this->once())->method('getUser')->willReturn($userMock); + + $this->_oController = $oControllerMock; + + $this->assertSame( + 'foo', + $this->callMethod( + $this->_oController, + 'getCurrentUserId' + ) + ); + } } diff --git a/Tests/Unit/Application/Model/d3backupcodeTest.php b/Tests/Unit/Application/Model/d3backupcodeTest.php index ed78d3d..d8a556d 100644 --- a/Tests/Unit/Application/Model/d3backupcodeTest.php +++ b/Tests/Unit/Application/Model/d3backupcodeTest.php @@ -19,6 +19,7 @@ use D3\TestingTools\Development\CanAccessRestricted; use D3\Totp\Application\Model\d3backupcode; use D3\Totp\Application\Model\d3totp_conf; use D3\Totp\Tests\Unit\d3TotpUnitTestCase; +use Doctrine\DBAL\Query\QueryBuilder; use OxidEsales\Eshop\Application\Model\User; use OxidEsales\Eshop\Core\Registry; use PHPUnit\Framework\MockObject\MockObject; @@ -157,15 +158,32 @@ class d3backupcodeTest extends d3TotpUnitTestCase */ public function d3GetUserReturnCurrentUser() { - Registry::getSession()->setVariable(d3totp_conf::SESSION_CURRENTUSER, 'foobar'); + /** @var User|MockObject $oUserMock */ + $oUserMock = $this->d3getMockBuilder(User::class) + ->onlyMethods(['d3TotpGetCurrentUser', 'load']) + ->getMock(); + $oUserMock->expects($this->once())->method('d3TotpGetCurrentUser')->willReturn('currentUserId'); + $oUserMock->expects($this->once())->method('load'); + $oUserMock->assign([ + 'oxid' => 'currentUserId', + ]); - $oUser = $this->callMethod($this->_oModel, 'd3GetUser'); + /** @var d3backupcode|MockObject $oModelMock */ + $oModelMock = $this->d3getMockBuilder(d3backupcode::class) + ->onlyMethods(['d3TotpGetUserObject']) + ->getMock(); + $oModelMock->method('d3TotpGetUserObject')->willReturn($oUserMock); + + $this->_oModel->setUser(null); + + $oUser = $this->callMethod($oModelMock, 'd3GetUser'); $this->assertInstanceOf( User::class, $oUser ); - $this->assertNull( + $this->assertSame( + 'currentUserId', $oUser->getId() ); } @@ -182,4 +200,21 @@ class d3backupcodeTest extends d3TotpUnitTestCase $this->callMethod($this->_oModel, 'd3TotpGetUserObject') ); } + + /** + * @test + * @return void + * @throws ReflectionException + * @covers \D3\Totp\Application\Model\d3backupcode::getQueryBuilder + */ + public function canGetQueryBuilder(): void + { + $this->assertInstanceOf( + QueryBuilder::class, + $this->callMethod( + $this->_oModel, + 'getQueryBuilder' + ) + ); + } } diff --git a/Tests/Unit/Application/Model/d3backupcodelistTest.php b/Tests/Unit/Application/Model/d3backupcodelistTest.php index 2e270cb..5fca778 100644 --- a/Tests/Unit/Application/Model/d3backupcodelistTest.php +++ b/Tests/Unit/Application/Model/d3backupcodelistTest.php @@ -393,4 +393,21 @@ class d3backupcodelistTest extends d3TotpUnitTestCase $this->callMethod($this->_oModel, 'd3GetUser') ); } + + /** + * @test + * @return void + * @throws ReflectionException + * @covers \D3\Totp\Application\Model\d3backupcodelist::getQueryBuilder + */ + public function canGetQueryBuilder(): void + { + $this->assertInstanceOf( + QueryBuilder::class, + $this->callMethod( + $this->_oModel, + 'getQueryBuilder' + ) + ); + } } diff --git a/Tests/Unit/Application/Model/d3totpTest.php b/Tests/Unit/Application/Model/d3totpTest.php index a99640f..261fb3e 100644 --- a/Tests/Unit/Application/Model/d3totpTest.php +++ b/Tests/Unit/Application/Model/d3totpTest.php @@ -23,6 +23,7 @@ use D3\Totp\Application\Model\d3backupcodelist; use D3\Totp\Application\Model\d3totp; use D3\Totp\Application\Model\Exceptions\d3totp_wrongOtpException; use D3\Totp\Tests\Unit\d3TotpUnitTestCase; +use Doctrine\DBAL\Connection; use Doctrine\DBAL\ForwardCompatibility\Result; use Doctrine\DBAL\Query\QueryBuilder; use OTPHP\TOTP; @@ -920,4 +921,38 @@ class d3totpTest extends d3TotpUnitTestCase $this->callMethod($this->_oModel, 'delete') ); } + + /** + * @test + * @return void + * @throws ReflectionException + * @covers \D3\Totp\Application\Model\d3totp::getQueryBuilder + */ + public function canGetQueryBuilder(): void + { + $this->assertInstanceOf( + QueryBuilder::class, + $this->callMethod( + $this->_oModel, + 'getQueryBuilder' + ) + ); + } + + /** + * @test + * @return void + * @throws ReflectionException + * @covers \D3\Totp\Application\Model\d3totp::getDbConnection + */ + public function canGetDbConnection(): void + { + $this->assertInstanceOf( + Connection::class, + $this->callMethod( + $this->_oModel, + 'getDbConnection' + ) + ); + } } diff --git a/Tests/Unit/Application/TranslationTest.php b/Tests/Unit/Application/TranslationTest.php new file mode 100644 index 0000000..bdd13ee --- /dev/null +++ b/Tests/Unit/Application/TranslationTest.php @@ -0,0 +1,31 @@ +assertIsArray($list); + $this->assertTrue(count($list) > 1); + $this->assertTrue($list['charset'] === 'UTF-8'); + } + + public static function canGetTranslationDataProvider(): Generator + { + yield 'frontend DE' => ['Application/translations/de/translations.php']; + yield 'frontend EN' => ['Application/translations/en/translations.php']; + yield 'backend DE' => ['Application/views/de/translations.php']; + yield 'backend EN' => ['Application/views/en/translations.php']; + } +} \ No newline at end of file diff --git a/Tests/Unit/Modules/Application/Component/d3_totp_UserComponentTest.php b/Tests/Unit/Modules/Application/Component/d3_totp_UserComponentTest.php index 618284d..29920e2 100644 --- a/Tests/Unit/Modules/Application/Component/d3_totp_UserComponentTest.php +++ b/Tests/Unit/Modules/Application/Component/d3_totp_UserComponentTest.php @@ -215,6 +215,70 @@ class d3_totp_UserComponentTest extends d3TotpUnitTestCase $this->callMethod($oControllerMock, 'afterLogin', [$oUserMock]); } + /** + * @test + * @throws ReflectionException + * @covers \D3\Totp\Modules\Application\Component\d3_totp_UserComponent::afterLogin + */ + public function afterFailedNoUserLoaded() + { + /** @var User|MockObject $oUserMock */ + $oUserMock = $this->d3getMockBuilder(User::class) + ->onlyMethods([ + 'logout', + 'getId', + ]) + ->getMock(); + $oUserMock->expects($this->never())->method('logout')->willReturn(false); + $oUserMock->method('getId')->willReturn(''); + + /** @var Utils|MockObject $oUtilsMock */ + $oUtilsMock = $this->d3getMockBuilder(Utils::class) + ->onlyMethods(['redirect']) + ->getMock(); + $oUtilsMock->expects($this->never())->method('redirect')->willReturn(true); + + /** @var Session|MockObject $oSessionMock */ + $oSessionMock = $this->d3getMockBuilder(Session::class) + ->onlyMethods(['setVariable', 'getVariable']) + ->getMock(); + $oSessionMock->expects($this->never())->method('setVariable'); + $oSessionMock->method('getVariable')->willReturn(null); + + /** @var BaseController|MockObject $oParentMock */ + $oParentMock = $this->d3getMockBuilder(BaseController::class) + ->onlyMethods(['getClassKey']) + ->getMock(); + $oParentMock->method('getClassKey')->willReturn('foo'); + + /** @var d3totp|MockObject $oTotpMock */ + $oTotpMock = $this->d3getMockBuilder(d3totp::class) + ->onlyMethods([ + 'isActive', + 'loadByUserId', + ]) + ->disableOriginalConstructor() + ->getMock(); + $oTotpMock->expects($this->never())->method('isActive')->willReturn(true); + $oTotpMock->method('loadByUserId'); + + /** @var UserComponent|MockObject $oControllerMock */ + $oControllerMock = $this->d3getMockBuilder(UserComponent::class) + ->onlyMethods([ + 'd3GetTotpObject', + 'd3TotpGetSession', + 'd3TotpGetUtils', + 'getParent', + ]) + ->getMock(); + $oControllerMock->method('d3GetTotpObject')->willReturn($oTotpMock); + $oControllerMock->method('getParent')->willReturn($oParentMock); + $oControllerMock->method('d3TotpGetSession')->willReturn($oSessionMock); + $oControllerMock->method('d3TotpGetUtils')->willReturn($oUtilsMock); + + $this->callMethod($oControllerMock, 'afterLogin', [$oUserMock]); + } + /** * @test * @throws ReflectionException diff --git a/Tests/Unit/Modules/Application/Model/d3_totp_userTest.php b/Tests/Unit/Modules/Application/Model/d3_totp_userTest.php index c847cbf..8ae72b8 100644 --- a/Tests/Unit/Modules/Application/Model/d3_totp_userTest.php +++ b/Tests/Unit/Modules/Application/Model/d3_totp_userTest.php @@ -21,6 +21,7 @@ use D3\Totp\Application\Model\d3totp_conf; use D3\Totp\Modules\Application\Model\d3_totp_user; use D3\Totp\Tests\Unit\d3TotpUnitTestCase; use OxidEsales\Eshop\Application\Model\User; +use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Core\Session; use PHPUnit\Framework\MockObject\MockObject; use ReflectionException; @@ -94,6 +95,31 @@ class d3_totp_userTest extends d3TotpUnitTestCase ); } + /** + * @test + * @throws ReflectionException + * @covers \D3\Totp\Modules\Application\Model\d3_totp_user::d3getSessionedTotp + */ + public function d3getSessionedTotpReturnsRightInstance() + { + $sut = oxNew(User::class); + + $otp = $this->callMethod( + $sut, + 'd3getSessionedTotp' + ); + + $this->assertInstanceOf( + d3totp::class, + $otp + ); + + $this->assertSame( + $otp, + Registry::getSession()->getVariable(d3totp_conf::OTP_SESSION_VARNAME) + ); + } + /** * @test * @param $currentUser diff --git a/Tests/Unit/Modules/Core/d3_totp_utilsTest.php b/Tests/Unit/Modules/Core/d3_totp_utilsTest.php index a22b93a..051f7f8 100644 --- a/Tests/Unit/Modules/Core/d3_totp_utilsTest.php +++ b/Tests/Unit/Modules/Core/d3_totp_utilsTest.php @@ -382,6 +382,23 @@ class d3_totp_utilsTest extends d3TotpUnitTestCase ); } + /** + * @test + * @return void + * @throws ReflectionException + * @covers \D3\Totp\Modules\Core\d3_totp_utils::getModuleConfiguration + */ + public function canGetModuleConfiguration() + { + $this->assertInstanceOf( + ModuleConfiguration::class, + $this->callMethod( + $this->_oCoreClass, + 'getModuleConfiguration' + ) + ); + } + /** * @return array */ diff --git a/Tests/Unit/Setup/ActionsTest.php b/Tests/Unit/Setup/ActionsTest.php new file mode 100644 index 0000000..11ea134 --- /dev/null +++ b/Tests/Unit/Setup/ActionsTest.php @@ -0,0 +1,387 @@ + + * @link https://www.oxidmodule.com + */ + +declare(strict_types=1); + +namespace D3\Totp\Tests\Unit\Setup; + +use D3\OxidServiceBridges\Internal\Framework\Templating\Cache\ShopTemplateCacheServiceBridge; +use D3\TestingTools\Development\CanAccessRestricted; +use D3\Totp\Setup\Actions; +use D3\Totp\Tests\Unit\d3TotpUnitTestCase; +use Generator; +use OxidEsales\DoctrineMigrationWrapper\Migrations; +use OxidEsales\DoctrineMigrationWrapper\MigrationsBuilder; +use OxidEsales\Eshop\Core\DbMetaDataHandler; +use OxidEsales\Eshop\Core\Exception\StandardException; +use OxidEsales\Eshop\Core\SeoEncoder; +use OxidEsales\Eshop\Core\Utils; +use OxidEsales\EshopCommunity\Internal\Framework\Logger\Wrapper\LoggerWrapper; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\MockObject\Rule\InvokedCount; +use Psr\Container\ContainerInterface; +use Psr\Log\LoggerInterface; +use ReflectionException; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; + +class ActionsTest extends d3TotpUnitTestCase +{ + use CanAccessRestricted; + + /** @var Actions */ + protected Actions $_sut; + + public function setUp(): void + { + parent::setUp(); + $this->_sut = oxNew(Actions::class); + } + + /** + * @test + * @return void + * @throws ReflectionException + * @covers \D3\Totp\Setup\Actions::getMigrationsBuilder + */ + public function canGetMigrationsBuilder(): void + { + $this->assertInstanceOf( + MigrationsBuilder::class, + $this->callMethod( + $this->_sut, + 'getMigrationsBuilder' + ) + ); + } + + /** + * @test + * @return void + * @throws ReflectionException + * @covers \D3\Totp\Setup\Actions::runModuleMigrations + */ + public function canRunModuleMigrations(): void + { + $migrationsMock = $this->d3getMockBuilder(Migrations::class) + ->onlyMethods(['execute']) + ->disableOriginalConstructor() + ->getMock(); + $migrationsMock->expects($this->once())->method('execute'); + + $migrationsBuilderMock = $this->d3getMockBuilder(MigrationsBuilder::class) + ->onlyMethods(['build']) + ->getMock(); + $migrationsBuilderMock->method("build")->willReturn($migrationsMock); + + $sutMock = $this->d3getMockBuilder(Actions::class) + ->onlyMethods(['getMigrationsBuilder']) + ->getMock(); + $sutMock->method('getMigrationsBuilder')->willReturn($migrationsBuilderMock); + + $this->callMethod( + $sutMock, + 'runModuleMigrations' + ); + } + + /** + * @test + * @return void + * @throws ReflectionException + * @covers \D3\Totp\Setup\Actions::getDbMetaDataHandler + */ + public function canGetDbMetaDataHandler(): void + { + $this->assertInstanceOf( + DbMetaDataHandler::class, + $this->callMethod( + $this->_sut, + 'getDbMetaDataHandler' + ) + ); + } + + /** + * @test + * @return void + * @throws ReflectionException + * @covers \D3\Totp\Setup\Actions::regenerateViews + */ + public function canRegenerateViews(): void + { + $dbMetaDataHandlerMock = $this->d3getMockBuilder(DbMetaDataHandler::class) + ->onlyMethods(['updateViews']) + ->getMock(); + $dbMetaDataHandlerMock->expects($this->once())->method("updateViews"); + + $sutMock = $this->d3getMockBuilder(Actions::class) + ->onlyMethods(['getDbMetaDataHandler']) + ->getMock(); + $sutMock->method('getDbMetaDataHandler')->willReturn($dbMetaDataHandlerMock); + + $this->callMethod( + $sutMock, + 'regenerateViews' + ); + } + + /** + * @test + * @return void + * @throws ReflectionException + * @covers \D3\Totp\Setup\Actions::getUtils + */ + public function canGetUtils(): void + { + $this->assertInstanceOf( + Utils::class, + $this->callMethod( + $this->_sut, + 'getUtils' + ) + ); + } + + /** + * @test + * @return void + * @throws ReflectionException + * @covers \D3\Totp\Setup\Actions::getLogger + */ + public function canGetLogger(): void + { + $this->assertInstanceOf( + LoggerInterface::class, + $this->callMethod( + $this->_sut, + 'getLogger' + ) + ); + } + + /** + * @test + * @param string|null $thrownException + * @return void + * @throws ReflectionException + * @covers \D3\Totp\Setup\Actions::clearCache + * @dataProvider canClearCacheDataProvider + */ + public function canClearCache(string $thrownException = null): void + { + $shopTemplateCacheServiceMock = $this->d3getMockBuilder(ShopTemplateCacheServiceBridge::class) + ->disableOriginalConstructor() + ->onlyMethods(['invalidateCache']) + ->getMock(); + $shopTemplateCacheServiceMock->expects($this->exactly((int) !$thrownException))->method("invalidateCache"); + + $DIContainerMock = $this->d3getMockBuilder(Container::class) + ->onlyMethods(['get', 'has']) + ->getMock(); + if ($thrownException === null) { + $DIContainerMock->method('get')->willReturn($shopTemplateCacheServiceMock); + } else { + /** @var ServiceNotFoundException|MockObject $exceptionMock */ + $exceptionMock = $this->d3getMockBuilder(ServiceNotFoundException::class) + ->disableOriginalConstructor() + ->getMock(); + $DIContainerMock->method('get')->willThrowException($exceptionMock); + } + + $utilsMock = $this->d3getMockBuilder(Utils::class) + ->onlyMethods(['resetLanguageCache']) + ->getMock(); + $utilsMock->expects($this->exactly((int) !$thrownException))->method('resetLanguageCache'); + + $loggerMock = $this->d3getMockBuilder(LoggerWrapper::class) + ->disableOriginalConstructor() + ->onlyMethods(['error']) + ->getMock(); + $loggerMock->expects($this->exactly((int) $thrownException))->method('error'); + + $sutMock = $this->d3getMockBuilder(Actions::class) + ->onlyMethods(['getDIContainer', 'getUtils', 'getLogger']) + ->getMock(); + $sutMock->method('getDIContainer')->willReturn($DIContainerMock); + $sutMock->method('getUtils')->willReturn($utilsMock); + $sutMock->method('getLogger')->willReturn($loggerMock); + + $this->callMethod( + $sutMock, + 'clearCache' + ); + } + + public static function canClearCacheDataProvider(): Generator + { + yield 'passed' => []; + yield 'container exception' => [ServiceNotFoundException::class]; + } + + /** + * @test + * @param bool $hasSeoUrls + * @param InvokedCount $createCount + * @param bool $throwException + * @return void + * @throws ReflectionException + * @covers \D3\Totp\Setup\Actions::seoUrl + * @dataProvider canHandleSeoUrlsDataProvider + */ + public function canHandleSeoUrls(bool $hasSeoUrls, InvokedCount $createCount, bool $throwException = false): void + { + $loggerMock = $this->d3getMockBuilder(LoggerWrapper::class) + ->disableOriginalConstructor() + ->onlyMethods(['error']) + ->getMock(); + $loggerMock->expects($this->exactly((int) $throwException))->method('error'); + + $sutMock = $this->d3getMockBuilder(Actions::class) + ->onlyMethods(['hasSeoUrls', 'createSeoUrls', 'getLogger']) + ->getMock(); + $sutMock->method('hasSeoUrls')->willReturn($hasSeoUrls); + $sutMock->method('getLogger')->willReturn($loggerMock); + if ($throwException) { + $sutMock->expects($createCount)->method('createSeoUrls')->willThrowException(new StandardException()); + } else { + $sutMock->expects($createCount)->method('createSeoUrls'); + } + + $this->callMethod( + $sutMock, + 'seoUrl' + ); + } + + public static function canHandleSeoUrlsDataProvider(): Generator + { + yield 'urls exists' => [true, self::never()]; + yield 'urls not exists' => [false, self::once()]; + yield 'throw exception' => [false, self::once(), true]; + } + + /** + * @test + * @param bool $hasSeoUrl + * @return void + * @throws ReflectionException + * @covers \D3\Totp\Setup\Actions::hasSeoUrls + * @dataProvider hasSeoUrlsDataProvider + */ + public function testHasSeoUrls(bool $hasSeoUrl): void + { + $sutMock = $this->d3getMockBuilder(Actions::class) + ->onlyMethods(['hasSeoUrl']) + ->getMock(); + $sutMock->method('hasSeoUrl')->willReturn($hasSeoUrl); + + $this->assertSame( + $hasSeoUrl, + $this->callMethod( + $sutMock, + 'hasSeoUrls', + [oxNew(SeoEncoder::class)] + ) + ); + } + + public static function hasSeoUrlsDataProvider(): Generator + { + yield 'url exists' => [true]; + yield 'url not exists' => [false]; + } + + /** + * @test + * @param string $staticUrl + * @param bool $expected + * @return void + * @throws ReflectionException + * @covers \D3\Totp\Setup\Actions::hasSeoUrl + * @dataProvider hasSeoUrlDataProvider + */ + public function testHasSeoUrl(string $staticUrl, bool $expected) + { + $seoEncoderMock = $this->d3getMockBuilder(SeoEncoder::class) + ->onlyMethods(['getStaticUrl']) + ->getMock(); + $seoEncoderMock->expects($this->once())->method('getStaticUrl')->willReturn($staticUrl); + + $this->assertSame( + $expected, + $this->callMethod( + $this->_sut, + 'hasSeoUrl', + [$seoEncoderMock, 'item', 0] + ) + ); + } + + public static function hasSeoUrlDataProvider(): Generator + { + yield 'passed' => ['staticFixture', true]; + yield 'failed' => ['', false]; + } + + /** + * @test + * @param bool $hasSeoUrl + * @param InvokedCount $expectedCount + * @return void + * @throws ReflectionException + * @covers \D3\Totp\Setup\Actions::createSeoUrls + * @dataProvider canCreateSeoUrlsDataProvider + */ + public function canCreateSeoUrls(bool $hasSeoUrl, invokedCount $expectedCount): void + { + $seoEncoderMock = $this->d3getMockBuilder(SeoEncoder::class) + ->onlyMethods(['addSeoEntry']) + ->getMock(); + $seoEncoderMock->expects($expectedCount)->method('addSeoEntry')->willReturn('addSeoEntry'); + + $sutMock = $this->d3getMockBuilder(Actions::class) + ->onlyMethods(['hasSeoUrl']) + ->getMock(); + $sutMock->method('hasSeoUrl')->willReturn($hasSeoUrl); + + $this->callMethod( + $sutMock, + 'createSeoUrls', + [$seoEncoderMock] + ); + } + + public static function canCreateSeoUrlsDataProvider(): Generator + { + yield 'url not exists' => [false, self::exactly(2)]; + yield 'url exists' => [true, self::never()]; + } + + /** + * @test + * @return void + * @throws ReflectionException + * @covers \D3\Totp\Setup\Actions::getDIContainer + */ + public function canGetDIContainer(): void + { + $this->assertInstanceOf( + ContainerInterface::class, + $this->callMethod( + $this->_sut, + 'getDIContainer' + ) + ); + } +} \ No newline at end of file diff --git a/Tests/phpunit.xml b/Tests/phpunit.xml index e3acd9d..a3845a6 100644 --- a/Tests/phpunit.xml +++ b/Tests/phpunit.xml @@ -31,6 +31,7 @@ ../.php-cs-fixer.php ../IntelliSenseHelper.php ../rector.php + ../metadata.php ../Tests/