From 8c87a3c5a881178453e0c6f07aef6d5f98666c21 Mon Sep 17 00:00:00 2001 From: TiMESPLiNTER Date: Tue, 18 Feb 2020 11:28:01 +0100 Subject: [PATCH 1/8] Decouples AcceptAndContentTypeMiddleware from ResponseManagerInterface --- src/Manager/ResponseManager.php | 25 +++++++++- .../AcceptAndContentTypeMiddleware.php | 27 ++++------- ...TypeMiddlewareResponseFactoryInterface.php | 22 +++++++++ .../AcceptAndContentTypeMiddlewareTest.php | 47 +++++++------------ 4 files changed, 73 insertions(+), 48 deletions(-) create mode 100644 src/Middleware/AcceptAndContentTypeMiddlewareResponseFactoryInterface.php diff --git a/src/Manager/ResponseManager.php b/src/Manager/ResponseManager.php index 6cdf61e..fff31e7 100644 --- a/src/Manager/ResponseManager.php +++ b/src/Manager/ResponseManager.php @@ -5,13 +5,16 @@ namespace Chubbyphp\ApiHttp\Manager; use Chubbyphp\ApiHttp\ApiProblem\ApiProblemInterface; +use Chubbyphp\ApiHttp\ApiProblem\ClientError\NotAcceptable; +use Chubbyphp\ApiHttp\ApiProblem\ClientError\UnsupportedMediaType; +use Chubbyphp\ApiHttp\Middleware\AcceptAndContentTypeMiddlewareResponseFactoryInterface; use Chubbyphp\Deserialization\DeserializerInterface; use Chubbyphp\Serialization\Normalizer\NormalizerContextInterface; use Chubbyphp\Serialization\SerializerInterface; use Psr\Http\Message\ResponseFactoryInterface; use Psr\Http\Message\ResponseInterface; -final class ResponseManager implements ResponseManagerInterface +final class ResponseManager implements ResponseManagerInterface, AcceptAndContentTypeMiddlewareResponseFactoryInterface { /** * @var ResponseFactoryInterface @@ -42,6 +45,10 @@ public function __construct() /** * @param object $object + * @param string $accept + * @param int $status + * @param NormalizerContextInterface|null $context + * @return ResponseInterface */ public function create( $object, @@ -98,4 +105,20 @@ private function setSerializer(SerializerInterface $serializer): void { $this->serializer = $serializer; } + + public function createForNotAcceptable( + string $accept, + array $acceptableMimeTypes, + string $mimeType + ): ResponseInterface { + return $this->createFromApiProblem(new NotAcceptable($accept, $acceptableMimeTypes), $mimeType); + } + + public function createForUnsupportedMediaType( + string $mediaType, + array $supportedMediaTypes, + string $mimeType + ): ResponseInterface { + return $this->createFromApiProblem(new UnsupportedMediaType($mediaType, $supportedMediaTypes), $mimeType); + } } diff --git a/src/Middleware/AcceptAndContentTypeMiddleware.php b/src/Middleware/AcceptAndContentTypeMiddleware.php index 8690dfd..ea63357 100644 --- a/src/Middleware/AcceptAndContentTypeMiddleware.php +++ b/src/Middleware/AcceptAndContentTypeMiddleware.php @@ -4,9 +4,6 @@ namespace Chubbyphp\ApiHttp\Middleware; -use Chubbyphp\ApiHttp\ApiProblem\ClientError\NotAcceptable; -use Chubbyphp\ApiHttp\ApiProblem\ClientError\UnsupportedMediaType; -use Chubbyphp\ApiHttp\Manager\ResponseManagerInterface; use Chubbyphp\Negotiation\AcceptNegotiatorInterface; use Chubbyphp\Negotiation\ContentTypeNegotiatorInterface; use Psr\Http\Message\ResponseInterface; @@ -27,18 +24,18 @@ final class AcceptAndContentTypeMiddleware implements MiddlewareInterface private $contentTypeNegotiator; /** - * @var ResponseManagerInterface + * @var AcceptAndContentTypeMiddlewareResponseFactoryInterface */ - private $responseManager; + private $responseFactory; public function __construct( AcceptNegotiatorInterface $acceptNegotiator, ContentTypeNegotiatorInterface $contentTypeNegotiator, - ResponseManagerInterface $responseManager + AcceptAndContentTypeMiddlewareResponseFactoryInterface $responseFactory ) { $this->acceptNegotiator = $acceptNegotiator; $this->contentTypeNegotiator = $contentTypeNegotiator; - $this->responseManager = $responseManager; + $this->responseFactory = $responseFactory; } public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface @@ -46,11 +43,9 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface if (null === $accept = $this->acceptNegotiator->negotiate($request)) { $supportedMediaTypes = $this->acceptNegotiator->getSupportedMediaTypes(); - return $this->responseManager->createFromApiProblem( - new NotAcceptable( - $request->getHeaderLine('Accept'), - $supportedMediaTypes - ), + return $this->responseFactory->createForNotAcceptable( + $request->getHeaderLine('Accept'), + $supportedMediaTypes, $supportedMediaTypes[0] ); } @@ -59,11 +54,9 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface if (in_array($request->getMethod(), ['POST', 'PUT', 'PATCH'], true)) { if (null === $contentType = $this->contentTypeNegotiator->negotiate($request)) { - return $this->responseManager->createFromApiProblem( - new UnsupportedMediaType( - $request->getHeaderLine('Content-Type'), - $this->contentTypeNegotiator->getSupportedMediaTypes() - ), + return $this->responseFactory->createForUnsupportedMediaType( + $request->getHeaderLine('Content-Type'), + $this->contentTypeNegotiator->getSupportedMediaTypes(), $accept->getValue() ); } diff --git a/src/Middleware/AcceptAndContentTypeMiddlewareResponseFactoryInterface.php b/src/Middleware/AcceptAndContentTypeMiddlewareResponseFactoryInterface.php new file mode 100644 index 0000000..22da850 --- /dev/null +++ b/src/Middleware/AcceptAndContentTypeMiddlewareResponseFactoryInterface.php @@ -0,0 +1,22 @@ +getMockByCalls(ContentTypeNegotiatorInterface::class, []); - /** @var ResponseManagerInterface|MockObject $responseManager */ - $responseManager = $this->getMockByCalls(ResponseManagerInterface::class, [ - Call::create('createFromApiProblem') - ->with( - new ArgumentCallback(function (NotAcceptable $apiProblem): void { - self::assertSame('application/xml', $apiProblem->getAccept()); - self::assertSame(['application/json'], $apiProblem->getAcceptables()); - }), - 'application/json', - null - ) + /** @var AcceptAndContentTypeMiddlewareResponseFactoryInterface|MockObject $responseFactory */ + $responseFactory = $this->getMockByCalls(AcceptAndContentTypeMiddlewareResponseFactoryInterface::class, [ + Call::create('createForNotAcceptable') + ->with('application/xml', ['application/json'], 'application/json') ->willReturn($response), ]); - $middleware = new AcceptAndContentTypeMiddleware($acceptNegotiator, $contentTypeNegotiator, $responseManager); + $middleware = new AcceptAndContentTypeMiddleware($acceptNegotiator, $contentTypeNegotiator, $responseFactory); self::assertSame($response, $middleware->process($request, $requestHandler)); } @@ -115,10 +109,10 @@ public function handle(ServerRequestInterface $request): ResponseInterface /** @var ContentTypeNegotiatorInterface|MockObject $contentTypeNegotiator */ $contentTypeNegotiator = $this->getMockByCalls(ContentTypeNegotiatorInterface::class, []); - /** @var ResponseManagerInterface|MockObject $responseManager */ - $responseManager = $this->getMockByCalls(ResponseManagerInterface::class, []); + /** @var AcceptAndContentTypeMiddlewareResponseFactoryInterface|MockObject $responseFactory */ + $responseFactory = $this->getMockByCalls(AcceptAndContentTypeMiddlewareResponseFactoryInterface::class, []); - $middleware = new AcceptAndContentTypeMiddleware($acceptNegotiator, $contentTypeNegotiator, $responseManager); + $middleware = new AcceptAndContentTypeMiddleware($acceptNegotiator, $contentTypeNegotiator, $responseFactory); self::assertSame($response, $middleware->process($request, $requestHandler)); } @@ -159,21 +153,14 @@ public function handle(ServerRequestInterface $request): ResponseInterface Call::create('getSupportedMediaTypes')->with()->willReturn(['application/json']), ]); - /** @var ResponseManagerInterface|MockObject $responseManager */ - $responseManager = $this->getMockByCalls(ResponseManagerInterface::class, [ - Call::create('createFromApiProblem') - ->with( - new ArgumentCallback(function (UnsupportedMediaType $apiProblem): void { - self::assertSame('application/xml', $apiProblem->getMediaType()); - self::assertSame(['application/json'], $apiProblem->getSupportedMediaTypes()); - }), - 'application/json', - null - ) + /** @var AcceptAndContentTypeMiddlewareResponseFactoryInterface|MockObject $responseFactory */ + $responseFactory = $this->getMockByCalls(AcceptAndContentTypeMiddlewareResponseFactoryInterface::class, [ + Call::create('createForUnsupportedMediaType') + ->with('application/xml', ['application/json'], 'application/json') ->willReturn($response), ]); - $middleware = new AcceptAndContentTypeMiddleware($acceptNegotiator, $contentTypeNegotiator, $responseManager); + $middleware = new AcceptAndContentTypeMiddleware($acceptNegotiator, $contentTypeNegotiator, $responseFactory); self::assertSame($response, $middleware->process($request, $requestHandler)); } @@ -227,10 +214,10 @@ public function handle(ServerRequestInterface $request): ResponseInterface Call::create('negotiate')->with($request)->willReturn($contentType), ]); - /** @var ResponseManagerInterface|MockObject $responseManager */ - $responseManager = $this->getMockByCalls(ResponseManagerInterface::class, []); + /** @var AcceptAndContentTypeMiddlewareResponseFactoryInterface|MockObject $responseFactory */ + $responseFactory = $this->getMockByCalls(AcceptAndContentTypeMiddlewareResponseFactoryInterface::class, []); - $middleware = new AcceptAndContentTypeMiddleware($acceptNegotiator, $contentTypeNegotiator, $responseManager); + $middleware = new AcceptAndContentTypeMiddleware($acceptNegotiator, $contentTypeNegotiator, $responseFactory); self::assertSame($response, $middleware->process($request, $requestHandler)); } From 7e4e4fd358e1b8353a9fe638a34248eb0ab1b1da Mon Sep 17 00:00:00 2001 From: TiMESPLiNTER Date: Tue, 18 Feb 2020 11:35:49 +0100 Subject: [PATCH 2/8] Add a bridge ResponseManager for the middleware --- ...ndContentTypeMiddlewareResponseManager.php | 44 +++++++++++++++++++ src/Manager/ResponseManager.php | 21 +-------- 2 files changed, 45 insertions(+), 20 deletions(-) create mode 100644 src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php diff --git a/src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php b/src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php new file mode 100644 index 0000000..92a64e5 --- /dev/null +++ b/src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php @@ -0,0 +1,44 @@ +responseManager = $responseManager; + } + + public function createForNotAcceptable( + string $accept, + array $acceptableMimeTypes, + string $mimeType + ): ResponseInterface { + return $this->responseManager->createFromApiProblem( + new NotAcceptable($accept, $acceptableMimeTypes), $mimeType + ); + } + + public function createForUnsupportedMediaType( + string $mediaType, + array $supportedMediaTypes, + string $mimeType + ): ResponseInterface { + return $this->responseManager->createFromApiProblem( + new UnsupportedMediaType($mediaType, $supportedMediaTypes), $mimeType + ); + } +} diff --git a/src/Manager/ResponseManager.php b/src/Manager/ResponseManager.php index fff31e7..010318d 100644 --- a/src/Manager/ResponseManager.php +++ b/src/Manager/ResponseManager.php @@ -5,16 +5,13 @@ namespace Chubbyphp\ApiHttp\Manager; use Chubbyphp\ApiHttp\ApiProblem\ApiProblemInterface; -use Chubbyphp\ApiHttp\ApiProblem\ClientError\NotAcceptable; -use Chubbyphp\ApiHttp\ApiProblem\ClientError\UnsupportedMediaType; -use Chubbyphp\ApiHttp\Middleware\AcceptAndContentTypeMiddlewareResponseFactoryInterface; use Chubbyphp\Deserialization\DeserializerInterface; use Chubbyphp\Serialization\Normalizer\NormalizerContextInterface; use Chubbyphp\Serialization\SerializerInterface; use Psr\Http\Message\ResponseFactoryInterface; use Psr\Http\Message\ResponseInterface; -final class ResponseManager implements ResponseManagerInterface, AcceptAndContentTypeMiddlewareResponseFactoryInterface +final class ResponseManager implements ResponseManagerInterface { /** * @var ResponseFactoryInterface @@ -105,20 +102,4 @@ private function setSerializer(SerializerInterface $serializer): void { $this->serializer = $serializer; } - - public function createForNotAcceptable( - string $accept, - array $acceptableMimeTypes, - string $mimeType - ): ResponseInterface { - return $this->createFromApiProblem(new NotAcceptable($accept, $acceptableMimeTypes), $mimeType); - } - - public function createForUnsupportedMediaType( - string $mediaType, - array $supportedMediaTypes, - string $mimeType - ): ResponseInterface { - return $this->createFromApiProblem(new UnsupportedMediaType($mediaType, $supportedMediaTypes), $mimeType); - } } From 53003792ed526ab292381c1eed0d5348328a06a2 Mon Sep 17 00:00:00 2001 From: TiMESPLiNTER Date: Tue, 18 Feb 2020 11:39:16 +0100 Subject: [PATCH 3/8] CS --- .../AcceptAndContentTypeMiddlewareResponseManager.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php b/src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php index 92a64e5..542fb22 100644 --- a/src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php +++ b/src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php @@ -28,7 +28,8 @@ public function createForNotAcceptable( string $mimeType ): ResponseInterface { return $this->responseManager->createFromApiProblem( - new NotAcceptable($accept, $acceptableMimeTypes), $mimeType + new NotAcceptable($accept, $acceptableMimeTypes), + $mimeType ); } @@ -38,7 +39,8 @@ public function createForUnsupportedMediaType( string $mimeType ): ResponseInterface { return $this->responseManager->createFromApiProblem( - new UnsupportedMediaType($mediaType, $supportedMediaTypes), $mimeType + new UnsupportedMediaType($mediaType, $supportedMediaTypes), + $mimeType ); } } From a24f97c374ddbd95289e82c1fe6d68bc6f92991e Mon Sep 17 00:00:00 2001 From: TiMESPLiNTER Date: Tue, 18 Feb 2020 11:46:03 +0100 Subject: [PATCH 4/8] Static analysis --- ...AcceptAndContentTypeMiddlewareResponseManager.php | 12 ++++++++++++ ...ContentTypeMiddlewareResponseFactoryInterface.php | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php b/src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php index 542fb22..6edfc14 100644 --- a/src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php +++ b/src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php @@ -22,6 +22,12 @@ public function __construct(ResponseManagerInterface $responseManager) $this->responseManager = $responseManager; } + /** + * @param string $accept + * @param array|string[] $acceptableMimeTypes + * @param string $mimeType + * @return ResponseInterface + */ public function createForNotAcceptable( string $accept, array $acceptableMimeTypes, @@ -33,6 +39,12 @@ public function createForNotAcceptable( ); } + /** + * @param string $mediaType + * @param array|string[] $supportedMediaTypes + * @param string $mimeType + * @return ResponseInterface + */ public function createForUnsupportedMediaType( string $mediaType, array $supportedMediaTypes, diff --git a/src/Middleware/AcceptAndContentTypeMiddlewareResponseFactoryInterface.php b/src/Middleware/AcceptAndContentTypeMiddlewareResponseFactoryInterface.php index 22da850..23b3b16 100644 --- a/src/Middleware/AcceptAndContentTypeMiddlewareResponseFactoryInterface.php +++ b/src/Middleware/AcceptAndContentTypeMiddlewareResponseFactoryInterface.php @@ -8,12 +8,24 @@ interface AcceptAndContentTypeMiddlewareResponseFactoryInterface { + /** + * @param string $accept + * @param array|string[] $acceptableMimeTypes + * @param string $mimeType + * @return ResponseInterface + */ public function createForNotAcceptable( string $accept, array $acceptableMimeTypes, string $mimeType ): ResponseInterface; + /** + * @param string $mediaType + * @param array|string[] $supportedMediaTypes + * @param string $mimeType + * @return ResponseInterface + */ public function createForUnsupportedMediaType( string $mediaType, array $supportedMediaTypes, From 12a74182d15ecebf11d80fbe440d6e5b465d838c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20M=C3=BCnst?= Date: Tue, 18 Feb 2020 14:43:57 +0100 Subject: [PATCH 5/8] Update src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php Co-Authored-By: Dominik Zogg --- src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php b/src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php index 6edfc14..5466a30 100644 --- a/src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php +++ b/src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php @@ -24,7 +24,7 @@ public function __construct(ResponseManagerInterface $responseManager) /** * @param string $accept - * @param array|string[] $acceptableMimeTypes + * @param array $acceptableMimeTypes * @param string $mimeType * @return ResponseInterface */ From b673a2961d089eb8e0bd6ff8a10e6412f2244073 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20M=C3=BCnst?= Date: Tue, 18 Feb 2020 14:44:07 +0100 Subject: [PATCH 6/8] Update src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php Co-Authored-By: Dominik Zogg --- src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php b/src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php index 5466a30..04d17f7 100644 --- a/src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php +++ b/src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php @@ -41,7 +41,7 @@ public function createForNotAcceptable( /** * @param string $mediaType - * @param array|string[] $supportedMediaTypes + * @param array $supportedMediaTypes * @param string $mimeType * @return ResponseInterface */ From 81b545ad7af21e038589334a7d1f0f8f3044d7fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20M=C3=BCnst?= Date: Tue, 18 Feb 2020 14:44:16 +0100 Subject: [PATCH 7/8] Update src/Middleware/AcceptAndContentTypeMiddlewareResponseFactoryInterface.php Co-Authored-By: Dominik Zogg --- .../AcceptAndContentTypeMiddlewareResponseFactoryInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Middleware/AcceptAndContentTypeMiddlewareResponseFactoryInterface.php b/src/Middleware/AcceptAndContentTypeMiddlewareResponseFactoryInterface.php index 23b3b16..c55c6fd 100644 --- a/src/Middleware/AcceptAndContentTypeMiddlewareResponseFactoryInterface.php +++ b/src/Middleware/AcceptAndContentTypeMiddlewareResponseFactoryInterface.php @@ -22,7 +22,7 @@ public function createForNotAcceptable( /** * @param string $mediaType - * @param array|string[] $supportedMediaTypes + * @param array $supportedMediaTypes * @param string $mimeType * @return ResponseInterface */ From 69de4d9c22532f7327b3c068737b8d8d0075bd52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20M=C3=BCnst?= Date: Tue, 18 Feb 2020 14:44:26 +0100 Subject: [PATCH 8/8] Update src/Middleware/AcceptAndContentTypeMiddlewareResponseFactoryInterface.php Co-Authored-By: Dominik Zogg --- .../AcceptAndContentTypeMiddlewareResponseFactoryInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Middleware/AcceptAndContentTypeMiddlewareResponseFactoryInterface.php b/src/Middleware/AcceptAndContentTypeMiddlewareResponseFactoryInterface.php index c55c6fd..0dcbbc4 100644 --- a/src/Middleware/AcceptAndContentTypeMiddlewareResponseFactoryInterface.php +++ b/src/Middleware/AcceptAndContentTypeMiddlewareResponseFactoryInterface.php @@ -10,7 +10,7 @@ interface AcceptAndContentTypeMiddlewareResponseFactoryInterface { /** * @param string $accept - * @param array|string[] $acceptableMimeTypes + * @param array $acceptableMimeTypes * @param string $mimeType * @return ResponseInterface */