Skip to content

Commit 00440d2

Browse files
Handle list value nodes
1 parent 9e5a150 commit 00440d2

7 files changed

+195
-3
lines changed

src/HotChocolate/Core/src/Validation/Rules/FieldVisitor.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,19 @@ private static bool IsValueIdentical(
394394
{
395395
var (currentA, currentB) = stack.Pop();
396396

397-
if (currentA is ObjectValueNode objectA && currentB is ObjectValueNode objectB)
397+
if (currentA is ListValueNode listA && currentB is ListValueNode listB)
398+
{
399+
if (listA.Items.Count != listB.Items.Count)
400+
{
401+
return false;
402+
}
403+
404+
for (var i = 0; i < listA.Items.Count; i++)
405+
{
406+
stack.Push((listA.Items[i], listB.Items[i]));
407+
}
408+
}
409+
else if (currentA is ObjectValueNode objectA && currentB is ObjectValueNode objectB)
398410
{
399411
if (objectA.Fields.Count != objectB.Fields.Count)
400412
{

src/HotChocolate/Core/test/Validation.Tests/FieldSelectionMergingRuleTests.cs

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ fragment mergeIdenticalFieldsWithIdenticalValues on Dog {
100100
}
101101

102102
[Fact]
103-
public void MergeIdenticalFieldsWithIdenticalInputFieldValuesButDifferentOrdering()
103+
public void IdenticalInputFieldValuesButDifferentOrdering()
104104
{
105105
ExpectValid(
106106
"""
@@ -125,7 +125,30 @@ public void ConflictingInputFieldValues()
125125
ExpectErrors(
126126
"""
127127
{
128-
findDog(complex: { name: "A", owner: "OTHER", child: { owner: "D", name: "C" } }) {
128+
findDog(complex: { name: "A", owner: "B" }) {
129+
name
130+
}
131+
... mergeIdenticalFieldsWithIdenticalInputFieldValuesButDifferentOrdering
132+
}
133+
134+
fragment mergeIdenticalFieldsWithIdenticalInputFieldValuesButDifferentOrdering on Query {
135+
findDog(complex: { owner: "OTHER", name: "A" }) {
136+
barks
137+
}
138+
}
139+
""",
140+
t => Assert.Equal(
141+
"Encountered fields for the same object that cannot be merged.",
142+
t.Message));
143+
}
144+
145+
[Fact]
146+
public void ConflictingNestedInputFieldValues()
147+
{
148+
ExpectErrors(
149+
"""
150+
{
151+
findDog(complex: { name: "A", owner: "B", child: { owner: "D", name: "C" } }) {
129152
name
130153
}
131154
... mergeIdenticalFieldsWithIdenticalInputFieldValuesButDifferentOrdering
@@ -142,6 +165,68 @@ fragment mergeIdenticalFieldsWithIdenticalInputFieldValuesButDifferentOrdering o
142165
t.Message));
143166
}
144167

168+
[Fact]
169+
public void IdenticalInputFieldListValuesButDifferentOrdering()
170+
{
171+
ExpectValid(
172+
"""
173+
{
174+
findDog3(complexList: [
175+
{ name: "A", owner: "B", childList: [{ name: "A1", owner: "B1" }, { owner: "C1", name: "D1" }] },
176+
{ owner: "C", name: "D", childList: [{ name: "A1", owner: "B1" }, { owner: "C1", name: "D1" }] }]) {
177+
name
178+
}
179+
findDog3(complexList: [
180+
{ owner: "B", name: "A", childList: [{ owner: "B1", name: "A1" }, { name: "D1", owner: "C1" }] },
181+
{ name: "D", owner: "C", childList: [{ owner: "B1", name: "A1" }, { name: "D1", owner: "C1" }] }]) {
182+
barks
183+
}
184+
}
185+
""");
186+
}
187+
188+
[Fact]
189+
public void ConflictingInputFieldListValues()
190+
{
191+
ExpectErrors(
192+
"""
193+
{
194+
findDog3(complexList: [{ name: "A", owner: "B" }, { owner: "C", name: "D" }]) {
195+
name
196+
}
197+
findDog3(complexList: [{ owner: "B", name: "A" }, { name: "OTHER", owner: "C" }]) {
198+
barks
199+
}
200+
}
201+
""",
202+
t => Assert.Equal(
203+
"Encountered fields for the same object that cannot be merged.",
204+
t.Message));
205+
}
206+
207+
[Fact]
208+
public void ConflictingNestedInputFieldListValues()
209+
{
210+
ExpectErrors(
211+
"""
212+
{
213+
findDog3(complexList: [
214+
{ name: "A", owner: "B", childList: [{ name: "A1", owner: "B1" }, { owner: "C1", name: "D1" }] },
215+
{ owner: "C", name: "D", childList: [{ name: "A1", owner: "B1" }, { owner: "C1", name: "D1" }] }]) {
216+
name
217+
}
218+
findDog3(complexList: [
219+
{ owner: "B", name: "A", childList: [{ owner: "B1", name: "A1" }, { name: "D1", owner: "C1" }] },
220+
{ name: "D", owner: "C", childList: [{ owner: "B1", name: "A1" }, { name: "D1", owner: "OTHER" }] }]) {
221+
barks
222+
}
223+
}
224+
""",
225+
t => Assert.Equal(
226+
"Encountered fields for the same object that cannot be merged.",
227+
t.Message));
228+
}
229+
145230
[Fact]
146231
public void ConflictingArgsOnValues()
147232
{
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
namespace HotChocolate.Validation;
2+
3+
public record ComplexInput3(string Name, string Owner, List<ComplexInput3>? ChildList = null);

src/HotChocolate/Core/test/Validation.Tests/Models/Query.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ public class Query
3535
return null;
3636
}
3737

38+
public Dog? FindDog3(List<ComplexInput3> complexList)
39+
{
40+
return null;
41+
}
42+
3843
public bool BooleanList(bool[]? booleanListArg)
3944
{
4045
return true;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[
2+
{
3+
"Message": "Encountered fields for the same object that cannot be merged.",
4+
"Code": null,
5+
"Path": null,
6+
"Locations": [
7+
{
8+
"Line": 2,
9+
"Column": 5
10+
},
11+
{
12+
"Line": 5,
13+
"Column": 5
14+
}
15+
],
16+
"Extensions": {
17+
"declaringTypeA": "Query",
18+
"declaringTypeB": "Query",
19+
"fieldA": "findDog3",
20+
"fieldB": "findDog3",
21+
"typeA": "Dog",
22+
"typeB": "Dog",
23+
"responseNameA": "findDog3",
24+
"responseNameB": "findDog3",
25+
"specifiedBy": "https://spec.graphql.org/October2021/#sec-Field-Selection-Merging"
26+
},
27+
"Exception": null
28+
}
29+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[
2+
{
3+
"Message": "Encountered fields for the same object that cannot be merged.",
4+
"Code": null,
5+
"Path": null,
6+
"Locations": [
7+
{
8+
"Line": 2,
9+
"Column": 5
10+
},
11+
{
12+
"Line": 7,
13+
"Column": 5
14+
}
15+
],
16+
"Extensions": {
17+
"declaringTypeA": "Query",
18+
"declaringTypeB": "Query",
19+
"fieldA": "findDog3",
20+
"fieldB": "findDog3",
21+
"typeA": "Dog",
22+
"typeB": "Dog",
23+
"responseNameA": "findDog3",
24+
"responseNameB": "findDog3",
25+
"specifiedBy": "https://spec.graphql.org/October2021/#sec-Field-Selection-Merging"
26+
},
27+
"Exception": null
28+
}
29+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[
2+
{
3+
"Message": "Encountered fields for the same object that cannot be merged.",
4+
"Code": null,
5+
"Path": null,
6+
"Locations": [
7+
{
8+
"Line": 2,
9+
"Column": 5
10+
},
11+
{
12+
"Line": 9,
13+
"Column": 5
14+
}
15+
],
16+
"Extensions": {
17+
"declaringTypeA": "Query",
18+
"declaringTypeB": "Query",
19+
"fieldA": "findDog",
20+
"fieldB": "findDog",
21+
"typeA": "Dog",
22+
"typeB": "Dog",
23+
"responseNameA": "findDog",
24+
"responseNameB": "findDog",
25+
"specifiedBy": "https://spec.graphql.org/October2021/#sec-Field-Selection-Merging"
26+
},
27+
"Exception": null
28+
}
29+
]

0 commit comments

Comments
 (0)