From 4e8929794d0cd163b0093cf7f4eaf16e5e76beee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Fr=C3=A9mont?= Date: Fri, 17 Nov 2023 09:25:47 +0100 Subject: [PATCH 1/9] Phpunit tests for Symfony flash listener --- .../EventListener/FlashListenerTest.php | 186 ++++++++++++++++++ .../EventListener/FlashListenerSpec.php | 179 ----------------- 2 files changed, 186 insertions(+), 179 deletions(-) create mode 100644 src/Component/Tests/Symfony/EventListener/FlashListenerTest.php delete mode 100644 src/Component/tests/spec/Symfony/EventListener/FlashListenerSpec.php diff --git a/src/Component/Tests/Symfony/EventListener/FlashListenerTest.php b/src/Component/Tests/Symfony/EventListener/FlashListenerTest.php new file mode 100644 index 000000000..1c1d160b5 --- /dev/null +++ b/src/Component/Tests/Symfony/EventListener/FlashListenerTest.php @@ -0,0 +1,186 @@ +operationInitiator = $this->prophesize(HttpOperationInitiatorInterface::class); + $this->requestContextInitiator = $this->prophesize(RequestContextInitiatorInterface::class); + $this->flashHelper = $this->prophesize(FlashHelperInterface::class); + + $this->flashListener = new FlashListener( + $this->operationInitiator->reveal(), + $this->requestContextInitiator->reveal(), + $this->flashHelper->reveal(), + ); + } + + /** @test */ + public function it_adds_flash(): void + { + $kernel = $this->prophesize(KernelInterface::class); + $request = $this->prophesize(Request::class); + $attributes = $this->prophesize(ParameterBag::class); + $operation = $this->prophesize(HttpOperation::class); + + $event = new ViewEvent( + $kernel->reveal(), + $request->reveal(), + HttpKernelInterface::MAIN_REQUEST, + ['foo' => 'fighters'], + ); + + $request->isMethodSafe()->willReturn(false); + + $request->attributes = $attributes; + + $attributes->getBoolean('is_valid', true)->willReturn(true); + + $this->operationInitiator->initializeOperation($request)->willReturn($operation); + + $context = new Context(); + + $this->requestContextInitiator->initializeContext($request)->willReturn($context); + + $this->flashHelper->addSuccessFlash($operation, $context)->shouldBeCalled(); + + $this->flashListener->onKernelView($event); + } + + /** @test */ + public function it_does_nothing_when_controller_result_is_a_response(): void + { + $kernel = $this->prophesize(KernelInterface::class); + $request = $this->prophesize(Request::class); + $attributes = $this->prophesize(ParameterBag::class); + $operation = $this->prophesize(HttpOperation::class); + $response = $this->prophesize(Response::class); + + $event = new ViewEvent( + $kernel->reveal(), + $request->reveal(), + HttpKernelInterface::MAIN_REQUEST, + $response->reveal(), + ); + + $request->isMethodSafe()->willReturn(false)->shouldNotBeCalled(); + + $request->attributes = $attributes; + + $attributes->getBoolean('is_valid', true)->willReturn(true)->shouldNotBeCalled(); + + $this->operationInitiator->initializeOperation($request)->willReturn($operation); + + $context = new Context(); + + $this->requestContextInitiator->initializeContext($request)->willReturn($context); + + $this->flashHelper->addSuccessFlash($operation, $context)->shouldNotBeCalled(); + + $this->flashListener->onKernelView($event); + } + + /** @test */ + public function it_does_nothing_when_method_is_safe(): void + { + $kernel = $this->prophesize(KernelInterface::class); + $request = $this->prophesize(Request::class); + $attributes = $this->prophesize(ParameterBag::class); + $operation = $this->prophesize(HttpOperation::class); + + $event = new ViewEvent( + $kernel->reveal(), + $request->reveal(), + HttpKernelInterface::MAIN_REQUEST, + ['foo' => 'fighters'], + ); + + $request->isMethodSafe()->willReturn(true)->shouldBeCalled(); + + $request->attributes = $attributes; + + $attributes->getBoolean('is_valid', true)->willReturn(true); + + $this->operationInitiator->initializeOperation($request)->willReturn($operation); + + $context = new Context(); + + $this->requestContextInitiator->initializeContext($request)->willReturn($context); + + $this->flashHelper->addSuccessFlash($operation, $context)->shouldNotBeCalled(); + + $this->flashListener->onKernelView($event); + } + + /** @test */ + public function it_does_nothing_when_validation_has_failed(): void + { + $kernel = $this->prophesize(KernelInterface::class); + $request = $this->prophesize(Request::class); + $attributes = $this->prophesize(ParameterBag::class); + $operation = $this->prophesize(HttpOperation::class); + + $event = new ViewEvent( + $kernel->reveal(), + $request->reveal(), + HttpKernelInterface::MAIN_REQUEST, + ['foo' => 'fighters'], + ); + + $request->isMethodSafe()->willReturn(false); + + $request->attributes = $attributes; + + $attributes->getBoolean('is_valid', true)->willReturn(false)->shouldBeCalled(); + + $this->operationInitiator->initializeOperation($request)->willReturn($operation); + + $context = new Context(); + + $this->requestContextInitiator->initializeContext($request)->willReturn($context); + + $this->flashHelper->addSuccessFlash($operation, $context)->shouldNotBeCalled(); + + $this->flashListener->onKernelView($event); + } +} diff --git a/src/Component/tests/spec/Symfony/EventListener/FlashListenerSpec.php b/src/Component/tests/spec/Symfony/EventListener/FlashListenerSpec.php deleted file mode 100644 index bf9f26edf..000000000 --- a/src/Component/tests/spec/Symfony/EventListener/FlashListenerSpec.php +++ /dev/null @@ -1,179 +0,0 @@ -beConstructedWith($operationInitiator, $requestContextInitiator, $flashHelper); - } - - function it_is_initializable(): void - { - $this->shouldHaveType(FlashListener::class); - } - - function it_adds_flash( - KernelInterface $kernel, - Request $request, - ParameterBag $attributes, - HttpOperationInitiatorInterface $operationInitiator, - RequestContextInitiatorInterface $requestContextInitiator, - FlashHelperInterface $flashHelper, - HttpOperation $operation, - ): void { - $event = new ViewEvent( - $kernel->getWrappedObject(), - $request->getWrappedObject(), - HttpKernelInterface::MAIN_REQUEST, - ['foo' => 'fighters'], - ); - - $request->isMethodSafe()->willReturn(false); - - $request->attributes = $attributes; - - $attributes->getBoolean('is_valid', true)->willReturn(true); - - $operationInitiator->initializeOperation($request)->willReturn($operation); - - $context = new Context(); - - $requestContextInitiator->initializeContext($request)->willReturn($context); - - $flashHelper->addSuccessFlash($operation, $context)->shouldBeCalled(); - - $this->onKernelView($event); - } - - function it_does_nothing_when_controller_result_is_a_response( - KernelInterface $kernel, - Request $request, - ParameterBag $attributes, - HttpOperationInitiatorInterface $operationInitiator, - RequestContextInitiatorInterface $requestContextInitiator, - FlashHelperInterface $flashHelper, - Response $response, - HttpOperation $operation, - ): void { - $event = new ViewEvent( - $kernel->getWrappedObject(), - $request->getWrappedObject(), - HttpKernelInterface::MAIN_REQUEST, - $response->getWrappedObject(), - ); - - $request->isMethodSafe()->willReturn(false)->shouldNotBeCalled(); - - $request->attributes = $attributes; - - $attributes->getBoolean('is_valid', true)->willReturn(true)->shouldNotBeCalled(); - - $operationInitiator->initializeOperation($request)->willReturn($operation); - - $context = new Context(); - - $requestContextInitiator->initializeContext($request)->willReturn($context); - - $flashHelper->addSuccessFlash($operation, $context)->shouldNotBeCalled(); - - $this->onKernelView($event); - } - - function it_does_nothing_when_method_is_safe( - KernelInterface $kernel, - Request $request, - ParameterBag $attributes, - HttpOperationInitiatorInterface $operationInitiator, - RequestContextInitiatorInterface $requestContextInitiator, - FlashHelperInterface $flashHelper, - HttpOperation $operation, - ): void { - $event = new ViewEvent( - $kernel->getWrappedObject(), - $request->getWrappedObject(), - HttpKernelInterface::MAIN_REQUEST, - ['foo' => 'fighters'], - ); - - $request->isMethodSafe()->willReturn(true)->shouldBeCalled(); - - $request->attributes = $attributes; - - $attributes->getBoolean('is_valid', true)->willReturn(true); - - $operationInitiator->initializeOperation($request)->willReturn($operation); - - $context = new Context(); - - $requestContextInitiator->initializeContext($request)->willReturn($context); - - $flashHelper->addSuccessFlash($operation, $context)->shouldNotBeCalled(); - - $this->onKernelView($event); - } - - function it_does_nothing_when_validation_has_failed( - KernelInterface $kernel, - Request $request, - ParameterBag $attributes, - HttpOperationInitiatorInterface $operationInitiator, - ResourceMetadataCollectionFactoryInterface $resourceMetadataCollectionFactory, - RequestContextInitiatorInterface $requestContextInitiator, - FlashHelperInterface $flashHelper, - HttpOperation $operation, - ): void { - $event = new ViewEvent( - $kernel->getWrappedObject(), - $request->getWrappedObject(), - HttpKernelInterface::MAIN_REQUEST, - ['foo' => 'fighters'], - ); - - $request->isMethodSafe()->willReturn(false); - - $request->attributes = $attributes; - - $attributes->getBoolean('is_valid', true)->willReturn(false)->shouldBeCalled(); - - $operationInitiator->initializeOperation($request)->willReturn($operation); - - $context = new Context(); - - $requestContextInitiator->initializeContext($request)->willReturn($context); - - $flashHelper->addSuccessFlash($operation, $context)->shouldNotBeCalled(); - - $this->onKernelView($event); - } -} From ed1b756f6a7ea8b94c75834b34c0ae5e2dad59b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Fr=C3=A9mont?= Date: Tue, 21 Nov 2023 11:11:02 +0100 Subject: [PATCH 2/9] Fix coding standard --- src/Component/Tests/Symfony/EventListener/FlashListenerTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Component/Tests/Symfony/EventListener/FlashListenerTest.php b/src/Component/Tests/Symfony/EventListener/FlashListenerTest.php index 1c1d160b5..53a7b7317 100644 --- a/src/Component/Tests/Symfony/EventListener/FlashListenerTest.php +++ b/src/Component/Tests/Symfony/EventListener/FlashListenerTest.php @@ -21,7 +21,6 @@ use Sylius\Resource\Context\Initiator\RequestContextInitiatorInterface; use Sylius\Resource\Metadata\HttpOperation; use Sylius\Resource\Metadata\Operation\HttpOperationInitiatorInterface; -use Sylius\Resource\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface; use Sylius\Resource\Symfony\EventListener\FlashListener; use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request; From 4740788ca8063e0eebf70045deea39889d8837b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Fr=C3=A9mont?= Date: Tue, 21 Nov 2023 11:17:31 +0100 Subject: [PATCH 3/9] Fix PHPUnit tests --- src/Component/Tests/Symfony/EventListener/FlashListenerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Component/Tests/Symfony/EventListener/FlashListenerTest.php b/src/Component/Tests/Symfony/EventListener/FlashListenerTest.php index 53a7b7317..70348470d 100644 --- a/src/Component/Tests/Symfony/EventListener/FlashListenerTest.php +++ b/src/Component/Tests/Symfony/EventListener/FlashListenerTest.php @@ -16,12 +16,12 @@ use PHPUnit\Framework\TestCase; use Prophecy\PhpUnit\ProphecyTrait; use Prophecy\Prophecy\ObjectProphecy; -use Sylius\Component\Resource\Symfony\Session\Flash\FlashHelperInterface; use Sylius\Resource\Context\Context; use Sylius\Resource\Context\Initiator\RequestContextInitiatorInterface; use Sylius\Resource\Metadata\HttpOperation; use Sylius\Resource\Metadata\Operation\HttpOperationInitiatorInterface; use Sylius\Resource\Symfony\EventListener\FlashListener; +use Sylius\Resource\Symfony\Session\Flash\FlashHelperInterface; use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; From d497e2e3534d0188eda938cb025576062f8dbba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Fr=C3=A9mont?= Date: Tue, 21 Nov 2023 11:25:37 +0100 Subject: [PATCH 4/9] Init flash processor --- .../State/Processor/FlashProcessorTest.php | 138 ++++++++++++++++++ src/Component/composer.json | 1 + .../src/State/Processor/FlashProcessor.php | 52 +++++++ 3 files changed, 191 insertions(+) create mode 100644 src/Component/Tests/State/Processor/FlashProcessorTest.php create mode 100644 src/Component/src/State/Processor/FlashProcessor.php diff --git a/src/Component/Tests/State/Processor/FlashProcessorTest.php b/src/Component/Tests/State/Processor/FlashProcessorTest.php new file mode 100644 index 000000000..573348cb8 --- /dev/null +++ b/src/Component/Tests/State/Processor/FlashProcessorTest.php @@ -0,0 +1,138 @@ +decorated = $this->prophesize(ProcessorInterface::class); + $this->flashHelper = $this->prophesize(FlashHelperInterface::class); + + $this->flashProcessor = new FlashProcessor( + $this->decorated->reveal(), + $this->flashHelper->reveal(), + ); + } + + /** @test */ + public function it_adds_flash(): void + { + $request = $this->prophesize(Request::class); + $attributes = $this->prophesize(ParameterBag::class); + $operation = $this->prophesize(HttpOperation::class); + + $request->isMethodSafe()->willReturn(false); + + $request->attributes = $attributes; + + $attributes->getBoolean('is_valid', true)->willReturn(true); + + $context = new Context(new RequestOption($request->reveal())); + + $this->decorated->process(['foo' => 'fighters'], $operation, $context)->willReturn(['foo' => 'fighters'])->shouldBeCalled(); + + $this->flashHelper->addSuccessFlash($operation, $context)->shouldBeCalled(); + + $this->flashProcessor->process(['foo' => 'fighters'], $operation->reveal(), $context); + } + + /** @test */ + public function it_does_nothing_when_controller_result_is_a_response(): void + { + $request = $this->prophesize(Request::class); + $attributes = $this->prophesize(ParameterBag::class); + $operation = $this->prophesize(HttpOperation::class); + $response = $this->prophesize(Response::class); + + $request->isMethodSafe()->willReturn(false)->shouldNotBeCalled(); + + $request->attributes = $attributes; + + $attributes->getBoolean('is_valid', true)->willReturn(true)->shouldNotBeCalled(); + + $context = new Context(new RequestOption($request->reveal())); + + $this->decorated->process($response, $operation, $context)->willReturn($response)->shouldBeCalled(); + + $this->flashHelper->addSuccessFlash($operation, $context)->shouldNotBeCalled(); + + $this->flashProcessor->process($response->reveal(), $operation->reveal(), $context); + } + + /** @test */ + public function it_does_nothing_when_method_is_safe(): void + { + $request = $this->prophesize(Request::class); + $attributes = $this->prophesize(ParameterBag::class); + $operation = $this->prophesize(HttpOperation::class); + + $request->isMethodSafe()->willReturn(true)->shouldBeCalled(); + + $request->attributes = $attributes; + + $attributes->getBoolean('is_valid', true)->willReturn(true); + + $context = new Context(new RequestOption($request->reveal())); + + $this->decorated->process(['foo' => 'fighters'], $operation, $context)->willReturn(['foo' => 'fighters'])->shouldBeCalled(); + + $this->flashHelper->addSuccessFlash($operation, $context)->shouldNotBeCalled(); + + $this->flashProcessor->process(['foo' => 'fighters'], $operation->reveal(), $context); + } + + /** @test */ + public function it_does_nothing_when_validation_has_failed(): void + { + $request = $this->prophesize(Request::class); + $attributes = $this->prophesize(ParameterBag::class); + $operation = $this->prophesize(HttpOperation::class); + + $request->isMethodSafe()->willReturn(false); + + $request->attributes = $attributes; + + $attributes->getBoolean('is_valid', true)->willReturn(false)->shouldBeCalled(); + + $context = new Context(new RequestOption($request->reveal())); + + $this->decorated->process(['foo' => 'fighters'], $operation, $context)->willReturn(['foo' => 'fighters'])->shouldBeCalled(); + + $this->flashHelper->addSuccessFlash($operation, $context)->shouldNotBeCalled(); + + $this->flashProcessor->process(['foo' => 'fighters'], $operation->reveal(), $context); + } +} diff --git a/src/Component/composer.json b/src/Component/composer.json index 935da2620..ecb129c7c 100644 --- a/src/Component/composer.json +++ b/src/Component/composer.json @@ -50,6 +50,7 @@ "behat/transliterator": "^1.3", "doctrine/orm": "^2.5", "phpspec/phpspec": "^7.3", + "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", "sylius/grid": "^1.7 || ^1.12", "symfony/serializer": "^5.4 || ^6.0", diff --git a/src/Component/src/State/Processor/FlashProcessor.php b/src/Component/src/State/Processor/FlashProcessor.php new file mode 100644 index 000000000..cadf7f329 --- /dev/null +++ b/src/Component/src/State/Processor/FlashProcessor.php @@ -0,0 +1,52 @@ +decorated->process($data, $operation, $context); + $request = $context->get(RequestOption::class)?->request(); + + if (null === $request) { + return $data; + } + + if ( + $data instanceof Response || + $request->isMethodSafe() || + !$request->attributes->getBoolean('is_valid', true) + ) { + return $data; + } + + $this->flashHelper->addSuccessFlash($operation, $context); + + return $data; + } +} From 28876a4ab848da680c909bb27b52526731245086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Fr=C3=A9mont?= Date: Tue, 21 Nov 2023 11:28:52 +0100 Subject: [PATCH 5/9] Fix coding standard --- src/Component/Tests/State/Processor/FlashProcessorTest.php | 4 ++-- src/Component/src/State/Processor/FlashProcessor.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Component/Tests/State/Processor/FlashProcessorTest.php b/src/Component/Tests/State/Processor/FlashProcessorTest.php index 573348cb8..488cf8a1b 100644 --- a/src/Component/Tests/State/Processor/FlashProcessorTest.php +++ b/src/Component/Tests/State/Processor/FlashProcessorTest.php @@ -16,12 +16,12 @@ use PHPUnit\Framework\TestCase; use Prophecy\PhpUnit\ProphecyTrait; use Prophecy\Prophecy\ObjectProphecy; -use Sylius\Resource\State\Processor\FlashProcessor; -use Sylius\Resource\Symfony\Session\Flash\FlashHelperInterface; use Sylius\Resource\Context\Context; use Sylius\Resource\Context\Option\RequestOption; use Sylius\Resource\Metadata\HttpOperation; +use Sylius\Resource\State\Processor\FlashProcessor; use Sylius\Resource\State\ProcessorInterface; +use Sylius\Resource\Symfony\Session\Flash\FlashHelperInterface; use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; diff --git a/src/Component/src/State/Processor/FlashProcessor.php b/src/Component/src/State/Processor/FlashProcessor.php index cadf7f329..156ab1e5d 100644 --- a/src/Component/src/State/Processor/FlashProcessor.php +++ b/src/Component/src/State/Processor/FlashProcessor.php @@ -13,11 +13,11 @@ namespace Sylius\Resource\State\Processor; -use Sylius\Resource\Symfony\Session\Flash\FlashHelperInterface; use Sylius\Resource\Context\Context; use Sylius\Resource\Context\Option\RequestOption; use Sylius\Resource\Metadata\Operation; use Sylius\Resource\State\ProcessorInterface; +use Sylius\Resource\Symfony\Session\Flash\FlashHelperInterface; use Symfony\Component\HttpFoundation\Response; final class FlashProcessor implements ProcessorInterface From 1a7dcaf319bd5b8a37f51d3329507f2c8fbfcb6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Fr=C3=A9mont?= Date: Tue, 21 Nov 2023 11:33:20 +0100 Subject: [PATCH 6/9] Phpunit tests for Symfony respond listener --- .../EventListener/RespondListenerTest.php | 122 ++++++++++++++++++ .../EventListener/RespondListenerSpec.php | 112 ---------------- 2 files changed, 122 insertions(+), 112 deletions(-) create mode 100644 src/Component/Tests/Symfony/EventListener/RespondListenerTest.php delete mode 100644 src/Component/tests/spec/Symfony/EventListener/RespondListenerSpec.php diff --git a/src/Component/Tests/Symfony/EventListener/RespondListenerTest.php b/src/Component/Tests/Symfony/EventListener/RespondListenerTest.php new file mode 100644 index 000000000..5aaa138a5 --- /dev/null +++ b/src/Component/Tests/Symfony/EventListener/RespondListenerTest.php @@ -0,0 +1,122 @@ +operationInitiator = $this->prophesize(HttpOperationInitiatorInterface::class); + $this->contextInitiator = $this->prophesize(RequestContextInitiatorInterface::class); + $this->responder = $this->prophesize(ResponderInterface::class); + + $this->respondListener = new RespondListener( + $this->operationInitiator->reveal(), + $this->contextInitiator->reveal(), + $this->responder->reveal(), + ); + } + + /** @test */ + public function it_sets_a_response_on_event(): void + { + $kernel = $this->prophesize(HttpKernelInterface::class); + $request = $this->prophesize(Request::class); + $response = $this->prophesize(Response::class); + $attributes = $this->prophesize(ParameterBag::class); + $operation = $this->prophesize(HttpOperation::class); + + $event = new ViewEvent( + $kernel->reveal(), + $request->reveal(), + HttpKernelInterface::MAIN_REQUEST, + ['foo' => 'fighters'], + ); + + $context = new Context(); + + $this->contextInitiator->initializeContext($request)->willReturn($context); + $this->operationInitiator->initializeOperation($request)->willReturn($operation); + + $request->attributes = $attributes; + $request->getMethod()->willReturn('POST'); + + $this->responder->respond(['foo' => 'fighters'], $operation, $context) + ->willReturn($response) + ->shouldBeCalled() + ; + + $this->respondListener->onKernelView($event); + + Assert::eq($event->getResponse(), $response->reveal()); + } + + /** @test */ + public function it_does_nothing_when_controller_result_is_a_response(): void + { + $kernel = $this->prophesize(HttpKernelInterface::class); + $request = $this->prophesize(Request::class); + $response = $this->prophesize(Response::class); + $attributes = $this->prophesize(ParameterBag::class); + $operation = $this->prophesize(HttpOperation::class); + + $event = new ViewEvent( + $kernel->reveal(), + $request->reveal(), + HttpKernelInterface::MAIN_REQUEST, + $response->reveal(), + ); + + $context = new Context(); + + $this->contextInitiator->initializeContext($request)->willReturn($context); + $this->operationInitiator->initializeOperation($request)->willReturn($operation); + + $request->attributes = $attributes; + $request->getMethod()->willReturn('POST'); + + $this->responder->respond($response, $operation, $context) + ->willReturn($response) + ->shouldNotBeCalled() + ; + + $this->respondListener->onKernelView($event); + } +} diff --git a/src/Component/tests/spec/Symfony/EventListener/RespondListenerSpec.php b/src/Component/tests/spec/Symfony/EventListener/RespondListenerSpec.php deleted file mode 100644 index b2f7278d5..000000000 --- a/src/Component/tests/spec/Symfony/EventListener/RespondListenerSpec.php +++ /dev/null @@ -1,112 +0,0 @@ -beConstructedWith($operationInitiator, $contextInitiator, $responder); - } - - function it_is_initializable(): void - { - $this->shouldHaveType(RespondListener::class); - } - - function it_sets_a_response_on_event( - HttpKernelInterface $kernel, - Request $request, - HttpOperationInitiatorInterface $operationInitiator, - RequestContextInitiatorInterface $contextInitiator, - ParameterBag $attributes, - HttpOperation $operation, - ResponderInterface $responder, - Response $response, - ): void { - $event = new ViewEvent( - $kernel->getWrappedObject(), - $request->getWrappedObject(), - HttpKernelInterface::MAIN_REQUEST, - ['foo' => 'fighters'], - ); - - $context = new Context(); - - $contextInitiator->initializeContext($request)->willReturn($context); - $operationInitiator->initializeOperation($request)->willReturn($operation); - - $request->attributes = $attributes; - $request->getMethod()->willReturn('POST'); - - $responder->respond(['foo' => 'fighters'], $operation, $context) - ->willReturn($response) - ->shouldBeCalled() - ; - - $this->onKernelView($event); - - Assert::eq($event->getResponse(), $response->getWrappedObject()); - } - - function it_does_nothing_when_controller_result_is_a_response( - HttpKernelInterface $kernel, - Request $request, - HttpOperationInitiatorInterface $operationInitiator, - RequestContextInitiatorInterface $contextInitiator, - ParameterBag $attributes, - HttpOperation $operation, - ResponderInterface $responder, - Response $response, - ): void { - $event = new ViewEvent( - $kernel->getWrappedObject(), - $request->getWrappedObject(), - HttpKernelInterface::MAIN_REQUEST, - $response->getWrappedObject(), - ); - - $context = new Context(); - - $contextInitiator->initializeContext($request)->willReturn($context); - $operationInitiator->initializeOperation($request)->willReturn($operation); - - $request->attributes = $attributes; - $request->getMethod()->willReturn('POST'); - - $responder->respond($response, $operation, $context) - ->willReturn($response) - ->shouldNotBeCalled() - ; - - $this->onKernelView($event); - } -} From 829cd5b49eabc5802f50ceb9ff1e8f34360ed77b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Fr=C3=A9mont?= Date: Fri, 17 Nov 2023 17:09:14 +0100 Subject: [PATCH 7/9] Init respond processor --- .../State/Processor/RespondProcessorTest.php | 88 +++++++++++++++++++ .../src/State/Processor/RespondProcessor.php | 44 ++++++++++ 2 files changed, 132 insertions(+) create mode 100644 src/Component/Tests/State/Processor/RespondProcessorTest.php create mode 100644 src/Component/src/State/Processor/RespondProcessor.php diff --git a/src/Component/Tests/State/Processor/RespondProcessorTest.php b/src/Component/Tests/State/Processor/RespondProcessorTest.php new file mode 100644 index 000000000..3ea1c3cc2 --- /dev/null +++ b/src/Component/Tests/State/Processor/RespondProcessorTest.php @@ -0,0 +1,88 @@ +decorated = $this->prophesize(ProcessorInterface::class); + $this->responder = $this->prophesize(ResponderInterface::class); + + $this->respondProcessor = new RespondProcessor( + $this->decorated->reveal(), + $this->responder->reveal(), + ); + } + + /** @test */ + public function it_returns_a_response(): void + { + $response = $this->prophesize(Response::class); + $operation = $this->prophesize(HttpOperation::class); + + $context = new Context(); + + $this->responder->respond(['foo' => 'fighters'], $operation, $context) + ->willReturn($response) + ->shouldBeCalled() + ; + + $this->decorated->process(['foo' => 'fighters'], $operation, $context)->willReturn(['foo' => 'fighters'])->shouldBeCalled(); + + $data = $this->respondProcessor->process(['foo' => 'fighters'], $operation->reveal(), $context); + Assert::eq($data, $response->reveal()); + } + + /** @test */ + public function it_does_nothing_when_data_is_a_response(): void + { + $response = $this->prophesize(Response::class); + $operation = $this->prophesize(HttpOperation::class); + + $context = new Context(); + + $this->decorated->process($response, $operation, $context)->willReturn($response)->shouldBeCalled(); + + $this->responder->respond($response, $operation, $context) + ->willReturn($response) + ->shouldNotBeCalled() + ; + + $data = $this->respondProcessor->process($response, $operation->reveal(), $context); + Assert::eq($data, $response->reveal()); + } +} diff --git a/src/Component/src/State/Processor/RespondProcessor.php b/src/Component/src/State/Processor/RespondProcessor.php new file mode 100644 index 000000000..0b8e59b11 --- /dev/null +++ b/src/Component/src/State/Processor/RespondProcessor.php @@ -0,0 +1,44 @@ +decorated->process($data, $operation, $context); + + if ($data instanceof Response) { + return $data; + } + + $response = $this->responder->respond($data, $operation, $context); + Assert::isInstanceOf($response, Response::class); + + return $response; + } +} From 32044d4dead470add2f91f4a087ae151e433780f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Fr=C3=A9mont?= Date: Mon, 20 Nov 2023 11:23:32 +0100 Subject: [PATCH 8/9] Phpunit tests for Symfony form listener --- .../EventListener/FormListenerTest.php} | 191 +++++++++--------- 1 file changed, 97 insertions(+), 94 deletions(-) rename src/Component/{tests/spec/Symfony/EventListener/FormListenerSpec.php => Tests/Symfony/EventListener/FormListenerTest.php} (51%) diff --git a/src/Component/tests/spec/Symfony/EventListener/FormListenerSpec.php b/src/Component/Tests/Symfony/EventListener/FormListenerTest.php similarity index 51% rename from src/Component/tests/spec/Symfony/EventListener/FormListenerSpec.php rename to src/Component/Tests/Symfony/EventListener/FormListenerTest.php index 9dcd59521..13baac23e 100644 --- a/src/Component/tests/spec/Symfony/EventListener/FormListenerSpec.php +++ b/src/Component/Tests/Symfony/EventListener/FormListenerTest.php @@ -11,11 +11,12 @@ declare(strict_types=1); -namespace spec\Sylius\Resource\Symfony\EventListener; +namespace Sylius\Component\Resource\Tests\Symfony\EventListener; -use PhpSpec\ObjectBehavior; -use Sylius\Component\Resource\Metadata\MetadataInterface; -use Sylius\Component\Resource\Metadata\RegistryInterface; +use PHPUnit\Framework\TestCase; +use Prophecy\PhpUnit\ProphecyTrait; +use Prophecy\Prophecy\ObjectProphecy; +use Sylius\Component\Resource\Symfony\Form\Factory\FormFactoryInterface; use Sylius\Resource\Context\Context; use Sylius\Resource\Context\Initiator\RequestContextInitiatorInterface; use Sylius\Resource\Metadata\BulkUpdate; @@ -24,7 +25,6 @@ use Sylius\Resource\Metadata\Operations; use Sylius\Resource\Metadata\Show; use Sylius\Resource\Symfony\EventListener\FormListener; -use Sylius\Resource\Symfony\Form\Factory\FormFactoryInterface; use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request; @@ -32,35 +32,42 @@ use Symfony\Component\HttpKernel\Event\ViewEvent; use Symfony\Component\HttpKernel\HttpKernelInterface; -final class FormListenerSpec extends ObjectBehavior +final class FormListenerTest extends TestCase { - function let( - HttpOperationInitiatorInterface $operationInitiator, - RequestContextInitiatorInterface $contextInitiator, - RegistryInterface $resourceRegistry, - MetadataInterface $metadata, - FormFactoryInterface $formFactory, - ): void { - $this->beConstructedWith($operationInitiator, $contextInitiator, $formFactory); - } + use ProphecyTrait; + + private HttpOperationInitiatorInterface|ObjectProphecy $operationInitiator; + + private RequestContextInitiatorInterface|ObjectProphecy $contextInitiator; + + private FormFactoryInterface|ObjectProphecy $formFactory; - function it_is_initializable(): void + private FormListener $formListener; + + protected function setUp(): void { - $this->shouldHaveType(FormListener::class); + $this->operationInitiator = $this->prophesize(HttpOperationInitiatorInterface::class); + $this->contextInitiator = $this->prophesize(RequestContextInitiatorInterface::class); + $this->formFactory = $this->prophesize(FormFactoryInterface::class); + + $this->formListener = new FormListener( + $this->operationInitiator->reveal(), + $this->contextInitiator->reveal(), + $this->formFactory->reveal(), + ); } - function it_handles_forms( - HttpKernelInterface $kernel, - Request $request, - ParameterBag $attributes, - HttpOperationInitiatorInterface $operationInitiator, - RequestContextInitiatorInterface $contextInitiator, - FormFactoryInterface $formFactory, - FormInterface $form, - ): void { + /** @test */ + public function it_handles_forms(): void + { + $kernel = $this->prophesize(HttpKernelInterface::class); + $request = $this->prophesize(Request::class); + $attributes = $this->prophesize(ParameterBag::class); + $form = $this->prophesize(FormInterface::class); + $event = new ViewEvent( - $kernel->getWrappedObject(), - $request->getWrappedObject(), + $kernel->reveal(), + $request->reveal(), HttpKernelInterface::MAIN_REQUEST, ['foo' => 'fighters'], ); @@ -73,15 +80,15 @@ function it_handles_forms( $operation = new Create(formType: 'App\Type\DummyType'); - $operationInitiator->initializeOperation($request)->willReturn($operation); + $this->operationInitiator->initializeOperation($request)->willReturn($operation); $operations = new Operations(); $operations->add('app_dummy_show', $operation); $context = new Context(); - $contextInitiator->initializeContext($request)->willReturn($context); + $this->contextInitiator->initializeContext($request)->willReturn($context); - $formFactory->create($operation, $context, ['foo' => 'fighters']) + $this->formFactory->create($operation, $context, ['foo' => 'fighters']) ->willReturn($form) ->shouldBeCalled() ; @@ -90,24 +97,23 @@ function it_handles_forms( $attributes->set('form', $form)->shouldBeCalled(); - $this->onKernelView($event); + $this->formListener->onKernelView($event); } - function it_does_nothing_when_controller_result_is_a_response( - HttpKernelInterface $kernel, - Request $request, - ParameterBag $attributes, - HttpOperationInitiatorInterface $operationInitiator, - RequestContextInitiatorInterface $contextInitiator, - FormFactoryInterface $formFactory, - FormInterface $form, - Response $response, - ): void { + /** @test */ + public function it_does_nothing_when_controller_result_is_a_response(): void + { + $kernel = $this->prophesize(HttpKernelInterface::class); + $request = $this->prophesize(Request::class); + $attributes = $this->prophesize(ParameterBag::class); + $form = $this->prophesize(FormInterface::class); + $response = $this->prophesize(Response::class); + $event = new ViewEvent( - $kernel->getWrappedObject(), - $request->getWrappedObject(), + $kernel->reveal(), + $request->reveal(), HttpKernelInterface::MAIN_REQUEST, - $response->getWrappedObject(), + $response->reveal(), ); $request->attributes = $attributes; @@ -118,15 +124,15 @@ function it_does_nothing_when_controller_result_is_a_response( $operation = new Create(formType: 'App\Type\DummyType'); - $operationInitiator->initializeOperation($request)->willReturn($operation); + $this->operationInitiator->initializeOperation($request)->willReturn($operation); $operations = new Operations(); $operations->add('app_dummy_show', $operation); $context = new Context(); - $contextInitiator->initializeContext($request)->willReturn($context); + $this->contextInitiator->initializeContext($request)->willReturn($context); - $formFactory->create($operation, $context, ['foo' => 'fighters']) + $this->formFactory->create($operation, $context, ['foo' => 'fighters']) ->willReturn($form) ->shouldNotBeCalled() ; @@ -135,21 +141,20 @@ function it_does_nothing_when_controller_result_is_a_response( $attributes->set('form', $form)->shouldNotBeCalled(); - $this->onKernelView($event); + $this->formListener->onKernelView($event); } - function it_does_nothing_when_operation_has_no_form_type( - HttpKernelInterface $kernel, - Request $request, - ParameterBag $attributes, - HttpOperationInitiatorInterface $operationInitiator, - RequestContextInitiatorInterface $contextInitiator, - FormFactoryInterface $formFactory, - FormInterface $form, - ): void { + /** @test */ + public function it_does_nothing_when_operation_has_no_form_type(): void + { + $kernel = $this->prophesize(HttpKernelInterface::class); + $request = $this->prophesize(Request::class); + $attributes = $this->prophesize(ParameterBag::class); + $form = $this->prophesize(FormInterface::class); + $event = new ViewEvent( - $kernel->getWrappedObject(), - $request->getWrappedObject(), + $kernel->reveal(), + $request->reveal(), HttpKernelInterface::MAIN_REQUEST, ['foo' => 'fighters'], ); @@ -162,15 +167,15 @@ function it_does_nothing_when_operation_has_no_form_type( $operation = new Create(formType: null); - $operationInitiator->initializeOperation($request)->willReturn($operation); + $this->operationInitiator->initializeOperation($request)->willReturn($operation); $operations = new Operations(); $operations->add('app_dummy_show', $operation); $context = new Context(); - $contextInitiator->initializeContext($request)->willReturn($context); + $this->contextInitiator->initializeContext($request)->willReturn($context); - $formFactory->create($operation, $context, ['foo' => 'fighters']) + $this->formFactory->create($operation, $context, ['foo' => 'fighters']) ->willReturn($form) ->shouldNotBeCalled() ; @@ -179,21 +184,20 @@ function it_does_nothing_when_operation_has_no_form_type( $attributes->set('form', $form)->shouldNotBeCalled(); - $this->onKernelView($event); + $this->formListener->onKernelView($event); } - function it_does_nothing_when_operation_is_not_a_create_or_update( - HttpKernelInterface $kernel, - Request $request, - ParameterBag $attributes, - HttpOperationInitiatorInterface $operationInitiator, - RequestContextInitiatorInterface $contextInitiator, - FormFactoryInterface $formFactory, - FormInterface $form, - ): void { + /** @test */ + public function it_does_nothing_when_operation_is_not_a_create_or_update(): void + { + $kernel = $this->prophesize(HttpKernelInterface::class); + $request = $this->prophesize(Request::class); + $attributes = $this->prophesize(ParameterBag::class); + $form = $this->prophesize(FormInterface::class); + $event = new ViewEvent( - $kernel->getWrappedObject(), - $request->getWrappedObject(), + $kernel->reveal(), + $request->reveal(), HttpKernelInterface::MAIN_REQUEST, ['foo' => 'fighters'], ); @@ -206,15 +210,15 @@ function it_does_nothing_when_operation_is_not_a_create_or_update( $operation = new Show(formType: 'App\Type\DummyType'); - $operationInitiator->initializeOperation($request)->willReturn($operation); + $this->operationInitiator->initializeOperation($request)->willReturn($operation); $operations = new Operations(); $operations->add('app_dummy_show', $operation); $context = new Context(); - $contextInitiator->initializeContext($request)->willReturn($context); + $this->contextInitiator->initializeContext($request)->willReturn($context); - $formFactory->create($operation, $context, ['foo' => 'fighters']) + $this->formFactory->create($operation, $context, ['foo' => 'fighters']) ->willReturn($form) ->shouldNotBeCalled() ; @@ -223,21 +227,20 @@ function it_does_nothing_when_operation_is_not_a_create_or_update( $attributes->set('form', $form)->shouldNotBeCalled(); - $this->onKernelView($event); + $this->formListener->onKernelView($event); } - function it_does_nothing_when_operation_is_a_bulk_update( - HttpKernelInterface $kernel, - Request $request, - ParameterBag $attributes, - HttpOperationInitiatorInterface $operationInitiator, - RequestContextInitiatorInterface $contextInitiator, - FormFactoryInterface $formFactory, - FormInterface $form, - ): void { + /** @test */ + public function it_does_nothing_when_operation_is_a_bulk_update(): void + { + $kernel = $this->prophesize(HttpKernelInterface::class); + $request = $this->prophesize(Request::class); + $attributes = $this->prophesize(ParameterBag::class); + $form = $this->prophesize(FormInterface::class); + $event = new ViewEvent( - $kernel->getWrappedObject(), - $request->getWrappedObject(), + $kernel->reveal(), + $request->reveal(), HttpKernelInterface::MAIN_REQUEST, ['foo' => 'fighters'], ); @@ -250,15 +253,15 @@ function it_does_nothing_when_operation_is_a_bulk_update( $operation = new BulkUpdate(formType: 'App\Type\DummyType'); - $operationInitiator->initializeOperation($request)->willReturn($operation); + $this->operationInitiator->initializeOperation($request)->willReturn($operation); $operations = new Operations(); $operations->add('app_dummy_show', $operation); $context = new Context(); - $contextInitiator->initializeContext($request)->willReturn($context); + $this->contextInitiator->initializeContext($request)->willReturn($context); - $formFactory->create($operation, $context, ['foo' => 'fighters']) + $this->formFactory->create($operation, $context, ['foo' => 'fighters']) ->willReturn($form) ->shouldNotBeCalled() ; @@ -267,6 +270,6 @@ function it_does_nothing_when_operation_is_a_bulk_update( $attributes->set('form', $form)->shouldNotBeCalled(); - $this->onKernelView($event); + $this->formListener->onKernelView($event); } } From 7e8ff9b0df7e81910168e5c3ec442c462c2e5698 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Fr=C3=A9mont?= Date: Tue, 21 Nov 2023 11:45:30 +0100 Subject: [PATCH 9/9] Fix PHPUnit tests --- src/Component/Tests/Symfony/EventListener/FormListenerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Component/Tests/Symfony/EventListener/FormListenerTest.php b/src/Component/Tests/Symfony/EventListener/FormListenerTest.php index 13baac23e..38c102fa0 100644 --- a/src/Component/Tests/Symfony/EventListener/FormListenerTest.php +++ b/src/Component/Tests/Symfony/EventListener/FormListenerTest.php @@ -16,7 +16,6 @@ use PHPUnit\Framework\TestCase; use Prophecy\PhpUnit\ProphecyTrait; use Prophecy\Prophecy\ObjectProphecy; -use Sylius\Component\Resource\Symfony\Form\Factory\FormFactoryInterface; use Sylius\Resource\Context\Context; use Sylius\Resource\Context\Initiator\RequestContextInitiatorInterface; use Sylius\Resource\Metadata\BulkUpdate; @@ -25,6 +24,7 @@ use Sylius\Resource\Metadata\Operations; use Sylius\Resource\Metadata\Show; use Sylius\Resource\Symfony\EventListener\FormListener; +use Sylius\Resource\Symfony\Form\Factory\FormFactoryInterface; use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request;