diff --git a/config/graphqlite.php b/config/graphqlite.php index eb50569..ae4e1f9 100644 --- a/config/graphqlite.php +++ b/config/graphqlite.php @@ -1,6 +1,7 @@ Debug::RETHROW_UNSAFE_EXCEPTIONS, 'uri' => env('GRAPHQLITE_URI', '/graphql'), 'middleware' => ['web'], + + // Sets the status code in the HTTP request where operations have errors. + 'decider' => HttpCodeDecider::class, ]; diff --git a/src/Controllers/GraphQLiteController.php b/src/Controllers/GraphQLiteController.php index 02b5705..345e530 100644 --- a/src/Controllers/GraphQLiteController.php +++ b/src/Controllers/GraphQLiteController.php @@ -11,6 +11,7 @@ use GraphQL\Server\StandardServer; use GraphQL\Upload\UploadMiddleware; use TheCodingMachine\GraphQLite\Http\HttpCodeDecider; +use TheCodingMachine\GraphQLite\Http\HttpCodeDeciderInterface; use function array_map; use function json_decode; use function json_last_error; @@ -32,12 +33,15 @@ class GraphQLiteController private $standardServer; /** @var bool|int */ private $debug; + /** @var HttpCodeDeciderInterface */ + private $codeDecider; public function __construct(StandardServer $standardServer, HttpMessageFactoryInterface $httpMessageFactory = null, ?int $debug = DebugFlag::RETHROW_UNSAFE_EXCEPTIONS) { $this->standardServer = $standardServer; $this->httpMessageFactory = $httpMessageFactory ?: new DiactorosFactory(); $this->debug = $debug === null ? false : $debug; + $this->codeDecider = new HttpCodeDecider(); } /** @@ -73,7 +77,7 @@ private function handlePsr7Request(ServerRequestInterface $request): JsonRespons { $result = $this->standardServer->executePsrRequest($request); - $httpCodeDecider = new HttpCodeDecider(); + $httpCodeDecider = $this->codeDecider; if ($result instanceof ExecutionResult) { return new JsonResponse($result->toArray($this->debug), $httpCodeDecider->decideHttpStatusCode($result)); } @@ -91,4 +95,9 @@ private function handlePsr7Request(ServerRequestInterface $request): JsonRespons } throw new RuntimeException('Unexpected response from StandardServer::executePsrRequest'); // @codeCoverageIgnore } + + public function setCodeDecider(HttpCodeDeciderInterface $decider): void + { + $this->codeDecider = $decider; + } } diff --git a/src/Providers/GraphQLiteServiceProvider.php b/src/Providers/GraphQLiteServiceProvider.php index 70db094..978f722 100644 --- a/src/Providers/GraphQLiteServiceProvider.php +++ b/src/Providers/GraphQLiteServiceProvider.php @@ -19,6 +19,7 @@ use Symfony\Component\Cache\Psr16Cache; use TheCodingMachine\GraphQLite\Context\Context; use TheCodingMachine\GraphQLite\Exceptions\WebonyxErrorHandler; +use TheCodingMachine\GraphQLite\Http\HttpCodeDecider; use TheCodingMachine\GraphQLite\Laravel\Listeners\CachePurger; use TheCodingMachine\GraphQLite\Laravel\Mappers\Parameters\ValidateFieldMiddleware; use TheCodingMachine\GraphQLite\Laravel\Mappers\PaginatorTypeMapper; @@ -88,8 +89,14 @@ public function register() $this->app->singleton(GraphQLiteController::class, function (Application $app) { $debug = config('graphqlite.debug', DebugFlag::RETHROW_UNSAFE_EXCEPTIONS); + $controller = new GraphQLiteController($app[StandardServer::class], $app[HttpMessageFactoryInterface::class], $debug); + $decider = config('graphqlite.decider'); - return new GraphQLiteController($app[StandardServer::class], $app[HttpMessageFactoryInterface::class], $debug); + if (!empty($decider)) { + $controller->setCodeDecider($app[$decider]); + } + + return $controller; }); $this->app->singleton(StandardServer::class, static function (Application $app) { diff --git a/tests/Providers/GraphQLiteServiceProviderTest.php b/tests/Providers/GraphQLiteServiceProviderTest.php index 72d53d7..85cffff 100644 --- a/tests/Providers/GraphQLiteServiceProviderTest.php +++ b/tests/Providers/GraphQLiteServiceProviderTest.php @@ -3,11 +3,20 @@ namespace TheCodingMachine\GraphQLite\Laravel\Providers; +use GraphQL\Error\Debug; +use GraphQL\Executor\ExecutionResult; +use GraphQL\Server\StandardServer; use Orchestra\Testbench\TestCase; +use TheCodingMachine\GraphQLite\Http\HttpCodeDeciderInterface; use TheCodingMachine\GraphQLite\Laravel\Listeners\CachePurger; use TheCodingMachine\GraphQLite\Schema; use TheCodingMachine\TDBM\TDBMService; use function json_decode; +use Illuminate\Http\Request; +use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory; +use TheCodingMachine\GraphQLite\Laravel\Controllers\GraphQLiteController; +use Symfony\Component\HttpFoundation\Request as SymfonyRequest; + class GraphQLiteServiceProviderTest extends TestCase { @@ -171,4 +180,43 @@ public function testCachePurger(): void $cachePurger->handle(); $this->assertTrue(true); } + + /** + * Asserts that the status code has been taken from the HttpCodeDeciderInterface. + */ + public function testChangeTheCodeDecider() + { + $controller = $this->newGraphQLiteController(); + $controller->setCodeDecider($this->newCodeDecider(418)); + + $response = $controller->index($this->newRequest()); + + $this->assertEquals(418, $response->getStatusCode()); + } + + private function newCodeDecider(int $statusCode): HttpCodeDeciderInterface + { + return new class implements HttpCodeDeciderInterface { + public function decideHttpStatusCode(ExecutionResult $result): int + { + return 418; + } + }; + } + + private function newGraphQLiteController(): GraphQLiteController + { + $server = $this->app->make(StandardServer::class); + $messageFactory = $this->app->make(PsrHttpFactory::class); + return new GraphQLiteController($server, $messageFactory, Debug::RETHROW_UNSAFE_EXCEPTIONS); + } + + private function newRequest(): Request + { + $baseRequest = SymfonyRequest::create('https://localhost', 'GET', [ + 'query' => '{ testValidatorMultiple(foo:"192.168.1.1") }' + ]); + + return Request::createFromBase($baseRequest); + } }