Skip to content

Commit f1afe1b

Browse files
committed
feat: add tests for validate policy THROW
1 parent 12be0ab commit f1afe1b

File tree

1 file changed

+257
-0
lines changed

1 file changed

+257
-0
lines changed

lib/validateThrow.test.ts

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
import gql from 'graphql-tag';
2+
import { graphql, GraphQLError, GraphQLResolveInfo } from 'graphql';
3+
import { print } from 'graphql/language/printer';
4+
import { makeExecutableSchema } from 'graphql-tools';
5+
6+
import range from './range';
7+
8+
interface ArgsTestResolverCtx {
9+
shouldCallResolver: boolean;
10+
shouldContainValidationErrors?: boolean;
11+
values?: Record<string, unknown>;
12+
}
13+
14+
describe('validate THROW policy', () => {
15+
const mockResolver = jest.fn(
16+
(
17+
_parent: unknown,
18+
_args: Record<string, unknown>,
19+
_ctx: unknown,
20+
_info: GraphQLResolveInfo & { validationErrors?: unknown[] },
21+
): boolean => true,
22+
);
23+
beforeEach(() => {
24+
mockResolver.mockClear();
25+
});
26+
const schema = range.addValidationResolversToSchema(
27+
makeExecutableSchema({
28+
resolvers: {
29+
Query: {
30+
argTest: mockResolver,
31+
inputTest: mockResolver,
32+
},
33+
},
34+
schemaDirectives: {
35+
range,
36+
},
37+
typeDefs: [
38+
...range.getTypeDefs(),
39+
...range.getMissingCommonTypeDefs(),
40+
gql`
41+
input ThirdInput {
42+
n: Int @range(max: 200, policy: THROW)
43+
}
44+
input SecondInput {
45+
thirdInput: ThirdInput
46+
numbersThrow: [Int!] @range(max: 100, policy: THROW)
47+
numbers: [Int] @range(max: 200)
48+
}
49+
input FirstInput {
50+
n: Int @range(max: 0, policy: THROW)
51+
secondInput: SecondInput
52+
}
53+
type Query {
54+
argTest(
55+
n: Int @range(policy: THROW, max: 2)
56+
n2: Int @range(policy: RESOLVER, max: 10)
57+
): Boolean
58+
inputTest(arg: FirstInput): Boolean
59+
}
60+
`,
61+
],
62+
}),
63+
);
64+
const doTest = async (
65+
query: string,
66+
resolverName: string,
67+
variables: Record<string, unknown>,
68+
{
69+
shouldCallResolver,
70+
values,
71+
shouldContainValidationErrors,
72+
}: ArgsTestResolverCtx,
73+
expectedErrors?: Error[],
74+
): Promise<void> => {
75+
const { data, errors } = await graphql(
76+
schema,
77+
query,
78+
null,
79+
null,
80+
variables,
81+
);
82+
expect(mockResolver.mock.calls.length).toBe(shouldCallResolver ? 1 : 0);
83+
if (shouldCallResolver) {
84+
const [call] = mockResolver.mock.calls;
85+
expect(call[1]).toEqual(values);
86+
if (shouldContainValidationErrors) {
87+
expect(call[3].validationErrors).toBeTruthy();
88+
} else {
89+
expect(call[3].validationErrors).toBeFalsy();
90+
}
91+
expect(data).toEqual({ [resolverName]: true });
92+
}
93+
if (!expectedErrors) {
94+
expect(errors).toBeFalsy();
95+
} else {
96+
expect(errors).toEqual(expectedErrors);
97+
expect(data).toEqual({ [resolverName]: null });
98+
}
99+
};
100+
describe('Validate throw in inputs', () => {
101+
const executeInputTests = doTest.bind(
102+
null,
103+
print(gql`
104+
query InputTest($arg: FirstInput) {
105+
inputTest(arg: $arg)
106+
}
107+
`),
108+
'inputTest',
109+
);
110+
it('Should throw if n on FirstInput is invalid', () =>
111+
executeInputTests(
112+
{ arg: { n: 2 } },
113+
{
114+
shouldCallResolver: false,
115+
},
116+
[new GraphQLError('More than 0')],
117+
));
118+
it('Should throw if numbersThrow on SecondInput is invalid', () =>
119+
executeInputTests(
120+
{ arg: { secondInput: { numbersThrow: [1, 2, 101] } } },
121+
{
122+
shouldCallResolver: false,
123+
},
124+
[new GraphQLError('More than 100')],
125+
));
126+
it('Should throw if both array inputs on SecondInput are invalid', () =>
127+
executeInputTests(
128+
{
129+
arg: { secondInput: { numbers: [10000], numbersThrow: [1, 2, 101] } },
130+
},
131+
{
132+
shouldCallResolver: false,
133+
},
134+
[new GraphQLError('More than 100')],
135+
));
136+
it('Should not throw if numbers on SecondInput is valid', () =>
137+
executeInputTests(
138+
{ arg: { secondInput: { numbers: [0, 2, 3], numbersThrow: [1, 2] } } },
139+
{
140+
shouldCallResolver: true,
141+
shouldContainValidationErrors: false,
142+
values: {
143+
arg: { secondInput: { numbers: [0, 2, 3], numbersThrow: [1, 2] } },
144+
},
145+
},
146+
));
147+
it('Should not throw if numbersThrow on SecondInput is null', () =>
148+
executeInputTests(
149+
{
150+
arg: {
151+
secondInput: { numbers: [0, 2, 3], numbersThrow: null },
152+
},
153+
},
154+
{
155+
shouldCallResolver: true,
156+
shouldContainValidationErrors: false,
157+
values: {
158+
arg: {
159+
secondInput: { numbers: [0, 2, 3], numbersThrow: null },
160+
},
161+
},
162+
},
163+
));
164+
it('Should populate validation errors if input is out of range', () =>
165+
executeInputTests(
166+
{
167+
arg: {
168+
secondInput: {
169+
numbers: [0, 2, 3, 20000],
170+
numbersThrow: [1, 2, 100],
171+
thirdInput: {
172+
n: 2,
173+
},
174+
},
175+
},
176+
},
177+
{
178+
shouldCallResolver: true,
179+
shouldContainValidationErrors: true,
180+
values: {
181+
arg: {
182+
secondInput: {
183+
numbers: null,
184+
numbersThrow: [1, 2, 100],
185+
thirdInput: {
186+
n: 2,
187+
},
188+
},
189+
},
190+
},
191+
},
192+
));
193+
it('Should populate validation errors if input is out of range', () =>
194+
executeInputTests(
195+
{
196+
arg: {
197+
secondInput: {
198+
numbers: [0, 2, 3, 20000],
199+
numbersThrow: [1, 2, 100],
200+
thirdInput: {
201+
n: 20000,
202+
},
203+
},
204+
},
205+
},
206+
{
207+
shouldCallResolver: false,
208+
},
209+
[new GraphQLError('More than 200')],
210+
));
211+
});
212+
describe('Validate throw in simple arguments', () => {
213+
const executeSimpleArgumentsTests = doTest.bind(
214+
null,
215+
print(gql`
216+
query ArgTest($n: Int, $n2: Int) {
217+
argTest(n: $n, n2: $n2)
218+
}
219+
`),
220+
'argTest',
221+
);
222+
it('Should if validation is ok', () =>
223+
executeSimpleArgumentsTests(
224+
{ n: 0, n2: 1 },
225+
{
226+
shouldCallResolver: true,
227+
shouldContainValidationErrors: false,
228+
values: { n: 0, n2: 1 },
229+
},
230+
));
231+
it('Should throw and not call resolver', () =>
232+
executeSimpleArgumentsTests(
233+
{ n: 200, n2: 1 },
234+
{
235+
shouldCallResolver: false,
236+
},
237+
[new GraphQLError('More than 2')],
238+
));
239+
it('Should call resolver and not throw', () =>
240+
executeSimpleArgumentsTests(
241+
{ n: 0, n2: 400 },
242+
{
243+
shouldCallResolver: true,
244+
shouldContainValidationErrors: true,
245+
values: { n: 0, n2: null },
246+
},
247+
));
248+
it('Should throw if both validations fail', () =>
249+
executeSimpleArgumentsTests(
250+
{ n: 200, n2: 400 },
251+
{
252+
shouldCallResolver: false,
253+
},
254+
[new GraphQLError('More than 2')],
255+
));
256+
});
257+
});

0 commit comments

Comments
 (0)