Skip to content

Commit 18d09a8

Browse files
authored
[typescript-operations] Split apollo unmask tests (#10301)
* Split apolloUnmask tests * Use toMatchInlineSnapshot for simplicity
1 parent a7f5aa9 commit 18d09a8

File tree

3 files changed

+260
-245
lines changed

3 files changed

+260
-245
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { buildSchema } from 'graphql';
2+
3+
export const schema = buildSchema(/* GraphQL */ `
4+
scalar DateTime
5+
6+
input InputType {
7+
t: String
8+
}
9+
10+
type User {
11+
id: ID!
12+
username: String!
13+
email: String!
14+
profile: Profile
15+
role: Role
16+
}
17+
18+
type Profile {
19+
age: Int
20+
firstName: String!
21+
}
22+
23+
type Mutation {
24+
test: String
25+
login(username: String!, password: String!): User
26+
}
27+
28+
type Subscription {
29+
userCreated: User
30+
}
31+
32+
interface Notifiction {
33+
id: ID!
34+
createdAt: String!
35+
}
36+
37+
type TextNotification implements Notifiction {
38+
id: ID!
39+
text: String!
40+
createdAt: String!
41+
}
42+
43+
type ImageNotification implements Notifiction {
44+
id: ID!
45+
imageUrl: String!
46+
metadata: ImageMetadata!
47+
createdAt: String!
48+
}
49+
50+
type ImageMetadata {
51+
createdBy: String!
52+
}
53+
54+
enum Role {
55+
USER
56+
ADMIN
57+
}
58+
59+
union MyUnion = User | Profile
60+
61+
union AnyNotification = TextNotification | ImageNotification
62+
union SearchResult = TextNotification | ImageNotification | User
63+
64+
type Query {
65+
me: User
66+
unionTest: MyUnion
67+
notifications: [Notifiction!]!
68+
mixedNotifications: [AnyNotification!]!
69+
search(term: String!): [SearchResult!]!
70+
dummy: String
71+
dummyNonNull: String!
72+
dummyArray: [String]
73+
dummyNonNullArray: [String]!
74+
dummyNonNullArrayWithValues: [String!]!
75+
dummyWithType: Profile
76+
}
77+
78+
schema {
79+
query: Query
80+
mutation: Mutation
81+
subscription: Subscription
82+
}
83+
`);
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
import { parse } from 'graphql';
2+
import { schema } from './shared/schema.js';
3+
import { plugin } from '../src/index.js';
4+
5+
describe('TypeScript Operations Plugin - apolloUnmask', () => {
6+
it("'mask' with @unmask configured with apolloUnmask yields correct types", async () => {
7+
const ast = parse(/* GraphQL */ `
8+
query {
9+
me {
10+
...UserFragment @unmask
11+
}
12+
}
13+
fragment UserFragment on User {
14+
id
15+
}
16+
`);
17+
const result = await plugin(
18+
schema,
19+
[{ location: 'test-file.ts', document: ast }],
20+
{ inlineFragmentTypes: 'mask', customDirectives: { apolloUnmask: true } },
21+
{ outputFile: '' }
22+
);
23+
24+
expect(result.content).toMatchInlineSnapshot(`
25+
"export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>;
26+
27+
28+
export type Unnamed_1_Query = { __typename?: 'Query', me?: (
29+
{ __typename?: 'User', id: string }
30+
& { ' $fragmentRefs'?: { 'UserFragmentFragment': UserFragmentFragment } }
31+
) | null };
32+
33+
export type UserFragmentFragment = { __typename?: 'User', id: string } & { ' $fragmentName'?: 'UserFragmentFragment' };
34+
"
35+
`);
36+
});
37+
38+
it("'mask' with @unmask without apolloUnmask yields correct types", async () => {
39+
const ast = parse(/* GraphQL */ `
40+
query {
41+
me {
42+
...UserFragment @unmask
43+
}
44+
}
45+
fragment UserFragment on User {
46+
id
47+
}
48+
`);
49+
const result = await plugin(
50+
schema,
51+
[{ location: 'test-file.ts', document: ast }],
52+
{ inlineFragmentTypes: 'mask' },
53+
{ outputFile: '' }
54+
);
55+
expect(result.content).toMatchInlineSnapshot(`
56+
"export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>;
57+
58+
59+
export type Unnamed_1_Query = { __typename?: 'Query', me?: (
60+
{ __typename?: 'User' }
61+
& { ' $fragmentRefs'?: { 'UserFragmentFragment': UserFragmentFragment } }
62+
) | null };
63+
64+
export type UserFragmentFragment = { __typename?: 'User', id: string } & { ' $fragmentName'?: 'UserFragmentFragment' };
65+
"
66+
`);
67+
});
68+
69+
it("'mask' with @unmask with apolloUnmask explicitly disabled yields correct types", async () => {
70+
const ast = parse(/* GraphQL */ `
71+
query {
72+
me {
73+
...UserFragment @unmask
74+
}
75+
}
76+
fragment UserFragment on User {
77+
id
78+
}
79+
`);
80+
const result = await plugin(
81+
schema,
82+
[{ location: 'test-file.ts', document: ast }],
83+
{ inlineFragmentTypes: 'mask', customDirectives: { apolloUnmask: false } },
84+
{ outputFile: '' }
85+
);
86+
expect(result.content).toMatchInlineSnapshot(`
87+
"export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>;
88+
89+
90+
export type Unnamed_1_Query = { __typename?: 'Query', me?: (
91+
{ __typename?: 'User' }
92+
& { ' $fragmentRefs'?: { 'UserFragmentFragment': UserFragmentFragment } }
93+
) | null };
94+
95+
export type UserFragmentFragment = { __typename?: 'User', id: string } & { ' $fragmentName'?: 'UserFragmentFragment' };
96+
"
97+
`);
98+
});
99+
100+
it("'mask' with @unmask and masked fragments yields correct types", async () => {
101+
const ast = parse(/* GraphQL */ `
102+
query {
103+
me {
104+
...UserFragment @unmask
105+
...UserFragment2
106+
}
107+
}
108+
fragment UserFragment on User {
109+
id
110+
}
111+
112+
fragment UserFragment2 on User {
113+
email
114+
}
115+
`);
116+
const result = await plugin(
117+
schema,
118+
[{ location: 'test-file.ts', document: ast }],
119+
{ inlineFragmentTypes: 'mask', customDirectives: { apolloUnmask: true } },
120+
{ outputFile: '' }
121+
);
122+
expect(result.content).toMatchInlineSnapshot(`
123+
"export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>;
124+
125+
126+
export type Unnamed_1_Query = { __typename?: 'Query', me?: (
127+
{ __typename?: 'User', id: string }
128+
& { ' $fragmentRefs'?: { 'UserFragmentFragment': UserFragmentFragment;'UserFragment2Fragment': UserFragment2Fragment } }
129+
) | null };
130+
131+
export type UserFragmentFragment = { __typename?: 'User', id: string } & { ' $fragmentName'?: 'UserFragmentFragment' };
132+
133+
export type UserFragment2Fragment = { __typename?: 'User', email: string } & { ' $fragmentName'?: 'UserFragment2Fragment' };
134+
"
135+
`);
136+
});
137+
138+
it("'mask' with @unmask and masked fragments on overlapping fields yields correct types", async () => {
139+
const ast = parse(/* GraphQL */ `
140+
query {
141+
me {
142+
...UserFragment @unmask
143+
...UserFragment2
144+
}
145+
}
146+
fragment UserFragment on User {
147+
id
148+
email
149+
}
150+
151+
fragment UserFragment2 on User {
152+
email
153+
}
154+
`);
155+
const result = await plugin(
156+
schema,
157+
[{ location: 'test-file.ts', document: ast }],
158+
{ inlineFragmentTypes: 'mask', customDirectives: { apolloUnmask: true } },
159+
{ outputFile: '' }
160+
);
161+
expect(result.content).toMatchInlineSnapshot(`
162+
"export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>;
163+
164+
165+
export type Unnamed_1_Query = { __typename?: 'Query', me?: (
166+
{ __typename?: 'User', id: string, email: string }
167+
& { ' $fragmentRefs'?: { 'UserFragmentFragment': UserFragmentFragment;'UserFragment2Fragment': UserFragment2Fragment } }
168+
) | null };
169+
170+
export type UserFragmentFragment = { __typename?: 'User', id: string, email: string } & { ' $fragmentName'?: 'UserFragmentFragment' };
171+
172+
export type UserFragment2Fragment = { __typename?: 'User', email: string } & { ' $fragmentName'?: 'UserFragment2Fragment' };
173+
"
174+
`);
175+
});
176+
});

0 commit comments

Comments
 (0)