Skip to content

Commit 7ef9f91

Browse files
authored
Merge pull request #98 from decebal/master
Make ResolveInfo::getFieldSelection() to merge field sub-selections defined in different fragments
2 parents f77bd17 + ca92ae4 commit 7ef9f91

File tree

2 files changed

+161
-2
lines changed

2 files changed

+161
-2
lines changed

src/Type/Definition/ResolveInfo.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,10 @@ private function foldSelectionSet(SelectionSetNode $selectionSet, $descend)
136136
if (isset($this->fragments[$spreadName])) {
137137
/** @var FragmentDefinitionNode $fragment */
138138
$fragment = $this->fragments[$spreadName];
139-
$fields += $this->foldSelectionSet($fragment->selectionSet, $descend);
139+
$fields = array_merge_recursive($this->foldSelectionSet($fragment->selectionSet, $descend), $fields);
140140
}
141141
} else if ($selectionNode instanceof InlineFragmentNode) {
142-
$fields += $this->foldSelectionSet($selectionNode->selectionSet, $descend);
142+
$fields = array_merge_recursive($this->foldSelectionSet($selectionNode->selectionSet, $descend), $fields);
143143
}
144144
}
145145

tests/Type/ResolveInfoTest.php

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,4 +162,163 @@ public function testFieldSelection()
162162
$this->assertEquals($expectedDefaultSelection, $actualDefaultSelection);
163163
$this->assertEquals($expectedDeepSelection, $actualDeepSelection);
164164
}
165+
166+
public function testMergedFragmentsFieldSelection()
167+
{
168+
$image = new ObjectType([
169+
'name' => 'Image',
170+
'fields' => [
171+
'url' => ['type' => Type::string()],
172+
'width' => ['type' => Type::int()],
173+
'height' => ['type' => Type::int()]
174+
]
175+
]);
176+
177+
$article = null;
178+
179+
$author = new ObjectType([
180+
'name' => 'Author',
181+
'fields' => function() use ($image, &$article) {
182+
return [
183+
'id' => ['type' => Type::string()],
184+
'name' => ['type' => Type::string()],
185+
'pic' => [ 'type' => $image, 'args' => [
186+
'width' => ['type' => Type::int()],
187+
'height' => ['type' => Type::int()]
188+
]],
189+
'recentArticle' => ['type' => $article],
190+
];
191+
},
192+
]);
193+
194+
$reply = new ObjectType([
195+
'name' => 'Reply',
196+
'fields' => [
197+
'author' => ['type' => $author],
198+
'body' => ['type' => Type::string()]
199+
]
200+
]);
201+
202+
$article = new ObjectType([
203+
'name' => 'Article',
204+
'fields' => [
205+
'id' => ['type' => Type::string()],
206+
'isPublished' => ['type' => Type::boolean()],
207+
'author' => ['type' => $author],
208+
'title' => ['type' => Type::string()],
209+
'body' => ['type' => Type::string()],
210+
'image' => ['type' => $image],
211+
'replies' => ['type' => Type::listOf($reply)]
212+
]
213+
]);
214+
215+
$doc = '
216+
query Test {
217+
article {
218+
author {
219+
name
220+
pic {
221+
url
222+
width
223+
}
224+
}
225+
image {
226+
width
227+
height
228+
...MyImage
229+
}
230+
...Replies01
231+
...Replies02
232+
}
233+
}
234+
fragment MyImage on Image {
235+
url
236+
}
237+
238+
fragment Replies01 on Article {
239+
_replies012: replies {
240+
body
241+
}
242+
}
243+
fragment Replies02 on Article {
244+
_replies012: replies {
245+
author {
246+
id
247+
name
248+
pic {
249+
url
250+
width
251+
... on Image {
252+
height
253+
}
254+
}
255+
recentArticle {
256+
id
257+
title
258+
body
259+
}
260+
}
261+
}
262+
}
263+
';
264+
265+
$expectedDeepSelection = [
266+
'author' => [
267+
'name' => true,
268+
'pic' => [
269+
'url' => true,
270+
'width' => true
271+
]
272+
],
273+
'image' => [
274+
'width' => true,
275+
'height' => true,
276+
'url' => true
277+
],
278+
'replies' => [
279+
'body' => true, //this would be missing if not for the fix https://github.com/webonyx/graphql-php/pull/98
280+
'author' => [
281+
'id' => true,
282+
'name' => true,
283+
'pic' => [
284+
'url' => true,
285+
'width' => true,
286+
'height' => true
287+
],
288+
'recentArticle' => [
289+
'id' => true,
290+
'title' => true,
291+
'body' => true
292+
]
293+
]
294+
]
295+
];
296+
297+
$hasCalled = false;
298+
$actualDefaultSelection = null;
299+
$actualDeepSelection = null;
300+
301+
$blogQuery = new ObjectType([
302+
'name' => 'Query',
303+
'fields' => [
304+
'article' => [
305+
'type' => $article,
306+
'resolve' => function($value, $args, $context, ResolveInfo $info) use (&$hasCalled, &$actualDeepSelection) {
307+
$hasCalled = true;
308+
$actualDeepSelection = $info->getFieldSelection(5);
309+
return null;
310+
}
311+
]
312+
]
313+
]);
314+
315+
$schema = new Schema(['query' => $blogQuery]);
316+
$result = GraphQL::execute($schema, $doc);
317+
318+
$this->assertTrue($hasCalled);
319+
$this->assertEquals(['data' => ['article' => null]], $result);
320+
$this->assertEquals($expectedDeepSelection, $actualDeepSelection);
321+
}
322+
323+
165324
}

0 commit comments

Comments
 (0)