diff --git a/test/src/test/kotlin/graphql/nadel/tests/hooks/polymorphic-hydration-hook-using-alias-helper.kt b/test/src/test/kotlin/graphql/nadel/tests/hooks/polymorphic-hydration-hook-using-alias-helper.kt index 6056e6043..11a68579f 100644 --- a/test/src/test/kotlin/graphql/nadel/tests/hooks/polymorphic-hydration-hook-using-alias-helper.kt +++ b/test/src/test/kotlin/graphql/nadel/tests/hooks/polymorphic-hydration-hook-using-alias-helper.kt @@ -62,6 +62,18 @@ open class PolymorphicHydrationWithAliasTestHook : EngineTestHook { @UseHook class `batch-polymorphic-hydration` : PolymorphicHydrationWithAliasTestHook() +@UseHook +class `batch-polymorphic-hydration-return-null-in-array` : PolymorphicHydrationWithAliasTestHook() + +@UseHook +class `batch-polymorphic-hydration-return-null-in-array-with-error` : PolymorphicHydrationWithAliasTestHook() + +@UseHook +class `batch-polymorphic-hydration-return-top-level-null` : PolymorphicHydrationWithAliasTestHook() + +@UseHook +class `batch-polymorphic-hydration-return-top-level-null-and-error` : PolymorphicHydrationWithAliasTestHook() + @UseHook class `batch-polymorphic-hydration-actor-fields-are-in-the-same-service` : PolymorphicHydrationWithAliasTestHook() diff --git a/test/src/test/resources/fixtures/new hydration/polymorphic hydrations/batch-polymorphic-hydration-return-null-in-array-with-error.yml b/test/src/test/resources/fixtures/new hydration/polymorphic hydrations/batch-polymorphic-hydration-return-null-in-array-with-error.yml new file mode 100644 index 000000000..4b0796dbf --- /dev/null +++ b/test/src/test/resources/fixtures/new hydration/polymorphic hydrations/batch-polymorphic-hydration-return-null-in-array-with-error.yml @@ -0,0 +1,267 @@ +name: "batch polymorphic hydration return null in array with error" +enabled: true +# language=GraphQL +overallSchema: + pets: | + type Query { + petById(ids: [ID]): [Pet] + } + + type Pet { + id: ID + breed: String + } + people: | + type Query { + humanById(ids: [ID]): [Human] + } + + type Human { + id: ID + name: String + } + foo: | + type Query { + foo: [Foo] + } + + type Foo { + id: ID + dataId: ID + data: Data + @hydrated( + service: "pets" + field: "petById" + arguments: [ + {name: "ids" value: "$source.dataId"} + ] + ) + @hydrated( + service: "people" + field: "humanById" + arguments: [ + {name: "ids" value: "$source.dataId"} + ] + ) + } + + union Data = Pet | Human +# language=GraphQL +underlyingSchema: + pets: | + type Query { + petById(ids: [ID]): [Pet] + } + + type Pet { + id: ID + breed: String + } + people: | + type Query { + humanById(ids: [ID]): [Human] + } + + type Human { + id: ID + name: String + } + foo: | + type Query { + foo: [Foo] + } + + type Foo { + id: ID + dataId: ID + } +# language=GraphQL +query: | + query { + foo { + __typename + id + data { + ... on Pet { + __typename + id + breed + } + ... on Human { + __typename + id + name + } + } + } + } +variables: { } +serviceCalls: + - serviceName: "foo" + request: + # language=GraphQL + query: | + query { + foo { + __typename + __typename__batch_hydration__data: __typename + batch_hydration__data__dataId: dataId + batch_hydration__data__dataId: dataId + id + } + } + variables: { } + # language=JSON + response: |- + { + "data": { + "foo": [ + { + "__typename": "Foo", + "__typename__batch_hydration__data": "Foo", + "batch_hydration__data__dataId": "PET-0", + "batch_hydration__data__dataId": "PET-0", + "id": "FOO-0" + }, + { + "__typename": "Foo", + "__typename__batch_hydration__data": "Foo", + "batch_hydration__data__dataId": "HUMAN-0", + "batch_hydration__data__dataId": "HUMAN-0", + "id": "FOO-1" + }, + { + "__typename": "Foo", + "__typename__batch_hydration__data": "Foo", + "batch_hydration__data__dataId": "PET-1", + "batch_hydration__data__dataId": "PET-1", + "id": "FOO-2" + }, + { + "__typename": "Foo", + "__typename__batch_hydration__data": "Foo", + "batch_hydration__data__dataId": "HUMAN-1", + "batch_hydration__data__dataId": "HUMAN-1", + "id": "FOO-3" + } + ] + }, + "extensions": {} + } + - serviceName: "pets" + request: + # language=GraphQL + query: | + query { + petById(ids: ["PET-0", "PET-1"]) { + __typename + breed + id + batch_hydration__data__id: id + } + } + variables: { } + # language=JSON + response: |- + { + "data": { + "petById": [ + null, + { + "__typename": "Pet", + "breed": "Labrador", + "id": "PET-1", + "batch_hydration__data__id": "PET-1" + } + ] + }, + "errors": [ + { + "message": "invalid id PET-0" + } + ], + "extensions": {} + } + - serviceName: "people" + request: + # language=GraphQL + query: | + query { + humanById(ids: ["HUMAN-0", "HUMAN-1"]) { + __typename + id + batch_hydration__data__id: id + name + } + } + variables: { } + # language=JSON + response: |- + { + "data": { + "humanById": [ + { + "__typename": "Human", + "id": "HUMAN-0", + "batch_hydration__data__id": "HUMAN-0", + "name": "Fanny Longbottom" + }, + { + "__typename": "Human", + "id": "HUMAN-1", + "batch_hydration__data__id": "HUMAN-1", + "name": "John Doe" + } + ] + }, + "extensions": {} + } +# language=JSON +response: |- + { + "data": { + "foo": [ + { + "__typename": "Foo", + "id": "FOO-0", + "data": null + }, + { + "__typename": "Foo", + "id": "FOO-1", + "data": { + "__typename": "Human", + "id": "HUMAN-0", + "name": "Fanny Longbottom" + } + }, + { + "__typename": "Foo", + "id": "FOO-2", + "data": { + "__typename": "Pet", + "breed": "Labrador", + "id": "PET-1" + } + }, + { + "__typename": "Foo", + "id": "FOO-3", + "data": { + "__typename": "Human", + "id": "HUMAN-1", + "name": "John Doe" + } + } + ] + }, + "errors": [ + { + "message": "invalid id PET-0", + "locations": [], + "extensions": { + "classification": "DataFetchingException" + } + } + ] + } diff --git a/test/src/test/resources/fixtures/new hydration/polymorphic hydrations/batch-polymorphic-hydration-return-null-in-array.yml b/test/src/test/resources/fixtures/new hydration/polymorphic hydrations/batch-polymorphic-hydration-return-null-in-array.yml new file mode 100644 index 000000000..976a2d229 --- /dev/null +++ b/test/src/test/resources/fixtures/new hydration/polymorphic hydrations/batch-polymorphic-hydration-return-null-in-array.yml @@ -0,0 +1,254 @@ +name: "batch polymorphic hydration return null in array" +enabled: true +# language=GraphQL +overallSchema: + pets: | + type Query { + petById(ids: [ID]): [Pet] + } + + type Pet { + id: ID + breed: String + } + people: | + type Query { + humanById(ids: [ID]): [Human] + } + + type Human { + id: ID + name: String + } + foo: | + type Query { + foo: [Foo] + } + + type Foo { + id: ID + dataId: ID + data: Data + @hydrated( + service: "pets" + field: "petById" + arguments: [ + {name: "ids" value: "$source.dataId"} + ] + ) + @hydrated( + service: "people" + field: "humanById" + arguments: [ + {name: "ids" value: "$source.dataId"} + ] + ) + } + + union Data = Pet | Human +# language=GraphQL +underlyingSchema: + pets: | + type Query { + petById(ids: [ID]): [Pet] + } + + type Pet { + id: ID + breed: String + } + people: | + type Query { + humanById(ids: [ID]): [Human] + } + + type Human { + id: ID + name: String + } + foo: | + type Query { + foo: [Foo] + } + + type Foo { + id: ID + dataId: ID + } +# language=GraphQL +query: | + query { + foo { + __typename + id + data { + ... on Pet { + __typename + id + breed + } + ... on Human { + __typename + id + name + } + } + } + } +variables: { } +serviceCalls: + - serviceName: "foo" + request: + # language=GraphQL + query: | + query { + foo { + __typename + __typename__batch_hydration__data: __typename + batch_hydration__data__dataId: dataId + batch_hydration__data__dataId: dataId + id + } + } + variables: { } + # language=JSON + response: |- + { + "data": { + "foo": [ + { + "__typename": "Foo", + "__typename__batch_hydration__data": "Foo", + "batch_hydration__data__dataId": "PET-0", + "batch_hydration__data__dataId": "PET-0", + "id": "FOO-0" + }, + { + "__typename": "Foo", + "__typename__batch_hydration__data": "Foo", + "batch_hydration__data__dataId": "HUMAN-0", + "batch_hydration__data__dataId": "HUMAN-0", + "id": "FOO-1" + }, + { + "__typename": "Foo", + "__typename__batch_hydration__data": "Foo", + "batch_hydration__data__dataId": "PET-1", + "batch_hydration__data__dataId": "PET-1", + "id": "FOO-2" + }, + { + "__typename": "Foo", + "__typename__batch_hydration__data": "Foo", + "batch_hydration__data__dataId": "HUMAN-1", + "batch_hydration__data__dataId": "HUMAN-1", + "id": "FOO-3" + } + ] + }, + "extensions": {} + } + - serviceName: "pets" + request: + # language=GraphQL + query: | + query { + petById(ids: ["PET-0", "PET-1"]) { + __typename + breed + id + batch_hydration__data__id: id + } + } + variables: { } + # language=JSON + response: |- + { + "data": { + "petById": [ + null, + { + "__typename": "Pet", + "breed": "Labrador", + "id": "PET-1", + "batch_hydration__data__id": "PET-1" + } + ] + }, + "extensions": {} + } + - serviceName: "people" + request: + # language=GraphQL + query: | + query { + humanById(ids: ["HUMAN-0", "HUMAN-1"]) { + __typename + id + batch_hydration__data__id: id + name + } + } + variables: { } + # language=JSON + response: |- + { + "data": { + "humanById": [ + { + "__typename": "Human", + "id": "HUMAN-0", + "batch_hydration__data__id": "HUMAN-0", + "name": "Fanny Longbottom" + }, + { + "__typename": "Human", + "id": "HUMAN-1", + "batch_hydration__data__id": "HUMAN-1", + "name": "John Doe" + } + ] + }, + "extensions": {} + } +# language=JSON +response: |- + { + "data": { + "foo": [ + { + "__typename": "Foo", + "id": "FOO-0", + "data": null + }, + { + "__typename": "Foo", + "id": "FOO-1", + "data": { + "__typename": "Human", + "id": "HUMAN-0", + "name": "Fanny Longbottom" + } + }, + { + "__typename": "Foo", + "id": "FOO-2", + "data": { + "__typename": "Pet", + "breed": "Labrador", + "id": "PET-1" + } + }, + { + "__typename": "Foo", + "id": "FOO-3", + "data": { + "__typename": "Human", + "id": "HUMAN-1", + "name": "John Doe" + } + } + ] + }, + "errors": [] + } diff --git a/test/src/test/resources/fixtures/new hydration/polymorphic hydrations/batch-polymorphic-hydration-return-top-level-null-and-error.yml b/test/src/test/resources/fixtures/new hydration/polymorphic hydrations/batch-polymorphic-hydration-return-top-level-null-and-error.yml new file mode 100644 index 000000000..d1a87f6ce --- /dev/null +++ b/test/src/test/resources/fixtures/new hydration/polymorphic hydrations/batch-polymorphic-hydration-return-top-level-null-and-error.yml @@ -0,0 +1,253 @@ +name: "batch polymorphic hydration return top level null and error" +enabled: true +# language=GraphQL +overallSchema: + pets: | + type Query { + petById(ids: [ID]): [Pet] + } + + type Pet { + id: ID + breed: String + } + people: | + type Query { + humanById(ids: [ID]): [Human] + } + + type Human { + id: ID + name: String + } + foo: | + type Query { + foo: [Foo] + } + + type Foo { + id: ID + dataId: ID + data: Data + @hydrated( + service: "pets" + field: "petById" + arguments: [ + {name: "ids" value: "$source.dataId"} + ] + ) + @hydrated( + service: "people" + field: "humanById" + arguments: [ + {name: "ids" value: "$source.dataId"} + ] + ) + } + + union Data = Pet | Human +# language=GraphQL +underlyingSchema: + pets: | + type Query { + petById(ids: [ID]): [Pet] + } + + type Pet { + id: ID + breed: String + } + people: | + type Query { + humanById(ids: [ID]): [Human] + } + + type Human { + id: ID + name: String + } + foo: | + type Query { + foo: [Foo] + } + + type Foo { + id: ID + dataId: ID + } +# language=GraphQL +query: | + query { + foo { + __typename + id + data { + ... on Pet { + __typename + id + breed + } + ... on Human { + __typename + id + name + } + } + } + } +variables: { } +serviceCalls: + - serviceName: "foo" + request: + # language=GraphQL + query: | + query { + foo { + __typename + __typename__batch_hydration__data: __typename + batch_hydration__data__dataId: dataId + batch_hydration__data__dataId: dataId + id + } + } + variables: { } + # language=JSON + response: |- + { + "data": { + "foo": [ + { + "__typename": "Foo", + "__typename__batch_hydration__data": "Foo", + "batch_hydration__data__dataId": "PET-0", + "batch_hydration__data__dataId": "PET-0", + "id": "FOO-0" + }, + { + "__typename": "Foo", + "__typename__batch_hydration__data": "Foo", + "batch_hydration__data__dataId": "HUMAN-0", + "batch_hydration__data__dataId": "HUMAN-0", + "id": "FOO-1" + }, + { + "__typename": "Foo", + "__typename__batch_hydration__data": "Foo", + "batch_hydration__data__dataId": "PET-1", + "batch_hydration__data__dataId": "PET-1", + "id": "FOO-2" + }, + { + "__typename": "Foo", + "__typename__batch_hydration__data": "Foo", + "batch_hydration__data__dataId": "HUMAN-1", + "batch_hydration__data__dataId": "HUMAN-1", + "id": "FOO-3" + } + ] + }, + "extensions": {} + } + - serviceName: "pets" + request: + # language=GraphQL + query: | + query { + petById(ids: ["PET-0", "PET-1"]) { + __typename + breed + id + batch_hydration__data__id: id + } + } + variables: { } + # language=JSON + response: |- + { + "data": null, + "errors": [ + { + "message": "something went wrong" + } + ], + "extensions": {} + } + - serviceName: "people" + request: + # language=GraphQL + query: | + query { + humanById(ids: ["HUMAN-0", "HUMAN-1"]) { + __typename + id + batch_hydration__data__id: id + name + } + } + variables: { } + # language=JSON + response: |- + { + "data": { + "humanById": [ + { + "__typename": "Human", + "id": "HUMAN-0", + "batch_hydration__data__id": "HUMAN-0", + "name": "Fanny Longbottom" + }, + { + "__typename": "Human", + "id": "HUMAN-1", + "batch_hydration__data__id": "HUMAN-1", + "name": "John Doe" + } + ] + }, + "extensions": {} + } +# language=JSON +response: |- + { + "data": { + "foo": [ + { + "__typename": "Foo", + "id": "FOO-0", + "data": null + }, + { + "__typename": "Foo", + "id": "FOO-1", + "data": { + "__typename": "Human", + "id": "HUMAN-0", + "name": "Fanny Longbottom" + } + }, + { + "__typename": "Foo", + "id": "FOO-2", + "data": null + }, + { + "__typename": "Foo", + "id": "FOO-3", + "data": { + "__typename": "Human", + "id": "HUMAN-1", + "name": "John Doe" + } + } + ] + }, + "errors": [ + { + "message": "something went wrong", + "locations": [], + "extensions": { + "classification": "DataFetchingException" + } + } + ] + } diff --git a/test/src/test/resources/fixtures/new hydration/polymorphic hydrations/batch-polymorphic-hydration-return-top-level-null.yml b/test/src/test/resources/fixtures/new hydration/polymorphic hydrations/batch-polymorphic-hydration-return-top-level-null.yml new file mode 100644 index 000000000..b3e77eb34 --- /dev/null +++ b/test/src/test/resources/fixtures/new hydration/polymorphic hydrations/batch-polymorphic-hydration-return-top-level-null.yml @@ -0,0 +1,239 @@ +name: "batch polymorphic hydration return top level null" +enabled: true +# language=GraphQL +overallSchema: + pets: | + type Query { + petById(ids: [ID]): [Pet] + } + + type Pet { + id: ID + breed: String + } + people: | + type Query { + humanById(ids: [ID]): [Human] + } + + type Human { + id: ID + name: String + } + foo: | + type Query { + foo: [Foo] + } + + type Foo { + id: ID + dataId: ID + data: Data + @hydrated( + service: "pets" + field: "petById" + arguments: [ + {name: "ids" value: "$source.dataId"} + ] + ) + @hydrated( + service: "people" + field: "humanById" + arguments: [ + {name: "ids" value: "$source.dataId"} + ] + ) + } + + union Data = Pet | Human +# language=GraphQL +underlyingSchema: + pets: | + type Query { + petById(ids: [ID]): [Pet] + } + + type Pet { + id: ID + breed: String + } + people: | + type Query { + humanById(ids: [ID]): [Human] + } + + type Human { + id: ID + name: String + } + foo: | + type Query { + foo: [Foo] + } + + type Foo { + id: ID + dataId: ID + } +# language=GraphQL +query: | + query { + foo { + __typename + id + data { + ... on Pet { + __typename + id + breed + } + ... on Human { + __typename + id + name + } + } + } + } +variables: { } +serviceCalls: + - serviceName: "foo" + request: + # language=GraphQL + query: | + query { + foo { + __typename + __typename__batch_hydration__data: __typename + batch_hydration__data__dataId: dataId + batch_hydration__data__dataId: dataId + id + } + } + variables: { } + # language=JSON + response: |- + { + "data": { + "foo": [ + { + "__typename": "Foo", + "__typename__batch_hydration__data": "Foo", + "batch_hydration__data__dataId": "PET-0", + "batch_hydration__data__dataId": "PET-0", + "id": "FOO-0" + }, + { + "__typename": "Foo", + "__typename__batch_hydration__data": "Foo", + "batch_hydration__data__dataId": "HUMAN-0", + "batch_hydration__data__dataId": "HUMAN-0", + "id": "FOO-1" + }, + { + "__typename": "Foo", + "__typename__batch_hydration__data": "Foo", + "batch_hydration__data__dataId": "PET-1", + "batch_hydration__data__dataId": "PET-1", + "id": "FOO-2" + }, + { + "__typename": "Foo", + "__typename__batch_hydration__data": "Foo", + "batch_hydration__data__dataId": "HUMAN-1", + "batch_hydration__data__dataId": "HUMAN-1", + "id": "FOO-3" + } + ] + }, + "extensions": {} + } + - serviceName: "pets" + request: + # language=GraphQL + query: | + query { + petById(ids: ["PET-0", "PET-1"]) { + __typename + breed + id + batch_hydration__data__id: id + } + } + variables: { } + # language=JSON + response: |- + { + "data": null, + "extensions": {} + } + - serviceName: "people" + request: + # language=GraphQL + query: | + query { + humanById(ids: ["HUMAN-0", "HUMAN-1"]) { + __typename + id + batch_hydration__data__id: id + name + } + } + variables: { } + # language=JSON + response: |- + { + "data": { + "humanById": [ + { + "__typename": "Human", + "id": "HUMAN-0", + "batch_hydration__data__id": "HUMAN-0", + "name": "Fanny Longbottom" + }, + { + "__typename": "Human", + "id": "HUMAN-1", + "batch_hydration__data__id": "HUMAN-1", + "name": "John Doe" + } + ] + }, + "extensions": {} + } +# language=JSON +response: |- + { + "data": { + "foo": [ + { + "__typename": "Foo", + "id": "FOO-0", + "data": null + }, + { + "__typename": "Foo", + "id": "FOO-1", + "data": { + "__typename": "Human", + "id": "HUMAN-0", + "name": "Fanny Longbottom" + } + }, + { + "__typename": "Foo", + "id": "FOO-2", + "data": null + }, + { + "__typename": "Foo", + "id": "FOO-3", + "data": { + "__typename": "Human", + "id": "HUMAN-1", + "name": "John Doe" + } + } + ] + } + }