From 68d868198359f8c29190c271f8108f37f6fa2f51 Mon Sep 17 00:00:00 2001 From: vladar Date: Fri, 1 Apr 2016 16:30:52 +0600 Subject: [PATCH] #30 Fixed recursion bug in ResolveInfo::getFieldSelection() --- src/Type/Definition/ResolveInfo.php | 2 +- tests/Type/ResolveInfoTest.php | 156 ++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 tests/Type/ResolveInfoTest.php diff --git a/src/Type/Definition/ResolveInfo.php b/src/Type/Definition/ResolveInfo.php index a7c0202..1c60b5d 100644 --- a/src/Type/Definition/ResolveInfo.php +++ b/src/Type/Definition/ResolveInfo.php @@ -107,7 +107,7 @@ class ResolveInfo foreach ($selectionSet->selections as $selectionAST) { if ($selectionAST instanceof Field) { $fields[$selectionAST->name->value] = $descend > 0 && !empty($selectionAST->selectionSet) - ? $this->foldSelectionSet($selectionAST->selectionSet, --$descend) + ? $this->foldSelectionSet($selectionAST->selectionSet, $descend - 1) : true; } else if ($selectionAST instanceof FragmentSpread) { $spreadName = $selectionAST->name->value; diff --git a/tests/Type/ResolveInfoTest.php b/tests/Type/ResolveInfoTest.php new file mode 100644 index 0000000..891e810 --- /dev/null +++ b/tests/Type/ResolveInfoTest.php @@ -0,0 +1,156 @@ + 'Image', + 'fields' => [ + 'url' => ['type' => Type::string()], + 'width' => ['type' => Type::int()], + 'height' => ['type' => Type::int()] + ] + ]); + + $article = null; + + $author = new ObjectType([ + 'name' => 'Author', + 'fields' => function() use ($image, &$article) { + return [ + 'id' => ['type' => Type::string()], + 'name' => ['type' => Type::string()], + 'pic' => [ 'type' => $image, 'args' => [ + 'width' => ['type' => Type::int()], + 'height' => ['type' => Type::int()] + ]], + 'recentArticle' => ['type' => $article], + ]; + }, + ]); + + $reply = new ObjectType([ + 'name' => 'Reply', + 'fields' => [ + 'author' => ['type' => $author], + 'body' => ['type' => Type::string()] + ] + ]); + + $article = new ObjectType([ + 'name' => 'Article', + 'fields' => [ + 'id' => ['type' => Type::string()], + 'isPublished' => ['type' => Type::boolean()], + 'author' => ['type' => $author], + 'title' => ['type' => Type::string()], + 'body' => ['type' => Type::string()], + 'image' => ['type' => $image], + 'replies' => ['type' => Type::listOf($reply)] + ] + ]); + + $doc = ' + query Test { + article { + author { + name + pic { + url + width + } + } + image { + width + height + } + replies { + body + author { + id + name + pic { + url + width + } + recentArticle { + id + title + body + } + } + } + } + } +'; + $expectedDefaultSelection = [ + 'author' => true, + 'image' => true, + 'replies' => true + ]; + $expectedDeepSelection = [ + 'author' => [ + 'name' => true, + 'pic' => [ + 'url' => true, + 'width' => true + ] + ], + 'image' => [ + 'width' => true, + 'height' => true + ], + 'replies' => [ + 'body' => true, + 'author' => [ + 'id' => true, + 'name' => true, + 'pic' => [ + 'url' => true, + 'width' => true + ], + 'recentArticle' => [ + 'id' => true, + 'title' => true, + 'body' => true + ] + ] + ] + ]; + + $hasCalled = false; + $actualDefaultSelection = null; + $actualDeepSelection = null; + + $blogQuery = new ObjectType([ + 'name' => 'Query', + 'fields' => [ + 'article' => [ + 'type' => $article, + 'resolve' => function($value, $args, ResolveInfo $info) use (&$hasCalled, &$actualDefaultSelection, &$actualDeepSelection) { + $hasCalled = true; + $actualDefaultSelection = $info->getFieldSelection(); + $actualDeepSelection = $info->getFieldSelection(5); + return null; + } + ] + ] + ]); + + $schema = new Schema($blogQuery); + $result = GraphQL::execute($schema, $doc); + + $this->assertTrue($hasCalled); + $this->assertEquals(['data' => ['article' => null]], $result); + $this->assertEquals($expectedDefaultSelection, $actualDefaultSelection); + $this->assertEquals($expectedDeepSelection, $actualDeepSelection); + } +} \ No newline at end of file