Skip to content

Commit

Permalink
Merge pull request #57 from proophsoftware/bugfix/optional_args_cause…
Browse files Browse the repository at this point in the history
…_json_schema_assertion_to_fail

Handle empty payload when asserting payload schema
  • Loading branch information
codeliner authored Jan 26, 2018
2 parents 54ce5a7 + 03834ae commit 5322ad3
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 1 deletion.
6 changes: 6 additions & 0 deletions examples/Messaging/MessageDescription.php
Original file line number Diff line number Diff line change
Expand Up @@ -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')));
}
}
1 change: 1 addition & 0 deletions examples/Messaging/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ final class Query
{
const GET_USER = 'GetUser';
const GET_USERS = 'GetUsers';
const GET_FILTERED_USERS = 'GetFilteredUsers';

private function __construct()
{
Expand Down
4 changes: 4 additions & 0 deletions src/JsonSchema/JustinRainbowJsonSchemaAssertion.php
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down
51 changes: 51 additions & 0 deletions tests/EventMachineTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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
*/
Expand Down
53 changes: 52 additions & 1 deletion tests/GraphQL/TypeLanguageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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([
Expand Down Expand Up @@ -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 = <<<TYPES
type User {
id: String!
username: String!
realName: String
}
type Query {
FilteredUsers(filter: String): [User!]!
}
schema {
query: Query
}
TYPES;

$this->assertEquals($expectedTypes, $graphQlTypes);
Expand Down

0 comments on commit 5322ad3

Please sign in to comment.