From 0afac11cd620398538d99acbe11558fb56057d94 Mon Sep 17 00:00:00 2001 From: Maxime Veber Date: Fri, 26 Nov 2021 16:28:48 +0100 Subject: [PATCH] feat: add json-api header See issue #46 and https://github.com/swagindustries/Melodiia/issues/46 --- CHANGELOG.md | 3 + .../Listener/SerializeOnKernelView.php | 18 +++--- .../Listener/SerializeOnKernelViewTest.php | 57 +++++++++++++++---- 3 files changed, 59 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf0a44c..5769cc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added +- Add json-api header in responses + ### Changed - Removed hard dependency to the form component (it is still required for many features) diff --git a/src/Response/Listener/SerializeOnKernelView.php b/src/Response/Listener/SerializeOnKernelView.php index f3ee931..e106417 100644 --- a/src/Response/Listener/SerializeOnKernelView.php +++ b/src/Response/Listener/SerializeOnKernelView.php @@ -19,6 +19,8 @@ */ class SerializeOnKernelView implements EventSubscriberInterface { + public const CONTENT_TYPE = 'application/vnd.api+json'; + /** * @var SerializerInterface */ @@ -49,13 +51,15 @@ public function onKernelView(ViewEvent $event) $context = $this->contextBuilderChain->buildContext([], $response); - $event->setResponse( - new JsonResponse( - $this->serializer->serialize($response, 'json', $context), - $response->httpStatus(), - $response->headers(), - true - ) + $jsonResponse = new JsonResponse( + $this->serializer->serialize($response, 'json', $context), + $response->httpStatus(), + $response->headers(), + true ); + + $jsonResponse->headers->set('Content-Type', self::CONTENT_TYPE); + + $event->setResponse($jsonResponse); } } diff --git a/tests/Melodiia/Response/Listener/SerializeOnKernelViewTest.php b/tests/Melodiia/Response/Listener/SerializeOnKernelViewTest.php index f32153c..6c445c6 100644 --- a/tests/Melodiia/Response/Listener/SerializeOnKernelViewTest.php +++ b/tests/Melodiia/Response/Listener/SerializeOnKernelViewTest.php @@ -13,6 +13,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\ViewEvent; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\KernelEvents; @@ -29,12 +30,26 @@ class SerializeOnKernelViewTest extends TestCase /** @var SerializeOnKernelView */ private $listener; + /** @var ApiResponse */ + private $dummyResponse; + public function setUp(): void { $this->serializer = $this->prophesize(SerializerInterface::class); $this->contextChain = $this->prophesize(ContextBuilderChainInterface::class); $this->contextChain->buildContext(Argument::cetera())->willReturn([]); $this->listener = new SerializeOnKernelView($this->serializer->reveal(), $this->contextChain->reveal()); + $this->dummyResponse = new class() implements ApiResponse { + public function httpStatus(): int + { + return 200; + } + + public function headers(): array + { + return []; + } + }; } public function tearDown(): void @@ -42,6 +57,7 @@ public function tearDown(): void $this->serializer = null; $this->contextChain = null; $this->listener = null; + $this->dummyResponse = null; } public function testItSubscribeOnKernelView() @@ -52,27 +68,44 @@ public function testItSubscribeOnKernelView() public function testItTransformApiResponse() { - $response = new class() implements ApiResponse { - public function httpStatus(): int - { - return 200; - } + $this->serializer->serialize($this->dummyResponse, Argument::cetera())->shouldBeCalled()->willReturn('"hello"'); + $event = new ViewEvent( + $this->prophesize(HttpKernelInterface::class)->reveal(), + $this->prophesize(Request::class)->reveal(), + HttpKernelInterface::MASTER_REQUEST, + $this->dummyResponse + ); - public function headers(): array - { - return []; - } - }; - $this->serializer->serialize($response, Argument::cetera())->shouldBeCalled()->willReturn('"hello"'); + $this->listener->onKernelView($event); + + $this->assertInstanceOf(JsonResponse::class, $event->getResponse()); + } + + public function testItDoesNotTransformSymfonyResponse() + { + $response = new Response('

Containing HTML?

'); $event = new ViewEvent( $this->prophesize(HttpKernelInterface::class)->reveal(), $this->prophesize(Request::class)->reveal(), HttpKernelInterface::MASTER_REQUEST, $response ); + $this->listener->onKernelView($event); + $this->assertSame(null, $event->getResponse()); + } + + public function testItSendsTheRightContentType() + { + $this->serializer->serialize($this->dummyResponse, Argument::cetera())->shouldBeCalled()->willReturn('"hello"'); + $event = new ViewEvent( + $this->prophesize(HttpKernelInterface::class)->reveal(), + $this->prophesize(Request::class)->reveal(), + HttpKernelInterface::MASTER_REQUEST, + $this->dummyResponse + ); $this->listener->onKernelView($event); - $this->assertInstanceOf(JsonResponse::class, $event->getResponse()); + $this->assertEquals($event->getResponse()->headers->get('content-type'), SerializeOnKernelView::CONTENT_TYPE); } }