diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index e1f39142..1cd07aec 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -640,6 +640,26 @@ parameters: count: 1 path: tests/Database/SelectFields/QueryArgsAndContextTests/UsersQuery.php + - + message: "#^Method Rebing\\\\GraphQL\\\\Tests\\\\Database\\\\SelectFields\\\\UnionTests\\\\SearchQuery\\:\\:resolve\\(\\) has no return type specified\\.$#" + count: 1 + path: tests/Database/SelectFields/UnionTests/SearchQuery.php + + - + message: "#^Method Rebing\\\\GraphQL\\\\Tests\\\\Database\\\\SelectFields\\\\UnionTests\\\\SearchQuery\\:\\:resolve\\(\\) has parameter \\$args with no type specified\\.$#" + count: 1 + path: tests/Database/SelectFields/UnionTests/SearchQuery.php + + - + message: "#^Method Rebing\\\\GraphQL\\\\Tests\\\\Database\\\\SelectFields\\\\UnionTests\\\\SearchQuery\\:\\:resolve\\(\\) has parameter \\$ctx with no type specified\\.$#" + count: 1 + path: tests/Database/SelectFields/UnionTests/SearchQuery.php + + - + message: "#^Method Rebing\\\\GraphQL\\\\Tests\\\\Database\\\\SelectFields\\\\UnionTests\\\\SearchQuery\\:\\:resolve\\(\\) has parameter \\$root with no type specified\\.$#" + count: 1 + path: tests/Database/SelectFields/UnionTests/SearchQuery.php + - message: "#^Method Rebing\\\\GraphQL\\\\Tests\\\\Database\\\\SelectFields\\\\ValidateDiffNodeTests\\\\UsersQuery\\:\\:resolve\\(\\) has no return type specified\\.$#" count: 1 diff --git a/tests/Database/SelectFields/UnionTests/CommentType.php b/tests/Database/SelectFields/UnionTests/CommentType.php new file mode 100644 index 00000000..b0803357 --- /dev/null +++ b/tests/Database/SelectFields/UnionTests/CommentType.php @@ -0,0 +1,31 @@ + 'Comment', + 'model' => Comment::class, + ]; + + public function fields(): array + { + return [ + 'body' => [ + 'type' => Type::string(), + ], + 'id' => [ + 'type' => Type::nonNull(Type::ID()), + ], + 'title' => [ + 'type' => Type::nonNull(Type::string()), + ], + ]; + } +} diff --git a/tests/Database/SelectFields/UnionTests/PostType.php b/tests/Database/SelectFields/UnionTests/PostType.php new file mode 100644 index 00000000..9b3abaa5 --- /dev/null +++ b/tests/Database/SelectFields/UnionTests/PostType.php @@ -0,0 +1,38 @@ + 'Post', + 'model' => Post::class, + ]; + + public function fields(): array + { + return [ + 'body' => [ + 'type' => Type::string(), + ], + 'comments' => [ + 'type' => Type::nonNull(Type::listOf(Type::nonNull(GraphQL::type('Comment')))), + 'query' => function (array $args, $query, $ctx) { + $query->where('title', 'like', 'lorem'); + }, + ], + 'id' => [ + 'type' => Type::nonNull(Type::ID()), + ], + 'title' => [ + 'type' => Type::nonNull(Type::string()), + ], + ]; + } +} diff --git a/tests/Database/SelectFields/UnionTests/SearchQuery.php b/tests/Database/SelectFields/UnionTests/SearchQuery.php new file mode 100644 index 00000000..8f04e9cc --- /dev/null +++ b/tests/Database/SelectFields/UnionTests/SearchQuery.php @@ -0,0 +1,53 @@ + 'searchQuery', + ]; + + public function type(): Type + { + return GraphQL::type('SearchUnion'); + } + + public function args(): array + { + return [ + 'id' => [ + 'type' => Type::nonNull(Type::string()), + ], + ]; + } + + public function resolve($root, $args, $ctx, ResolveInfo $info, Closure $getSelectFields) + { + /** @var SelectFields $selectFields */ + $selectFields = $getSelectFields(); + + if (Str::startsWith($args['id'], 'comment:')) { + return Comment::select($selectFields->getSelect()) + ->with($selectFields->getRelations()) + ->where('id', (int) Str::after($args['id'], 'comment:')) + ->first(); + } + + return Post::select($selectFields->getSelect()) + ->with($selectFields->getRelations()) + ->where('id', (int) $args['id']) + ->first(); + } +} diff --git a/tests/Database/SelectFields/UnionTests/SearchUnionTest.php b/tests/Database/SelectFields/UnionTests/SearchUnionTest.php new file mode 100644 index 00000000..b44759d4 --- /dev/null +++ b/tests/Database/SelectFields/UnionTests/SearchUnionTest.php @@ -0,0 +1,71 @@ +set('graphql.schemas.default', [ + 'query' => [ + SearchQuery::class, + ], + ]); + + $app['config']->set('graphql.types', [ + CommentType::class, + PostType::class, + SearchUnionType::class, + ]); + } + + public function testCustomQueryIsExecutedUsingUnionTypeOnQuery(): void + { + /** @var Post $post */ + $post = factory(Post::class)->create(); + /** @var Comment $comment1 */ + $comment1 = factory(Comment::class)->create(['post_id' => $post->id, 'title' => 'lorem']); + /** @var Comment $comment2 */ + $comment2 = factory(Comment::class)->create(['post_id' => $post->id, 'title' => 'ipsum']); + + $query = <<<'GRAQPHQL' +query ($id: String!) { + searchQuery(id: $id) { + ... on Post { + id + comments { + id + } + } + ... on Comment { + id + } + } +} +GRAQPHQL; + + $result = $this->httpGraphql($query, [ + 'variables' => ['id' => (string)$post->id], + ]); + + $expectedResult = [ + 'data' => [ + 'searchQuery' => [ + 'id' => (string)$post->id, + 'comments' => [ + ['id' => $comment1->id], + ], + ], + ], + ]; + self::assertEquals($expectedResult, $result); + } +} diff --git a/tests/Database/SelectFields/UnionTests/SearchUnionType.php b/tests/Database/SelectFields/UnionTests/SearchUnionType.php new file mode 100644 index 00000000..bab1faa3 --- /dev/null +++ b/tests/Database/SelectFields/UnionTests/SearchUnionType.php @@ -0,0 +1,40 @@ + 'SearchUnion', + ]; + + public function types(): array + { + return [ + GraphQL::type('Post'), + GraphQL::type('Comment'), + ]; + } + + /** + * @param object $value + * @return Type|null + */ + public function resolveType($value): ?Type + { + if ($value instanceof Post) { + return GraphQL::type('Post'); + } elseif ($value instanceof Comment) { + return GraphQL::type('Comment'); + } else { + return null; + } + } +}