diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Execution/Planning/OperationPlanner.BuildExecutionTree.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Execution/Planning/OperationPlanner.BuildExecutionTree.cs index e0ebd290913..d64b0de1136 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Execution/Planning/OperationPlanner.BuildExecutionTree.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Execution/Planning/OperationPlanner.BuildExecutionTree.cs @@ -851,6 +851,7 @@ private static bool DoVariablesContainUploadScalar( ISchemaDefinition schema) { var inputObjectTypes = new Queue(); + var visited = new HashSet(ReferenceEqualityComparer.Instance); foreach (var variable in variables) { @@ -862,7 +863,7 @@ private static bool DoVariablesContainUploadScalar( return true; } - if (variableType is IInputObjectTypeDefinition inputObjectType) + if (variableType is IInputObjectTypeDefinition inputObjectType && visited.Add(inputObjectType)) { inputObjectTypes.Enqueue(inputObjectType); } @@ -879,7 +880,7 @@ private static bool DoVariablesContainUploadScalar( return true; } - if (fieldType is IInputObjectTypeDefinition nestedInputObjectType) + if (fieldType is IInputObjectTypeDefinition nestedInputObjectType && visited.Add(nestedInputObjectType)) { inputObjectTypes.Enqueue(nestedInputObjectType); } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/IntegrationTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/IntegrationTests.cs new file mode 100644 index 00000000000..cd322cec532 --- /dev/null +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/IntegrationTests.cs @@ -0,0 +1,53 @@ +using HotChocolate.Transport; +using HotChocolate.Transport.Http; + +namespace HotChocolate.Fusion; + +public class IntegrationTests : FusionTestBase +{ + [Fact] + public async Task Recursive_Input_Object_Type() + { + // arrange + using var server1 = CreateSourceSchema( + "A", + """ + type Query { + field(input: RecursiveInput!): String + } + + input RecursiveInput { + child: RecursiveInput + } + """); + + using var gateway = await CreateCompositeSchemaAsync( + [ + ("A", server1) + ]); + + // act + using var client = GraphQLHttpClient.Create(gateway.CreateClient()); + + var request = new OperationRequest( + """ + query testQuery($input: RecursiveInput!) { + field(input: $input) + } + """, + variables: new Dictionary + { + ["input"] = new Dictionary + { + ["child"] = null + } + }); + + using var result = await client.PostAsync( + request, + new Uri("http://localhost:5000/graphql")); + + // assert + await MatchSnapshotAsync(gateway, request, result); + } +} diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/IntegrationTests.Recursive_Input_Object_Type.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/IntegrationTests.Recursive_Input_Object_Type.yaml new file mode 100644 index 00000000000..17ebc236a91 --- /dev/null +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/IntegrationTests.Recursive_Input_Object_Type.yaml @@ -0,0 +1,81 @@ +title: Recursive_Input_Object_Type +request: + document: | + query testQuery( + $input: RecursiveInput! + ) { + field(input: $input) + } + variables: | + { + "input": { + "child": null + } + } +response: + body: | + { + "data": { + "field": "Query" + } + } +sourceSchemas: + - name: A + schema: | + schema { + query: Query + } + + type Query { + field(input: RecursiveInput!): String + } + + input RecursiveInput { + child: RecursiveInput + } + interactions: + - request: + document: | + query testQuery_4b201a4f_1( + $input: RecursiveInput! + ) { + field(input: $input) + } + variables: | + { + "input": { + "child": null + } + } + response: + results: + - | + { + "data": { + "field": "Query" + } + } +operationPlan: + operation: + - document: | + query testQuery( + $input: RecursiveInput! + ) { + field(input: $input) + } + name: testQuery + hash: 4b201a4f390fe386d2d0db5091a152b3 + searchSpace: 1 + expandedNodes: 1 + nodes: + - id: 1 + type: Operation + schema: A + operation: | + query testQuery_4b201a4f_1( + $input: RecursiveInput! + ) { + field(input: $input) + } + forwardedVariables: + - input