diff --git a/src/core/blueprint/operators/graphql.rs b/src/core/blueprint/operators/graphql.rs index d54547b714..f292deeb19 100644 --- a/src/core/blueprint/operators/graphql.rs +++ b/src/core/blueprint/operators/graphql.rs @@ -20,7 +20,6 @@ fn create_related_fields( if visited.contains(type_name) { return RelatedFields(map); } - visited.insert(type_name.to_string()); if let Some(type_) = config.find_type(type_name) { for (name, field) in &type_.fields { @@ -34,6 +33,8 @@ fn create_related_fields( create_related_fields(config, field.type_of.name(), visited), ), ); + + visited.insert(type_name.to_string()); } } else { map.insert( @@ -43,6 +44,7 @@ fn create_related_fields( create_related_fields(config, field.type_of.name(), visited), ), ); + visited.insert(type_name.to_string()); } } } @@ -51,7 +53,7 @@ fn create_related_fields( map.extend(create_related_fields(config, type_name, visited).0); } }; - + visited.insert(type_name.to_string()); RelatedFields(map) } diff --git a/tests/core/snapshots/graphql-conformance-019.md_0.snap b/tests/core/snapshots/graphql-conformance-019.md_0.snap new file mode 100644 index 0000000000..aac2aedd4d --- /dev/null +++ b/tests/core/snapshots/graphql-conformance-019.md_0.snap @@ -0,0 +1,21 @@ +--- +source: tests/core/spec.rs +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": { + "user": { + "newName": "Tailcall", + "userPost": { + "id": 0, + "content": "Hello from user 4" + } + } + } + } +} diff --git a/tests/core/snapshots/graphql-conformance-019.md_1.snap b/tests/core/snapshots/graphql-conformance-019.md_1.snap new file mode 100644 index 0000000000..851fbb2a18 --- /dev/null +++ b/tests/core/snapshots/graphql-conformance-019.md_1.snap @@ -0,0 +1,21 @@ +--- +source: tests/core/spec.rs +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": { + "page": { + "name": "Tailcall_page", + "pagePost": { + "id": 1, + "content": "Hello from page 4" + } + } + } + } +} diff --git a/tests/core/snapshots/graphql-conformance-019.md_client.snap b/tests/core/snapshots/graphql-conformance-019.md_client.snap new file mode 100644 index 0000000000..d9a4392d36 --- /dev/null +++ b/tests/core/snapshots/graphql-conformance-019.md_client.snap @@ -0,0 +1,29 @@ +--- +source: tests/core/spec.rs +expression: formatted +--- +type Page { + id: ID! + name: String! + pagePost: Post +} + +type Post { + content: String + id: ID! +} + +type Query { + page(id: ID!): Page! + user(id: ID!): User! +} + +type User { + id: ID! + newName: String! + userPost: Post +} + +schema { + query: Query +} diff --git a/tests/core/snapshots/graphql-conformance-019.md_merged.snap b/tests/core/snapshots/graphql-conformance-019.md_merged.snap new file mode 100644 index 0000000000..3ee2db138e --- /dev/null +++ b/tests/core/snapshots/graphql-conformance-019.md_merged.snap @@ -0,0 +1,31 @@ +--- +source: tests/core/spec.rs +expression: formatter +--- +schema @server(hostname: "0.0.0.0", port: 8001, queryValidation: false) @upstream(httpCache: 42) { + query: Query +} + +type Page { + id: ID! + name: String! + post: Post @modify(name: "pagePost") +} + +type Post { + content: String + id: ID! +} + +type Query { + page(id: ID!): Page! + @graphQL(args: [{key: "id", value: "{{.args.id}}"}], url: "http://upstream/graphql", name: "page") + user(id: ID!): User! + @graphQL(args: [{key: "id", value: "{{.args.id}}"}], url: "http://upstream/graphql", name: "user") +} + +type User { + id: ID! + name: String! @modify(name: "newName") + post: Post @modify(name: "userPost") +} diff --git a/tests/execution/graphql-conformance-019.md b/tests/execution/graphql-conformance-019.md new file mode 100644 index 0000000000..0ed73cd6a4 --- /dev/null +++ b/tests/execution/graphql-conformance-019.md @@ -0,0 +1,91 @@ +# Composed queries with field modify check + +```graphql @config +schema @server(port: 8001, queryValidation: false, hostname: "0.0.0.0") @upstream(httpCache: 42) { + query: Query +} + +type Query { + user(id: ID!): User! + @graphQL(url: "http://upstream/graphql", name: "user", args: [{key: "id", value: "{{.args.id}}"}]) + page(id: ID!): Page! + @graphQL(url: "http://upstream/graphql", name: "page", args: [{key: "id", value: "{{.args.id}}"}]) +} + +type User { + id: ID! + name: String! @modify(name: "newName") + post: Post @modify(name: "userPost") +} + +type Page { + id: ID! + name: String! + post: Post @modify(name: "pagePost") +} + +type Post { + id: ID! + content: String +} +``` + +```yml @mock +- request: + method: POST + url: http://upstream/graphql + textBody: '{ "query": "query { user(id: 4) { name post { id content } } }" }' + expectedHits: 1 + response: + status: 200 + body: + data: + user: + name: Tailcall + post: + id: 0 + content: Hello from user 4 +- request: + method: POST + url: http://upstream/graphql + textBody: '{ "query": "query { page(id: 4) { name post { id content } } }" }' + expectedHits: 1 + response: + status: 200 + body: + data: + page: + name: Tailcall_page + post: + id: 1 + content: Hello from page 4 +``` + +```yml @test +- method: POST + url: http://localhost:8080/graphql + body: + query: | + query getUser { + user(id: 4) { + newName + userPost { + id + content + } + } + } +- method: POST + url: http://localhost:8080/graphql + body: + query: | + query getPage { + page(id: 4) { + name + pagePost { + id + content + } + } + } +```