From 64c7870be7986cdb0b8f5ed181a7dfc9cc8e5203 Mon Sep 17 00:00:00 2001 From: Jonathan Haines Date: Wed, 8 Jun 2022 07:22:13 +1000 Subject: [PATCH 1/2] tests: query for nested interface --- __tests__/gql/queries/object-kitchen-sink.gql | 9 +++++++++ __tests__/gql/schema.gql | 2 ++ .../integration/queries/object-kitchen-sink-test.js | 12 ++++++++++++ 3 files changed, 23 insertions(+) diff --git a/__tests__/gql/queries/object-kitchen-sink.gql b/__tests__/gql/queries/object-kitchen-sink.gql index 3248ab6..1d4f3ff 100644 --- a/__tests__/gql/queries/object-kitchen-sink.gql +++ b/__tests__/gql/queries/object-kitchen-sink.gql @@ -66,6 +66,15 @@ query TestObject($id: ID!) { label } } + interfaceNestedNonNullField { + ... on TestInterface { + id + label + } + ... on TestImplOne { + description + } + } relayConnectionField(first: 1, after: "VGVzdFJlbGF5Tm9kZTox") { ...testRelayConnection } diff --git a/__tests__/gql/schema.gql b/__tests__/gql/schema.gql index 4ebb7ba..f5b3577 100644 --- a/__tests__/gql/schema.gql +++ b/__tests__/gql/schema.gql @@ -29,6 +29,7 @@ type Query { testInterface(id: ID, label: String): TestInterface testInterfaceNonNull(id: ID, label: String): TestInterface! testInterfaceOptional(id: ID!): TestInterface + testInterfaceMultiple(id: ID, label: String): [TestInterface] testObject(id: ID!): TestObject testObjectNonNull(id: ID!): TestObject! testObjects(size: String): [TestObject] @@ -91,6 +92,7 @@ type TestObject { hasManyNestedNonNullField: [TestOption!]! interfaceField: TestInterface interfaceNonNullField: TestInterface! + interfaceNestedNonNullField: [TestInterface!]! relayConnectionField(first: Int, after: String): TestRelayConnection relayConnectionFilteredField( first: Int diff --git a/__tests__/integration/queries/object-kitchen-sink-test.js b/__tests__/integration/queries/object-kitchen-sink-test.js index 1a10973..86f7b8b 100644 --- a/__tests__/integration/queries/object-kitchen-sink-test.js +++ b/__tests__/integration/queries/object-kitchen-sink-test.js @@ -28,6 +28,13 @@ describe("Integration | queries | object", function () { server.create("test-union-one", { oneName: "foo" }), server.create("test-union-two", { twoName: "bar" }), ]; + const testInterfaces = [ + server.create("test-impl-one", { + description: "description", + label: "impl", + }), + server.create("test-impl-two", { label: "impl" }), + ]; seedUnassociatedRecords(server); @@ -41,6 +48,7 @@ describe("Integration | queries | object", function () { hasManyNonNullField: testOptions, hasManyNestedNonNullField: testOptions, interfaceField: testImpl, + interfaceNestedNonNullField: testInterfaces, interfaceNonNullField: testImpl, relayConnectionField: testRelayNodes, relayConnectionFilteredField: testRelayNodes, @@ -66,6 +74,10 @@ describe("Integration | queries | object", function () { hasManyNonNullField: [{ id: "1", name: "opt" }], hasManyNestedNonNullField: [{ id: "1", name: "opt" }], interfaceField: { id: "1", label: "impl" }, + interfaceNestedNonNullField: [ + { id: "2", label: "impl", description: "description" }, + { id: "1", label: "impl" }, + ], interfaceNonNullField: { id: "1", label: "impl" }, relayConnectionField: { edges: [{ cursor: "VGVzdFJlbGF5Tm9kZToy", node: { id: "2" } }], From d82f525ebf8e1e44a3912dedab9df3a6857b9eae Mon Sep 17 00:00:00 2001 From: Jonathan Haines Date: Wed, 8 Jun 2022 07:23:20 +1000 Subject: [PATCH 2/2] fix: resolve interface list types --- .../resolvers/mirage-field-resolver-test.js | 17 +++++++++++++++++ lib/resolvers/interface.js | 15 +++++++++++++-- lib/resolvers/mirage.js | 2 +- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/__tests__/unit/resolvers/mirage-field-resolver-test.js b/__tests__/unit/resolvers/mirage-field-resolver-test.js index 408106f..147822f 100644 --- a/__tests__/unit/resolvers/mirage-field-resolver-test.js +++ b/__tests__/unit/resolvers/mirage-field-resolver-test.js @@ -106,6 +106,23 @@ describe("Unit | resolvers | mirage field resolver", function () { args, context, info, + false, + type + ); + }); + + it("can resolve interface list types", function () { + const type = typeMap.TestInterface; + const info = { returnType: queryFields.testInterfaceMultiple.type }; + + mirageGraphQLFieldResolver(obj, args, context, info); + + expect(resolveInterface).toHaveBeenCalledWith( + obj, + args, + context, + info, + true, type ); }); diff --git a/lib/resolvers/interface.js b/lib/resolvers/interface.js index 898a0d6..42ffd8f 100644 --- a/lib/resolvers/interface.js +++ b/lib/resolvers/interface.js @@ -1,3 +1,4 @@ +import resolveList from "./list"; import resolveObject from "./object"; function getTypeFromInlineFragment(info) { @@ -39,15 +40,25 @@ function resolveFromImplementations(obj, args, context, info, type) { * @param {Object} args * @param {Object} context * @param {Object} info + * @param {Boolean} isList * @param {Object} type An unwrapped type. * @see {@link https://graphql.org/learn/execution/#root-fields-resolvers} * @see resolveObject * @returns {Object} A record from Mirage's database. */ -export default function resolveInterface(obj, args, context, info, type) { +export default function resolveInterface( + obj, + args, + context, + info, + isList, + type +) { const implType = getTypeFromInlineFragment(info); - return implType + return isList + ? resolveList(obj, args, context, info, type) + : implType ? resolveObject(obj, args, context, info, implType) : resolveFromImplementations(obj, args, context, info, type); } diff --git a/lib/resolvers/mirage.js b/lib/resolvers/mirage.js index b0eaebf..88fdbc0 100644 --- a/lib/resolvers/mirage.js +++ b/lib/resolvers/mirage.js @@ -30,7 +30,7 @@ export default function mirageGraphQLFieldResolver(obj, args, context, info) { let { isList, type } = unwrapType(info.returnType); return isInterfaceType(type) - ? resolveInterface(obj, args, context, info, type) + ? resolveInterface(obj, args, context, info, isList, type) : isUnionType(type) ? resolveUnion(obj, args, context, info, isList, type) : !isObjectType(type)