diff --git a/composer-dependency-analyser.php b/composer-dependency-analyser.php index f93b241..efb5e00 100644 --- a/composer-dependency-analyser.php +++ b/composer-dependency-analyser.php @@ -7,6 +7,9 @@ // Exclude test app ->addPathToExclude(__DIR__ . '/tests/app') + // Ignore false-positive unused dependency + ->ignoreErrorsOnPackage('symfony/browser-kit', [ErrorType::UNUSED_DEPENDENCY]) + // Ignore optional dependency ->ignoreErrorsOnPackageAndPath('dama/doctrine-test-bundle', __DIR__ . '/src/Database/ResetDatabase.php', [ErrorType::DEV_DEPENDENCY_IN_PROD]) ->ignoreErrorsOnPackageAndPath('dama/doctrine-test-bundle', __DIR__ . '/src/Database/DatabaseResetter.php', [ErrorType::DEV_DEPENDENCY_IN_PROD]) diff --git a/composer.json b/composer.json index 52ce676..d71458d 100644 --- a/composer.json +++ b/composer.json @@ -24,12 +24,14 @@ "phpunit/phpunit": "^9.6.0", "pimcore/pimcore": "^10.6 || ~11.0.0 || ~11.1.0 || ~11.2.2 || ~11.3.0 || ~11.4.0", "psr/log": "^1.1.3 || ^2.0 || ^3.0", + "symfony/browser-kit": "^5.4 || ^6.4", "symfony/config": "^5.4 || ^6.4", "symfony/console": "^5.4 || ^6.4", "symfony/dependency-injection": "^5.4 || ^6.4", "symfony/event-dispatcher": "^5.4 || ^6.4", "symfony/filesystem": "^5.4 || ^6.4", "symfony/framework-bundle": "^5.4 || ^6.4", + "symfony/http-foundation": "^5.4 || ^6.4", "symfony/http-kernel": "^5.4 || ^6.4" }, "require-dev": { @@ -43,7 +45,8 @@ "phpstan/phpstan": "^1.10.60", "phpstan/phpstan-phpunit": "^1.3.16", "phpstan/phpstan-symfony": "^1.3.8", - "shipmonk/composer-dependency-analyser": "^1.7" + "shipmonk/composer-dependency-analyser": "^1.7", + "symfony/security-core": "^5.4 || ^6.4" }, "suggest": { "dama/doctrine-test-bundle": "To isolate database tests in transactions and improve test performance", diff --git a/src/Browser/PimcoreKernelBrowser.php b/src/Browser/PimcoreKernelBrowser.php new file mode 100644 index 0000000..378d519 --- /dev/null +++ b/src/Browser/PimcoreKernelBrowser.php @@ -0,0 +1,46 @@ +setServerParameter('HTTP_X_PIMCORE_CSRF_TOKEN', 'test-csrf-token'); + $this->loginUser(new SecurityUser($user), 'pimcore_admin'); + $this->request('GET', '/admin/login'); + + Session::useBag( + $this->getRequest()->getSession(), + function (AttributeBagInterface $adminSession) use ($user) { + $adminSession->set('user', $user); + // Sign your POST requests with this CSRF token to avoid 403 responses + $adminSession->set('csrfToken', 'test-csrf-token'); + }, + ); + } + + public function logoutFromPimcoreBackend(): void + { + Session::useBag( + $this->getRequest()->getSession(), + function (AttributeBagInterface $adminSession) { + $adminSession->set('user', null); + $adminSession->set('csrfToken', null); + }, + ); + + $this->getCookieJar()->clear(); + } +} diff --git a/src/Kernel/TestKernel.php b/src/Kernel/TestKernel.php index addffa2..fcb3f2a 100644 --- a/src/Kernel/TestKernel.php +++ b/src/Kernel/TestKernel.php @@ -3,6 +3,7 @@ namespace Neusta\Pimcore\TestingFramework\Kernel; +use Neusta\Pimcore\TestingFramework\Browser\PimcoreKernelBrowser; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Compiler\PassConfig; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -103,6 +104,15 @@ protected function buildContainer(): ContainerBuilder { $container = parent::buildContainer(); + $container->addCompilerPass(new class implements CompilerPassInterface { + public function process(ContainerBuilder $container): void + { + if ($container->has('test.client')) { + $container->findDefinition('test.client')->setClass(PimcoreKernelBrowser::class); + } + } + }); + foreach ($this->testCompilerPasses as $compilerPass) { $container->addCompilerPass(...$compilerPass); } diff --git a/src/WebTestCase.php b/src/WebTestCase.php new file mode 100644 index 0000000..4460da8 --- /dev/null +++ b/src/WebTestCase.php @@ -0,0 +1,13 @@ +catchExceptions(false); + + // Access should be denied before login + try { + $client->request('GET', '/admin/user/get-minimal'); + $this->fail('AccessDeniedException expected.'); + } catch (AccessDeniedException) { + } + + // Access should be granted after login + $client->loginToPimcoreBackend(); + $client->request('GET', '/admin/user/get-minimal'); + static::assertResponseIsSuccessful(); + + // Access should be denied again after logout + $client->logoutFromPimcoreBackend(); + try { + $client->request('GET', '/admin/user/get-minimal'); + $this->fail('AccessDeniedException expected.'); + } catch (AccessDeniedException) { + } + } +} diff --git a/tests/app/config/routes.yaml b/tests/app/config/routes.yaml new file mode 100644 index 0000000..47b4e06 --- /dev/null +++ b/tests/app/config/routes.yaml @@ -0,0 +1,4 @@ +# auto loads routes from all bundles in config/pimcore/routing.yaml +_pimcore_bundle_auto: + resource: . + type: pimcore_bundle diff --git a/tests/app/templates/.gitkeep b/tests/app/templates/.gitkeep new file mode 100644 index 0000000..e69de29