diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/ConfigBuilderCacheWarmerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/ConfigBuilderCacheWarmerTest.php index a0e8fe834ef8..294a3cd25c1d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/ConfigBuilderCacheWarmerTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/ConfigBuilderCacheWarmerTest.php @@ -14,15 +14,26 @@ use Symfony\Bundle\FrameworkBundle\CacheWarmer\ConfigBuilderCacheWarmer; use Symfony\Bundle\FrameworkBundle\FrameworkBundle; use Symfony\Bundle\FrameworkBundle\Tests\TestCase; +use Symfony\Component\Config\Definition\Builder\NodeDefinition; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Extension\Extension; +use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Bundle\Bundle; +use Symfony\Component\HttpKernel\Bundle\BundleInterface; use Symfony\Component\HttpKernel\Kernel; +use Symfony\Component\HttpKernel\KernelInterface; class ConfigBuilderCacheWarmerTest extends TestCase { - private $varDir; + private string $varDir; protected function setUp(): void { @@ -40,21 +51,110 @@ protected function tearDown(): void public function testBuildDirIsUsedAsConfigBuilderOutputDir() { - $kernel = new class($this->varDir) extends Kernel implements CompilerPassInterface { + $kernel = new TestKernel($this->varDir); + $kernel->boot(); + + self::assertDirectoryDoesNotExist($kernel->getBuildDir().'/Symfony'); + self::assertDirectoryDoesNotExist($kernel->getCacheDir().'/Symfony'); + + $warmer = new ConfigBuilderCacheWarmer($kernel); + $warmer->warmUp($kernel->getCacheDir()); + + self::assertDirectoryDoesNotExist($kernel->getBuildDir().'/Symfony'); + self::assertDirectoryDoesNotExist($kernel->getCacheDir().'/Symfony'); + + $warmer->warmUp($kernel->getCacheDir(), $kernel->getBuildDir()); + + self::assertDirectoryExists($kernel->getBuildDir().'/Symfony'); + self::assertDirectoryDoesNotExist($kernel->getCacheDir().'/Symfony'); + } + + public function testWithCustomKernelImplementation() + { + $kernel = new class($this->varDir) implements KernelInterface { private $varDir; public function __construct(string $varDir) { - parent::__construct('test', false); - $this->varDir = $varDir; } + public function handle(Request $request, int $type = self::MAIN_REQUEST, bool $catch = true): Response + { + return new Response(); + } + public function registerBundles(): iterable { yield new FrameworkBundle(); } + public function registerContainerConfiguration(LoaderInterface $loader): void + { + } + + public function boot(): void + { + } + + public function shutdown(): void + { + } + + public function getBundles(): array + { + $bundles = []; + foreach ($this->registerBundles() as $bundle) { + $bundles[$bundle->getName()] = $bundle; + } + + return $bundles; + } + + public function getBundle(string $name): BundleInterface + { + foreach ($this->getBundles() as $bundleName => $bundle) { + if ($bundleName === $name) { + return $bundle; + } + } + + throw new \InvalidArgumentException(); + } + + public function locateResource(string $name): string + { + return __DIR__; + } + + public function getEnvironment(): string + { + return 'test'; + } + + public function isDebug(): bool + { + return false; + } + + public function getProjectDir(): string + { + return __DIR__; + } + + public function getContainer(): ContainerInterface + { + $container = new ContainerBuilder(); + $container->setParameter('kernel.debug', $this->isDebug()); + + return $container; + } + + public function getStartTime(): float + { + return -\INF; + } + public function getBuildDir(): string { return $this->varDir.'/build'; @@ -65,37 +165,269 @@ public function getCacheDir(): string return $this->varDir.'/cache'; } - public function registerContainerConfiguration(LoaderInterface $loader): void + public function getLogDir(): string { - $loader->load(static function (ContainerBuilder $container) { - $container->loadFromExtension('framework', [ - 'annotations' => false, - 'handle_all_throwables' => true, - 'http_method_override' => false, - 'php_errors' => ['log' => true], - ]); - }); + return $this->varDir.'/log'; } - public function process(ContainerBuilder $container): void + public function getCharset(): string { - $container->removeDefinition('config_builder.warmer'); + return 'UTF-8'; } }; $kernel->boot(); - self::assertDirectoryDoesNotExist($kernel->getBuildDir().'/Symfony'); - self::assertDirectoryDoesNotExist($kernel->getCacheDir().'/Symfony'); + $warmer = new ConfigBuilderCacheWarmer($kernel); + $warmer->warmUp($kernel->getCacheDir(), $kernel->getBuildDir()); + + self::assertFileExists($kernel->getBuildDir().'/Symfony/Config/FrameworkConfig.php'); + } + + public function testExtensionAddedInKernel() + { + $kernel = new class($this->varDir) extends TestKernel { + protected function build(ContainerBuilder $container): void + { + $container->registerExtension(new class() extends Extension implements ConfigurationInterface { + public function load(array $configs, ContainerBuilder $container): void + { + } + + public function getConfigTreeBuilder(): TreeBuilder + { + $treeBuilder = new TreeBuilder('app'); + $rootNode = $treeBuilder->getRootNode(); + + $rootNode + ->children() + ->scalarNode('provider')->end() + ->end() + ; + + return $treeBuilder; + } + + public function getAlias(): string + { + return 'app'; + } + }); + } + }; + $kernel->boot(); $warmer = new ConfigBuilderCacheWarmer($kernel); - $warmer->warmUp($kernel->getCacheDir()); + $warmer->warmUp($kernel->getCacheDir(), $kernel->getBuildDir()); - self::assertDirectoryDoesNotExist($kernel->getBuildDir().'/Symfony'); - self::assertDirectoryDoesNotExist($kernel->getCacheDir().'/Symfony'); + self::assertFileExists($kernel->getBuildDir().'/Symfony/Config/FrameworkConfig.php'); + self::assertFileExists($kernel->getBuildDir().'/Symfony/Config/AppConfig.php'); + } + public function testKernelAsExtension() + { + $kernel = new class($this->varDir) extends TestKernel implements ExtensionInterface, ConfigurationInterface { + public function load(array $configs, ContainerBuilder $container): void + { + } + + public function getXsdValidationBasePath(): string|false + { + return false; + } + + public function getNamespace(): string + { + return 'http://www.example.com/schema/acme'; + } + + public function getAlias(): string + { + return 'kernel'; + } + + public function getConfigTreeBuilder(): TreeBuilder + { + $treeBuilder = new TreeBuilder('kernel'); + $rootNode = $treeBuilder->getRootNode(); + + $rootNode + ->children() + ->scalarNode('provider')->end() + ->end() + ; + + return $treeBuilder; + } + }; + $kernel->boot(); + + $warmer = new ConfigBuilderCacheWarmer($kernel); $warmer->warmUp($kernel->getCacheDir(), $kernel->getBuildDir()); - self::assertDirectoryExists($kernel->getBuildDir().'/Symfony'); - self::assertDirectoryDoesNotExist($kernel->getCacheDir().'/Symfony'); + self::assertFileExists($kernel->getBuildDir().'/Symfony/Config/FrameworkConfig.php'); + self::assertFileExists($kernel->getBuildDir().'/Symfony/Config/KernelConfig.php'); + } + + public function testExtensionsExtendedInBuildMethods() + { + $kernel = new class($this->varDir) extends TestKernel { + protected function build(ContainerBuilder $container): void + { + /** @var TestSecurityExtension $extension */ + $extension = $container->getExtension('test_security'); + $extension->addAuthenticatorFactory(new class() implements TestAuthenticatorFactoryInterface { + public function getKey(): string + { + return 'token'; + } + + public function addConfiguration(NodeDefinition $node): void + { + } + }); + } + + public function registerBundles(): iterable + { + yield from parent::registerBundles(); + + yield new class() extends Bundle { + public function getContainerExtension(): ExtensionInterface + { + return new TestSecurityExtension(); + } + }; + + yield new class() extends Bundle { + public function build(ContainerBuilder $container): void + { + /** @var TestSecurityExtension $extension */ + $extension = $container->getExtension('test_security'); + $extension->addAuthenticatorFactory(new class() implements TestAuthenticatorFactoryInterface { + public function getKey(): string + { + return 'form-login'; + } + + public function addConfiguration(NodeDefinition $node): void + { + $node + ->children() + ->scalarNode('provider')->end() + ->end() + ; + } + }); + } + }; + } + }; + $kernel->boot(); + + $warmer = new ConfigBuilderCacheWarmer($kernel); + $warmer->warmUp($kernel->getCacheDir(), $kernel->getBuildDir()); + + self::assertFileExists($kernel->getBuildDir().'/Symfony/Config/FrameworkConfig.php'); + self::assertFileExists($kernel->getBuildDir().'/Symfony/Config/SecurityConfig.php'); + self::assertFileExists($kernel->getBuildDir().'/Symfony/Config/Security/FirewallConfig.php'); + self::assertFileExists($kernel->getBuildDir().'/Symfony/Config/Security/FirewallConfig/FormLoginConfig.php'); + self::assertFileExists($kernel->getBuildDir().'/Symfony/Config/Security/FirewallConfig/TokenConfig.php'); + } +} + +class TestKernel extends Kernel implements CompilerPassInterface +{ + private $varDir; + + public function __construct(string $varDir) + { + parent::__construct('test', false); + + $this->varDir = $varDir; + } + + public function registerBundles(): iterable + { + yield new FrameworkBundle(); + } + + public function getBuildDir(): string + { + return $this->varDir.'/build'; + } + + public function getCacheDir(): string + { + return $this->varDir.'/cache'; + } + + public function registerContainerConfiguration(LoaderInterface $loader): void + { + $loader->load(static function (ContainerBuilder $container) { + $container->loadFromExtension('framework', [ + 'annotations' => false, + 'handle_all_throwables' => true, + 'http_method_override' => false, + 'php_errors' => ['log' => true], + ]); + }); + } + + public function process(ContainerBuilder $container): void + { + $container->removeDefinition('config_builder.warmer'); + } +} + +interface TestAuthenticatorFactoryInterface +{ + public function getKey(): string; + + public function addConfiguration(NodeDefinition $builder): void; +} + +class TestSecurityExtension extends Extension implements ConfigurationInterface +{ + /** @var TestAuthenticatorFactoryInterface[] */ + private $factories; + + public function load(array $configs, ContainerBuilder $container): void + { + } + + public function getConfiguration(array $config, ContainerBuilder $container): ConfigurationInterface + { + return $this; + } + + public function addAuthenticatorFactory(TestAuthenticatorFactoryInterface $factory): void + { + $this->factories[] = $factory; + } + + public function getConfigTreeBuilder(): TreeBuilder + { + $treeBuilder = new TreeBuilder('security'); + $rootNode = $treeBuilder->getRootNode(); + + $firewallNodeBuilder = $rootNode + ->fixXmlConfig('firewall') + ->children() + ->arrayNode('firewalls') + ->isRequired() + ->requiresAtLeastOneElement() + ->useAttributeAsKey('name') + ->prototype('array') + ->children() + ; + + foreach ($this->factories as $factory) { + $name = str_replace('-', '_', $factory->getKey()); + $factoryNode = $firewallNodeBuilder->arrayNode($name); + + $factory->addConfiguration($factoryNode); + } + + return $treeBuilder; } }
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: