Skip to content

Commit 17d5bf5

Browse files
authored
tests: Split federation tests to distribute evenly over workers (#6804)
1 parent cc5a9b7 commit 17d5bf5

File tree

6 files changed

+928
-918
lines changed

6 files changed

+928
-918
lines changed
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
import { normalizeCliOutput } from '../../../scripts/serializers/cli-output';
2+
import { cases, isLegacyComposition, prepare } from './federation-utils';
3+
4+
describe('check', () => {
5+
describe.concurrent.each(cases)('%s', (caseName, ffs) => {
6+
const legacyComposition = isLegacyComposition(caseName);
7+
8+
test.concurrent('accepted: composable, no breaking changes', async () => {
9+
const {
10+
cli: { publish, check },
11+
} = await prepare(ffs, legacyComposition);
12+
13+
await publish({
14+
sdl: /* GraphQL */ `
15+
type Query {
16+
topProduct: String
17+
}
18+
`,
19+
serviceName: 'products',
20+
serviceUrl: 'http://products:3000/graphql',
21+
expect: 'latest-composable',
22+
});
23+
24+
const message = await check({
25+
sdl: /* GraphQL */ `
26+
type Query {
27+
topProduct: String
28+
topProductName: String
29+
}
30+
`,
31+
serviceName: 'products',
32+
expect: 'approved',
33+
});
34+
35+
expect(message).toMatch('topProductName');
36+
});
37+
38+
test.concurrent('accepted: composable, previous version was not', async () => {
39+
const {
40+
cli: { publish, check },
41+
} = await prepare(ffs, legacyComposition);
42+
43+
await publish({
44+
sdl: /* GraphQL */ `
45+
type Query {
46+
product(id: ID!): Product
47+
}
48+
type Product @key(fields: "it") {
49+
id: ID!
50+
name: String
51+
}
52+
`,
53+
serviceName: 'products',
54+
serviceUrl: 'http://products:3000/graphql',
55+
expect: 'latest',
56+
});
57+
58+
await check({
59+
sdl: /* GraphQL */ `
60+
type Query {
61+
product(id: ID!): Product
62+
topProduct: Product
63+
}
64+
type Product @key(fields: "id") {
65+
id: ID!
66+
name: String
67+
}
68+
`,
69+
serviceName: 'products',
70+
expect: 'approved',
71+
});
72+
});
73+
74+
test.concurrent('accepted: no changes', async () => {
75+
const {
76+
cli: { publish, check },
77+
} = await prepare(ffs, legacyComposition);
78+
79+
await publish({
80+
sdl: /* GraphQL */ `
81+
type Query {
82+
topProduct: String
83+
}
84+
`,
85+
serviceName: 'products',
86+
serviceUrl: 'http://products:3000/graphql',
87+
expect: 'latest-composable',
88+
});
89+
90+
await check({
91+
sdl: /* GraphQL */ `
92+
type Query {
93+
topProduct: String
94+
}
95+
`,
96+
serviceName: 'products',
97+
expect: 'approved',
98+
});
99+
});
100+
101+
test.concurrent('rejected: missing service name', async () => {
102+
const {
103+
cli: { check },
104+
} = await prepare(ffs, legacyComposition);
105+
106+
const message = await check({
107+
sdl: /* GraphQL */ `
108+
type Query {
109+
topProduct: String
110+
}
111+
`,
112+
expect: 'rejected',
113+
});
114+
115+
expect(message).toMatch('name');
116+
});
117+
118+
test.concurrent('rejected: composable, breaking changes', async () => {
119+
const {
120+
cli: { publish, check },
121+
} = await prepare(ffs, legacyComposition);
122+
123+
await publish({
124+
sdl: /* GraphQL */ `
125+
type Query {
126+
topProduct: String
127+
}
128+
`,
129+
serviceName: 'products',
130+
serviceUrl: 'http://products:3000/graphql',
131+
expect: 'latest-composable',
132+
});
133+
134+
const message = await check({
135+
sdl: /* GraphQL */ `
136+
type Query {
137+
topProductName: String
138+
}
139+
`,
140+
serviceName: 'products',
141+
expect: 'rejected',
142+
});
143+
144+
expect(message).toMatch('removed');
145+
});
146+
147+
test.concurrent('rejected: not composable, no breaking changes', async () => {
148+
const {
149+
cli: { publish, check },
150+
} = await prepare(ffs, legacyComposition);
151+
152+
await publish({
153+
sdl: /* GraphQL */ `
154+
type Query {
155+
topProduct: String
156+
}
157+
`,
158+
serviceName: 'products',
159+
serviceUrl: 'http://products:3000/graphql',
160+
expect: 'latest-composable',
161+
});
162+
163+
const message = await check({
164+
sdl: /* GraphQL */ `
165+
type Query {
166+
topProduct: String
167+
topProductName: Strin
168+
}
169+
`,
170+
serviceName: 'products',
171+
expect: 'rejected',
172+
});
173+
174+
expect(message).toMatch('Strin');
175+
});
176+
177+
test.concurrent('rejected: not composable, breaking changes', async () => {
178+
const {
179+
cli: { publish, check },
180+
} = await prepare(ffs, legacyComposition);
181+
182+
await publish({
183+
sdl: /* GraphQL */ `
184+
type Query {
185+
topProduct: Product
186+
}
187+
188+
type Product @key(fields: "id") {
189+
id: ID!
190+
name: String
191+
}
192+
`,
193+
serviceName: 'products',
194+
serviceUrl: 'http://products:3000/graphql',
195+
expect: 'latest-composable',
196+
});
197+
198+
const message = normalizeCliOutput(
199+
await check({
200+
sdl: /* GraphQL */ `
201+
type Query {
202+
product(id: ID!): Product
203+
}
204+
205+
type Product @key(fields: "it") {
206+
id: ID!
207+
name: String
208+
}
209+
`,
210+
serviceName: 'products',
211+
expect: 'rejected',
212+
}),
213+
);
214+
215+
if (legacyComposition) {
216+
expect(message).toMatch('Product.it');
217+
expect(message).toMatch('topProduct');
218+
} else {
219+
expect(message).toContain('Cannot query field it on type Product');
220+
}
221+
});
222+
});
223+
});
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { cases, isLegacyComposition, prepare } from './federation-utils';
2+
3+
describe('delete', () => {
4+
describe.concurrent.each(cases)('%s', (caseName, ffs) => {
5+
const legacyComposition = isLegacyComposition(caseName);
6+
7+
test.concurrent('accepted: composable before and after', async () => {
8+
const { cli } = await prepare(ffs, legacyComposition);
9+
10+
await cli.publish({
11+
sdl: /* GraphQL */ `
12+
type Query {
13+
topProduct: Product
14+
}
15+
16+
type Product @key(fields: "id") {
17+
id: ID!
18+
name: String
19+
}
20+
`,
21+
serviceName: 'products',
22+
serviceUrl: 'http://products:3000/graphql',
23+
expect: 'latest-composable',
24+
});
25+
26+
await cli.publish({
27+
sdl: /* GraphQL */ `
28+
type Query {
29+
topReview: Review
30+
}
31+
32+
type Review @key(fields: "id") {
33+
id: ID!
34+
title: String
35+
}
36+
`,
37+
serviceName: 'reviews',
38+
serviceUrl: 'http://reviews:3000/graphql',
39+
expect: 'latest-composable',
40+
});
41+
42+
const message = await cli.delete({
43+
serviceName: 'reviews',
44+
expect: 'latest-composable',
45+
});
46+
47+
expect(message).toMatch('reviews deleted');
48+
});
49+
50+
test.concurrent('rejected: unknown service', async () => {
51+
const { cli } = await prepare(ffs, legacyComposition);
52+
53+
await cli.publish({
54+
sdl: /* GraphQL */ `
55+
type Query {
56+
topProduct: Product
57+
}
58+
59+
type Product @key(fields: "id") {
60+
id: ID!
61+
name: String
62+
}
63+
`,
64+
serviceName: 'products',
65+
serviceUrl: 'http://products:3000/graphql',
66+
expect: 'latest-composable',
67+
});
68+
69+
const message = await cli.delete({
70+
serviceName: 'unknown_service',
71+
expect: 'rejected',
72+
});
73+
74+
expect(message).toMatch('not found');
75+
});
76+
});
77+
});

0 commit comments

Comments
 (0)