diff --git a/src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php b/src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php new file mode 100644 index 0000000..04d17f7 --- /dev/null +++ b/src/Manager/AcceptAndContentTypeMiddlewareResponseManager.php @@ -0,0 +1,58 @@ +responseManager = $responseManager; + } + + /** + * @param string $accept + * @param array $acceptableMimeTypes + * @param string $mimeType + * @return ResponseInterface + */ + public function createForNotAcceptable( + string $accept, + array $acceptableMimeTypes, + string $mimeType + ): ResponseInterface { + return $this->responseManager->createFromApiProblem( + new NotAcceptable($accept, $acceptableMimeTypes), + $mimeType + ); + } + + /** + * @param string $mediaType + * @param array $supportedMediaTypes + * @param string $mimeType + * @return ResponseInterface + */ + 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 6cdf61e..010318d 100644 --- a/src/Manager/ResponseManager.php +++ b/src/Manager/ResponseManager.php @@ -42,6 +42,10 @@ public function __construct() /** * @param object $object + * @param string $accept + * @param int $status + * @param NormalizerContextInterface|null $context + * @return ResponseInterface */ public function create( $object, 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..0dcbbc4 --- /dev/null +++ b/src/Middleware/AcceptAndContentTypeMiddlewareResponseFactoryInterface.php @@ -0,0 +1,34 @@ + $acceptableMimeTypes + * @param string $mimeType + * @return ResponseInterface + */ + public function createForNotAcceptable( + string $accept, + array $acceptableMimeTypes, + string $mimeType + ): ResponseInterface; + + /** + * @param string $mediaType + * @param array $supportedMediaTypes + * @param string $mimeType + * @return ResponseInterface + */ + public function createForUnsupportedMediaType( + string $mediaType, + array $supportedMediaTypes, + string $mimeType + ): ResponseInterface; +} diff --git a/tests/Unit/Middleware/AcceptAndContentTypeMiddlewareTest.php b/tests/Unit/Middleware/AcceptAndContentTypeMiddlewareTest.php index e5b52cb..c55e719 100644 --- a/tests/Unit/Middleware/AcceptAndContentTypeMiddlewareTest.php +++ b/tests/Unit/Middleware/AcceptAndContentTypeMiddlewareTest.php @@ -8,6 +8,7 @@ use Chubbyphp\ApiHttp\ApiProblem\ClientError\UnsupportedMediaType; use Chubbyphp\ApiHttp\Manager\ResponseManagerInterface; use Chubbyphp\ApiHttp\Middleware\AcceptAndContentTypeMiddleware; +use Chubbyphp\ApiHttp\Middleware\AcceptAndContentTypeMiddlewareResponseFactoryInterface; use Chubbyphp\Mock\Argument\ArgumentCallback; use Chubbyphp\Mock\Call; use Chubbyphp\Mock\MockByCallsTrait; @@ -55,21 +56,14 @@ public function handle(ServerRequestInterface $request): ResponseInterface /** @var ContentTypeNegotiatorInterface|MockObject $contentTypeNegotiator */ $contentTypeNegotiator = $this->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)); }