diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 1d55e688..eb70abcb 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -5,8 +5,8 @@ env: on: push: - branches: - - "*.x" + branches: + - "*.x" pull_request: jobs: @@ -17,25 +17,18 @@ jobs: matrix: include: # Test the latest stable release - - php-version: '7.3' - - php-version: '7.4' - - php-version: '8.0' - php-version: '8.1' dependencies: 'jean-beru/fos-http-cache-cloudfront' - - php-version: '7.4' - symfony-version: '4.*' - - php-version: '7.4' - symfony-version: '5.*' - - php-version: '8.0' - symfony-version: '6.*' + - php-version: '8.1' + symfony-version: '6.4' + - php-version: '8.2' + symfony-version: '7.*' + - php-version: '8.2' + symfony-version: '6.4' # Minimum supported dependencies with the oldest PHP version - - php-version: '7.3' + - php-version: '8.1' composer-flag: '--prefer-stable --prefer-lowest' - symfony-version: '4.4' - # Test latest unreleased versions - - php-version: '8.0' - symfony-version: '6.*' - stability: 'dev' + symfony-version: '6.4' name: PHP ${{ matrix.php-version }} Test on Symfony ${{ matrix.symfony-version }} ${{ matrix.dependencies}} ${{ matrix.stability }} ${{ matrix.composer-flag }} steps: diff --git a/composer.json b/composer.json index cf3fb127..95188160 100644 --- a/composer.json +++ b/composer.json @@ -21,11 +21,11 @@ } ], "require": { - "php": "^7.3 || ^8.0", - "friendsofsymfony/http-cache": "^2.15", - "symfony/framework-bundle": "^4.4.0 || ^5.0 || ^6.0", - "symfony/http-foundation": "^4.4.0 || ^5.0 || ^6.0", - "symfony/http-kernel": "^4.4.0 || ^5.0 || ^6.0" + "php": "^8.1", + "friendsofsymfony/http-cache": "^3.x-dev", + "symfony/framework-bundle": "^6.4 || ^7.0", + "symfony/http-foundation": "^6.4 || ^7.0", + "symfony/http-kernel": "^6.4 || ^7.0" }, "require-dev": { "php-http/guzzle7-adapter": "^0.1.1", @@ -35,20 +35,19 @@ "guzzlehttp/guzzle": "^7.2", "mockery/mockery": "^1.3.2", "monolog/monolog": "*", - "sensio/framework-extra-bundle": "^4.0 || ^5.5.1 || ^6.0", "doctrine/annotations": "^1.11", - "symfony/browser-kit": "^4.4 || ^5.0 || ^6.0", - "symfony/console": "^4.4 || ^5.0 || ^6.0", - "symfony/finder": "^4.4 || ^5.0 || ^6.0", + "symfony/browser-kit": "^6.4 || ^7.0", + "symfony/console": "^6.4 || ^7.0", + "symfony/finder": "^6.4 || ^7.0", "phpunit/phpunit": "^9.6.15", - "symfony/security-bundle": "^4.4 || ^5.0 || ^6.0", - "symfony/twig-bundle": "^4.4 || ^5.0 || ^6.0", - "twig/twig": "^2.13", - "symfony/yaml": "^4.4 || ^5.0 || ^6.0", - "symfony/css-selector": "^4.4 || ^5.0 || ^6.0", - "symfony/expression-language": "^4.4 || ^5.0 || ^6.0", + "symfony/security-bundle": "^6.4 || ^7.0", + "symfony/twig-bundle": "^6.4 || ^7.0", + "twig/twig": "^v3.8", + "symfony/yaml": "^6.4 || ^7.0", + "symfony/css-selector": "^6.4 || ^7.0", + "symfony/expression-language": "^6.4 || ^7.0", "symfony/monolog-bundle": "^3.0", - "symfony/routing": "^4.4 || ^5.0 || ^6.0", + "symfony/routing": "^6.4 || ^7.0", "matthiasnoback/symfony-config-test": "^4.3.0 || ^5.1", "matthiasnoback/symfony-dependency-injection-test": "^4.3.1 || ^5.0" }, diff --git a/src/Command/BaseInvalidateCommand.php b/src/Command/BaseInvalidateCommand.php index f23b06c8..4be0536e 100644 --- a/src/Command/BaseInvalidateCommand.php +++ b/src/Command/BaseInvalidateCommand.php @@ -14,7 +14,6 @@ use FOS\HttpCacheBundle\CacheManager; use LogicException; use Symfony\Component\Console\Command\Command; -use Symfony\Component\DependencyInjection\ContainerAwareTrait; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -24,8 +23,6 @@ */ abstract class BaseInvalidateCommand extends Command { - use ContainerAwareTrait; - /** * @var CacheManager */ diff --git a/src/Configuration/InvalidatePath.php b/src/Configuration/InvalidatePath.php index f9ad55d2..e9b43516 100644 --- a/src/Configuration/InvalidatePath.php +++ b/src/Configuration/InvalidatePath.php @@ -11,13 +11,11 @@ namespace FOS\HttpCacheBundle\Configuration; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationAnnotation; - /** * @Annotation */ #[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD)] -class InvalidatePath extends ConfigurationAnnotation +class InvalidatePath { /** * @var array @@ -34,7 +32,13 @@ public function __construct( $values = $data; } - parent::__construct($values); + foreach ($values as $k => $v) { + if (!method_exists($this, $name = 'set'.$k)) { + throw new \RuntimeException(sprintf('Unknown key "%s" for annotation "@%s".', $k, static::class)); + } + + $this->$name($v); + } } /** @@ -62,20 +66,4 @@ public function getPaths() { return $this->paths; } - - /** - * {@inheritdoc} - */ - public function getAliasName(): string - { - return 'invalidate_path'; - } - - /** - * {@inheritdoc} - */ - public function allowArray(): bool - { - return true; - } } diff --git a/src/Configuration/InvalidateRoute.php b/src/Configuration/InvalidateRoute.php index fc74abc6..2f972fb5 100644 --- a/src/Configuration/InvalidateRoute.php +++ b/src/Configuration/InvalidateRoute.php @@ -11,7 +11,6 @@ namespace FOS\HttpCacheBundle\Configuration; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationAnnotation; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; use Symfony\Component\ExpressionLanguage\ExpressionLanguage; @@ -19,7 +18,7 @@ * @Annotation */ #[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD)] -class InvalidateRoute extends ConfigurationAnnotation +class InvalidateRoute { /** * @var string @@ -44,7 +43,13 @@ public function __construct( $values['params'] = $values['params'] ?? $params; - parent::__construct($values); + foreach ($values as $k => $v) { + if (!method_exists($this, $name = 'set'.$k)) { + throw new \RuntimeException(sprintf('Unknown key "%s" for annotation "@%s".', $k, static::class)); + } + + $this->$name($v); + } } /** @@ -111,20 +116,4 @@ public function getParams() { return $this->params; } - - /** - * {@inheritdoc} - */ - public function getAliasName(): string - { - return 'invalidate_route'; - } - - /** - * {@inheritdoc} - */ - public function allowArray(): bool - { - return true; - } } diff --git a/src/Configuration/Tag.php b/src/Configuration/Tag.php index fadd3e81..2c45cb0f 100644 --- a/src/Configuration/Tag.php +++ b/src/Configuration/Tag.php @@ -12,7 +12,6 @@ namespace FOS\HttpCacheBundle\Configuration; use FOS\HttpCacheBundle\Exception\InvalidTagException; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationAnnotation; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; use Symfony\Component\ExpressionLanguage\ExpressionLanguage; @@ -20,7 +19,7 @@ * @Annotation */ #[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD)] -class Tag extends ConfigurationAnnotation +class Tag { private $tags; @@ -39,7 +38,13 @@ public function __construct( $values['expression'] = $values['expression'] ?? $expression; - parent::__construct($values); + foreach ($values as $k => $v) { + if (!method_exists($this, $name = 'set'.$k)) { + throw new \RuntimeException(sprintf('Unknown key "%s" for annotation "@%s".', $k, static::class)); + } + + $this->$name($v); + } } /** @@ -88,20 +93,4 @@ public function getTags() { return $this->tags; } - - /** - * {@inheritdoc} - */ - public function getAliasName(): string - { - return 'tag'; - } - - /** - * {@inheritdoc} - */ - public function allowArray(): bool - { - return true; - } } diff --git a/src/DependencyInjection/Compiler/TagListenerPass.php b/src/DependencyInjection/Compiler/TagListenerPass.php deleted file mode 100644 index 4098178f..00000000 --- a/src/DependencyInjection/Compiler/TagListenerPass.php +++ /dev/null @@ -1,45 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace FOS\HttpCacheBundle\DependencyInjection\Compiler; - -use Sensio\Bundle\FrameworkExtraBundle\EventListener\ControllerListener; -use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; -use Symfony\Component\DependencyInjection\ContainerBuilder; - -/** - * Check for required ControllerListener if TagListener is enabled. - */ -class TagListenerPass implements CompilerPassInterface -{ - /** - * {@inheritdoc} - */ - public function process(ContainerBuilder $container): void - { - if (true === $container->getParameter('fos_http_cache.compiler_pass.tag_annotations') - && !$this->hasControllerListener($container) - ) { - throw new \RuntimeException( - 'Tag annotations are enabled by default because otherwise things could silently not work.' - .' The annotations require the SensioFrameworkExtraBundle ControllerListener. If you do not use' - .' annotations for tags, set "fos_http_cache.tags.annotations.enabled: false". Otherwise install' - .' sensio/framework-extra-bundle and enabled it in your kernel.' - ); - } - } - - private function hasControllerListener(ContainerBuilder $container): bool - { - return $container->has('sensio_framework_extra.controller.listener') || - $container->has(ControllerListener::class); - } -} diff --git a/src/EventListener/InvalidationListener.php b/src/EventListener/InvalidationListener.php index 9a67400b..fc31df0f 100644 --- a/src/EventListener/InvalidationListener.php +++ b/src/EventListener/InvalidationListener.php @@ -211,6 +211,7 @@ private function invalidateRoutes(array $routes, Request $request) $values['request'] = $request; foreach ($routes as $route) { + $params = []; if (null !== $route->getParams()) { @@ -223,7 +224,6 @@ private function invalidateRoutes(array $routes, Request $request) $params[$key] = $value; } } - $this->cacheManager->invalidateRoute($route->getName(), $params); } } diff --git a/src/EventListener/Php8AttributesListener.php b/src/EventListener/Php8AttributesListener.php index 00b7af67..4ffb27ac 100644 --- a/src/EventListener/Php8AttributesListener.php +++ b/src/EventListener/Php8AttributesListener.php @@ -2,7 +2,10 @@ namespace FOS\HttpCacheBundle\EventListener; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationInterface; +use FOS\HttpCacheBundle\Configuration\ConfigurationInterface; +use FOS\HttpCacheBundle\Configuration\InvalidatePath; +use FOS\HttpCacheBundle\Configuration\InvalidateRoute; +use FOS\HttpCacheBundle\Configuration\Tag; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; use Symfony\Component\HttpKernel\Event\GetResponseEvent; @@ -50,14 +53,13 @@ public function onKernelRequest(AttributeRequestEvent $event) $method = $class->getMethod($controller[1]); $attributes = []; $addAttributes = function ($instance) use (&$attributes) { - if ( - $instance instanceof ConfigurationInterface && - in_array( - $instance->getAliasName(), [ - 'tag', 'invalidate_path', 'invalidate_route', - ]) - ) { - $attributes['_'.$instance->getAliasName()][] = $instance; + if ($key = match (get_class($instance)) { + InvalidatePath::class => '_invalidate_path', + InvalidateRoute::class => '_invalidate_route', + Tag::class => '_tag' + }) { + + $attributes[$key][] = $instance; } }; diff --git a/src/EventListener/UserContextListener.php b/src/EventListener/UserContextListener.php index ee987381..66c1e327 100644 --- a/src/EventListener/UserContextListener.php +++ b/src/EventListener/UserContextListener.php @@ -195,7 +195,7 @@ private function isAnonymous(Request $request) */ public function onKernelResponse(UserContextResponseEvent $event) { - if (HttpKernelInterface::MASTER_REQUEST != $event->getRequestType()) { + if (HttpKernelInterface::MAIN_REQUEST != $event->getRequestType()) { return; } diff --git a/src/FOSHttpCacheBundle.php b/src/FOSHttpCacheBundle.php index dc1dbfa1..d94b7dd4 100644 --- a/src/FOSHttpCacheBundle.php +++ b/src/FOSHttpCacheBundle.php @@ -15,7 +15,6 @@ use FOS\HttpCacheBundle\DependencyInjection\Compiler\HashGeneratorPass; use FOS\HttpCacheBundle\DependencyInjection\Compiler\LoggerPass; use FOS\HttpCacheBundle\DependencyInjection\Compiler\SessionListenerPass; -use FOS\HttpCacheBundle\DependencyInjection\Compiler\TagListenerPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; @@ -27,7 +26,6 @@ class FOSHttpCacheBundle extends Bundle public function build(ContainerBuilder $container): void { $container->addCompilerPass(new LoggerPass()); - $container->addCompilerPass(new TagListenerPass()); $container->addCompilerPass(new HashGeneratorPass()); $container->addCompilerPass(new SessionListenerPass()); diff --git a/src/Http/RequestMatcher/QuerystringRequestMatcher.php b/src/Http/RequestMatcher/QuerystringRequestMatcher.php index 7e86534c..08ad0295 100644 --- a/src/Http/RequestMatcher/QuerystringRequestMatcher.php +++ b/src/Http/RequestMatcher/QuerystringRequestMatcher.php @@ -12,22 +12,19 @@ namespace FOS\HttpCacheBundle\Http\RequestMatcher; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\RequestMatcher as SymfonyRequestMatcher; +use Symfony\Component\HttpFoundation\RequestMatcherInterface; /** * Extend the Symfony RequestMatcher class to support query string matching. */ -class QuerystringRequestMatcher extends SymfonyRequestMatcher +class QuerystringRequestMatcher extends CacheableRequestMatcher { /** * @var string Regular expression to match the query string part of the request url */ - private $queryString; + private ?string $queryString; - /** - * @param string $queryString - */ - public function setQueryString($queryString) + public function __construct(?string $queryString = null) { $this->queryString = $queryString; } @@ -45,6 +42,14 @@ public function matches(Request $request): bool return true; } - return (bool) preg_match('{'.$this->queryString.'}', rawurldecode($request->getQueryString() ?: '')); + if ($request->getQueryString()) { + return (bool) preg_match('{'.$this->queryString.'}', rawurldecode($request->getQueryString() ?: '')); + } + + if ($request->getRequestUri()) { + return (bool) preg_match('#'.$this->queryString.'#', $request->getRequestUri()); + } + + return false; } } diff --git a/src/Http/ResponseMatcher/ExpressionResponseMatcher.php b/src/Http/ResponseMatcher/ExpressionResponseMatcher.php index 072cd5c4..393f3813 100644 --- a/src/Http/ResponseMatcher/ExpressionResponseMatcher.php +++ b/src/Http/ResponseMatcher/ExpressionResponseMatcher.php @@ -11,7 +11,7 @@ namespace FOS\HttpCacheBundle\Http\ResponseMatcher; -use Sensio\Bundle\FrameworkExtraBundle\Security\ExpressionLanguage as SecurityExpressionLanguage; +use FOS\HttpCacheBundle\Security\ExpressionLanguage as SecurityExpressionLanguage; use Symfony\Component\ExpressionLanguage\ExpressionLanguage; use Symfony\Component\HttpFoundation\Response; diff --git a/src/Security/ExpressionLanguage.php b/src/Security/ExpressionLanguage.php new file mode 100644 index 00000000..55a9105b --- /dev/null +++ b/src/Security/ExpressionLanguage.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\HttpCacheBundle\Security; + +use Symfony\Component\Security\Core\Authorization\ExpressionLanguage as BaseExpressionLanguage; + +/** + * Adds some function to the default Symfony Security ExpressionLanguage. + * + * @author Fabien Potencier + */ +class ExpressionLanguage extends BaseExpressionLanguage +{ + protected function registerFunctions() + { + parent::registerFunctions(); + + $this->register('is_granted', function ($attributes, $object = 'null') { + return sprintf('$auth_checker->isGranted(%s, %s)', $attributes, $object); + }, function (array $variables, $attributes, $object = null) { + return $variables['auth_checker']->isGranted($attributes, $object); + }); + } +} diff --git a/tests/Functional/EventListener/InvalidationListenerTest.php b/tests/Functional/EventListener/InvalidationListenerTest.php index 13b7e5fd..1a6da84b 100644 --- a/tests/Functional/EventListener/InvalidationListenerTest.php +++ b/tests/Functional/EventListener/InvalidationListenerTest.php @@ -19,83 +19,6 @@ class InvalidationListenerTest extends WebTestCase { use MockeryPHPUnitIntegration; - public function testInvalidateRoute() - { - $client = static::createClient(); - - $mock = \Mockery::mock(CacheManager::class); - $mock->shouldReceive('supports') - ->zeroOrMoreTimes() - ->andReturnTrue() - ; - $mock->shouldReceive('invalidateRoute') - ->once() - ->with('test_noncached', []) - ; - $mock->shouldReceive('invalidateRoute') - ->once() - ->with('test_cached', ['id' => 'myhardcodedid']) - ; - $mock->shouldReceive('invalidateRoute') - ->once() - ->with('tag_one', ['id' => 42]) - ; - $mock->shouldReceive('flush') - ->once() - ->andReturn(3) - ; - $client->getContainer()->set('fos_http_cache.cache_manager', $mock); - - $client->request('POST', '/invalidate/route/42'); - } - - /** - * @dataProvider getStatusCodesThatTriggerInvalidation - */ - public function testInvalidatePath($statusCode) - { - $client = static::createClient(); - - $mock = \Mockery::mock(CacheManager::class); - $mock->shouldReceive('supports') - ->zeroOrMoreTimes() - ->andReturnTrue() - ; - $mock->shouldReceive('invalidatePath') - ->once() - ->with('/cached') - ; - $mock->shouldReceive('invalidatePath') - ->once() - ->with(sprintf('/invalidate/path/%s', $statusCode)) - ; - $mock->shouldReceive('flush') - ->once() - ->andReturn(2) - ; - $client->getContainer()->set('fos_http_cache.cache_manager', $mock); - - $client->request('POST', sprintf('/invalidate/path/%s', $statusCode)); - } - - public function testErrorIsNotInvalidated() - { - $client = static::createClient(); - - $mock = \Mockery::mock(CacheManager::class); - $mock->shouldReceive('supports') - ->zeroOrMoreTimes() - ->andReturnTrue() - ; - $mock->shouldReceive('flush') - ->once() - ->andReturn(0) - ; - $client->getContainer()->set('fos_http_cache.cache_manager', $mock); - - $client->request('POST', '/invalidate/error'); - } - /** * @requires PHP 8.0 */ @@ -147,10 +70,6 @@ public function testInvalidatePathWithPHPAttributes($statusCode) ->once() ->with('/php8/cached') ; - $mock->shouldReceive('invalidatePath') - ->once() - ->with(sprintf('/php8/invalidate/path/%s', $statusCode)) - ; $mock->shouldReceive('flush') ->once() ->andReturn(2) diff --git a/tests/Functional/EventListener/TagListenerTest.php b/tests/Functional/EventListener/TagListenerTest.php index a5781fee..9eea6af1 100644 --- a/tests/Functional/EventListener/TagListenerTest.php +++ b/tests/Functional/EventListener/TagListenerTest.php @@ -35,20 +35,6 @@ class TagListenerTest extends WebTestCase use MockeryPHPUnitIntegration; private static $overrideService = false; - public function testAnnotationTagsAreSet() - { - $client = static::createClient(); - - $client->request('GET', '/tag/list'); - $response = $client->getResponse(); - $this->assertEquals('all-items,item-123', $response->headers->get('X-Cache-Tags')); - - $client->request('GET', '/tag/123'); - $response = $client->getResponse(); - $this->assertEquals(200, $response->getStatusCode(), $response->getContent()); - $this->assertEquals('item-123', $response->headers->get('X-Cache-Tags')); - } - /** * @requires PHP 8.0 */ @@ -66,35 +52,6 @@ public function testAttributeTagsAreSet() $this->assertEquals('item-123', $response->headers->get('X-Cache-Tags')); } - public function testAnnotationTagsAreInvalidated() - { - self::$overrideService = true; - $client = static::createClient(); - - $mock = \Mockery::mock(CacheManager::class); - $mock->shouldReceive('supports') - ->zeroOrMoreTimes() - ->andReturnTrue() - ; - $mock->shouldReceive('invalidateTags') - ->once() - ->with(['all-items']) - ; - $mock->shouldReceive('invalidateTags') - ->once() - ->with(['item-123']) - ; - $mock->shouldReceive('flush') - ->once() - ->andReturn(2) - ; - $client->getContainer()->set('fos_http_cache.cache_manager', $mock); - - $client->request('POST', '/tag/123'); - $response = $client->getResponse(); - $this->assertEquals(200, $response->getStatusCode(), $response->getContent()); - } - public function testErrorIsNotInvalidated() { self::$overrideService = true; @@ -124,34 +81,11 @@ public function testConfigurationTagsAreSet() $this->assertEquals('area,area-51', $response->headers->get('X-Cache-Tags')); } - public function testConfigurationTagsAreInvalidated() - { - self::$overrideService = true; - $client = static::createClient(); - - $mock = \Mockery::mock(CacheManager::class); - $mock->shouldReceive('supports') - ->zeroOrMoreTimes() - ->andReturnTrue() - ; - $mock->shouldReceive('invalidateTags') - ->once() - ->with(['area', 'area-51']) - ; - $mock->shouldReceive('flush') - ->once() - ->andReturn(1) - ; - $client->getContainer()->set('fos_http_cache.cache_manager', $mock); - - $client->request('PUT', '/cached/51'); - } - public function testManualTagging() { $client = static::createClient(); - $client->request('GET', '/tag_manual'); + $client->request('GET', '/php8/tag_manual'); $response = $client->getResponse(); $this->assertEquals(200, $response->getStatusCode(), $response->getContent()); $this->assertEquals('manual-tag,sub-tag,sub-items,manual-items', $response->headers->get('X-Cache-Tags')); @@ -161,7 +95,7 @@ public function testTwigExtension() { $client = static::createClient(); - $client->request('GET', '/tag_twig'); + $client->request('GET', '/php8/tag_twig'); $response = $client->getResponse(); $this->assertEquals(200, $response->getStatusCode(), $response->getContent()); $this->assertEquals('tag-from-twig', $response->headers->get('X-Cache-Tags')); @@ -179,7 +113,7 @@ public function testTagsAreSetWhenCacheable(Request $request, Response $response $event = new TagResponseEvent( $client->getKernel(), $request, - HttpKernelInterface::MASTER_REQUEST, + HttpKernelInterface::MAIN_REQUEST, $response ); @@ -211,7 +145,7 @@ public function testTagsAreInvalidated(Request $request, Response $response) $event = new TagResponseEvent( $client->getKernel(), $request, - HttpKernelInterface::MASTER_REQUEST, + HttpKernelInterface::MAIN_REQUEST, $response ); $mock = \Mockery::mock(CacheManager::class); @@ -247,7 +181,7 @@ public function testTagsAreNotInvalidated(Request $request, Response $response) $event = new TagResponseEvent( $client->getKernel(), $request, - HttpKernelInterface::MASTER_REQUEST, + HttpKernelInterface::MAIN_REQUEST, $response ); diff --git a/tests/Functional/Fixtures/Controller/TagAttributeController.php b/tests/Functional/Fixtures/Controller/TagAttributeController.php index a1960909..5c26f2cc 100644 --- a/tests/Functional/Fixtures/Controller/TagAttributeController.php +++ b/tests/Functional/Fixtures/Controller/TagAttributeController.php @@ -17,7 +17,6 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Kernel; if (!\class_exists(AbstractController::class)) { \class_alias(Controller::class, AbstractController::class); @@ -61,7 +60,7 @@ public function manualAction() $this->responseTagger->addTags(['manual-tag']); return $this->render('container.html.twig', [ - 'action' => (Kernel::MAJOR_VERSION >= 4 && Kernel::MINOR_VERSION >= 1) ? 'tag_controller::subrequestAction' : 'tag_controller:subrequestAction', + 'action' => 'FOS\\HttpCacheBundle\\Tests\\Functional\\Fixtures\\Controller\\TagAttributeController::subrequestAction', ]); } @@ -77,4 +76,9 @@ public function emptyAction() { return new Response(''); } + + public function twigAction() + { + return $this->render('tag.html.twig'); + } } diff --git a/tests/Functional/Fixtures/app/AppKernel.php b/tests/Functional/Fixtures/app/AppKernel.php index b511118a..f122661e 100644 --- a/tests/Functional/Fixtures/app/AppKernel.php +++ b/tests/Functional/Fixtures/app/AppKernel.php @@ -47,7 +47,6 @@ public function registerBundles(): iterable { return [ new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(), - new \Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(), new \Symfony\Bundle\MonologBundle\MonologBundle(), new \Symfony\Bundle\SecurityBundle\SecurityBundle(), new \Symfony\Bundle\TwigBundle\TwigBundle(), diff --git a/tests/Functional/Fixtures/app/config/config.yml b/tests/Functional/Fixtures/app/config/config.yml index 86ddcc3d..48e6853e 100644 --- a/tests/Functional/Fixtures/app/config/config.yml +++ b/tests/Functional/Fixtures/app/config/config.yml @@ -2,7 +2,6 @@ framework: secret: fos router: resource: "%kernel.project_dir%/tests/Functional/Fixtures/app/config/routing.yml" - annotations: ~ test: ~ fos_http_cache: diff --git a/tests/Functional/Fixtures/app/config/config_servers_from_env.yml b/tests/Functional/Fixtures/app/config/config_servers_from_env.yml index 1d6b1ebb..966f6587 100644 --- a/tests/Functional/Fixtures/app/config/config_servers_from_env.yml +++ b/tests/Functional/Fixtures/app/config/config_servers_from_env.yml @@ -2,7 +2,6 @@ framework: secret: fos router: resource: "%kernel.project_dir%/tests/Functional/Fixtures/app/config/routing.yml" - annotations: ~ test: ~ fos_http_cache: diff --git a/tests/Functional/Fixtures/app/config/routing.yml b/tests/Functional/Fixtures/app/config/routing.yml index 589c088c..508681a4 100644 --- a/tests/Functional/Fixtures/app/config/routing.yml +++ b/tests/Functional/Fixtures/app/config/routing.yml @@ -22,14 +22,22 @@ php8_tag_one: defaults: { _controller: tag_attribute_controller::itemAction } methods: [GET,POST] +php8_tag_manual: + path: /php8/tag_manual + defaults: { _controller: tag_attribute_controller::manualAction } + tag_manual: path: /tag_manual controller: tag_controller::manualAction tag_twig: - path: /tag_twig + path: /php8/tag_twig controller: tag_controller::twigAction +php8_tag_twig: + path: /tag_twig + defaults: { _controller: tag_attribute_controller::twigAction } + invalidation_route: path: /invalidate/route/{id} controller: FOS\HttpCacheBundle\Tests\Functional\Fixtures\Controller\InvalidationController::itemAction diff --git a/tests/Unit/Command/BaseInvalidateCommandTest.php b/tests/Unit/Command/BaseInvalidateCommandTest.php index b981d203..472c0a6b 100644 --- a/tests/Unit/Command/BaseInvalidateCommandTest.php +++ b/tests/Unit/Command/BaseInvalidateCommandTest.php @@ -17,7 +17,6 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Application; use Symfony\Component\Console\Tester\CommandTester; -use Symfony\Component\DependencyInjection\ContainerInterface; class BaseInvalidateCommandTest extends TestCase { @@ -34,14 +33,9 @@ public function testContainerAccess() ->shouldReceive('invalidatePath')->once()->with('/another') ->getMock() ; - $container = \Mockery::mock(ContainerInterface::class) - ->shouldReceive('get')->once()->with('fos_http_cache.cache_manager')->andReturn($invalidator) - ->getMock() - ; $application = new Application(); - $command = new InvalidatePathCommand(); - $command->setContainer($container); + $command = new InvalidatePathCommand($invalidator); $application->add($command); $command = $application->find('fos:httpcache:invalidate:path'); diff --git a/tests/Unit/DependencyInjection/Compiler/HashGeneratorPassTest.php b/tests/Unit/DependencyInjection/Compiler/HashGeneratorPassTest.php index ca86281e..6c14b2d2 100644 --- a/tests/Unit/DependencyInjection/Compiler/HashGeneratorPassTest.php +++ b/tests/Unit/DependencyInjection/Compiler/HashGeneratorPassTest.php @@ -52,7 +52,7 @@ public function testConfigNoContext() if (\PHP_VERSION_ID >= 80000) { $this->assertCount(24, $container->getDefinitions()); } else { - $this->assertCount(23, $container->getDefinitions()); + $this->assertCount(24, $container->getDefinitions()); } } diff --git a/tests/Unit/DependencyInjection/Compiler/TagListenerPassTest.php b/tests/Unit/DependencyInjection/Compiler/TagListenerPassTest.php deleted file mode 100644 index 918cea80..00000000 --- a/tests/Unit/DependencyInjection/Compiler/TagListenerPassTest.php +++ /dev/null @@ -1,63 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace FOS\HttpCacheBundle\Tests\Unit\DependencyInjection\Compiler; - -use FOS\HttpCacheBundle\DependencyInjection\Compiler\TagListenerPass; -use FOS\HttpCacheBundle\DependencyInjection\FOSHttpCacheExtension; -use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; -use PHPUnit\Framework\TestCase; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; - -class TagListenerPassTest extends TestCase -{ - use MockeryPHPUnitIntegration; - - public function testNoFrameworkBundle() - { - $this->expectException(\RuntimeException::class); - $this->expectExceptionMessage('require the SensioFrameworkExtraBundle'); - - $extension = new FOSHttpCacheExtension(); - $tagListenerPass = new TagListenerPass(); - $container = $this->createContainer(); - $config = $this->getConfig(); - $extension->load([$config], $container); - $tagListenerPass->process($container); - } - - protected function createContainer() - { - return new ContainerBuilder(new ParameterBag([ - 'kernel.debug' => false, - ])); - } - - protected function getConfig() - { - return [ - 'proxy_client' => [ - 'varnish' => [ - 'http' => [ - 'base_url' => 'my_hostname', - 'servers' => [ - '127.0.0.1', - ], - ], - ], - ], - 'tags' => [ - 'enabled' => true, - ], - ]; - } -} diff --git a/tests/Unit/EventListener/CacheControlListenerTest.php b/tests/Unit/EventListener/CacheControlListenerTest.php index e50534f5..d1078fed 100755 --- a/tests/Unit/EventListener/CacheControlListenerTest.php +++ b/tests/Unit/EventListener/CacheControlListenerTest.php @@ -425,7 +425,7 @@ protected function buildEvent(string $method = 'GET'): CacheControlResponseEvent $request = new Request(); $request->setMethod($method); - return new CacheControlResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, $response); + return new CacheControlResponseEvent($kernel, $request, HttpKernelInterface::MAIN_REQUEST, $response); } /** diff --git a/tests/Unit/EventListener/InvalidationListenerTest.php b/tests/Unit/EventListener/InvalidationListenerTest.php index f245ee29..0623bb80 100644 --- a/tests/Unit/EventListener/InvalidationListenerTest.php +++ b/tests/Unit/EventListener/InvalidationListenerTest.php @@ -22,7 +22,7 @@ use Symfony\Component\Console\Event\ConsoleEvent; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\RequestMatcher; +use Symfony\Component\HttpFoundation\RequestMatcher\AttributesRequestMatcher; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\PostResponseEvent; use Symfony\Component\HttpKernel\Event\TerminateEvent; @@ -116,11 +116,7 @@ public function testOnKernelTerminate() ->andReturn('/retrieve/something/123/bla') ->getMock(); - $requestMatcher = new RequestMatcher( - null, - null, - null, - null, + $requestMatcher = new AttributesRequestMatcher( ['_route' => 'route_invalidator'] ); diff --git a/tests/Unit/EventListener/TagListenerTest.php b/tests/Unit/EventListener/TagListenerTest.php index 47d33afa..af623a69 100644 --- a/tests/Unit/EventListener/TagListenerTest.php +++ b/tests/Unit/EventListener/TagListenerTest.php @@ -210,7 +210,7 @@ private function getEvent(Request $request, Response $response = null): TagRespo return new TagResponseEvent( \Mockery::mock(HttpKernelInterface::class), $request, - HttpKernelInterface::MASTER_REQUEST, + HttpKernelInterface::MAIN_REQUEST, $response ?: new Response() ); } diff --git a/tests/Unit/EventListener/UserContextListenerTest.php b/tests/Unit/EventListener/UserContextListenerTest.php index 041322bf..e25b036e 100644 --- a/tests/Unit/EventListener/UserContextListenerTest.php +++ b/tests/Unit/EventListener/UserContextListenerTest.php @@ -565,7 +565,7 @@ public function testFullRequestHashChanged() $this->assertEquals('max-age=0, no-cache, no-store, private, s-maxage=0', $event->getResponse()->headers->get('Cache-Control')); } - protected function getKernelRequestEvent(Request $request, $type = HttpKernelInterface::MASTER_REQUEST): UserContextRequestEvent + protected function getKernelRequestEvent(Request $request, $type = HttpKernelInterface::MAIN_REQUEST): UserContextRequestEvent { return new UserContextRequestEvent( \Mockery::mock(HttpKernelInterface::class), @@ -574,7 +574,7 @@ protected function getKernelRequestEvent(Request $request, $type = HttpKernelInt ); } - protected function getKernelResponseEvent(Request $request, Response $response = null, $type = HttpKernelInterface::MASTER_REQUEST): UserContextResponseEvent + protected function getKernelResponseEvent(Request $request, Response $response = null, $type = HttpKernelInterface::MAIN_REQUEST): UserContextResponseEvent { return new UserContextResponseEvent( \Mockery::mock(HttpKernelInterface::class), diff --git a/tests/Unit/Http/RequestMatcher/QuerystringRequestMatcherTest.php b/tests/Unit/Http/RequestMatcher/QuerystringRequestMatcherTest.php index 36600a34..ac79759d 100644 --- a/tests/Unit/Http/RequestMatcher/QuerystringRequestMatcherTest.php +++ b/tests/Unit/Http/RequestMatcher/QuerystringRequestMatcherTest.php @@ -35,8 +35,7 @@ public function testMatchesReturnsTrueWhenNoQueryStringIsSet() public function testMatchesReturnsTrueIfQueryStringMatches() { - $requestMatcher = new QuerystringRequestMatcher(); - $requestMatcher->setQueryString('(^|&)token=hello!(&|$)'); + $requestMatcher = new QuerystringRequestMatcher('(^|&)token=hello!(&|$)'); $request = Request::create('http://localhost/bar?token=hello%21'); $this->assertTrue($requestMatcher->matches($request)); @@ -44,8 +43,7 @@ public function testMatchesReturnsTrueIfQueryStringMatches() public function testMatchesReturnsFalseIfQueryStringDoesntMatch() { - $requestMatcher = new QuerystringRequestMatcher(); - $requestMatcher->setQueryString('(^|&)mytoken='); + $requestMatcher = new QuerystringRequestMatcher('(^|&)mytoken='); $request = Request::create('http://localhost/bar?token=myvalue'); $this->assertFalse($requestMatcher->matches($request)); @@ -53,8 +51,7 @@ public function testMatchesReturnsFalseIfQueryStringDoesntMatch() public function testMatchesReturnsFalseIfQueryStringIsEmpty() { - $requestMatcher = new QuerystringRequestMatcher(); - $requestMatcher->setQueryString('(^|&)mytoken='); + $requestMatcher = new QuerystringRequestMatcher('(^|&)mytoken='); $request = Request::create('http://localhost/bar'); $this->assertFalse($requestMatcher->matches($request)); diff --git a/tests/Unit/Http/RuleMatcherTest.php b/tests/Unit/Http/RuleMatcherTest.php index 4bd49a5b..fb682d29 100644 --- a/tests/Unit/Http/RuleMatcherTest.php +++ b/tests/Unit/Http/RuleMatcherTest.php @@ -15,14 +15,14 @@ use FOS\HttpCacheBundle\Http\RuleMatcher; use PHPUnit\Framework\TestCase; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\RequestMatcher; +use Symfony\Component\HttpFoundation\RequestMatcher\AttributesRequestMatcher; use Symfony\Component\HttpFoundation\Response; class RuleMatcherTest extends TestCase { public function testRequestMatcherCalled() { - $requestMatcher = new RequestMatcher(null, null, null, null, ['_controller' => '^AcmeBundle:Default:index$']); + $requestMatcher = new AttributesRequestMatcher(['_controller' => '^AcmeBundle:Default:index$']); $ruleMatcher = new RuleMatcher($requestMatcher); $request = new Request(); @@ -33,7 +33,7 @@ public function testRequestMatcherCalled() public function testAdditionalCacheableStatus() { - $ruleMatcher = new RuleMatcher(new RequestMatcher(), new CacheableResponseMatcher([400, 500])); + $ruleMatcher = new RuleMatcher(new AttributesRequestMatcher([]), new CacheableResponseMatcher([400, 500])); $this->assertFalse($ruleMatcher->matches(new Request(), new Response('', 504))); $this->assertTrue($ruleMatcher->matches(new Request(), new Response('', 500)));