Skip to content

Commit

Permalink
fix(typeMerging): field selection sets (#1958)
Browse files Browse the repository at this point in the history
should work on their own when necessary

see: #1956
  • Loading branch information
yaacovCR committed Aug 27, 2020
1 parent 024b49a commit fd404d1
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 15 deletions.
34 changes: 19 additions & 15 deletions packages/delegate/src/results/mergeFields.ts
Expand Up @@ -26,23 +26,27 @@ const sortSubschemasByProxiability = memoize4(function (
targetSubschemas.forEach(t => {
const selectionSet = mergedTypeInfo.selectionSets.get(t);
const fieldSelectionSets = mergedTypeInfo.fieldSelectionSets.get(t);
if (!subschemaTypesContainSelectionSet(mergedTypeInfo, sourceSubschemaOrSourceSubschemas, selectionSet)) {
nonProxiableSubschemas.push(t);
} else if (fieldSelectionSets == null) {
proxiableSubschemas.push(t);
} else if (
fieldNodes.every(fieldNode => {
const fieldName = fieldNode.name.value;
const fieldSelectionSet = fieldSelectionSets[fieldName];
return (
fieldSelectionSet == null ||
subschemaTypesContainSelectionSet(mergedTypeInfo, sourceSubschemaOrSourceSubschemas, fieldSelectionSet)
);
})
if (
selectionSet != null &&
!subschemaTypesContainSelectionSet(mergedTypeInfo, sourceSubschemaOrSourceSubschemas, selectionSet)
) {
proxiableSubschemas.push(t);
} else {
nonProxiableSubschemas.push(t);
} else {
if (
fieldSelectionSets == null ||
fieldNodes.every(fieldNode => {
const fieldName = fieldNode.name.value;
const fieldSelectionSet = fieldSelectionSets[fieldName];
return (
fieldSelectionSet == null ||
subschemaTypesContainSelectionSet(mergedTypeInfo, sourceSubschemaOrSourceSubschemas, fieldSelectionSet)
);
})
) {
proxiableSubschemas.push(t);
} else {
nonProxiableSubschemas.push(t);
}
}
});

Expand Down
117 changes: 117 additions & 0 deletions packages/stitch/tests/fieldSelectionSets.test.ts
@@ -0,0 +1,117 @@
import { graphql } from 'graphql';
import { makeExecutableSchema } from '@graphql-tools/schema';
import { stitchSchemas } from '@graphql-tools/stitch';

describe('type merging with only field selection sets', () => {
const listingsSchema = makeExecutableSchema({
typeDefs: `
type Listing {
id: ID!
sellerId: ID!
buyerId: ID
}
type Query {
listing(id: ID!): Listing
}
`,
resolvers: {
Query: {
listing: () => ({ id: 1, buyerId: 2, sellerId: 3 })
},
},
});

const usersSchema = makeExecutableSchema({
typeDefs: `
type User {
id: ID!
userName: String
}
type Listing {
seller: User!
buyer: User
}
input ListingKeys {
sellerId: ID
buyerId: ID
}
type Query {
_listings(keys: [ListingKeys!]!): [Listing]!
}
`,
resolvers: {
Query: {
_listings: (_root, args) => args.keys,
},
Listing: {
buyer: (_root, args) => ({ id: args.buyerId, userName: 'Bob' }),
seller: (_root, args) => ({ id: args.sellerId, userName: 'Tom' }),
}
},
});

const stitchedSchema = stitchSchemas({
subschemas: [
{
schema: listingsSchema,
merge: {
Listing: {
selectionSet: '{ id }',
fieldName: 'listing',
args: ({ id }) => ({ id })
}
}
},
{
schema: usersSchema,
merge: {
Listing: {
// selectionSet: '{ id }', // <~ required? We don't need this data for anything here
fields: {
buyer: { selectionSet: '{ buyerId }' },
seller: { selectionSet: '{ sellerId }' },
},
fieldName: '_listings',
key: ({ buyerId, sellerId }) => ({ buyerId, sellerId }),
argsFromKeys: (keys) => ({ keys }),
}
}
}
],
mergeTypes: true,
});

test('errors without selectionSet...', async () => {
const result = await graphql(
stitchedSchema, `
query {
listing(id: 23) {
id
buyer {
userName
}
seller {
userName
}
}
}
`,
);

const expectedResult = {
data: {
listing: {
id: '1',
buyer: {
userName: 'Bob',
},
seller: {
userName: 'Tom',
}
},
},
};

expect(result).toEqual(expectedResult);
});
});

0 comments on commit fd404d1

Please sign in to comment.