diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fabab144d..1f9069250 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,6 +14,8 @@ jobs: tests: runs-on: ubuntu-latest name: "PHP ${{ matrix.php }}, Symfony ${{ matrix.symfony }}, Twig ${{ matrix.twig }}, Persistence: ${{ matrix.persistence }}, Collections: ${{ matrix.collections }}" + env: + APP_ENV: ${{ matrix.app_env }} strategy: fail-fast: false matrix: @@ -22,10 +24,15 @@ jobs: symfony: ["^5.4", "^6.4"] persistence: ["^2.0", "^3.0"] collections: ["^1.8", "^2.0"] + app_env: ["test"] include: - php: "8.1" pagerfanta: "^3.7" symfony: "^5.4" + app_env: "test" + - php: "8.3" + symfony: "^7.0" + app_env: "test_without_hateoas" exclude: - php: "8.1" collections: "^2.0" @@ -82,6 +89,11 @@ jobs: if: matrix.collections != '' run: composer require "doctrine/collections:${{ matrix.collections }}" --no-update --no-scripts + - + name: Remove hateoas on Symfony 7 + if: matrix.symfony == '^7.0' + run: composer remove --dev willdurand/hateoas-bundle --no-update --no-scripts + - name: Install dependencies run: | @@ -124,7 +136,7 @@ jobs: if: ${{ true != contains( matrix.php, '8.2' ) }} run: | sed -i -e 's/state_machine_component: symfony/state_machine_component: winzou/g' tests/Application/config/packages/test/sylius_resource.yaml - (cd tests/Application && bin/console cache:clear --env=test) + (cd tests/Application && bin/console cache:clear) vendor/bin/phpspec run --ansi --no-interaction sed -i -e 's/state_machine_component: winzou/state_machine_component: symfony/g' tests/Application/config/packages/test/sylius_resource.yaml @@ -133,7 +145,7 @@ jobs: name: Run state machine PHPUnit tests with winzou/state-machine package run: | sed -i -e 's/state_machine_component: symfony/state_machine_component: winzou/g' tests/Application/config/packages/test/sylius_resource.yaml - (cd tests/Application && bin/console cache:clear --env=test) + (cd tests/Application && bin/console cache:clear) vendor/bin/phpunit --colors=always sed -i -e 's/state_machine_component: winzou/state_machine_component: symfony/g' tests/Application/config/packages/test/sylius_resource.yaml @@ -142,7 +154,7 @@ jobs: if: ${{ true != contains( matrix.php, '8.2' ) }} run: | sed -i -e 's/state_machine_component: winzou/state_machine_component: symfony/g' tests/Application/config/packages/test/sylius_resource.yaml - (cd tests/Application && bin/console cache:clear --env=test) + (cd tests/Application && bin/console cache:clear) vendor/bin/phpspec run --ansi --no-interaction sed -i -e 's/state_machine_component: symfony/state_machine_component: winzou/g' tests/Application/config/packages/test/sylius_resource.yaml @@ -150,20 +162,22 @@ jobs: name: Run state machine PHPUnit tests with symfony/workflow package run: | sed -i -e 's/state_machine_component: winzou/state_machine_component: symfony/g' tests/Application/config/packages/test/sylius_resource.yaml - (cd tests/Application && bin/console cache:clear --env=test) + (cd tests/Application && bin/console cache:clear) vendor/bin/phpunit --colors=always sed -i -e 's/state_machine_component: symfony/state_machine_component: winzou/g' tests/Application/config/packages/test/sylius_resource.yaml - name: Run lint container without friendsofsymfony/rest-bundle willdurand/hateoas-bundle jms/serializer-bundle packages + if: matrix.app_env == 'test' run: | composer remove --dev friendsofsymfony/rest-bundle willdurand/hateoas-bundle jms/serializer-bundle --no-scripts (cd tests/Application && bin/console cache:clear --env=test_without_fosrest) (cd tests/Application && bin/console lint:container --env=test_without_fosrest) - composer require friendsofsymfony/rest-bundle willdurand/hateoas-bundle jms/serializer-bundle --no-scripts + composer require --dev friendsofsymfony/rest-bundle willdurand/hateoas-bundle jms/serializer-bundle --no-scripts - name: Run lint container without winzou/state-machine-bundle package + if: matrix.app_env == 'test' run: | composer remove winzou/state-machine-bundle --no-scripts (cd tests/Application && bin/console cache:clear --env=test_without_state_machine) @@ -172,6 +186,7 @@ jobs: - name: Run lint container without twig/twig package + if: matrix.app_env == 'test' run: | composer remove symfony/twig-bundle --no-scripts composer remove sylius/grid-bundle --no-scripts --dev diff --git a/CONFLICTS.md b/CONFLICTS.md index fc6774114..b2d085b82 100644 --- a/CONFLICTS.md +++ b/CONFLICTS.md @@ -2,3 +2,8 @@ This document explains why certain conflicts were added to `composer.json` and references related issues. + +- `willdurand/hateoas-bundle: ^2.6` + +This version allows Symfony 7 but does not support the "annotation_reader" service removal. +@see https://github.com/willdurand/BazingaHateoasBundle/issues/108 diff --git a/Dockerfile b/Dockerfile index f984fdcc7..f95848270 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,6 +15,8 @@ COPY . /app WORKDIR /app +RUN composer global config --no-plugins allow-plugins.symfony/flex true +RUN composer global require --no-progress --no-scripts --no-plugins "symfony/flex:^1.10" RUN composer update --with-all-dependencies --no-interaction --no-progress WORKDIR /app/tests/Application diff --git a/composer.json b/composer.json index 760f37b13..48ed4cc80 100644 --- a/composer.json +++ b/composer.json @@ -30,27 +30,27 @@ "doctrine/annotations": "^2.0", "doctrine/collections": "^1.8 || ^2.0", "doctrine/doctrine-bundle": "^2.0", - "doctrine/event-manager": "^1.1", + "doctrine/event-manager": "^1.1 || ^2.0", "doctrine/inflector": "^1.4 || ^2.0", "doctrine/persistence": "^2.0 || ^3.0", "gedmo/doctrine-extensions": "^2.4.12 || ^3.0", "sylius/registry": "^1.2", - "symfony/config": "^5.4 || ^6.4", + "symfony/config": "^5.4 || ^6.4 || ^7.0", "symfony/deprecation-contracts": "^2.1 || ^3.0", - "symfony/expression-language": "^5.4 || ^6.4", - "symfony/form": "^5.4 || ^6.4", - "symfony/framework-bundle": "^5.4 || ^6.4", - "symfony/http-foundation": "^5.4 || ^6.4", - "symfony/intl": "^5.4 || ^6.4", - "symfony/security-core": "^5.4 || ^6.4", - "symfony/security-csrf": "^5.4 || ^6.4", - "symfony/routing": "^5.4 || ^6.4", - "symfony/translation": "^5.4 || ^6.4", - "symfony/twig-bundle": "^5.4 || ^6.4", - "symfony/validator": "^5.4 || ^6.4", - "symfony/yaml": "^5.4 || ^6.4", + "symfony/expression-language": "^5.4 || ^6.4 || ^7.0", + "symfony/form": "^5.4 || ^6.4 || ^7.0", + "symfony/framework-bundle": "^5.4 || ^6.4 || ^7.0", + "symfony/http-foundation": "^5.4 || ^6.4 || ^7.0", + "symfony/intl": "^5.4 || ^6.4 || ^7.0", + "symfony/security-core": "^5.4 || ^6.4 || ^7.0", + "symfony/security-csrf": "^5.4 || ^6.4 || ^7.0", + "symfony/routing": "^5.4 || ^6.4 || ^7.0", + "symfony/translation": "^5.4 || ^6.4 || ^7.0", + "symfony/twig-bundle": "^5.4 || ^6.4 || ^7.0", + "symfony/validator": "^5.4 || ^6.4 || ^7.0", + "symfony/yaml": "^5.4 || ^6.4 || ^7.0", "webmozart/assert": "^1.8", - "winzou/state-machine-bundle": "^0.6", + "winzou/state-machine-bundle": "^0.6.2", "willdurand/negotiation": "^3.1" }, "replace": { @@ -61,7 +61,7 @@ "friendsofsymfony/rest-bundle": "^3.0", "jms/serializer-bundle": "^3.5 || ^4.0 || ^5.0", "lchrusciel/api-test-case": "^5.0", - "matthiasnoback/symfony-dependency-injection-test": "^4.2.1", + "matthiasnoback/symfony-dependency-injection-test": "^4.2.1 || ^5.1", "pagerfanta/pagerfanta": "^3.7 || ^4.0", "pamil/phpspec-skip-example-extension": "^4.2", "phpspec/phpspec": "^7.3", @@ -70,26 +70,27 @@ "phpstan/phpstan-phpunit": "^1.1", "phpstan/phpstan-webmozart-assert": "^1.2", "phpunit/phpunit": "^9.5", + "rector/rector": "^0.18.2", "sylius-labs/coding-standard": "^4.0", - "sylius/grid-bundle": "^1.7 || v1.12.0-ALPHA.1", - "symfony/console": "^5.4 || ^6.4", - "symfony/dependency-injection": "^5.4 || ^6.4", - "symfony/dotenv": "^5.4 || ^6.4", - "symfony/stopwatch": "^5.4 || ^6.4", - "symfony/uid": "^5.4 || ^6.4", - "symfony/workflow": "^5.4 || ^6.4", + "sylius/grid-bundle": "^1.7 || dev-symfony-7", + "symfony/console": "^5.4 || ^6.4 || ^7.0", + "symfony/dependency-injection": "^5.4 || ^6.4 || ^7.0", + "symfony/dotenv": "^5.4 || ^6.4 || ^7.0", + "symfony/http-kernel": "^5.4 || ^6.4 || ^7.0", + "symfony/stopwatch": "^5.4 || ^6.4 || ^7.0", + "symfony/uid": "^5.4 || ^6.4 || ^7.0", + "symfony/workflow": "^5.4 || ^6.4 || ^7.0", + "symfony/messenger": "^5.4 || ^6.4 || ^7.0", + "symfony/serializer": "^5.4 || ^6.4 || ^7.0", + "symfony/security-bundle": "^5.4 || ^6.4 || ^7.0", "twig/twig": "^2.12 || ^3.0", "vimeo/psalm": "^5.20", - "rector/rector": "^0.18.2", - "symfony/messenger": "^5.4 || ^6.4", - "symfony/serializer": "^5.4 || ^6.4", - "symfony/security-bundle": "^5.4 || ^6.4", "willdurand/hateoas-bundle": "^2.0" }, "conflict": { "friendsofsymfony/rest-bundle": "<3.0", "jms/serializer-bundle": "<3.5", - "willdurand/hateoas-bundle": "<2.0" + "willdurand/hateoas-bundle": "<2.0 || ^2.6" }, "suggest": { "doctrine/orm": "^2.5", @@ -101,6 +102,11 @@ "dealerdirect/phpcodesniffer-composer-installer": false } }, + "extra": { + "symfony": { + "require": "^6.4" + } + }, "autoload": { "psr-4": { "Sylius\\Bundle\\ResourceBundle\\": "src/Bundle/", diff --git a/phpstan.neon b/phpstan.neon index caecd249a..e2780adb2 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -44,6 +44,7 @@ parameters: - '/Call to method isChangeTrackingDeferredExplicit\(\) on an unknown class Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadata./' - '/Call to an undefined method ReflectionClass::getAttributes\(\)./' - '/Call to an undefined method object::getRealClassName\(\)./' + - '/Class Bazinga\\Bundle\\HateoasBundle\\BazingaHateoasBundle not found\./' - '/Class Doctrine\\Bundle\\MongoDBBundle/' - '/Class Doctrine\\Bundle\\PHPCRBundle/' - '/Class Doctrine\\Common\\Persistence\\ObjectManager not found\./' diff --git a/psalm.xml b/psalm.xml index 08b527b10..879f534e7 100644 --- a/psalm.xml +++ b/psalm.xml @@ -67,6 +67,12 @@ + + + + + + @@ -168,6 +174,12 @@ + + + + + + @@ -198,6 +210,7 @@ + @@ -250,10 +263,13 @@ + + + diff --git a/src/Bundle/Controller/ContainerAwareTrait.php b/src/Bundle/Controller/ContainerAwareTrait.php new file mode 100644 index 000000000..0b50463b2 --- /dev/null +++ b/src/Bundle/Controller/ContainerAwareTrait.php @@ -0,0 +1,34 @@ +container = $container; + } +} diff --git a/src/Bundle/Controller/Parameters.php b/src/Bundle/Controller/Parameters.php index 510b86232..a9b39700e 100644 --- a/src/Bundle/Controller/Parameters.php +++ b/src/Bundle/Controller/Parameters.php @@ -16,7 +16,7 @@ use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpKernel\Kernel; -if (Kernel::MAJOR_VERSION === 6) { +if (Kernel::MAJOR_VERSION >= 6) { class Parameters extends ParameterBag { /** diff --git a/src/Bundle/Controller/ResourceController.php b/src/Bundle/Controller/ResourceController.php index e672f1eb2..defd989de 100644 --- a/src/Bundle/Controller/ResourceController.php +++ b/src/Bundle/Controller/ResourceController.php @@ -23,7 +23,6 @@ use Sylius\Resource\Metadata\MetadataInterface; use Sylius\Resource\Model\ResourceInterface; use Sylius\Resource\ResourceActions; -use Symfony\Component\DependencyInjection\ContainerAwareTrait; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; diff --git a/src/Bundle/DependencyInjection/Compiler/DoctrineTargetEntitiesResolverPass.php b/src/Bundle/DependencyInjection/Compiler/DoctrineTargetEntitiesResolverPass.php index 565907b13..a89e9ffda 100644 --- a/src/Bundle/DependencyInjection/Compiler/DoctrineTargetEntitiesResolverPass.php +++ b/src/Bundle/DependencyInjection/Compiler/DoctrineTargetEntitiesResolverPass.php @@ -13,7 +13,6 @@ namespace Sylius\Bundle\ResourceBundle\DependencyInjection\Compiler; -use Doctrine\Common\EventSubscriber; use Sylius\Bundle\ResourceBundle\DependencyInjection\Compiler\Helper\TargetEntitiesResolverInterface; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -47,13 +46,7 @@ public function process(ContainerBuilder $container): void $resolveTargetEntityListener->addMethodCall('addResolveTargetEntity', [$interface, $model, []]); } - /** @var object|string $resolveTargetEntityListenerClass */ - $resolveTargetEntityListenerClass = $container->getParameterBag()->resolveValue($resolveTargetEntityListener->getClass()); - if (is_a($resolveTargetEntityListenerClass, EventSubscriber::class, true)) { - if (!$resolveTargetEntityListener->hasTag('doctrine.event_subscriber')) { - $resolveTargetEntityListener->addTag('doctrine.event_subscriber'); - } - } elseif (!$resolveTargetEntityListener->hasTag('doctrine.event_listener')) { + if (!$resolveTargetEntityListener->hasTag('doctrine.event_listener')) { $resolveTargetEntityListener->addTag('doctrine.event_listener', ['event' => 'loadClassMetadata']); } } diff --git a/src/Bundle/Form/DataTransformer/ResourceToIdentifierTransformer.php b/src/Bundle/Form/DataTransformer/ResourceToIdentifierTransformer.php index ac6ae0492..8b52bdbf9 100644 --- a/src/Bundle/Form/DataTransformer/ResourceToIdentifierTransformer.php +++ b/src/Bundle/Form/DataTransformer/ResourceToIdentifierTransformer.php @@ -33,13 +33,9 @@ public function __construct(RepositoryInterface $repository, ?string $identifier } /** - * @psalm-suppress MissingParamType - * - * @param object|null $value - * - * @return mixed + * @inheritDoc */ - public function transform($value) + public function transform(mixed $value): mixed { if (null === $value) { return null; @@ -51,8 +47,10 @@ public function transform($value) return PropertyAccess::createPropertyAccessor()->getValue($value, $this->identifier); } - /** @param int|string|null $value */ - public function reverseTransform($value): ?ResourceInterface + /** + * @inheritDoc + */ + public function reverseTransform(mixed $value): ?ResourceInterface { if (null === $value) { return null; diff --git a/src/Bundle/Resources/config/services/integrations/translation.xml b/src/Bundle/Resources/config/services/integrations/translation.xml index c99a666b8..521a9a220 100644 --- a/src/Bundle/Resources/config/services/integrations/translation.xml +++ b/src/Bundle/Resources/config/services/integrations/translation.xml @@ -30,7 +30,8 @@ - + + diff --git a/src/Bundle/Resources/config/services/routing.xml b/src/Bundle/Resources/config/services/routing.xml index 1b39b901d..567598b92 100644 --- a/src/Bundle/Resources/config/services/routing.xml +++ b/src/Bundle/Resources/config/services/routing.xml @@ -20,6 +20,7 @@ + %kernel.environment% diff --git a/src/Bundle/Routing/ResourceLoader.php b/src/Bundle/Routing/ResourceLoader.php index c271a8a62..639182163 100644 --- a/src/Bundle/Routing/ResourceLoader.php +++ b/src/Bundle/Routing/ResourceLoader.php @@ -17,20 +17,24 @@ use Sylius\Resource\Metadata\MetadataInterface; use Sylius\Resource\Metadata\RegistryInterface; use Symfony\Component\Config\Definition\Processor; -use Symfony\Component\Config\Loader\LoaderInterface; -use Symfony\Component\Config\Loader\LoaderResolverInterface; +use Symfony\Component\Config\Loader\Loader; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Yaml\Yaml; -final class ResourceLoader implements LoaderInterface +final class ResourceLoader extends Loader { private RegistryInterface $resourceRegistry; private RouteFactoryInterface $routeFactory; - public function __construct(RegistryInterface $resourceRegistry, RouteFactoryInterface $routeFactory) - { + public function __construct( + RegistryInterface $resourceRegistry, + RouteFactoryInterface $routeFactory, + ?string $env = null, + ) { + parent::__construct($env); + $this->resourceRegistry = $resourceRegistry; $this->routeFactory = $routeFactory; } @@ -103,21 +107,6 @@ public function supports($resource, $type = null): bool return 'sylius.resource' === $type || 'sylius.resource_api' === $type; } - /** - * @psalm-suppress InvalidReturnType Symfony docblocks are messing with us - * - * @return LoaderResolverInterface - */ - public function getResolver() - { - // Intentionally left blank. - } - - public function setResolver(LoaderResolverInterface $resolver): void - { - // Intentionally left blank. - } - private function createRoute( MetadataInterface $metadata, array $configuration, diff --git a/src/Bundle/spec/Controller/RedirectHandlerSpec.php b/src/Bundle/spec/Controller/RedirectHandlerSpec.php index 2d752ebf2..3630d2673 100644 --- a/src/Bundle/spec/Controller/RedirectHandlerSpec.php +++ b/src/Bundle/spec/Controller/RedirectHandlerSpec.php @@ -17,7 +17,7 @@ use Sylius\Bundle\ResourceBundle\Controller\RedirectHandlerInterface; use Sylius\Bundle\ResourceBundle\Controller\RequestConfiguration; use Sylius\Resource\Model\ResourceInterface; -use Symfony\Component\HttpFoundation\ParameterBag; +use Symfony\Component\HttpFoundation\HeaderBag; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -104,7 +104,7 @@ function it_redirects(RequestConfiguration $configuration): void $this->redirect($configuration, 'http://myurl.com')->shouldHaveType(RedirectResponse::class); } - function it_redirect_to_referer(RequestConfiguration $configuration, Request $request, ParameterBag $bag): void + function it_redirect_to_referer(RequestConfiguration $configuration, Request $request, HeaderBag $bag): void { $request->headers = $bag; diff --git a/src/Bundle/spec/Controller/RequestConfigurationFactorySpec.php b/src/Bundle/spec/Controller/RequestConfigurationFactorySpec.php index 739ea73dc..9909f4a60 100644 --- a/src/Bundle/spec/Controller/RequestConfigurationFactorySpec.php +++ b/src/Bundle/spec/Controller/RequestConfigurationFactorySpec.php @@ -138,7 +138,7 @@ function it_creates_configuration_using_only_those_serialization_groups_that_are ParametersParserInterface $parametersParser, MetadataInterface $metadata, Request $request, - ParameterBag $headersBag, + HeaderBag $headersBag, ParameterBag $attributesBag, ): void { $request->headers = $headersBag; @@ -167,7 +167,7 @@ function it_creates_configuration_using_only_those_serialization_groups_that_are ParametersParserInterface $parametersParser, MetadataInterface $metadata, Request $request, - ParameterBag $headersBag, + HeaderBag $headersBag, ParameterBag $attributesBag, ): void { $request->headers = $headersBag; @@ -197,7 +197,7 @@ function it_creates_configuration_using_only_those_serialization_groups_that_are ParametersParserInterface $parametersParser, MetadataInterface $metadata, Request $request, - ParameterBag $headersBag, + HeaderBag $headersBag, ParameterBag $attributesBag, ): void { $request->headers = $headersBag; diff --git a/src/Bundle/spec/Controller/RequestConfigurationSpec.php b/src/Bundle/spec/Controller/RequestConfigurationSpec.php index e29bc2b40..c9e45464b 100644 --- a/src/Bundle/spec/Controller/RequestConfigurationSpec.php +++ b/src/Bundle/spec/Controller/RequestConfigurationSpec.php @@ -17,6 +17,8 @@ use Prophecy\Argument; use Sylius\Bundle\ResourceBundle\Controller\Parameters; use Sylius\Resource\Metadata\MetadataInterface; +use Symfony\Component\HttpFoundation\HeaderBag; +use Symfony\Component\HttpFoundation\InputBag; use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request; @@ -132,7 +134,7 @@ function it_generates_route_names(MetadataInterface $metadata, Parameters $param $this->getRouteName('custom')->shouldReturn('sylius_admin_product_custom'); } - function it_generates_redirect_referer(Parameters $parameters, Request $request, ParameterBag $bag): void + function it_generates_redirect_referer(Parameters $parameters, Request $request, HeaderBag $bag): void { $request->headers = $bag; $bag->get('referer')->willReturn('http://myurl.com'); @@ -275,9 +277,10 @@ function it_has_criteria_parameter( Parameters $parameters, Request $request, ParameterBag $attributesBag, - ParameterBag $queryBag, - ParameterBag $requestBag, ): void { + $queryBag = new InputBag(); + $requestBag = new InputBag(); + $criteria = ['property' => 'myNewValue']; $request->attributes = $attributesBag; $request->query = $queryBag; @@ -287,9 +290,10 @@ function it_has_criteria_parameter( $parameters->get('criteria', Argument::any())->willReturn([]); $attributesBag->get('criteria', $request)->willReturn($request); - $queryBag->has('criteria')->willReturn(true); - $queryBag->all()->willReturn(['criteria' => $criteria]); - $requestBag->all()->willReturn(['criteria' => []]); + + $queryBag->set('criteria', $criteria); + + $requestBag->set('criteria', []); $this->getCriteria()->shouldReturn($criteria); } @@ -298,9 +302,10 @@ function it_has_criteria_parameter_in_request( Parameters $parameters, Request $request, ParameterBag $attributesBag, - ParameterBag $queryBag, - ParameterBag $requestBag, ): void { + $queryBag = new InputBag(); + $requestBag = new InputBag(); + $criteria = ['property' => 'myNewValue']; $request->attributes = $attributesBag; $request->query = $queryBag; @@ -310,9 +315,8 @@ function it_has_criteria_parameter_in_request( $parameters->get('criteria', Argument::any())->willReturn([]); $attributesBag->get('criteria', $request)->willReturn($request); - $queryBag->has('criteria')->willReturn(false); - $requestBag->has('criteria')->willReturn(true); - $requestBag->all()->willReturn(['criteria' => $criteria]); + + $requestBag->set('criteria', $criteria); $this->getCriteria()->shouldReturn($criteria); } @@ -321,9 +325,10 @@ function it_allows_to_override_criteria_parameter_in_route( Parameters $parameters, Request $request, ParameterBag $attributesBag, - ParameterBag $queryBag, - ParameterBag $requestBag, ): void { + $queryBag = new InputBag(); + $requestBag = new InputBag(); + $criteria = ['property' => 'myValue']; $overriddenCriteria = ['other_property' => 'myNewValue']; $combinedCriteria = ['property' => 'myValue', 'other_property' => 'myNewValue']; @@ -333,10 +338,12 @@ function it_allows_to_override_criteria_parameter_in_route( $parameters->get('filterable', false)->willReturn(true); $parameters->get('criteria', [])->willReturn($criteria); + $attributesBag->get('criteria', $request)->willReturn($request); - $queryBag->has('criteria')->willReturn(true); - $queryBag->all()->willReturn(['criteria' => $overriddenCriteria]); - $requestBag->all()->willReturn(['criteria' => []]); + + $queryBag->set('criteria', $overriddenCriteria); + + $requestBag->set('criteria', []); $this->getCriteria()->shouldReturn($combinedCriteria); @@ -346,18 +353,16 @@ function it_allows_to_override_criteria_parameter_in_route( $parameters->get('filterable', false)->willReturn(true); $parameters->get('criteria', Argument::any())->willReturn($criteria); $attributesBag->get('criteria', $request)->willReturn($request); - $queryBag->has('criteria')->willReturn(true); - $queryBag->all()->willReturn(['criteria' => $overriddenCriteria]); - $requestBag->all()->willReturn(['criteria' => []]); + $queryBag->set('criteria', $overriddenCriteria); + $requestBag->set('criteria', []); $this->getCriteria($defaultCriteria)->shouldReturn($combinedDefaultCriteria); $parameters->get('filterable', false)->willReturn(true); $parameters->get('criteria', [])->willReturn(['filter' => 'route']); $attributesBag->get('criteria', $request)->willReturn($request); - $queryBag->has('criteria')->willReturn(true); - $queryBag->all()->willReturn(['criteria' => ['filter' => 'request']]); - $requestBag->all()->willReturn(['criteria' => []]); + $queryBag->set('criteria', ['filter' => 'request']); + $requestBag->set('criteria', []); $this->getCriteria(['filter' => 'default'])->shouldReturn(['filter' => 'request']); } @@ -375,9 +380,10 @@ function it_has_sorting_parameter( Parameters $parameters, Request $request, ParameterBag $attributesBag, - ParameterBag $queryBag, - ParameterBag $requestBag, ): void { + $queryBag = new InputBag(); + $requestBag = new InputBag(); + $sorting = ['property' => 'asc']; $request->attributes = $attributesBag; $request->query = $queryBag; @@ -385,10 +391,12 @@ function it_has_sorting_parameter( $parameters->get('sortable', false)->willReturn(true); $parameters->get('sorting', Argument::any())->willReturn($sorting); + $attributesBag->get('sorting', $request)->willReturn($request); - $queryBag->has('sorting')->willReturn(true); - $queryBag->all()->willReturn(['sorting' => $sorting]); - $requestBag->get('sorting', [])->willReturn([]); + + $queryBag->set('sorting', $sorting); + + $requestBag->set('sorting', []); $this->getSorting()->shouldReturn($sorting); } @@ -408,9 +416,10 @@ function it_allows_to_override_sorting_parameter_in_route( Parameters $parameters, Request $request, ParameterBag $attributesBag, - ParameterBag $queryBag, - ParameterBag $requestBag, ): void { + $queryBag = new InputBag(); + $requestBag = new InputBag(); + $sorting = ['property' => 'desc']; $overriddenSorting = ['other_property' => 'asc']; $combinedSorting = ['other_property' => 'asc', 'property' => 'desc']; @@ -421,9 +430,8 @@ function it_allows_to_override_sorting_parameter_in_route( $parameters->get('sortable', false)->willReturn(true); $parameters->get('sorting', [])->willReturn($sorting); $attributesBag->get('sorting', $request)->willReturn($request); - $queryBag->has('sorting')->willReturn(true); - $queryBag->all()->willReturn(['sorting' => $overriddenSorting]); - $requestBag->get('sorting', [])->willReturn([]); + $queryBag->set('sorting', $overriddenSorting); + $requestBag->set('sorting', []); $this->getSorting()->shouldReturn($combinedSorting); @@ -433,18 +441,16 @@ function it_allows_to_override_sorting_parameter_in_route( $parameters->get('sortable', false)->willReturn(true); $parameters->get('sorting', Argument::any())->willReturn($sorting); $attributesBag->get('sorting', $request)->willReturn($request); - $queryBag->has('sorting')->willReturn(true); - $queryBag->all()->willReturn(['sorting' => $overriddenSorting]); - $requestBag->get('sorting', [])->willReturn([]); + $queryBag->set('sorting', $overriddenSorting); + $requestBag->set('sorting', []); $this->getSorting($defaultSorting)->shouldReturn($combinedDefaultSorting); $parameters->get('sortable', false)->willReturn(true); $parameters->get('sorting', [])->willReturn(['sort' => 'route']); $attributesBag->get('sorting', $request)->willReturn($request); - $queryBag->has('sorting')->willReturn(true); - $queryBag->all()->willReturn(['sorting' => ['sort' => 'request']]); - $requestBag->get('sorting', [])->willReturn([]); + $queryBag->set('sorting', ['sort' => 'request']); + $requestBag->set('sorting', []); $this->getSorting(['sort' => 'default'])->shouldReturn(['sort' => 'request']); } diff --git a/src/Bundle/spec/Controller/ResourceControllerSpec.php b/src/Bundle/spec/Controller/ResourceControllerSpec.php index 4daf97dcc..270c25110 100644 --- a/src/Bundle/spec/Controller/ResourceControllerSpec.php +++ b/src/Bundle/spec/Controller/ResourceControllerSpec.php @@ -43,7 +43,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\Form\Form; use Symfony\Component\Form\FormView; -use Symfony\Component\HttpFoundation\ParameterBag; +use Symfony\Component\HttpFoundation\InputBag; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; @@ -1784,7 +1784,7 @@ function it_deletes_multiple_resources_and_redirects_to_index_for_html_request( $requestConfigurationFactory->create($metadata, $request)->willReturn($configuration); $configuration->hasPermission()->willReturn(true); $configuration->getPermission(ResourceActions::BULK_DELETE)->willReturn('sylius.product.bulk_delete'); - $request->request = new ParameterBag(['_csrf_token' => 'xyz']); + $request->request = new InputBag(['_csrf_token' => 'xyz']); $container->has('security.csrf.token_manager')->willReturn(true); $container->get('security.csrf.token_manager')->willReturn($csrfTokenManager); @@ -1903,7 +1903,7 @@ function it_deletes_a_resource_and_redirects_to_index_by_for_html_request( $requestConfigurationFactory->create($metadata, $request)->willReturn($configuration); $configuration->hasPermission()->willReturn(true); $configuration->getPermission(ResourceActions::DELETE)->willReturn('sylius.product.delete'); - $request->request = new ParameterBag(['_csrf_token' => 'xyz']); + $request->request = new InputBag(['_csrf_token' => 'xyz']); $container->has('security.csrf.token_manager')->willReturn(true); $container->get('security.csrf.token_manager')->willReturn($csrfTokenManager); @@ -1954,7 +1954,7 @@ function it_uses_response_from_post_delete_event_if_defined( $requestConfigurationFactory->create($metadata, $request)->willReturn($configuration); $configuration->hasPermission()->willReturn(true); $configuration->getPermission(ResourceActions::DELETE)->willReturn('sylius.product.delete'); - $request->request = new ParameterBag(['_csrf_token' => 'xyz']); + $request->request = new InputBag(['_csrf_token' => 'xyz']); $container->has('security.csrf.token_manager')->willReturn(true); $container->get('security.csrf.token_manager')->willReturn($csrfTokenManager); @@ -2005,7 +2005,7 @@ function it_does_not_delete_a_resource_and_redirects_to_index_for_html_requests_ $requestConfigurationFactory->create($metadata, $request)->willReturn($configuration); $configuration->hasPermission()->willReturn(true); $configuration->getPermission(ResourceActions::DELETE)->willReturn('sylius.product.delete'); - $request->request = new ParameterBag(['_csrf_token' => 'xyz']); + $request->request = new InputBag(['_csrf_token' => 'xyz']); $container->has('security.csrf.token_manager')->willReturn(true); $container->get('security.csrf.token_manager')->willReturn($csrfTokenManager); @@ -2056,7 +2056,7 @@ function it_does_not_delete_a_resource_and_uses_response_from_event_if_defined( $requestConfigurationFactory->create($metadata, $request)->willReturn($configuration); $configuration->hasPermission()->willReturn(true); $configuration->getPermission(ResourceActions::DELETE)->willReturn('sylius.product.delete'); - $request->request = new ParameterBag(['_csrf_token' => 'xyz']); + $request->request = new InputBag(['_csrf_token' => 'xyz']); $container->has('security.csrf.token_manager')->willReturn(true); $container->get('security.csrf.token_manager')->willReturn($csrfTokenManager); @@ -2109,7 +2109,7 @@ function it_does_not_correctly_delete_a_resource_and_returns_500_for_not_html_re $requestConfigurationFactory->create($metadata, $request)->willReturn($configuration); $configuration->hasPermission()->willReturn(true); $configuration->getPermission(ResourceActions::DELETE)->willReturn('sylius.product.delete'); - $request->request = new ParameterBag(['_csrf_token' => 'xyz']); + $request->request = new InputBag(['_csrf_token' => 'xyz']); $container->has('security.csrf.token_manager')->willReturn(true); $container->get('security.csrf.token_manager')->willReturn($csrfTokenManager); @@ -2159,7 +2159,7 @@ function it_deletes_a_resource_and_returns_204_for_non_html_requests( $requestConfigurationFactory->create($metadata, $request)->willReturn($configuration); $configuration->hasPermission()->willReturn(true); $configuration->getPermission(ResourceActions::DELETE)->willReturn('sylius.product.delete'); - $request->request = new ParameterBag(['_csrf_token' => 'xyz']); + $request->request = new InputBag(['_csrf_token' => 'xyz']); $container->has('security.csrf.token_manager')->willReturn(true); $container->get('security.csrf.token_manager')->willReturn($csrfTokenManager); @@ -2207,7 +2207,7 @@ function it_does_not_delete_a_resource_and_throws_http_exception_for_non_html_re $requestConfigurationFactory->create($metadata, $request)->willReturn($configuration); $configuration->hasPermission()->willReturn(true); $configuration->getPermission(ResourceActions::DELETE)->willReturn('sylius.product.delete'); - $request->request = new ParameterBag(['_csrf_token' => 'xyz']); + $request->request = new InputBag(['_csrf_token' => 'xyz']); $container->has('security.csrf.token_manager')->willReturn(true); $container->get('security.csrf.token_manager')->willReturn($csrfTokenManager); @@ -2259,7 +2259,7 @@ function it_throws_a_403_exception_if_csrf_token_is_invalid_during_delete_action $requestConfigurationFactory->create($metadata, $request)->willReturn($configuration); $configuration->hasPermission()->willReturn(true); $configuration->getPermission(ResourceActions::DELETE)->willReturn('sylius.product.delete'); - $request->request = new ParameterBag(['_csrf_token' => 'xyz']); + $request->request = new InputBag(['_csrf_token' => 'xyz']); $container->has('security.csrf.token_manager')->willReturn(true); $container->get('security.csrf.token_manager')->willReturn($csrfTokenManager); diff --git a/src/Bundle/spec/Controller/ResourcesCollectionProviderSpec.php b/src/Bundle/spec/Controller/ResourcesCollectionProviderSpec.php index c385bbee1..1b92ead68 100644 --- a/src/Bundle/spec/Controller/ResourcesCollectionProviderSpec.php +++ b/src/Bundle/spec/Controller/ResourcesCollectionProviderSpec.php @@ -13,27 +13,34 @@ namespace spec\Sylius\Bundle\ResourceBundle\Controller; -use Hateoas\Configuration\Route; use Hateoas\Representation\Factory\PagerfantaFactory; use Hateoas\Representation\PaginatedRepresentation; +use Pagerfanta\Adapter\ArrayAdapter; use Pagerfanta\Pagerfanta; +use PhpSpec\Exception\Example\SkippingException; use PhpSpec\ObjectBehavior; -use Prophecy\Argument; +use Prophecy\PhpUnit\ProphecyTrait; +use Sylius\Bundle\ResourceBundle\Controller\Parameters; use Sylius\Bundle\ResourceBundle\Controller\RequestConfiguration; use Sylius\Bundle\ResourceBundle\Controller\ResourcesCollectionProviderInterface; +use Sylius\Bundle\ResourceBundle\Controller\ResourcesResolver; use Sylius\Bundle\ResourceBundle\Controller\ResourcesResolverInterface; use Sylius\Bundle\ResourceBundle\Grid\View\ResourceGridView; use Sylius\Component\Grid\Definition\Grid; use Sylius\Resource\Doctrine\Persistence\RepositoryInterface; +use Sylius\Resource\Metadata\MetadataInterface; use Sylius\Resource\Model\ResourceInterface; +use Symfony\Component\HttpFoundation\InputBag; use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request; final class ResourcesCollectionProviderSpec extends ObjectBehavior { - function let(ResourcesResolverInterface $resourcesResolver, PagerfantaFactory $pagerfantaRepresentationFactory): void + use ProphecyTrait; + + function let(ResourcesResolverInterface $resourcesResolver): void { - $this->beConstructedWith($resourcesResolver, $pagerfantaRepresentationFactory); + $this->beConstructedWith($resourcesResolver, null); } function it_implements_resources_collection_provider_interface(): void @@ -61,8 +68,9 @@ function it_handles_Pagerfanta( RepositoryInterface $repository, Pagerfanta $paginator, Request $request, - ParameterBag $queryParameters, ): void { + $queryParameters = new InputBag(); + $requestConfiguration->isHtmlRequest()->willReturn(true); $requestConfiguration->getPaginationMaxPerPage()->willReturn(5); @@ -70,9 +78,8 @@ function it_handles_Pagerfanta( $requestConfiguration->getRequest()->willReturn($request); $request->query = $queryParameters; - $queryParameters->has('limit')->willReturn(true); - $queryParameters->getInt('limit')->willReturn(5); - $queryParameters->get('page', 1)->willReturn(6); + $queryParameters->set('limit', 5); + $queryParameters->set('page', 6); $paginator->setMaxPerPage(5)->shouldBeCalled(); $paginator->setCurrentPage(6)->shouldBeCalled(); @@ -89,8 +96,9 @@ function it_restricts_max_pagination_limit_based_on_grid_configuration( Grid $grid, Pagerfanta $paginator, Request $request, - ParameterBag $queryParameters, ): void { + $queryParameters = new InputBag(); + $requestConfiguration->isHtmlRequest()->willReturn(true); $requestConfiguration->getPaginationMaxPerPage()->willReturn(1000); @@ -103,9 +111,8 @@ function it_restricts_max_pagination_limit_based_on_grid_configuration( $requestConfiguration->getRequest()->willReturn($request); $request->query = $queryParameters; - $queryParameters->has('limit')->willReturn(true); - $queryParameters->getInt('limit')->willReturn(1000); - $queryParameters->get('page', 1)->willReturn(1); + $queryParameters->set('limit', 1000); + $queryParameters->set('page', 1); $paginator->setMaxPerPage(99)->shouldBeCalled(); $paginator->setCurrentPage(1)->shouldBeCalled(); @@ -115,39 +122,24 @@ function it_restricts_max_pagination_limit_based_on_grid_configuration( } function it_creates_a_paginated_representation_for_pagerfanta_for_non_html_requests( - ResourcesResolverInterface $resourcesResolver, - RequestConfiguration $requestConfiguration, RepositoryInterface $repository, - Pagerfanta $paginator, - Request $request, - ParameterBag $queryParameters, - ParameterBag $requestAttributes, - PagerfantaFactory $pagerfantaRepresentationFactory, - PaginatedRepresentation $paginatedRepresentation, + MetadataInterface $metadata, ): void { - $requestConfiguration->isHtmlRequest()->willReturn(false); - $requestConfiguration->getPaginationMaxPerPage()->willReturn(8); + if (!class_exists(PagerfantaFactory::class)) { + throw new SkippingException('PagerfantaFactory is not installed.'); + } - $resourcesResolver->getResources($requestConfiguration, $repository)->willReturn($paginator); + $this->beConstructedWith(new ResourcesResolver(), new PagerfantaFactory()); - $requestConfiguration->getRequest()->willReturn($request); - $request->query = $queryParameters; - $queryParameters->has('limit')->willReturn(true); - $queryParameters->getInt('limit')->willReturn(8); - $queryParameters->get('page', 1)->willReturn(6); - $queryParameters->all()->willReturn(['foo' => 2, 'bar' => 15]); + $paginator = new Pagerfanta(new ArrayAdapter([])); + $repository->createPaginator([], [])->willReturn($paginator); - $request->attributes = $requestAttributes; - $requestAttributes->get('_route')->willReturn('sylius_product_index'); - $requestAttributes->get('_route_params')->willReturn(['slug' => 'foo-bar']); + $request = new Request(); + $request->query = new InputBag(['limit' => 8, 'page' => 1]); + $request->attributes = new ParameterBag(['_format' => 'json', '_route' => 'sylius_product_index', '_route_params' => ['slug' => 'foo-bar']]); + $requestConfiguration = new RequestConfiguration($metadata->getWrappedObject(), $request, new Parameters(['paginate' => true])); - $paginator->setMaxPerPage(8)->shouldBeCalled(); - $paginator->setCurrentPage(6)->shouldBeCalled(); - $paginator->getCurrentPageResults()->willReturn([]); - - $pagerfantaRepresentationFactory->createRepresentation($paginator, Argument::type(Route::class))->willReturn($paginatedRepresentation); - - $this->get($requestConfiguration, $repository)->shouldReturn($paginatedRepresentation); + $this->get($requestConfiguration, $repository)->shouldHaveType(PaginatedRepresentation::class); } function it_handles_resource_grid_view( @@ -158,8 +150,9 @@ function it_handles_resource_grid_view( Grid $grid, Pagerfanta $paginator, Request $request, - ParameterBag $queryParameters, ): void { + $queryParameters = new InputBag(); + $requestConfiguration->isHtmlRequest()->willReturn(true); $requestConfiguration->getPaginationMaxPerPage()->willReturn(5); @@ -171,9 +164,8 @@ function it_handles_resource_grid_view( $requestConfiguration->getRequest()->willReturn($request); $request->query = $queryParameters; - $queryParameters->has('limit')->willReturn(true); - $queryParameters->getInt('limit')->willReturn(5); - $queryParameters->get('page', 1)->willReturn(6); + $queryParameters->set('limit', 5); + $queryParameters->set('page', 6); $paginator->setMaxPerPage(5)->shouldBeCalled(); $paginator->setCurrentPage(6)->shouldBeCalled(); diff --git a/src/Bundle/spec/Grid/Controller/ResourcesResolverSpec.php b/src/Bundle/spec/Grid/Controller/ResourcesResolverSpec.php index cea6e0b6b..563c22cb4 100644 --- a/src/Bundle/spec/Grid/Controller/ResourcesResolverSpec.php +++ b/src/Bundle/spec/Grid/Controller/ResourcesResolverSpec.php @@ -26,7 +26,7 @@ use Sylius\Resource\Doctrine\Persistence\RepositoryInterface; use Sylius\Resource\Metadata\MetadataInterface; use Sylius\Resource\Model\ResourceInterface; -use Symfony\Component\HttpFoundation\ParameterBag; +use Symfony\Component\HttpFoundation\InputBag; use Symfony\Component\HttpFoundation\Request; final class ResourcesResolverSpec extends ObjectBehavior @@ -66,7 +66,6 @@ function it_returns_grid_view( ResourceGridView $gridView, MetadataInterface $metadata, Request $request, - ParameterBag $queryParameters, ): void { $requestConfiguration->hasGrid()->willReturn(true); $requestConfiguration->getGrid()->willReturn('sylius_admin_tax_category'); @@ -74,8 +73,7 @@ function it_returns_grid_view( $requestConfiguration->isHtmlRequest()->willReturn(true); $requestConfiguration->getRequest()->willReturn($request); - $request->query = $queryParameters; - $queryParameters->all()->willReturn(['foo' => 'bar']); + $request->query = new InputBag(['foo' => 'bar']); $gridProvider->get('sylius_admin_tax_category')->willReturn($gridDefinition); $gridViewFactory->create($gridDefinition, Argument::type(Parameters::class), $metadata, $requestConfiguration)->willReturn($gridView); @@ -93,7 +91,6 @@ function it_returns_grid_data_for_non_html_requests( Pagerfanta $paginator, MetadataInterface $metadata, Request $request, - ParameterBag $queryParameters, ): void { $requestConfiguration->hasGrid()->willReturn(true); $requestConfiguration->getGrid()->willReturn('sylius_admin_tax_category'); @@ -101,8 +98,7 @@ function it_returns_grid_data_for_non_html_requests( $requestConfiguration->isHtmlRequest()->willReturn(false); $requestConfiguration->getRequest()->willReturn($request); - $request->query = $queryParameters; - $queryParameters->all()->willReturn(['foo' => 'bar']); + $request->query = new InputBag(['foo' => 'bar']); $gridProvider->get('sylius_admin_tax_category')->willReturn($gridDefinition); $gridViewFactory->create($gridDefinition, Argument::type(Parameters::class), $metadata, $requestConfiguration)->willReturn($gridView); diff --git a/src/Component/composer.json b/src/Component/composer.json index fa1ff149b..8853f32d2 100644 --- a/src/Component/composer.json +++ b/src/Component/composer.json @@ -27,35 +27,35 @@ } ], "require": { - "php": "^8.0", + "php": "^8.1", "doctrine/collections": "^1.8 || ^2.0", "doctrine/inflector": "^1.4 || ^2.0", "gedmo/doctrine-extensions": "^2.4.12 || ^3.0", "pagerfanta/core": "^3.7 || ^4.0", - "symfony/event-dispatcher": "^5.4 || ^6.4", - "symfony/form": "^5.4 || ^6.4", - "symfony/http-foundation": "^5.4 || ^6.4", - "symfony/http-kernel": "^5.4 || ^6.4", - "symfony/property-access": "^5.4 || ^6.4", - "symfony/routing": "^5.4 || ^6.4", - "symfony/security-core": "^5.4 || ^6.4", - "symfony/security-csrf": "^5.4 || ^6.4", - "symfony/string": "^5.4 || ^6.4", - "symfony/translation": "^5.4 || ^6.4", - "symfony/validator": "^5.4 || ^6.4", + "symfony/event-dispatcher": "^5.4 || ^6.4 || ^7.0", + "symfony/form": "^5.4 || ^6.4 || ^7.0", + "symfony/http-foundation": "^5.4 || ^6.4 || ^7.0", + "symfony/http-kernel": "^5.4 || ^6.4 || ^7.0", + "symfony/property-access": "^5.4 || ^6.4 || ^7.0", + "symfony/routing": "^5.4 || ^6.4 || ^7.0", + "symfony/security-core": "^5.4 || ^6.4 || ^7.0", + "symfony/security-csrf": "^5.4 || ^6.4 || ^7.0", + "symfony/string": "^5.4 || ^6.4 || ^7.0", + "symfony/translation": "^5.4 || ^6.4 || ^7.0", + "symfony/validator": "^5.4 || ^6.4 || ^7.0", "willdurand/negotiation": "^3.1", "winzou/state-machine": "^0.4" }, "require-dev": { "behat/transliterator": "^1.3", "doctrine/orm": "^2.5", - "matthiasnoback/symfony-dependency-injection-test": "^4.2.1", + "matthiasnoback/symfony-dependency-injection-test": "^4.2.1 || ^5.1", "phpspec/phpspec": "^7.3", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "sylius/grid": "^1.7 || ^1.12", - "symfony/serializer": "^5.4 || ^6.4", - "symfony/workflow": "^5.4 || ^6.4", + "sylius/grid": "^1.7 || dev-symfony-7", + "symfony/serializer": "^5.4 || ^6.4 || ^7.0", + "symfony/workflow": "^5.4 || ^6.4 || ^7.0", "twig/twig": "^2.12 || ^3.0" }, "extra": { diff --git a/src/Component/legacy/tests/Symfony/EventListener/AddFormatListenerTest.php b/src/Component/legacy/tests/Symfony/EventListener/AddFormatListenerTest.php index ce3285167..2692ea2b1 100644 --- a/src/Component/legacy/tests/Symfony/EventListener/AddFormatListenerTest.php +++ b/src/Component/legacy/tests/Symfony/EventListener/AddFormatListenerTest.php @@ -20,6 +20,7 @@ use Sylius\Resource\Metadata\HttpOperation; use Sylius\Resource\Metadata\Operation\HttpOperationInitiatorInterface; use Sylius\Resource\Symfony\EventListener\AddFormatListener; +use Symfony\Component\HttpFoundation\HeaderBag; use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Event\RequestEvent; @@ -55,7 +56,7 @@ public function it_sets_format_from_accept_header(): void $this->operationInitiator->initializeOperation($request)->willReturn($operation); $request->attributes = new ParameterBag(); - $request->headers = new ParameterBag(['Accept' => 'application/json']); + $request->headers = new HeaderBag(['Accept' => 'application/json']); $request->getFormat('application/json')->willReturn('json')->shouldBeCalled(); @@ -76,7 +77,7 @@ public function it_sets_format_from_request(): void $this->operationInitiator->initializeOperation($request)->willReturn($operation); $request->attributes = new ParameterBag(['_format' => 'json']); - $request->headers = new ParameterBag(); + $request->headers = new HeaderBag(); $request->getRequestFormat(null)->willReturn('json')->shouldBeCalled(); @@ -97,7 +98,7 @@ public function it_throws_an_exception_when_format_is_not_accepted(): void $this->operationInitiator->initializeOperation($request)->willReturn($operation); $request->attributes = new ParameterBag(['_format' => 'json-ld']); - $request->headers = new ParameterBag(); + $request->headers = new HeaderBag(); $request->getRequestFormat(null)->willReturn('json-ld')->shouldBeCalled(); diff --git a/src/Component/spec/Symfony/Request/RepositoryArgumentResolverSpec.php b/src/Component/spec/Symfony/Request/RepositoryArgumentResolverSpec.php index c6417fae6..1cc796e1b 100644 --- a/src/Component/spec/Symfony/Request/RepositoryArgumentResolverSpec.php +++ b/src/Component/spec/Symfony/Request/RepositoryArgumentResolverSpec.php @@ -34,7 +34,7 @@ function it_gets_arguments_to_sent_to_the_repository( ): void { $request->attributes = $attributes; $request->query = new InputBag([]); - $request->request = new ParameterBag(); + $request->request = new InputBag(); $attributes->all('_route_params')->willReturn(['id' => 'my_id']); @@ -52,7 +52,7 @@ function it_uses_query_params_when_route_params_are_not_matching( ): void { $request->attributes = $attributes; $request->query = new InputBag(['id' => 'my_id']); - $request->request = new ParameterBag(); + $request->request = new InputBag(); $attributes->all('_route_params')->willReturn(['_sylius' => ['resource' => 'app.dummy']]); @@ -70,7 +70,7 @@ function it_uses_request_params_when_route_params_are_not_matching( ): void { $request->attributes = $attributes; $request->query = new InputBag(); - $request->request = new ParameterBag(['id' => 'my_id']); + $request->request = new InputBag(['id' => 'my_id']); $attributes->all('_route_params')->willReturn(['_sylius' => ['resource' => 'app.dummy']]); @@ -88,7 +88,7 @@ function it_encapsulates_arguments_when_the_method_has_only_one_required_array_a ): void { $request->attributes = $attributes; $request->query = new InputBag([]); - $request->request = new ParameterBag(); + $request->request = new InputBag(); $attributes->all('_route_params')->willReturn(['enabled' => 'true', 'author' => 'author@example.com']); @@ -109,7 +109,7 @@ function it_return_array_values_when_method_is_magic( ): void { $request->attributes = $attributes; $request->query = new InputBag(); - $request->request = new ParameterBag(['ids' => ['first_id', 'second_id']]); + $request->request = new InputBag(['ids' => ['first_id', 'second_id']]); $attributes->all('_route_params')->willReturn(['_sylius' => ['resource' => 'app.dummy']]); diff --git a/src/Component/spec/Symfony/Request/State/ProviderSpec.php b/src/Component/spec/Symfony/Request/State/ProviderSpec.php index 22d5fca3c..05d3fbb89 100644 --- a/src/Component/spec/Symfony/Request/State/ProviderSpec.php +++ b/src/Component/spec/Symfony/Request/State/ProviderSpec.php @@ -50,7 +50,7 @@ function it_calls_repository_as_callable( $request->attributes = new ParameterBag(['_route_params' => ['id' => 'my_id']]); $request->query = new InputBag([]); - $request->request = new ParameterBag(); + $request->request = new InputBag(); $response = $this->provide($operation, new Context(new RequestOption($request->getWrappedObject()))); $response->shouldHaveType(\stdClass::class); @@ -70,7 +70,7 @@ function it_calls_repository_as_string( $request->attributes = new ParameterBag(['_route_params' => ['id' => 'my_id', '_sylius' => ['resource' => 'app.dummy']]]); $request->query = new InputBag([]); - $request->request = new ParameterBag(); + $request->request = new InputBag(); $locator->has('App\Repository')->willReturn(true); $locator->get('App\Repository')->willReturn($repository); @@ -91,7 +91,7 @@ function it_calls_create_paginator_by_default_on_collection_operations( $request->attributes = new ParameterBag(['_route_params' => ['id' => 'my_id', '_sylius' => ['resource' => 'app.dummy']]]); $request->query = new InputBag([]); - $request->request = new ParameterBag(); + $request->request = new InputBag(); $locator->has('App\Repository')->willReturn(true); $locator->get('App\Repository')->willReturn($repository); @@ -113,7 +113,7 @@ function it_sets_current_page_from_request_when_data_is_a_paginator( $request->attributes = new ParameterBag(['_route_params' => ['id' => 'my_id', '_sylius' => ['resource' => 'app.dummy']]]); $request->query = new InputBag(['page' => 42]); - $request->request = new ParameterBag(); + $request->request = new InputBag(); $locator->has('App\Repository')->willReturn(true); $locator->get('App\Repository')->willReturn($repository); @@ -139,7 +139,7 @@ function it_calls_repository_as_string_with_specific_repository_method( $request->attributes = new ParameterBag(['_route_params' => ['id' => 'my_id', '_sylius' => ['resource' => 'app.dummy']]]); $request->query = new InputBag([]); - $request->request = new ParameterBag(); + $request->request = new InputBag(); $locator->has('App\Repository')->willReturn(true); $locator->get('App\Repository')->willReturn($repository); diff --git a/tests/Application/config/bundles.php b/tests/Application/config/bundles.php index 194769143..1eb88eee0 100644 --- a/tests/Application/config/bundles.php +++ b/tests/Application/config/bundles.php @@ -34,7 +34,7 @@ TwigBundle::class => ['all' => true, 'test_without_twig' => false], FOSRestBundle::class => ['all' => true, 'test_without_fosrest' => false], JMSSerializerBundle::class => ['all' => true, 'test_without_fosrest' => false], - BazingaHateoasBundle::class => ['all' => true, 'test_without_fosrest' => false], + BazingaHateoasBundle::class => ['all' => true, 'test_without_hateoas' => false, 'test_without_fosrest' => false, 'test_with_attributes' => false], FidryAliceDataFixturesBundle::class => ['all' => true], NelmioAliceBundle::class => ['all' => true], winzouStateMachineBundle::class => ['all' => true, 'test_without_state_machine' => false], diff --git a/tests/Application/config/packages/security.yaml b/tests/Application/config/packages/security.yaml index 789a9ac14..367af25a5 100644 --- a/tests/Application/config/packages/security.yaml +++ b/tests/Application/config/packages/security.yaml @@ -1,5 +1,4 @@ security: - enable_authenticator_manager: true # https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords password_hashers: Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto' diff --git a/tests/Application/config/packages/test_without_fosrest/framework.yaml b/tests/Application/config/packages/test_without_fosrest/framework.yaml new file mode 100644 index 000000000..cf8f08807 --- /dev/null +++ b/tests/Application/config/packages/test_without_fosrest/framework.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: '../test/framework.yaml' } diff --git a/tests/Application/config/packages/test_without_fosrest/grids.yaml b/tests/Application/config/packages/test_without_fosrest/grids.yaml new file mode 100644 index 000000000..c9750ae87 --- /dev/null +++ b/tests/Application/config/packages/test_without_fosrest/grids.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: '../test/grids.yaml' } diff --git a/tests/Application/config/packages/test_without_fosrest/sylius_grid.yaml b/tests/Application/config/packages/test_without_fosrest/sylius_grid.yaml new file mode 100644 index 000000000..b702c5814 --- /dev/null +++ b/tests/Application/config/packages/test_without_fosrest/sylius_grid.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: '../test/sylius_grid.yaml' } diff --git a/tests/Application/config/packages/test_without_fosrest/winzou_state_machine.yaml b/tests/Application/config/packages/test_without_fosrest/winzou_state_machine.yaml new file mode 100644 index 000000000..5854ae021 --- /dev/null +++ b/tests/Application/config/packages/test_without_fosrest/winzou_state_machine.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: '../test/winzou_state_machine.yaml' } diff --git a/tests/Application/config/packages/test_without_hateoas/fos_rest.yaml b/tests/Application/config/packages/test_without_hateoas/fos_rest.yaml new file mode 100644 index 000000000..dbd0f9f27 --- /dev/null +++ b/tests/Application/config/packages/test_without_hateoas/fos_rest.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: '../test/fos_rest.yaml' } diff --git a/tests/Application/config/packages/test_without_hateoas/framework.yaml b/tests/Application/config/packages/test_without_hateoas/framework.yaml new file mode 100644 index 000000000..cf8f08807 --- /dev/null +++ b/tests/Application/config/packages/test_without_hateoas/framework.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: '../test/framework.yaml' } diff --git a/tests/Application/config/packages/test_without_hateoas/grids.yaml b/tests/Application/config/packages/test_without_hateoas/grids.yaml new file mode 100644 index 000000000..c9750ae87 --- /dev/null +++ b/tests/Application/config/packages/test_without_hateoas/grids.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: '../test/grids.yaml' } diff --git a/tests/Application/config/packages/test_without_hateoas/jms_serializer.yaml b/tests/Application/config/packages/test_without_hateoas/jms_serializer.yaml new file mode 100644 index 000000000..e236b51c9 --- /dev/null +++ b/tests/Application/config/packages/test_without_hateoas/jms_serializer.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: '../test/jms_serializer.yaml' } diff --git a/tests/Application/config/packages/test_without_hateoas/sylius_grid.yaml b/tests/Application/config/packages/test_without_hateoas/sylius_grid.yaml new file mode 100644 index 000000000..b702c5814 --- /dev/null +++ b/tests/Application/config/packages/test_without_hateoas/sylius_grid.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: '../test/sylius_grid.yaml' } diff --git a/tests/Application/config/packages/test_without_hateoas/twig.yaml b/tests/Application/config/packages/test_without_hateoas/twig.yaml new file mode 100644 index 000000000..7a00b552f --- /dev/null +++ b/tests/Application/config/packages/test_without_hateoas/twig.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: '../test/twig.yaml' } diff --git a/tests/Application/config/packages/test_without_hateoas/winzou_state_machine.yaml b/tests/Application/config/packages/test_without_hateoas/winzou_state_machine.yaml new file mode 100644 index 000000000..5854ae021 --- /dev/null +++ b/tests/Application/config/packages/test_without_hateoas/winzou_state_machine.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: '../test/winzou_state_machine.yaml' } diff --git a/tests/Application/config/services.yaml b/tests/Application/config/services.yaml index 5fa061e74..e688256a7 100644 --- a/tests/Application/config/services.yaml +++ b/tests/Application/config/services.yaml @@ -70,14 +70,22 @@ services: - '%app.model.book_translation.class%' tags: ['form.type'] - Gedmo\Sortable\SortableListener: - calls: - - - setAnnotationReader: ['@?annotation_reader'] + gedmo_doctrine_extensions.mapping.driver.attribute: + class: Gedmo\Mapping\Driver\AttributeReader + public: false + + gedmo.listener.sortable: + class: Gedmo\Sortable\SortableListener tags: - - - name: doctrine.event_subscriber - connection: default + - { name: doctrine.event_listener, event: 'onFlush' } + - { name: doctrine.event_listener, event: 'loadClassMetadata' } + - { name: doctrine.event_listener, event: 'prePersist' } + - { name: doctrine.event_listener, event: 'postPersist' } + - { name: doctrine.event_listener, event: 'preUpdate' } + - { name: doctrine.event_listener, event: 'postRemove' } + - { name: doctrine.event_listener, event: 'postFlush' } + calls: + - [ setAnnotationReader, [ "@gedmo_doctrine_extensions.mapping.driver.attribute" ] ] App\Repository\ComicBookRepository: null App\Repository\LegacyBookRepository: null diff --git a/tests/Application/config/sylius/resources.yaml b/tests/Application/config/sylius/resources.yaml index d5dec35e1..4e6b60b9d 100644 --- a/tests/Application/config/sylius/resources.yaml +++ b/tests/Application/config/sylius/resources.yaml @@ -50,3 +50,13 @@ sylius_resource: classes: model: App\Entity\PullRequest form: App\Form\Type\PullRequestType + + app.zone: + classes: + model: App\Entity\Zone\Zone + interface: App\Entity\Zone\ZoneInterface + + app.zone_member: + classes: + model: App\Entity\Zone\ZoneMember + interface: App\Entity\Zone\ZoneMemberInterface diff --git a/tests/Application/src/Entity/Zone/Zone.php b/tests/Application/src/Entity/Zone/Zone.php new file mode 100644 index 000000000..6b2c25513 --- /dev/null +++ b/tests/Application/src/Entity/Zone/Zone.php @@ -0,0 +1,40 @@ +id; + } +} diff --git a/tests/Application/src/Entity/Zone/ZoneInterface.php b/tests/Application/src/Entity/Zone/ZoneInterface.php new file mode 100644 index 000000000..a45f62cc5 --- /dev/null +++ b/tests/Application/src/Entity/Zone/ZoneInterface.php @@ -0,0 +1,20 @@ +id; + } +} diff --git a/tests/Application/src/Entity/Zone/ZoneMemberInterface.php b/tests/Application/src/Entity/Zone/ZoneMemberInterface.php new file mode 100644 index 000000000..54460a935 --- /dev/null +++ b/tests/Application/src/Entity/Zone/ZoneMemberInterface.php @@ -0,0 +1,20 @@ +registerForAutoconfiguration(CommandHandlerInterface::class) ->addTag('messenger.message_handler', ['bus' => 'command.bus']) ; + + if (self::MAJOR_VERSION < 7) { + $container->prependExtensionConfig('security', [ + 'enable_authenticator_manager' => true, + ]); + } } } diff --git a/tests/Application/src/Subscription/Entity/Subscription.php b/tests/Application/src/Subscription/Entity/Subscription.php index 29b1af116..1e2aa6e50 100644 --- a/tests/Application/src/Subscription/Entity/Subscription.php +++ b/tests/Application/src/Subscription/Entity/Subscription.php @@ -41,11 +41,12 @@ #[Update] #[Delete] #[BulkDelete] -#[ApplyStateMachineTransition(stateMachineTransition: 'accept')] -#[ApplyStateMachineTransition(stateMachineTransition: 'reject')] +#[ApplyStateMachineTransition(stateMachineTransition: 'accept', stateMachineGraph: 'subscription')] +#[ApplyStateMachineTransition(stateMachineTransition: 'reject', stateMachineGraph: 'subscription')] #[BulkUpdate( shortName: 'bulk_accept', stateMachineTransition: 'accept', + stateMachineGraph: 'subscription', )] #[Show( template: 'subscription/show.html.twig', diff --git a/tests/Application/src/Tests/Controller/BookApiTest.php b/tests/Application/src/Tests/Controller/BookApiTest.php index ef9c23950..cfec84916 100644 --- a/tests/Application/src/Tests/Controller/BookApiTest.php +++ b/tests/Application/src/Tests/Controller/BookApiTest.php @@ -23,6 +23,8 @@ class BookApiTest extends JsonApiTestCase */ public function it_allows_creating_a_book() { + $this->markAsSkippedIfNecessary(); + $data = <<markAsSkippedIfNecessary(); + $objects = $this->loadFixturesFromFile('books.yml'); $this->client->request('GET', '/books/' . $objects['book1']->getId()); @@ -115,6 +119,8 @@ public function it_allows_showing_a_book() */ public function it_allows_indexing_books() { + $this->markAsSkippedIfNecessary(); + $this->loadFixturesFromFile('books.yml'); $this->client->request('GET', '/books/'); @@ -127,6 +133,8 @@ public function it_allows_indexing_books() */ public function it_allows_paginating_the_index_of_books() { + $this->markAsSkippedIfNecessary(); + $this->loadFixturesFromFile('more_books.yml'); $this->client->request('GET', '/books/', ['page' => 2]); @@ -139,6 +147,8 @@ public function it_allows_paginating_the_index_of_books() */ public function it_does_not_allow_showing_resource_if_it_not_exists() { + $this->markAsSkippedIfNecessary(); + $this->loadFixturesFromFile('books.yml'); $this->client->request('GET', '/books/3'); @@ -151,6 +161,8 @@ public function it_does_not_allow_showing_resource_if_it_not_exists() */ public function it_does_not_apply_sorting_for_un_existing_field() { + $this->markAsSkippedIfNecessary(); + $this->loadFixturesFromFile('more_books.yml'); $this->client->request('GET', '/sortable-books/', ['sorting' => ['name' => 'DESC']]); @@ -164,6 +176,8 @@ public function it_does_not_apply_sorting_for_un_existing_field() */ public function it_does_not_apply_filtering_for_un_existing_field() { + $this->markAsSkippedIfNecessary(); + $this->loadFixturesFromFile('more_books.yml'); $this->client->request('GET', '/filterable-books/', ['criteria' => ['name' => 'John']]); @@ -177,6 +191,8 @@ public function it_does_not_apply_filtering_for_un_existing_field() */ public function it_applies_sorting_for_existing_field() { + $this->markAsSkippedIfNecessary(); + $this->loadFixturesFromFile('more_books.yml'); $this->client->request('GET', '/sortable-books/', ['sorting' => ['id' => 'DESC']]); @@ -190,6 +206,8 @@ public function it_applies_sorting_for_existing_field() */ public function it_applies_filtering_for_existing_field() { + $this->markAsSkippedIfNecessary(); + $this->loadFixturesFromFile('more_books.yml'); $this->client->request('GET', '/filterable-books/', ['criteria' => ['author' => 'J.R.R. Tolkien']]); @@ -203,6 +221,8 @@ public function it_applies_filtering_for_existing_field() */ public function it_allows_creating_a_book_via_custom_factory() { + $this->markAsSkippedIfNecessary(); + $data = <<markAsSkippedIfNecessary(); + $this->loadFixturesFromFile('books.yml'); $this->client->request('GET', '/find-custom-books'); @@ -237,10 +259,19 @@ public function it_allows_indexing_books_via_custom_repository(): void */ public function it_allows_showing_a_book_via_custom_repository() { + $this->markAsSkippedIfNecessary(); + $this->loadFixturesFromFile('books.yml'); $this->client->request('GET', '/find-custom-book'); $response = $this->client->getResponse(); $this->assertResponse($response, 'books/show_response'); } + + private function markAsSkippedIfNecessary(): void + { + if ('test_without_hateoas' === self::$sharedKernel->getEnvironment()) { + $this->markTestSkipped(); + } + } } diff --git a/tests/Application/src/Tests/Controller/ComicBookApiTest.php b/tests/Application/src/Tests/Controller/ComicBookApiTest.php index d4ece7e29..7a5286a79 100644 --- a/tests/Application/src/Tests/Controller/ComicBookApiTest.php +++ b/tests/Application/src/Tests/Controller/ComicBookApiTest.php @@ -44,6 +44,8 @@ public function it_allows_creating_a_comic_book() */ public function it_allows_versioned_creating_a_comic_book() { + $this->markAsSkippedIfNecessary(); + $data = <<markAsSkippedIfNecessary(); + $objects = $this->loadFixturesFromFile('comic_books.yml'); $this->client->request('GET', '/v1.2/comic-books/' . $objects['comic-book1']->getId()); @@ -146,6 +150,8 @@ public function it_allows_versioning_of_a_showing_comic_book_serialization() */ public function it_allows_indexing_of_comic_books() { + $this->markAsSkippedIfNecessary(); + $this->loadFixturesFromFile('comic_books.yml'); $this->client->request('GET', '/v1/comic-books/'); @@ -158,6 +164,8 @@ public function it_allows_indexing_of_comic_books() */ public function it_allows_versioned_indexing_of_comic_books() { + $this->markAsSkippedIfNecessary(); + $this->loadFixturesFromFile('comic_books.yml'); $this->client->request('GET', '/v1.2/comic-books/'); @@ -176,4 +184,11 @@ public function it_does_not_allow_showing_resource_if_it_does_not_exist() $response = $this->client->getResponse(); $this->assertResponseCode($response, Response::HTTP_NOT_FOUND); } + + private function markAsSkippedIfNecessary(): void + { + if ('test_without_hateoas' === self::$sharedKernel->getEnvironment()) { + $this->markTestSkipped(); + } + } }