From 5b10edf977d2c71e9aa96b42ba9fea36121d9435 Mon Sep 17 00:00:00 2001 From: David Buchmann Date: Thu, 28 Mar 2024 11:06:41 +0100 Subject: [PATCH] upgrade to phpunit 10 and adjust to FOSHttpCache strict typing --- .github/workflows/php.yml | 4 +- composer.json | 2 +- phpunit.xml.dist | 38 +++--- src/CacheManager.php | 31 ++--- .../FOSHttpCacheExtension.php | 6 +- .../InvalidationListenerTest.php | 7 +- .../EventListener/TagListenerTest.php | 19 ++- .../EventListener/UserContextListenerTest.php | 13 +- tests/Unit/CacheManagerTest.php | 2 +- tests/Unit/Command/PathSanityCheckTest.php | 11 +- .../DependencyInjection/ConfigurationTest.php | 89 +++++++------- .../FOSHttpCacheExtensionTest.php | 114 ++++++++---------- .../CacheableResponseMatcherTest.php | 13 +- 13 files changed, 155 insertions(+), 194 deletions(-) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 445948b0..f250d39c 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -67,10 +67,10 @@ jobs: if: ${{ matrix.stability != 'dev' }} - name: Run tests - run: php vendor/bin/phpunit -v + run: php vendor/bin/phpunit if: ${{ matrix.stability != 'dev' }} - name: Run tests allow to fail - run: php vendor/bin/phpunit -v || true + run: php vendor/bin/phpunit || true continue-on-error: true if: ${{ matrix.stability == 'dev' }} diff --git a/composer.json b/composer.json index eedf1320..50e84540 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,7 @@ "symfony/browser-kit": "^6.4 || ^7.0", "symfony/console": "^6.4 || ^7.0", "symfony/finder": "^6.4 || ^7.0", - "phpunit/phpunit": "^9.6.15", + "phpunit/phpunit": "^10.5", "symfony/security-bundle": "^6.4 || ^7.0", "symfony/twig-bundle": "^6.4 || ^7.0", "twig/twig": "^v3.8", diff --git a/phpunit.xml.dist b/phpunit.xml.dist index dc246058..25a46d14 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,10 +1,19 @@ - - + cacheDirectory=".phpunit.cache" +> + + + ./src + + + ./src/Resources + + + ./tests/Unit @@ -14,22 +23,9 @@ - - - ./src - - ./src/Resources - - - - - - - - - - - + + + diff --git a/src/CacheManager.php b/src/CacheManager.php index ae100c53..aa5ea041 100644 --- a/src/CacheManager.php +++ b/src/CacheManager.php @@ -24,22 +24,14 @@ */ class CacheManager extends CacheInvalidator { - /** - * @var ProxyClient - */ - private $cache; + private ProxyClient $cache; - /** - * @var UrlGeneratorInterface - */ - private $urlGenerator; + private UrlGeneratorInterface $urlGenerator; /** * What type of urls to generate. - * - * @var bool|string */ - private $generateUrlType = UrlGeneratorInterface::ABSOLUTE_PATH; + private int $generateUrlType = UrlGeneratorInterface::ABSOLUTE_PATH; /** * Constructor. @@ -57,9 +49,9 @@ public function __construct(ProxyClient $cache, UrlGeneratorInterface $urlGenera /** * Set what type of URLs to generate. * - * @param bool|string $generateUrlType One of the constants in UrlGeneratorInterface + * @param int $generateUrlType One of the constants in UrlGeneratorInterface */ - public function setGenerateUrlType($generateUrlType) + public function setGenerateUrlType(int $generateUrlType): void { $this->generateUrlType = $generateUrlType; } @@ -73,7 +65,7 @@ public function setGenerateUrlType($generateUrlType) * * @return $this */ - public function invalidateRoute($name, array $parameters = [], array $headers = []) + public function invalidateRoute(string $name, array $parameters = [], array $headers = []): static { $this->invalidatePath($this->urlGenerator->generate($name, $parameters, $this->generateUrlType), $headers); @@ -89,21 +81,14 @@ public function invalidateRoute($name, array $parameters = [], array $headers = * * @return $this */ - public function refreshRoute($route, array $parameters = [], array $headers = []) + public function refreshRoute(string $route, array $parameters = [], array $headers = []): static { $this->refreshPath($this->urlGenerator->generate($route, $parameters, $this->generateUrlType), $headers); return $this; } - /** - * Send all pending invalidation requests. - * - * @return int the number of cache invalidations performed per caching server - * - * @throws \FOS\HttpCache\Exception\ExceptionCollection - */ - public function flush() + public function flush(): int { if (!$this->cache instanceof LazyObjectInterface || $this->cache->isLazyObjectInitialized()) { return parent::flush(); diff --git a/src/DependencyInjection/FOSHttpCacheExtension.php b/src/DependencyInjection/FOSHttpCacheExtension.php index 447c9119..8595b751 100644 --- a/src/DependencyInjection/FOSHttpCacheExtension.php +++ b/src/DependencyInjection/FOSHttpCacheExtension.php @@ -382,6 +382,7 @@ private function createHttpDispatcherDefinition(ContainerBuilder $container, arr } $config['servers'] = $config['servers_from_jsonenv']; } + if (!empty($config['base_url'])) { $baseUrl = $config['base_url']; $usedEnvs = []; @@ -391,8 +392,9 @@ private function createHttpDispatcherDefinition(ContainerBuilder $container, arr $this->validateUrl($baseUrl, 'Not a valid base path: "%s"'); } } else { - $baseUrl = null; + $baseUrl = ''; } + $httpClient = null; if ($config['http_client']) { $httpClient = new Reference($config['http_client']); @@ -629,7 +631,7 @@ private function validateUrl($url, $msg): void { $prefixed = $this->prefixSchema($url); - if (!$parts = parse_url($prefixed)) { + if (!parse_url($prefixed)) { throw new InvalidConfigurationException(sprintf($msg, $url)); } } diff --git a/tests/Functional/EventListener/InvalidationListenerTest.php b/tests/Functional/EventListener/InvalidationListenerTest.php index 9d584f90..5fa650d2 100644 --- a/tests/Functional/EventListener/InvalidationListenerTest.php +++ b/tests/Functional/EventListener/InvalidationListenerTest.php @@ -13,6 +13,7 @@ use FOS\HttpCacheBundle\CacheManager; use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; +use PHPUnit\Framework\Attributes as PHPUnit; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; class InvalidationListenerTest extends WebTestCase @@ -49,9 +50,7 @@ public function testInvalidateRoute(): void $client->request('POST', '/invalidate/route/42'); } - /** - * @dataProvider getStatusCodesThatTriggerInvalidation - */ + #[PHPUnit\DataProvider('getStatusCodesThatTriggerInvalidation')] public function testInvalidatePath($statusCode): void { $client = static::createClient(); @@ -96,7 +95,7 @@ public function testErrorIsNotInvalidated(): void $client->request('POST', '/invalidate/error'); } - public function getStatusCodesThatTriggerInvalidation(): array + public static function getStatusCodesThatTriggerInvalidation(): array { return [[200], [204], [302]]; } diff --git a/tests/Functional/EventListener/TagListenerTest.php b/tests/Functional/EventListener/TagListenerTest.php index 392d0bd6..d4c62ef7 100644 --- a/tests/Functional/EventListener/TagListenerTest.php +++ b/tests/Functional/EventListener/TagListenerTest.php @@ -15,6 +15,7 @@ use FOS\HttpCacheBundle\Configuration\Tag; use FOS\HttpCacheBundle\EventListener\TagListener; use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; +use PHPUnit\Framework\Attributes as PHPUnit; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -143,9 +144,7 @@ public function testTwigExtension(): void $this->assertEquals('tag-from-twig', $response->headers->get('X-Cache-Tags')); } - /** - * @dataProvider cacheableRequestResponseCombinations - */ + #[PHPUnit\DataProvider('cacheableRequestResponseCombinations')] public function testTagsAreSetWhenCacheable(Request $request, Response $response): void { self::$overrideService = true; @@ -175,9 +174,7 @@ public function testTagsAreSetWhenCacheable(Request $request, Response $response $this->assertEquals('cacheable-is-tagged', $headers->get('X-Cache-Tags')); } - /** - * @dataProvider mustInvalidateRequestResponseCombinations - */ + #[PHPUnit\DataProvider('mustInvalidateRequestResponseCombinations')] public function testTagsAreInvalidated(Request $request, Response $response): void { self::$overrideService = true; @@ -211,9 +208,7 @@ public function testTagsAreInvalidated(Request $request, Response $response): vo $this->assertFalse($headers->has('X-Cache-Tags')); } - /** - * @dataProvider mustNotInvalidateRequestResponseCombinations - */ + #[PHPUnit\DataProvider('mustNotInvalidateRequestResponseCombinations')] public function testTagsAreNotInvalidated(Request $request, Response $response): void { self::$overrideService = true; @@ -244,7 +239,7 @@ public function testTagsAreNotInvalidated(Request $request, Response $response): $this->assertFalse($headers->has('X-Cache-Tags')); } - public function cacheableRequestResponseCombinations(): array + public static function cacheableRequestResponseCombinations(): array { return [ [Request::create('', 'GET'), new Response('', 200)], @@ -254,7 +249,7 @@ public function cacheableRequestResponseCombinations(): array ]; } - public function mustInvalidateRequestResponseCombinations(): array + public static function mustInvalidateRequestResponseCombinations(): array { return [ // https://github.com/FriendsOfSymfony/FOSHttpCacheBundle/issues/241 @@ -262,7 +257,7 @@ public function mustInvalidateRequestResponseCombinations(): array ]; } - public function mustNotInvalidateRequestResponseCombinations(): array + public static function mustNotInvalidateRequestResponseCombinations(): array { return [ // https://github.com/FriendsOfSymfony/FOSHttpCacheBundle/issues/279 diff --git a/tests/Functional/EventListener/UserContextListenerTest.php b/tests/Functional/EventListener/UserContextListenerTest.php index e0137782..76e19990 100644 --- a/tests/Functional/EventListener/UserContextListenerTest.php +++ b/tests/Functional/EventListener/UserContextListenerTest.php @@ -12,6 +12,7 @@ namespace FOS\HttpCacheBundle\Tests\Functional\EventListener; use FOS\HttpCacheBundle\Tests\Functional\SessionHelperTrait; +use PHPUnit\Framework\Attributes as PHPUnit; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\HttpKernel\Event\RequestEvent; @@ -19,9 +20,7 @@ class UserContextListenerTest extends WebTestCase { use SessionHelperTrait; - /** - * @dataProvider userHashDataProvider - */ + #[PHPUnit\DataProvider('userHashDataProvider')] public function testHashLookup(string $username, string $hash) { // as we tamper with the session id, make sure no previous session is around @@ -48,10 +47,8 @@ public function testHashLookup(string $username, string $hash) $this->assertSame('max-age=60, public', $response->headers->get('Cache-Control')); } - /** - * @dataProvider userHashDataProvider - */ - public function testSessionCanBeCached(string $username, string $hash) + #[PHPUnit\DataProvider('userHashDataProvider')] + public function testSessionCanBeCached(string $username, string $hash): void { $client = static::createClient([], $username ? [ 'PHP_AUTH_USER' => $username, @@ -66,7 +63,7 @@ public function testSessionCanBeCached(string $username, string $hash) $this->assertEquals('max-age=60, public', $response->headers->get('Cache-Control')); } - public function userHashDataProvider() + public static function userHashDataProvider(): \Generator { yield 'anonymous' => ['', '5224d8f5b85429624e2160e538a3376a479ec87b89251b295c44ecbf7498ea3c']; yield 'user' => ['user', '14cea38921d7f2284a52ac67eafb9ed5d30bed84684711591747d9110cae8be9']; diff --git a/tests/Unit/CacheManagerTest.php b/tests/Unit/CacheManagerTest.php index 996ffc5d..c5ba8948 100644 --- a/tests/Unit/CacheManagerTest.php +++ b/tests/Unit/CacheManagerTest.php @@ -38,7 +38,7 @@ public function testInvalidateRoute() ->shouldReceive('purge')->once()->with('/my/route', []) ->shouldReceive('purge')->once()->with('/route/with/params/id/123', []) ->shouldReceive('purge')->once()->with('/route/with/params/id/123', ['X-Foo' => 'bar']) - ->shouldReceive('flush')->once() + ->shouldReceive('flush')->once()->andReturn(2) ->getMock(); $router = \Mockery::mock(UrlGeneratorInterface::class) diff --git a/tests/Unit/Command/PathSanityCheckTest.php b/tests/Unit/Command/PathSanityCheckTest.php index cc8e9644..61e807e9 100644 --- a/tests/Unit/Command/PathSanityCheckTest.php +++ b/tests/Unit/Command/PathSanityCheckTest.php @@ -13,13 +13,14 @@ use FOS\HttpCacheBundle\Command\PathSanityCheck; use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; +use PHPUnit\Framework\Attributes as PHPUnit; use PHPUnit\Framework\TestCase; class PathSanityCheckTest extends TestCase { use MockeryPHPUnitIntegration; - public function pathProvider() + public static function pathProvider(): array { return [ [false, '/foo'], @@ -32,10 +33,8 @@ public function pathProvider() ]; } - /** - * @dataProvider pathProvider - */ - public function testLooksLikeRegularExpression($expected, $path) + #[PHPUnit\DataProvider('pathProvider')] + public function testLooksLikeRegularExpression(bool $expected, string $path): void { $sanityChecking = new SanityChecking(); $this->assertEquals($expected, $sanityChecking->looksLikeRegularExpression($path)); @@ -48,7 +47,7 @@ class SanityChecking looksLikeRegularExpression as traitFunction; } - public function looksLikeRegularExpression($path) + public function looksLikeRegularExpression(string $path): bool { return $this->traitFunction($path); } diff --git a/tests/Unit/DependencyInjection/ConfigurationTest.php b/tests/Unit/DependencyInjection/ConfigurationTest.php index ba7177c7..a3ac1cc8 100644 --- a/tests/Unit/DependencyInjection/ConfigurationTest.php +++ b/tests/Unit/DependencyInjection/ConfigurationTest.php @@ -15,6 +15,7 @@ use FOS\HttpCacheBundle\DependencyInjection\FOSHttpCacheExtension; use JeanBeru\HttpCacheCloudFront\Proxy\CloudFront; use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractExtensionConfigurationTestCase; +use PHPUnit\Framework\Attributes as PHPUnit; use Symfony\Component\Config\Definition\ConfigurationInterface; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; use Symfony\Component\Config\Definition\Processor; @@ -32,11 +33,11 @@ protected function getConfiguration(): ConfigurationInterface return new Configuration(false); } - public function testEmptyConfiguration() + public function testEmptyConfiguration(): void { $expectedConfiguration = $this->getEmptyConfig(); - $formats = array_map(function ($path) { + $formats = array_map(static function (string $path) { return __DIR__.'/../../Resources/Fixtures/'.$path; }, [ 'config/empty.yml', @@ -49,7 +50,7 @@ public function testEmptyConfiguration() } } - public function testSupportsAllConfigFormats() + public function testSupportsAllConfigFormats(): void { $expectedConfiguration = [ 'cacheable' => [ @@ -191,7 +192,7 @@ public function testSupportsAllConfigFormats() ], ]; - $formats = array_map(function ($path) { + $formats = array_map(static function (string $path) { return __DIR__.'/../../Resources/Fixtures/'.$path; }, [ 'config/full.yml', @@ -204,7 +205,7 @@ public function testSupportsAllConfigFormats() } } - public function testCustomProxyClient() + public function testCustomProxyClient(): void { $expectedConfiguration = $this->getEmptyConfig(); $expectedConfiguration['cache_manager'] = [ @@ -229,7 +230,7 @@ public function testCustomProxyClient() } } - public function testSupportsNginx() + public function testSupportsNginx(): void { $expectedConfiguration = $this->getEmptyConfig(); $expectedConfiguration['proxy_client'] = [ @@ -248,7 +249,7 @@ public function testSupportsNginx() $expectedConfiguration['invalidation']['enabled'] = 'auto'; $expectedConfiguration['user_context']['logout_handler']['enabled'] = false; - $formats = array_map(function ($path) { + $formats = array_map(static function (string $path) { return __DIR__.'/../../Resources/Fixtures/'.$path; }, [ 'config/nginx.yml', @@ -261,7 +262,7 @@ public function testSupportsNginx() } } - public function testSupportsSymfony() + public function testSupportsSymfony(): void { $expectedConfiguration = $this->getEmptyConfig(); $expectedConfiguration['proxy_client'] = [ @@ -297,7 +298,7 @@ public function testSupportsSymfony() } } - public function testSupportsCloudflare() + public function testSupportsCloudflare(): void { $expectedConfiguration = $this->getEmptyConfig(); $expectedConfiguration['proxy_client'] = [ @@ -313,7 +314,7 @@ public function testSupportsCloudflare() $expectedConfiguration['invalidation']['enabled'] = 'auto'; $expectedConfiguration['user_context']['logout_handler']['enabled'] = false; - $formats = array_map(function ($path) { + $formats = array_map(static function (string $path) { return __DIR__.'/../../Resources/Fixtures/'.$path; }, [ 'config/cloudflare.yml', @@ -326,7 +327,7 @@ public function testSupportsCloudflare() } } - public function testSupportsCloudfront() + public function testSupportsCloudfront(): void { if (!class_exists(CloudFront::class)) { $this->markTestSkipped('jean-beru/fos-http-cache-cloudfront not available'); @@ -345,7 +346,7 @@ public function testSupportsCloudfront() $expectedConfiguration['tags']['enabled'] = 'auto'; $expectedConfiguration['invalidation']['enabled'] = 'auto'; - $formats = array_map(function ($path) { + $formats = array_map(static function (string $path) { return __DIR__.'/../../Resources/Fixtures/'.$path; }, [ 'config/cloudfront.yml', @@ -358,7 +359,7 @@ public function testSupportsCloudfront() } } - public function testCloudfrontConfigurationWithClientIsNotAllowed() + public function testCloudfrontConfigurationWithClientIsNotAllowed(): void { if (!class_exists(CloudFront::class)) { $this->markTestSkipped('jean-beru/fos-http-cache-cloudfront not available'); @@ -380,7 +381,7 @@ public function testCloudfrontConfigurationWithClientIsNotAllowed() (new Processor())->processConfiguration($configuration, ['fos_http_cache' => $params]); } - public function testSupportsFastly() + public function testSupportsFastly(): void { $expectedConfiguration = $this->getEmptyConfig(); $expectedConfiguration['proxy_client'] = [ @@ -398,7 +399,7 @@ public function testSupportsFastly() $expectedConfiguration['tags']['separator'] = ' '; $expectedConfiguration['invalidation']['enabled'] = 'auto'; - $formats = array_map(function ($path) { + $formats = array_map(static function (string $path) { return __DIR__.'/../../Resources/Fixtures/'.$path; }, [ 'config/fastly.yml', @@ -411,7 +412,7 @@ public function testSupportsFastly() } } - public function testEmptyServerConfigurationIsNotAllowed() + public function testEmptyServerConfigurationIsNotAllowed(): void { $this->expectException(InvalidConfigurationException::class); $this->expectExceptionMessage('Either configure the "http.servers" or "http.servers_from_jsonenv" section or enable "proxy_client.symfony.use_kernel_dispatcher'); @@ -430,7 +431,7 @@ public function testEmptyServerConfigurationIsNotAllowed() (new Processor())->processConfiguration($configuration, ['fos_http_cache' => $params]); } - public function testDefaultIsNotConsideredAsServerConfig() + public function testDefaultIsNotConsideredAsServerConfig(): void { $params = $this->getEmptyConfig(); $params['proxy_client'] = [ @@ -444,7 +445,7 @@ public function testDefaultIsNotConsideredAsServerConfig() $this->addToAssertionCount(1); } - public function testSupportsNoop() + public function testSupportsNoop(): void { $expectedConfiguration = $this->getEmptyConfig(); $expectedConfiguration['proxy_client'] = [ @@ -456,7 +457,7 @@ public function testSupportsNoop() $expectedConfiguration['invalidation']['enabled'] = 'auto'; $expectedConfiguration['user_context']['logout_handler']['enabled'] = true; - $formats = array_map(function ($path) { + $formats = array_map(static function (string $path) { return __DIR__.'/../../Resources/Fixtures/'.$path; }, [ 'config/noop.yml', @@ -469,7 +470,7 @@ public function testSupportsNoop() } } - public function testSplitOptions() + public function testSplitOptions(): void { $expectedConfiguration = $this->getEmptyConfig(); $expectedConfiguration['cache_control'] = [ @@ -522,7 +523,7 @@ public function testSplitOptions() $expectedConfiguration['invalidation']['enabled'] = 'auto'; $expectedConfiguration['user_context']['logout_handler']['enabled'] = true; - $formats = array_map(function ($path) { + $formats = array_map(static function (string $path) { return __DIR__.'/../../Resources/Fixtures/'.$path; }, [ 'config/split.yml', @@ -535,13 +536,13 @@ public function testSplitOptions() } } - public function testSupportsCacheableResponseExpression() + public function testSupportsCacheableResponseExpression(): void { $expectedConfiguration = $this->getEmptyConfig(); $expectedConfiguration['cacheable']['response']['expression'] = 'response.getStatusCode() >= 300'; - $formats = array_map(function ($path) { + $formats = array_map(static function (string $path) { return __DIR__.'/../../Resources/Fixtures/'.$path; }, [ 'config/cacheable_response_expression.yml', @@ -554,9 +555,9 @@ public function testSupportsCacheableResponseExpression() } } - public function testCacheManagerNoClient() + public function testCacheManagerNoClient(): void { - $formats = array_map(function ($path) { + $formats = array_map(static function (string $path) { return __DIR__.'/../../Resources/Fixtures/'.$path; }, [ 'config/cachemanager_noclient.yml', @@ -574,9 +575,9 @@ public function testCacheManagerNoClient() } } - public function testTagsNoCacheManager() + public function testTagsNoCacheManager(): void { - $formats = array_map(function ($path) { + $formats = array_map(static function (string $path) { return __DIR__.'/../../Resources/Fixtures/'.$path; }, [ 'config/tags_nocachemanager.yml', @@ -594,12 +595,12 @@ public function testTagsNoCacheManager() } } - public function testTagsStrict() + public function testTagsStrict(): void { $expectedConfiguration = $this->getEmptyConfig(); $expectedConfiguration['tags']['strict'] = true; - $formats = array_map(function ($path) { + $formats = array_map(static function (string $path) { return __DIR__.'/../../Resources/Fixtures/'.$path; }, [ 'config/tags_strict.yml', @@ -612,7 +613,7 @@ public function testTagsStrict() } } - public function testWeakETags() + public function testWeakETags(): void { $expectedConfiguration = $this->getEmptyConfig(); $expectedConfiguration['cache_control'] = [ @@ -641,7 +642,7 @@ public function testWeakETags() ], ]; - $formats = array_map(function ($path) { + $formats = array_map(static function (string $path) { return __DIR__.'/../../Resources/Fixtures/'.$path; }, [ 'config/etag_weak.yml', @@ -654,7 +655,7 @@ public function testWeakETags() } } - public function testStrongETags() + public function testStrongETags(): void { $expectedConfiguration = $this->getEmptyConfig(); $expectedConfiguration['cache_control'] = [ @@ -683,7 +684,7 @@ public function testStrongETags() ], ]; - $formats = array_map(function ($path) { + $formats = array_map(static function (string $path) { return __DIR__.'/../../Resources/Fixtures/'.$path; }, [ 'config/etag_true.yml', @@ -696,9 +697,9 @@ public function testStrongETags() } } - public function testInvalidationNoCacheManager() + public function testInvalidationNoCacheManager(): void { - $formats = array_map(function ($path) { + $formats = array_map(static function (string $path) { return __DIR__.'/../../Resources/Fixtures/'.$path; }, [ 'config/invalidation_nocachemanager.yml', @@ -716,7 +717,7 @@ public function testInvalidationNoCacheManager() } } - public function userContextLogoutHandlerProvider() + public static function userContextLogoutHandlerProvider(): array { return [ 'auto no client' => ['config/user_context_auto_noclient.yml', false, false, false, false, null], @@ -728,10 +729,8 @@ public function userContextLogoutHandlerProvider() ]; } - /** - * @dataProvider userContextLogoutHandlerProvider - */ - public function testUserContextLogoutHandler(string $configFile, $expected, $cacheManager, $proxyClient, $tags, $exception) + #[PHPUnit\DataProvider('userContextLogoutHandlerProvider')] + public function testUserContextLogoutHandler(string $configFile, $expected, $cacheManager, $proxyClient, $tags, $exception): void { $configFile = __DIR__.'/../../Resources/Fixtures/'.$configFile; if ($exception) { @@ -764,9 +763,9 @@ public function testUserContextLogoutHandler(string $configFile, $expected, $cac $this->assertProcessedConfigurationEquals($expectedConfiguration, [$configFile]); } - public function testInvalidDate() + public function testInvalidDate(): void { - $formats = array_map(function ($path) { + $formats = array_map(static function (string $path) { return __DIR__.'/../../Resources/Fixtures/'.$path; }, [ 'config/invalid_date.yml', @@ -804,7 +803,7 @@ public function testSupportsServersFromJsonEnv(): void $expectedConfiguration['invalidation']['enabled'] = 'auto'; $expectedConfiguration['user_context']['logout_handler']['enabled'] = true; - $formats = array_map(function ($path) { + $formats = array_map(static function (string $path) { return __DIR__.'/../../Resources/Fixtures/'.$path; }, [ 'config/servers_from_jsonenv.yml', @@ -837,7 +836,7 @@ public function testConfigureExpressionLanguageService(): void $expectedConfiguration['invalidation']['enabled'] = 'auto'; $expectedConfiguration['user_context']['logout_handler']['enabled'] = true; - $formats = array_map(function ($path) { + $formats = array_map(static function (string $path) { return __DIR__.'/../../Resources/Fixtures/'.$path; }, [ 'config/servers_from_jsonenv.yml', @@ -853,7 +852,7 @@ public function testConfigureExpressionLanguageService(): void /** * @return array The configuration when nothing is specified */ - private function getEmptyConfig() + private function getEmptyConfig(): array { return [ 'cacheable' => [ diff --git a/tests/Unit/DependencyInjection/FOSHttpCacheExtensionTest.php b/tests/Unit/DependencyInjection/FOSHttpCacheExtensionTest.php index 553a868b..611dc44a 100644 --- a/tests/Unit/DependencyInjection/FOSHttpCacheExtensionTest.php +++ b/tests/Unit/DependencyInjection/FOSHttpCacheExtensionTest.php @@ -15,6 +15,7 @@ use FOS\HttpCacheBundle\DependencyInjection\FOSHttpCacheExtension; use JeanBeru\HttpCacheCloudFront\Proxy\CloudFront; use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; +use PHPUnit\Framework\Attributes as PHPUnit; use PHPUnit\Framework\TestCase; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; use Symfony\Component\DependencyInjection\ChildDefinition; @@ -32,17 +33,14 @@ class FOSHttpCacheExtensionTest extends TestCase { use MockeryPHPUnitIntegration; - /** - * @var FOSHttpCacheExtension - */ - protected $extension; + protected FOSHttpCacheExtension $extension; protected function setUp(): void { $this->extension = new FOSHttpCacheExtension(); } - public function testConfigLoadVarnish() + public function testConfigLoadVarnish(): void { $container = $this->createContainer(); $this->extension->load([$this->getBaseConfig()], $container); @@ -54,7 +52,7 @@ public function testConfigLoadVarnish() $this->assertTrue($container->hasDefinition('fos_http_cache.event_listener.tag')); } - public function testConfigLoadVarnishCustomClient() + public function testConfigLoadVarnishCustomClient(): void { $container = $this->createContainer(); @@ -68,7 +66,7 @@ public function testConfigLoadVarnishCustomClient() $this->assertEquals('my_guzzle', $def->getArgument(2)->__toString()); } - public function testConfigLoadVarnishInvalidUrl() + public function testConfigLoadVarnishInvalidUrl(): void { $this->expectException(InvalidConfigurationException::class); @@ -79,7 +77,7 @@ public function testConfigLoadVarnishInvalidUrl() $this->extension->load([$config], $container); } - public function testConfigLoadNginx() + public function testConfigLoadNginx(): void { $container = $this->createContainer(); $this->extension->load([ @@ -104,7 +102,7 @@ public function testConfigLoadNginx() $this->assertFalse($container->hasDefinition('fos_http_cache.http.symfony_response_tagger')); } - public function testConfigLoadSymfony() + public function testConfigLoadSymfony(): void { $container = $this->createContainer(); $this->extension->load([ @@ -130,7 +128,7 @@ public function testConfigLoadSymfony() $this->assertTrue($container->hasDefinition('fos_http_cache.http.symfony_response_tagger')); } - public function testConfigLoadSymfonyWithKernelDispatcher() + public function testConfigLoadSymfonyWithKernelDispatcher(): void { $container = $this->createContainer(); $this->extension->load([ @@ -147,7 +145,7 @@ public function testConfigLoadSymfonyWithKernelDispatcher() $this->assertSame(KernelDispatcher::class, $container->getDefinition('fos_http_cache.proxy_client.symfony.http_dispatcher')->getClass()); } - public function testConfigLoadCloudflare() + public function testConfigLoadCloudflare(): void { $container = $this->createContainer(); $this->extension->load([ @@ -167,7 +165,7 @@ public function testConfigLoadCloudflare() $this->assertTrue($container->hasDefinition('fos_http_cache.event_listener.invalidation')); } - public function testConfigLoadCloudfront() + public function testConfigLoadCloudfront(): void { if (!class_exists(CloudFront::class)) { $this->markTestSkipped('jean-beru/fos-http-cache-cloudfront not available'); @@ -193,7 +191,7 @@ public function testConfigLoadCloudfront() $this->assertTrue($container->hasDefinition('fos_http_cache.event_listener.invalidation')); } - public function testConfigLoadCloudfrontWithClient() + public function testConfigLoadCloudfrontWithClient(): void { if (!class_exists(CloudFront::class)) { $this->markTestSkipped('jean-beru/fos-http-cache-cloudfront not available'); @@ -220,7 +218,7 @@ public function testConfigLoadCloudfrontWithClient() $this->assertTrue($container->hasDefinition('fos_http_cache.event_listener.invalidation')); } - public function testConfigLoadFastly() + public function testConfigLoadFastly(): void { $container = $this->createContainer(); $this->extension->load([ @@ -240,7 +238,7 @@ public function testConfigLoadFastly() $this->assertTrue($container->hasDefinition('fos_http_cache.event_listener.invalidation')); } - public function testConfigLoadNoop() + public function testConfigLoadNoop(): void { $container = $this->createContainer(); $this->extension->load([ @@ -259,7 +257,7 @@ public function testConfigLoadNoop() $this->assertFalse($container->hasDefinition('fos_http_cache.http.symfony_response_tagger')); } - public function testConfigCustomClient() + public function testConfigCustomClient(): void { $container = $this->createContainer(); $this->extension->load([ @@ -278,7 +276,7 @@ public function testConfigCustomClient() $this->assertFalse($container->hasDefinition('fos_http_cache.http.symfony_response_tagger')); } - public function testEmptyConfig() + public function testEmptyConfig(): void { $config = []; @@ -288,7 +286,7 @@ public function testEmptyConfig() $this->assertFalse($container->has('fos_http_cache.user_context.logout_handler')); } - public function testConfigTagNotSupported() + public function testConfigTagNotSupported(): void { $this->expectException(InvalidConfigurationException::class); $this->expectExceptionMessage('You can not enable cache tagging with the nginx client'); @@ -313,7 +311,7 @@ public function testConfigTagNotSupported() $this->extension->load([$config], $container); } - public function testConfigLoadTagRules() + public function testConfigLoadTagRules(): void { $config = $this->getBaseConfig() + [ 'tags' => [ @@ -342,7 +340,7 @@ public function testConfigLoadTagRules() $this->assertFalse($container->hasDefinition('fos_http_cache.tag_handler.max_header_value_length_header_formatter')); } - public function testConfigWithMaxHeaderLengthValueDecoratesTagService() + public function testConfigWithMaxHeaderLengthValueDecoratesTagService(): void { $config = $this->getBaseConfig() + [ 'tags' => [ @@ -361,7 +359,7 @@ public function testConfigWithMaxHeaderLengthValueDecoratesTagService() $this->assertSame(2048, $definition->getArgument(1)); } - public function testConfigLoadInvalidatorRules() + public function testConfigLoadInvalidatorRules(): void { $config = $this->getBaseConfig() + [ 'invalidation' => [ @@ -391,7 +389,7 @@ public function testConfigLoadInvalidatorRules() $container->compile(); } - public function testConfigLoadCacheControl() + public function testConfigLoadCacheControl(): void { $config = [ 'cache_control' => [ @@ -427,7 +425,7 @@ public function testConfigLoadCacheControl() $this->assertListenerHasRule($container, 'fos_http_cache.event_listener.cache_control'); } - public function testConfigLoadCacheControlResponseStatus() + public function testConfigLoadCacheControlResponseStatus(): void { $config = [ 'cache_control' => [ @@ -459,7 +457,7 @@ public function testConfigLoadCacheControlResponseStatus() $this->assertListenerHasRule($container, 'fos_http_cache.event_listener.cache_control'); } - public function testConfigLoadCacheControlExpression() + public function testConfigLoadCacheControlExpression(): void { $config = [ 'cache_control' => [ @@ -494,7 +492,7 @@ public function testConfigLoadCacheControlExpression() /** * Check if comma separated strings are parsed as expected. */ - public function testConfigLoadCacheControlSplit() + public function testConfigLoadCacheControlSplit(): void { $config = [ 'cache_control' => [ @@ -521,7 +519,7 @@ public function testConfigLoadCacheControlSplit() $this->assertRequestMatcherCreated($container, ['_controller' => '^AcmeBundle:Default:index$'], ['GET', 'HEAD']); } - public function testConfigLoadCacheControlDuplicateRule() + public function testConfigLoadCacheControlDuplicateRule(): void { $config = [ 'cache_control' => [ @@ -556,7 +554,7 @@ public function testConfigLoadCacheControlDuplicateRule() $this->extension->load([$config], $container); } - public function testConfigUserContext() + public function testConfigUserContext(): void { $config = $this->getBaseConfig() + [ 'user_context' => [ @@ -585,7 +583,7 @@ public function testConfigUserContext() $this->assertEquals(['fos_http_cache.user_context.role_provider' => [[]]], $container->findTaggedServiceIds('fos_http_cache.user_context_provider')); } - public function testConfigWithoutUserContext() + public function testConfigWithoutUserContext(): void { $config = [[ 'user_context' => [ @@ -614,7 +612,7 @@ public function testConfigWithoutUserContext() $this->assertFalse($container->has('fos_http_cache.user_context.session_listener')); } - public function testConfigLoadFlashMessageListener() + public function testConfigLoadFlashMessageListener(): void { $config = [ [ @@ -628,7 +626,7 @@ public function testConfigLoadFlashMessageListener() $this->assertTrue($container->has('fos_http_cache.event_listener.flash_message')); } - public function testVarnishDefaultTagMode() + public function testVarnishDefaultTagMode(): void { $container = $this->createContainer(); @@ -640,7 +638,7 @@ public function testVarnishDefaultTagMode() $this->assertEquals(['tag_mode' => 'ban', 'tags_header' => 'X-Cache-Tags'], $container->getParameter('fos_http_cache.proxy_client.varnish.options')); } - public function testVarnishBanTagMode() + public function testVarnishBanTagMode(): void { $container = $this->createContainer(); @@ -653,7 +651,7 @@ public function testVarnishBanTagMode() $this->assertEquals(['tag_mode' => 'ban', 'tags_header' => 'X-Cache-Tags'], $container->getParameter('fos_http_cache.proxy_client.varnish.options')); } - public function testVarnishBanTagModeOverrides() + public function testVarnishBanTagModeOverrides(): void { $container = $this->createContainer(); @@ -668,7 +666,7 @@ public function testVarnishBanTagModeOverrides() $this->assertEquals(['tag_mode' => 'ban', 'tags_header' => 'my-tags'], $container->getParameter('fos_http_cache.proxy_client.varnish.options')); } - public function testVarnishXkeyTagMode() + public function testVarnishXkeyTagMode(): void { $container = $this->createContainer(); @@ -681,7 +679,7 @@ public function testVarnishXkeyTagMode() $this->assertEquals(['tag_mode' => 'purgekeys', 'tags_header' => 'xkey-softpurge'], $container->getParameter('fos_http_cache.proxy_client.varnish.options')); } - public function testVarnishXkeyTagModeOverrides() + public function testVarnishXkeyTagModeOverrides(): void { $container = $this->createContainer(); @@ -697,7 +695,7 @@ public function testVarnishXkeyTagModeOverrides() $this->assertEquals(['tag_mode' => 'purgekeys', 'tags_header' => 'my-tags'], $container->getParameter('fos_http_cache.proxy_client.varnish.options')); } - public function testVarnishCustomTagsHeader() + public function testVarnishCustomTagsHeader(): void { $container = $this->createContainer(); @@ -709,16 +707,15 @@ public function testVarnishCustomTagsHeader() } /** - * @param array|null $serversValue array that contains servers, `null` if not set - * @param string|null $serversFromJsonEnvValue string that should contain an env var (use `VARNISH_SERVERS` for this test), `null` if not set - * @param string|mixed|null $envValue _ENV['VARNISH_SERVERS'] will be set to this value; only used if `$serversFromJsonEnvValue` is used; should be a string, otherwise an error will show up - * @param array|null $expectedServersValue expected servers value the http dispatcher receives - * @param string|null $expectExceptionClass the exception class the configuration might throw, `null` if no exception is thrown - * @param string|null $expectExceptionMessage the message the exception throws, anything if no exception is thrown - * - * @dataProvider dataVarnishServersConfig + * @param array|null $serversValue array that contains servers, `null` if not set + * @param string|int|null $serversFromJsonEnvValue string that should contain an env var (use `VARNISH_SERVERS` for this test), `null` if not set + * @param mixed $envValue _ENV['VARNISH_SERVERS'] will be set to this value; only used if `$serversFromJsonEnvValue` is used; should be a string, otherwise an error will show up + * @param array|null $expectedServersValue expected servers value the http dispatcher receives + * @param string|null $expectExceptionClass the exception class the configuration might throw, `null` if no exception is thrown + * @param string|null $expectExceptionMessage the message the exception throws, anything if no exception is thrown */ - public function testVarnishServersConfig($serversValue, $serversFromJsonEnvValue, $envValue, $expectedServersValue, $expectExceptionClass, $expectExceptionMessage): void + #[PHPUnit\DataProvider('dataVarnishServersConfig')] + public function testVarnishServersConfig(?array $serversValue, string|int|null $serversFromJsonEnvValue, mixed $envValue, ?array $expectedServersValue, ?string $expectExceptionClass, ?string $expectExceptionMessage): void { $_ENV['VARNISH_SERVERS'] = $envValue; $container = $this->createContainer(); @@ -762,7 +759,7 @@ public function testVarnishServersConfig($serversValue, $serversFromJsonEnvValue static::assertEquals($expectedServersValue, $definition->getArgument(0)); } - public function dataVarnishServersConfig() + public static function dataVarnishServersConfig(): array { return [ // working case before implementing the feature 'env vars in servers key' @@ -772,14 +769,14 @@ public function dataVarnishServersConfig() // not allowed cases (servers_from_jsonenv) 'plain string as servers value is forbidden' => [null, 'plain_string_not_allowed_as_servers_from_jsonenv_value', null, null, InvalidConfigurationException::class, 'Not a valid Varnish servers_from_jsonenv configuration: plain_string_not_allowed_as_servers_from_jsonenv_value'], 'an int as servers value is forbidden' => [null, 1, 'env_value_not_used', null, InvalidConfigurationException::class, 'The "http.servers" or "http.servers_from_jsonenv" section must be defined for the proxy "varnish"'], - 'env var with string as servers value is forbidden (at runtime)' => [null, '%env(json:VARNISH_SERVERS)%', 'wrong_usage_of_env_value', 'no_servers_value', RuntimeException::class, 'Invalid JSON in env var "VARNISH_SERVERS": Syntax error'], + 'env var with string as servers value is forbidden (at runtime)' => [null, '%env(json:VARNISH_SERVERS)%', 'wrong_usage_of_env_value', ['no_servers_value'], RuntimeException::class, 'Invalid JSON in env var "VARNISH_SERVERS": Syntax error'], // more cases - 'no definition leads to error' => [null, null, 'not_used', 'not_used', InvalidConfigurationException::class, 'The "http.servers" or "http.servers_from_jsonenv" section must be defined for the proxy "varnish"'], - 'both servers and servers_from_jsonenv defined leads to error' => [['my-server-1', 'my-server-2'], '%env(json:VARNISH_SERVERS)%', 'not_used', 'not_used', InvalidConfigurationException::class, 'You can only set one of "http.servers" or "http.servers_from_jsonenv" but not both to avoid ambiguity for the proxy "varnish"'], + 'no definition leads to error' => [null, null, 'not_used', ['not_used'], InvalidConfigurationException::class, 'The "http.servers" or "http.servers_from_jsonenv" section must be defined for the proxy "varnish"'], + 'both servers and servers_from_jsonenv defined leads to error' => [['my-server-1', 'my-server-2'], '%env(json:VARNISH_SERVERS)%', 'not_used', ['not_used'], InvalidConfigurationException::class, 'You can only set one of "http.servers" or "http.servers_from_jsonenv" but not both to avoid ambiguity for the proxy "varnish"'], ]; } - private function createContainer() + private function createContainer(): ContainerBuilder { $container = new ContainerBuilder( new EnvPlaceholderParameterBag(['kernel.debug' => false]) @@ -800,7 +797,7 @@ private function createContainer() return $container; } - private function getBaseConfig() + private function getBaseConfig(): array { return [ 'proxy_client' => [ @@ -857,10 +854,8 @@ private function assertRequestMatcherCreated(ContainerBuilder $container, array /** * @param int[] $additionalStatus - * - * @return string */ - private function assertResponseCacheableMatcherCreated(ContainerBuilder $container, array $additionalStatus) + private function assertResponseCacheableMatcherCreated(ContainerBuilder $container, array $additionalStatus): string { // Extract the corresponding definition $matcherDefinition = null; @@ -878,17 +873,13 @@ private function assertResponseCacheableMatcherCreated(ContainerBuilder $contain } $this->assertNotNull($matcherDefinition, 'No matcher found'); + $this->assertNotNull($matcherId, 'Matcher id not determined'); $this->assertEquals($additionalStatus, $matcherDefinition->getArgument(0)); return $matcherId; } - /** - * @param string $expression - * - * @return string - */ - private function assertResponseExpressionMatcherCreated(ContainerBuilder $container, $expression) + private function assertResponseExpressionMatcherCreated(ContainerBuilder $container, string $expression): string { // Extract the corresponding definition $matcherDefinition = null; @@ -906,6 +897,7 @@ private function assertResponseExpressionMatcherCreated(ContainerBuilder $contai } $this->assertNotNull($matcherDefinition, 'No matcher found'); + $this->assertNotNull($matcherId, 'Matcher id not determined'); $this->assertEquals($expression, $matcherDefinition->getArgument(0)); return $matcherId; @@ -913,10 +905,8 @@ private function assertResponseExpressionMatcherCreated(ContainerBuilder $contai /** * Assert that the service $id exists and has a method call mapped onto it. - * - * @param string $id The service id to investigate */ - private function assertListenerHasRule(ContainerBuilder $container, $id) + private function assertListenerHasRule(ContainerBuilder $container, string $id): void { $this->assertTrue($container->hasDefinition($id)); $listener = $container->getDefinition($id); diff --git a/tests/Unit/Http/ResponseMatcher/CacheableResponseMatcherTest.php b/tests/Unit/Http/ResponseMatcher/CacheableResponseMatcherTest.php index 8111f357..8b8fd65d 100644 --- a/tests/Unit/Http/ResponseMatcher/CacheableResponseMatcherTest.php +++ b/tests/Unit/Http/ResponseMatcher/CacheableResponseMatcherTest.php @@ -12,12 +12,13 @@ namespace FOS\HttpCacheBundle\Tests\Unit\Http\ResponseMatcher; use FOS\HttpCacheBundle\Http\ResponseMatcher\CacheableResponseMatcher; +use PHPUnit\Framework\Attributes as PHPUnit; use PHPUnit\Framework\TestCase; use Symfony\Component\HttpFoundation\Response; class CacheableResponseMatcherTest extends TestCase { - public function cacheableStatusCodeProvider() + public static function cacheableStatusCodeProvider(): array { return [ [200], [203], [204], [206], @@ -27,10 +28,8 @@ public function cacheableStatusCodeProvider() ]; } - /** - * @dataProvider cacheableStatusCodeProvider - */ - public function testCacheableStatus(int $status) + #[PHPUnit\DataProvider('cacheableStatusCodeProvider')] + public function testCacheableStatus(int $status): void { $matcher = new CacheableResponseMatcher(); $response = new Response('', $status); @@ -38,7 +37,7 @@ public function testCacheableStatus(int $status) $this->assertTrue($matcher->matches($response)); } - public function testNonCacheableStatus() + public function testNonCacheableStatus(): void { $matcher = new CacheableResponseMatcher(); $response = new Response('', 500); @@ -46,7 +45,7 @@ public function testNonCacheableStatus() $this->assertFalse($matcher->matches($response)); } - public function testCustomCacheableStatus() + public function testCustomCacheableStatus(): void { $matcher = new CacheableResponseMatcher([400]);