@apollo/federation
Version:
Apollo Federation Utilities
143 lines (126 loc) • 3.59 kB
text/typescript
import {
GraphQLSchema,
specifiedDirectives,
Kind,
DocumentNode,
} from 'graphql';
import { validateSDL } from 'graphql/validation/validate';
import {
typeSerializer,
graphqlErrorSerializer,
gql,
} from 'apollo-federation-integration-testsuite';
import { UniqueUnionTypes } from '..';
import { ServiceDefinition } from '../../../types';
import { buildMapsFromServiceList } from '../../../compose';
import { knownSubgraphDirectives } from '@apollo/subgraph/dist/directives';
expect.addSnapshotSerializer(graphqlErrorSerializer);
expect.addSnapshotSerializer(typeSerializer);
function createDocumentsForServices(
serviceList: ServiceDefinition[],
): DocumentNode[] {
const { typeDefinitionsMap, typeExtensionsMap } = buildMapsFromServiceList(
serviceList,
);
return [
{
kind: Kind.DOCUMENT,
definitions: Object.values(typeDefinitionsMap).flat(),
},
{
kind: Kind.DOCUMENT,
definitions: Object.values(typeExtensionsMap).flat(),
},
];
}
describe('MatchingUnions', () => {
let schema: GraphQLSchema;
// create a blank schema for each test
beforeEach(() => {
schema = new GraphQLSchema({
query: undefined,
directives: [...specifiedDirectives, ...knownSubgraphDirectives],
});
});
it('enforces unique union names on non-identical union types', () => {
const [definitions] = createDocumentsForServices([
{
typeDefs: gql`
union ProductOrError = Product | Error
type Error {
code: Int!
message: String!
}
type Product (fields: "sku") {
sku: ID!
}
`,
name: 'serviceA',
},
{
typeDefs: gql`
union ProductOrError = Product
type Error {
code: Int!
message: String!
}
extend type Product (fields: "sku") {
sku: ID!
colors: [String]
}
`,
name: 'serviceB',
},
]);
const errors = validateSDL(definitions, schema, [UniqueUnionTypes]);
expect(errors).toHaveLength(1);
expect(errors[0]).toMatchInlineSnapshot(`
Object {
"code": "VALUE_TYPE_UNION_TYPES_MISMATCH",
"locations": Array [
Object {
"column": 1,
"line": 2,
},
Object {
"column": 1,
"line": 2,
},
],
"message": "[serviceA] ProductOrError -> The union \`ProductOrError\` is defined in services \`serviceA\` and \`serviceB\`, however their types do not match. Union types with the same name must also consist of identical types. The type Error is mismatched.",
}
`);
});
it('permits duplicate union names for identical union types', () => {
const [definitions] = createDocumentsForServices([
{
typeDefs: gql`
union ProductOrError = Product | Error
type Error {
code: Int!
message: String!
}
type Product (fields: "sku") {
sku: ID!
}
`,
name: 'serviceA',
},
{
typeDefs: gql`
union ProductOrError = Product | Error
type Error {
code: Int!
message: String!
}
type Product (fields: "sku") {
sku: ID!
}
`,
name: 'serviceB',
},
]);
const errors = validateSDL(definitions, schema, [UniqueUnionTypes]);
expect(errors).toHaveLength(0);
});
});