1import { Kind, InlineFragmentNode } from 'graphql';
2import { describe, it, expect } from 'vitest';
3
4import { buildClientSchema } from './schema';
5import * as SchemaPredicates from './schemaPredicates';
6import { minifyIntrospectionQuery } from '@urql/introspection';
7
8const mocked = (x: any): any => x;
9
10describe('SchemaPredicates', () => {
11 const schema = buildClientSchema(
12 // eslint-disable-next-line
13 minifyIntrospectionQuery(require('../test-utils/simple_schema.json'))
14 );
15
16 const frag = (value: string): InlineFragmentNode => ({
17 kind: Kind.INLINE_FRAGMENT,
18 typeCondition: {
19 kind: Kind.NAMED_TYPE,
20 name: {
21 kind: Kind.NAME,
22 value,
23 },
24 },
25 selectionSet: {
26 kind: Kind.SELECTION_SET,
27 selections: [],
28 },
29 });
30
31 it('should match fragments by interface/union', () => {
32 expect(
33 SchemaPredicates.isInterfaceOfType(schema, frag('ITodo'), 'BigTodo')
34 ).toBeTruthy();
35 expect(
36 SchemaPredicates.isInterfaceOfType(schema, frag('ITodo'), 'SmallTodo')
37 ).toBeTruthy();
38 expect(
39 SchemaPredicates.isInterfaceOfType(schema, frag('Search'), 'BigTodo')
40 ).toBeTruthy();
41 expect(
42 SchemaPredicates.isInterfaceOfType(schema, frag('Search'), 'SmallTodo')
43 ).toBeTruthy();
44 expect(
45 SchemaPredicates.isInterfaceOfType(schema, frag('ITodo'), 'Todo')
46 ).toBeFalsy();
47 expect(
48 SchemaPredicates.isInterfaceOfType(schema, frag('Search'), 'Todo')
49 ).toBeFalsy();
50
51 const typeConditionLess = frag('Type');
52 (typeConditionLess as any).typeCondition = undefined;
53 expect(
54 SchemaPredicates.isInterfaceOfType(schema, typeConditionLess, 'Todo')
55 ).toBeTruthy();
56 });
57
58 it('should indicate nullability', () => {
59 expect(
60 SchemaPredicates.isFieldNullable(schema, 'Todo', 'text', undefined)
61 ).toBeFalsy();
62 expect(
63 SchemaPredicates.isFieldNullable(schema, 'Todo', 'complete', undefined)
64 ).toBeTruthy();
65 expect(
66 SchemaPredicates.isFieldNullable(schema, 'Todo', 'author', undefined)
67 ).toBeTruthy();
68 });
69
70 it('should handle unions of objects', () => {
71 expect(
72 SchemaPredicates.isInterfaceOfType(
73 schema,
74 frag('LatestTodoResult'),
75 'Todo'
76 )
77 ).toBeTruthy();
78 expect(
79 SchemaPredicates.isInterfaceOfType(
80 schema,
81 frag('LatestTodoResult'),
82 'NoTodosError'
83 )
84 ).toBeTruthy();
85 expect(
86 SchemaPredicates.isInterfaceOfType(schema, frag('Todo'), 'NoTodosError')
87 ).toBeFalsy();
88 });
89
90 it('should throw if a requested type does not exist', () => {
91 expect(() =>
92 SchemaPredicates.isFieldNullable(
93 schema,
94 'SomeInvalidType',
95 'complete',
96 undefined
97 )
98 ).toThrow(
99 'The type `SomeInvalidType` is not an object in the defined schema, but the GraphQL document is traversing it.\nhttps://bit.ly/2XbVrpR#3'
100 );
101 });
102
103 it('should warn in console if a requested field does not exist', () => {
104 expect(
105 SchemaPredicates.isFieldNullable(schema, 'Todo', 'goof', undefined)
106 ).toBeFalsy();
107
108 expect(console.warn).toBeCalledTimes(1);
109 const warnMessage = mocked(console.warn).mock.calls[0][0];
110 expect(warnMessage).toContain('The field `goof` does not exist on `Todo`');
111 expect(warnMessage).toContain('https://bit.ly/2XbVrpR#4');
112 });
113});