From 03834ae0c580c3e019965d1a756dae6869c1bb5e Mon Sep 17 00:00:00 2001 From: codeliner Date: Fri, 26 Jan 2018 12:48:09 +0100 Subject: [PATCH] Handle empty payload --- examples/Messaging/MessageDescription.php | 6 +++ examples/Messaging/Query.php | 1 + .../JustinRainbowJsonSchemaAssertion.php | 4 ++ tests/EventMachineTest.php | 51 ++++++++++++++++++ tests/GraphQL/TypeLanguageTest.php | 53 ++++++++++++++++++- 5 files changed, 114 insertions(+), 1 deletion(-) diff --git a/examples/Messaging/MessageDescription.php b/examples/Messaging/MessageDescription.php index 0690232..47c36ca 100644 --- a/examples/Messaging/MessageDescription.php +++ b/examples/Messaging/MessageDescription.php @@ -84,5 +84,11 @@ public static function describe(EventMachine $eventMachine): void $eventMachine->registerQuery(Query::GET_USERS) ->resolveWith(GetUsersResolver::class) ->returnType(JsonSchema::array(JsonSchema::typeRef('User'))); + + $eventMachine->registerQuery(Query::GET_FILTERED_USERS, JsonSchema::object([], [ + 'filter' => JsonSchema::nullOr(JsonSchema::string()) + ])) + ->resolveWith(GetUsersResolver::class) + ->returnType(JsonSchema::array(JsonSchema::typeRef('User'))); } } diff --git a/examples/Messaging/Query.php b/examples/Messaging/Query.php index af223f1..9c31097 100644 --- a/examples/Messaging/Query.php +++ b/examples/Messaging/Query.php @@ -7,6 +7,7 @@ final class Query { const GET_USER = 'GetUser'; const GET_USERS = 'GetUsers'; + const GET_FILTERED_USERS = 'GetFilteredUsers'; private function __construct() { diff --git a/src/JsonSchema/JustinRainbowJsonSchemaAssertion.php b/src/JsonSchema/JustinRainbowJsonSchemaAssertion.php index 0b6dd00..7e9ad87 100644 --- a/src/JsonSchema/JustinRainbowJsonSchemaAssertion.php +++ b/src/JsonSchema/JustinRainbowJsonSchemaAssertion.php @@ -11,6 +11,10 @@ final class JustinRainbowJsonSchemaAssertion implements JsonSchemaAssertion public function assert(string $objectName, array $data, array $jsonSchema) { + if($data === [] && JsonSchema::isObjectType($jsonSchema)) { + $data = new \stdClass(); + } + $enforcedObjectData = json_decode(json_encode($data)); $jsonSchema = json_decode(json_encode($jsonSchema)); diff --git a/tests/EventMachineTest.php b/tests/EventMachineTest.php index 8079efd..354c886 100644 --- a/tests/EventMachineTest.php +++ b/tests/EventMachineTest.php @@ -551,6 +551,9 @@ public function it_provides_message_schemas() UserDescription::IDENTIFIER => $userId, ]), Query::GET_USERS => null, + Query::GET_FILTERED_USERS => JsonSchema::object([], [ + 'filter' => JsonSchema::nullOr(JsonSchema::string()) + ]) ] ], $this->eventMachine->messageSchemas() @@ -783,6 +786,54 @@ public function __invoke(Message $getUsers, Deferred $deferred) ]), (string)$response->getBody()); } + /** + * @test + */ + public function it_handles_queries_with_missing_optional_args_with_graphql() + { + $getUsersResolver = new class() { + public function __invoke(Message $getUsers, Deferred $deferred) + { + $deferred->resolve([ + [ + UserDescription::IDENTIFIER => '123', + UserDescription::USERNAME => 'Alex', + ] + ]); + } + }; + + $this->appContainer->has(GetUsersResolver::class)->willReturn(true); + $this->appContainer->get(GetUsersResolver::class)->will(function ($args) use ($getUsersResolver) { + return $getUsersResolver; + }); + + $this->eventMachine->initialize($this->containerChain); + + $server = $this->eventMachine->bootstrap(EventMachine::ENV_TEST, true)->graphqlServer(); + + $this->assertInstanceOf(RequestHandlerInterface::class, $server); + + $queryName = Query::GET_FILTERED_USERS; + $username = UserDescription::USERNAME; + + $query = "{ $queryName { $username } }"; + + $stream = new \Zend\Diactoros\CallbackStream(function () use ($query) { + return $query; + }); + + $request = new ServerRequest([], [], "/graphql", 'POST', $stream, [ + 'Content-Type' => 'application/graphql' + ]); + + $response = $server->handle($request); + + $this->assertEquals(json_encode([ + "data" => ["GetFilteredUsers" => [[$username => "Alex"]]] + ]), (string)$response->getBody()); + } + /** * @test */ diff --git a/tests/GraphQL/TypeLanguageTest.php b/tests/GraphQL/TypeLanguageTest.php index 715746b..69e56e0 100644 --- a/tests/GraphQL/TypeLanguageTest.php +++ b/tests/GraphQL/TypeLanguageTest.php @@ -62,7 +62,7 @@ public function it_converts_a_query_with_an_argument_and_registered_return_type( /** * @test */ - public function it_converts_a_query_with_one_required_and_one_optional_argument() + public function it_converts_a_query_with_one_required_and_one_optional_argument_with_default_val() { $types = [ 'User' => JsonSchema::object([ @@ -99,6 +99,57 @@ public function it_converts_a_query_with_one_required_and_one_optional_argument( query: Query } +TYPES; + + $this->assertEquals($expectedTypes, $graphQlTypes); + + $schema = BuildSchema::build($graphQlTypes); + + $schema->assertValid(); + } + + /** + * @test + */ + public function it_converts_a_query_with_optional_argument() + { + $types = [ + 'User' => JsonSchema::object([ + 'id' => JsonSchema::string(), + 'username' => JsonSchema::string(), + 'realName' => JsonSchema::nullOr(JsonSchema::string()) + ]) + ]; + + $queries = [ + "FilteredUsers" => JsonSchema::object([], [ + 'filter' => JsonSchema::nullOr(JsonSchema::string()) + ]) + ]; + + $queryReturnTypes = [ + 'FilteredUsers' => JsonSchema::array(JsonSchema::typeRef('User')), + ]; + + $graphQlTypes = TypeLanguage::fromEventMachineDescriptions($queries, [], $queryReturnTypes, $types); + + $expectedTypes = <<assertEquals($expectedTypes, $graphQlTypes);