@apollo/gateway 2.4.5 → 2.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/__generated__/graphqlTypes.d.ts +19 -1
  2. package/dist/__generated__/graphqlTypes.d.ts.map +1 -1
  3. package/dist/__generated__/graphqlTypes.js +1 -0
  4. package/dist/__generated__/graphqlTypes.js.map +1 -1
  5. package/dist/executeQueryPlan.js +1 -1
  6. package/dist/executeQueryPlan.js.map +1 -1
  7. package/package.json +4 -4
  8. package/src/__generated__/graphqlTypes.ts +33 -2
  9. package/src/executeQueryPlan.ts +1 -1
  10. package/src/__mocks__/tsconfig.json +0 -7
  11. package/src/__tests__/.gitkeep +0 -0
  12. package/src/__tests__/CucumberREADME.md +0 -96
  13. package/src/__tests__/build-query-plan.feature +0 -1471
  14. package/src/__tests__/buildQueryPlan.test.ts +0 -1225
  15. package/src/__tests__/executeQueryPlan.conditions.test.ts +0 -1488
  16. package/src/__tests__/executeQueryPlan.introspection.test.ts +0 -140
  17. package/src/__tests__/executeQueryPlan.test.ts +0 -6140
  18. package/src/__tests__/execution-utils.ts +0 -124
  19. package/src/__tests__/gateway/__snapshots__/opentelemetry.test.ts.snap +0 -195
  20. package/src/__tests__/gateway/buildService.test.ts +0 -249
  21. package/src/__tests__/gateway/endToEnd.test.ts +0 -486
  22. package/src/__tests__/gateway/executor.test.ts +0 -96
  23. package/src/__tests__/gateway/extensions.test.ts +0 -37
  24. package/src/__tests__/gateway/lifecycle-hooks.test.ts +0 -239
  25. package/src/__tests__/gateway/opentelemetry.test.ts +0 -123
  26. package/src/__tests__/gateway/queryPlanCache.test.ts +0 -231
  27. package/src/__tests__/gateway/queryPlannerConfig.test.ts +0 -101
  28. package/src/__tests__/gateway/reporting.test.ts +0 -616
  29. package/src/__tests__/gateway/supergraphSdl.test.ts +0 -396
  30. package/src/__tests__/gateway/testUtils.ts +0 -89
  31. package/src/__tests__/integration/abstract-types.test.ts +0 -1861
  32. package/src/__tests__/integration/aliases.test.ts +0 -180
  33. package/src/__tests__/integration/boolean.test.ts +0 -279
  34. package/src/__tests__/integration/complex-key.test.ts +0 -197
  35. package/src/__tests__/integration/configuration.test.ts +0 -404
  36. package/src/__tests__/integration/custom-directives.test.ts +0 -174
  37. package/src/__tests__/integration/execution-style.test.ts +0 -35
  38. package/src/__tests__/integration/fragments.test.ts +0 -237
  39. package/src/__tests__/integration/list-key.test.ts +0 -128
  40. package/src/__tests__/integration/logger.test.ts +0 -122
  41. package/src/__tests__/integration/managed.test.ts +0 -319
  42. package/src/__tests__/integration/merge-arrays.test.ts +0 -34
  43. package/src/__tests__/integration/multiple-key.test.ts +0 -327
  44. package/src/__tests__/integration/mutations.test.ts +0 -287
  45. package/src/__tests__/integration/networkRequests.test.ts +0 -542
  46. package/src/__tests__/integration/nockMocks.ts +0 -157
  47. package/src/__tests__/integration/provides.test.ts +0 -77
  48. package/src/__tests__/integration/requires.test.ts +0 -359
  49. package/src/__tests__/integration/scope.test.ts +0 -557
  50. package/src/__tests__/integration/single-service.test.ts +0 -119
  51. package/src/__tests__/integration/unions.test.ts +0 -79
  52. package/src/__tests__/integration/value-types.test.ts +0 -382
  53. package/src/__tests__/integration/variables.test.ts +0 -120
  54. package/src/__tests__/nockAssertions.ts +0 -20
  55. package/src/__tests__/queryPlanCucumber.test.ts +0 -55
  56. package/src/__tests__/resultShaping.test.ts +0 -605
  57. package/src/__tests__/testSetup.ts +0 -1
  58. package/src/__tests__/tsconfig.json +0 -8
  59. package/src/core/__tests__/core.test.ts +0 -412
  60. package/src/datasources/__tests__/LocalGraphQLDataSource.test.ts +0 -51
  61. package/src/datasources/__tests__/RemoteGraphQLDataSource.test.ts +0 -574
  62. package/src/schema-helper/__tests__/addExtensions.test.ts +0 -70
  63. package/src/supergraphManagers/IntrospectAndCompose/__tests__/IntrospectAndCompose.test.ts +0 -364
  64. package/src/supergraphManagers/IntrospectAndCompose/__tests__/loadServicesFromRemoteEndpoint.test.ts +0 -40
  65. package/src/supergraphManagers/UplinkSupergraphManager/__tests__/UplinkSupergraphManager.test.ts +0 -65
  66. package/src/supergraphManagers/UplinkSupergraphManager/__tests__/loadSupergraphSdlFromStorage.test.ts +0 -511
  67. package/src/utilities/__tests__/deepMerge.test.ts +0 -77
@@ -1,239 +0,0 @@
1
- import gql from 'graphql-tag';
2
- import { ApolloGateway } from '../..';
3
- import {
4
- DynamicGatewayConfig,
5
- Experimental_DidResolveQueryPlanCallback,
6
- Experimental_UpdateServiceDefinitions,
7
- ServiceDefinitionUpdate,
8
- } from '../../config';
9
- import {
10
- product,
11
- reviews,
12
- inventory,
13
- accounts,
14
- books,
15
- documents,
16
- fixtures,
17
- fixturesWithUpdate,
18
- } from 'apollo-federation-integration-testsuite';
19
- import { createHash } from '@apollo/utils.createhash';
20
- import type { Logger } from '@apollo/utils.logger';
21
- import resolvable from '@josephg/resolvable';
22
- import { getTestingSupergraphSdl } from '../execution-utils';
23
-
24
- // The order of this was specified to preserve existing test coverage. Typically
25
- // we would just import and use the `fixtures` array.
26
- const serviceDefinitions = [
27
- product,
28
- reviews,
29
- inventory,
30
- accounts,
31
- books,
32
- documents,
33
- ].map((s, i) => ({
34
- name: s.name,
35
- typeDefs: s.typeDefs,
36
- url: `http://localhost:${i}`,
37
- }));
38
-
39
- let logger: Logger;
40
-
41
- beforeEach(() => {
42
- const warn = jest.fn();
43
- const debug = jest.fn();
44
- const error = jest.fn();
45
- const info = jest.fn();
46
-
47
- logger = {
48
- warn,
49
- debug,
50
- error,
51
- info,
52
- };
53
- });
54
-
55
- describe('lifecycle hooks', () => {
56
- it('uses updateServiceDefinitions override', async () => {
57
- const experimental_updateServiceDefinitions: Experimental_UpdateServiceDefinitions =
58
- jest.fn(async () => {
59
- return { serviceDefinitions, isNewSchema: true };
60
- });
61
-
62
- const gateway = new ApolloGateway({
63
- serviceList: serviceDefinitions,
64
- experimental_updateServiceDefinitions,
65
- logger,
66
- });
67
-
68
- await gateway.load();
69
-
70
- expect(experimental_updateServiceDefinitions).toBeCalled();
71
- expect(gateway.schema!.getType('Furniture')).toBeDefined();
72
- await gateway.stop();
73
- });
74
-
75
- it('calls experimental_didUpdateSupergraph on schema update', async () => {
76
- const compositionMetadata = {
77
- formatVersion: 1,
78
- id: 'abc',
79
- implementingServiceLocations: [],
80
- schemaHash: 'hash1',
81
- };
82
-
83
- const mockUpdate = jest
84
- .fn<Promise<ServiceDefinitionUpdate>, [config: DynamicGatewayConfig]>()
85
- .mockImplementationOnce(async () => {
86
- return {
87
- serviceDefinitions: fixtures,
88
- isNewSchema: true,
89
- compositionMetadata: {
90
- ...compositionMetadata,
91
- id: '123',
92
- schemaHash: 'hash2',
93
- },
94
- };
95
- })
96
- // We want to return a different composition across two ticks, so we mock it
97
- // slightly differently
98
- .mockImplementationOnce(async () => {
99
- return {
100
- serviceDefinitions: fixturesWithUpdate,
101
- isNewSchema: true,
102
- compositionMetadata,
103
- };
104
- });
105
-
106
- const mockDidUpdate = jest.fn();
107
-
108
- const gateway = new ApolloGateway({
109
- experimental_updateServiceDefinitions: mockUpdate,
110
- experimental_didUpdateSupergraph: mockDidUpdate,
111
- logger,
112
- });
113
- // for testing purposes, a short pollInterval is ideal so we'll override here
114
- gateway['pollIntervalInMs'] = 100;
115
-
116
- const schemaChangeBlocker1 = resolvable();
117
- const schemaChangeBlocker2 = resolvable();
118
-
119
- gateway.onSchemaLoadOrUpdate(
120
- jest
121
- .fn()
122
- .mockImplementationOnce(() => schemaChangeBlocker1.resolve())
123
- .mockImplementationOnce(() => schemaChangeBlocker2.resolve()),
124
- );
125
-
126
- await gateway.load();
127
-
128
- await schemaChangeBlocker1;
129
-
130
- expect(mockUpdate).toBeCalledTimes(1);
131
- expect(mockDidUpdate).toBeCalledTimes(1);
132
-
133
- await schemaChangeBlocker2;
134
-
135
- expect(mockUpdate).toBeCalledTimes(2);
136
- expect(mockDidUpdate).toBeCalledTimes(2);
137
-
138
- const [firstCall, secondCall] = mockDidUpdate.mock.calls;
139
-
140
- // Note that we've composing our usual test fixtures here
141
- const expectedFirstId = createHash('sha256').update(getTestingSupergraphSdl()).digest('hex');
142
- expect(firstCall[0]!.compositionId).toEqual(expectedFirstId);
143
- // first call should have no second "previous" argument
144
- expect(firstCall[1]).toBeUndefined();
145
-
146
- // Note that this assertion is a tad fragile in that every time we modify
147
- // the supergraph (even just formatting differences), this ID will change
148
- // and this test will have to updated.
149
- expect(secondCall[0]!.compositionId).toEqual(
150
- '4644102bb30ec7e254fac2577f78137bbab156cb965973ae481f309120738ff6',
151
- );
152
- // second call should have previous info in the second arg
153
- expect(secondCall[1]!.compositionId).toEqual(expectedFirstId);
154
-
155
- await gateway.stop();
156
- });
157
-
158
- it('uses default service definition updater', async () => {
159
- const gateway = new ApolloGateway({
160
- localServiceList: serviceDefinitions,
161
- logger,
162
- });
163
-
164
- const { schema } = await gateway.load();
165
-
166
- // spying on gateway.loadServiceDefinitions wasn't working, so this also
167
- // should test functionality. If there's no overwriting service definition
168
- // updater, it has to use the default. If there's a valid schema, then
169
- // the loader had to have been called.
170
- expect(schema.getType('User')).toBeDefined();
171
-
172
- await gateway.stop();
173
- });
174
-
175
- it('warns when polling on the default fetcher', async () => {
176
- new ApolloGateway({
177
- serviceList: serviceDefinitions,
178
- pollIntervalInMs: 10,
179
- logger,
180
- });
181
- expect(logger.warn).toHaveBeenCalledWith(
182
- 'Polling running services is dangerous and not recommended in production. Polling should only be used against a registry. If you are polling running services, use with caution.',
183
- );
184
- });
185
-
186
- it('registers schema change callbacks when pollIntervalInMs is set for unmanaged configs', async () => {
187
- const experimental_updateServiceDefinitions: Experimental_UpdateServiceDefinitions =
188
- jest.fn(async (_config) => {
189
- return { serviceDefinitions, isNewSchema: true };
190
- });
191
-
192
- const gateway = new ApolloGateway({
193
- serviceList: [{ name: 'book', url: 'http://localhost:32542' }],
194
- experimental_updateServiceDefinitions,
195
- pollIntervalInMs: 100,
196
- logger,
197
- });
198
-
199
- const schemaChangeBlocker = resolvable();
200
- const schemaChangeCallback = jest.fn(() => schemaChangeBlocker.resolve());
201
-
202
- gateway.onSchemaLoadOrUpdate(schemaChangeCallback);
203
- await gateway.load();
204
-
205
- await schemaChangeBlocker;
206
-
207
- expect(schemaChangeCallback).toBeCalledTimes(1);
208
- await gateway.stop();
209
- });
210
-
211
- it('calls experimental_didResolveQueryPlan when executor is called', async () => {
212
- const experimental_didResolveQueryPlan: Experimental_DidResolveQueryPlanCallback =
213
- jest.fn();
214
-
215
- const gateway = new ApolloGateway({
216
- localServiceList: [books],
217
- experimental_didResolveQueryPlan,
218
- });
219
-
220
- const { executor } = await gateway.load();
221
-
222
- const source = `#graphql
223
- { book(isbn: "0262510871") { year } }
224
- `;
225
-
226
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
227
- // @ts-ignore
228
- await executor({
229
- source,
230
- document: gql(source),
231
- request: {},
232
- queryHash: 'hashed',
233
- context: {},
234
- });
235
-
236
- expect(experimental_didResolveQueryPlan).toBeCalled();
237
- await gateway.stop();
238
- });
239
- });
@@ -1,123 +0,0 @@
1
- import gql from 'graphql-tag';
2
- import {ApolloGateway, LocalGraphQLDataSource} from '../../';
3
- import {fixtures, spanSerializer} from 'apollo-federation-integration-testsuite';
4
- import {InMemorySpanExporter, SimpleSpanProcessor} from '@opentelemetry/tracing'
5
- import {NodeTracerProvider} from '@opentelemetry/node';
6
- import { buildSubgraphSchema } from '@apollo/subgraph';
7
-
8
- expect.addSnapshotSerializer(spanSerializer);
9
-
10
- const inMemorySpans = new InMemorySpanExporter();
11
- const tracerProvider = new NodeTracerProvider();
12
- tracerProvider.addSpanProcessor(new SimpleSpanProcessor(inMemorySpans));
13
- tracerProvider.register();
14
-
15
- beforeEach(() => {
16
- inMemorySpans.reset();
17
- });
18
-
19
- describe('opentelemetry', () => {
20
- async function execute(executor: any, source: string, variables: any, operationName: string) {
21
- await executor({
22
- source,
23
- document: gql(source),
24
- request: {
25
- variables,
26
- },
27
- operationName,
28
- queryHash: 'hashed',
29
- context: null,
30
- cache: {} as any,
31
- });
32
- }
33
-
34
- describe('with local data', () =>
35
- {
36
- async function gateway() {
37
- const localDataSources = Object.fromEntries(
38
- fixtures.map((f) => [
39
- f.name,
40
- new LocalGraphQLDataSource(buildSubgraphSchema(f)),
41
- ]),
42
- );
43
- const gateway = new ApolloGateway({
44
- localServiceList: fixtures,
45
- buildService(service) {
46
- return localDataSources[service.name];
47
- },
48
- });
49
-
50
- const {executor} = await gateway.load();
51
- return executor;
52
- }
53
-
54
- it('receives spans on success', async () => {
55
- const executor = await gateway();
56
-
57
- const source = `#graphql
58
- query GetProduct($upc: String!) {
59
- product(upc: $upc) {
60
- name
61
- }
62
- }
63
- `;
64
-
65
- await execute(executor, source, {upc: '1'}, 'GetProduct');
66
- expect(inMemorySpans.getFinishedSpans()).toMatchSnapshot();
67
- });
68
-
69
- it('receives spans on validation failure', async () => {
70
- const executor = await gateway();
71
- const source = `#graphql
72
- query InvalidVariables($first: Int!) {
73
- topReviews(first: $first) {
74
- body
75
- }
76
- }
77
- `;
78
-
79
- await execute(executor, source, { upc: '1' }, 'InvalidVariables');
80
- expect(inMemorySpans.getFinishedSpans()).toMatchSnapshot();
81
- });
82
-
83
- it('receives spans on plan failure', async () => {
84
- const executor = await gateway();
85
- const source = `#graphql
86
- subscription GetProduct($upc: String!) {
87
- product(upc: $upc) {
88
- name
89
- }
90
- }
91
- `;
92
-
93
- try {
94
- await execute(executor, source, {upc: '1'}, 'GetProduct');
95
- }
96
- catch(err) {}
97
- expect(inMemorySpans.getFinishedSpans()).toMatchSnapshot();
98
- });
99
- });
100
-
101
-
102
- it('receives spans on fetch failure', async () => {
103
- const gateway = new ApolloGateway({
104
- localServiceList: fixtures,
105
- fetcher: () => {
106
- throw Error('Nooo');
107
- },
108
- });
109
-
110
- const { executor } = await gateway.load();
111
-
112
- const source = `#graphql
113
- query GetProduct($upc: String!) {
114
- product(upc: $upc) {
115
- name
116
- }
117
- }
118
- `;
119
-
120
- await execute(executor, source, {upc: '1'}, 'GetProduct');
121
- expect(inMemorySpans.getFinishedSpans()).toMatchSnapshot();
122
- });
123
- });
@@ -1,231 +0,0 @@
1
- import gql from 'graphql-tag';
2
- import { ApolloServer } from '@apollo/server';
3
- import { buildSubgraphSchema } from '@apollo/subgraph';
4
-
5
- import { LocalGraphQLDataSource } from '../../datasources/LocalGraphQLDataSource';
6
- import { ApolloGateway } from '../../';
7
- import { fixtures } from 'apollo-federation-integration-testsuite';
8
- import { QueryPlanner } from '@apollo/query-planner';
9
- import { unwrapSingleResultKind } from '../gateway/testUtils';
10
-
11
- it('caches the query plan for a request', async () => {
12
- const buildQueryPlanSpy = jest.spyOn(QueryPlanner.prototype, 'buildQueryPlan');
13
-
14
- const localDataSources = Object.fromEntries(
15
- fixtures.map((f) => [
16
- f.name,
17
- new LocalGraphQLDataSource(buildSubgraphSchema(f)),
18
- ]),
19
- );
20
- const gateway = new ApolloGateway({
21
- localServiceList: fixtures,
22
- buildService(service) {
23
- return localDataSources[service.name];
24
- },
25
- });
26
-
27
- const server = new ApolloServer({ gateway });
28
- await server.start();
29
-
30
- const upc = '1';
31
-
32
- const query = `#graphql
33
- query GetProduct($upc: String!) {
34
- product(upc: $upc) {
35
- name
36
- }
37
- }
38
- `;
39
-
40
- const result = await server.executeOperation({
41
- query,
42
- variables: { upc },
43
- });
44
-
45
- const { data: result1Data } = unwrapSingleResultKind(result);
46
- expect(result1Data).toEqual({
47
- product: {
48
- name: 'Table',
49
- },
50
- });
51
-
52
- const secondResult = await server.executeOperation({
53
- query,
54
- variables: { upc },
55
- });
56
-
57
- expect(unwrapSingleResultKind(secondResult).data).toEqual(result1Data);
58
- expect(buildQueryPlanSpy).toHaveBeenCalledTimes(1);
59
- });
60
-
61
- it('supports multiple operations and operationName', async () => {
62
- const query = `#graphql
63
- query GetUser {
64
- me {
65
- username
66
- }
67
- }
68
- query GetReviews {
69
- topReviews {
70
- body
71
- }
72
- }
73
- `;
74
-
75
- const localDataSources = Object.fromEntries(
76
- fixtures.map((f) => [
77
- f.name,
78
- new LocalGraphQLDataSource(buildSubgraphSchema(f)),
79
- ]),
80
- );
81
-
82
- const gateway = new ApolloGateway({
83
- localServiceList: fixtures,
84
- buildService(service) {
85
- return localDataSources[service.name];
86
- },
87
- });
88
-
89
- const server = new ApolloServer({ gateway });
90
- await server.start();
91
-
92
- const userResult = await server.executeOperation({
93
- query,
94
- operationName: 'GetUser',
95
- });
96
-
97
- const reviewsResult = await server.executeOperation({
98
- query,
99
- operationName: 'GetReviews',
100
- });
101
-
102
- expect(unwrapSingleResultKind(userResult).data).toEqual({
103
- me: { username: '@ada' },
104
- });
105
- expect(unwrapSingleResultKind(reviewsResult).data).toEqual({
106
- topReviews: [
107
- { body: 'Love it!' },
108
- { body: 'Too expensive.' },
109
- { body: 'Could be better.' },
110
- { body: 'Prefer something else.' },
111
- { body: 'Wish I had read this before.' },
112
- ],
113
- });
114
- });
115
-
116
- it('does not corrupt cached queryplan data across requests', async () => {
117
- const serviceA = {
118
- name: 'a',
119
- typeDefs: gql`
120
- type Query {
121
- user: User
122
- }
123
-
124
- type User @key(fields: "id") {
125
- id: ID!
126
- preferences: Preferences
127
- }
128
-
129
- type Preferences {
130
- favorites: Things
131
- }
132
-
133
- type Things {
134
- color: String
135
- animal: String
136
- }
137
- `,
138
- resolvers: {
139
- Query: {
140
- user() {
141
- return {
142
- id: '1',
143
- preferences: {
144
- favorites: { color: 'limegreen', animal: 'platypus' },
145
- },
146
- };
147
- },
148
- },
149
- },
150
- };
151
-
152
- const serviceB = {
153
- name: 'b',
154
- typeDefs: gql`
155
- extend type User @key(fields: "id") {
156
- id: ID! @external
157
- preferences: Preferences @external
158
- favoriteColor: String
159
- @requires(fields: "preferences { favorites { color } }")
160
- favoriteAnimal: String
161
- @requires(fields: "preferences { favorites { animal } }")
162
- }
163
-
164
- extend type Preferences {
165
- favorites: Things @external
166
- }
167
-
168
- extend type Things {
169
- color: String @external
170
- animal: String @external
171
- }
172
- `,
173
- resolvers: {
174
- User: {
175
- favoriteColor(user: any) {
176
- return user.preferences.favorites.color;
177
- },
178
- favoriteAnimal(user: any) {
179
- return user.preferences.favorites.animal;
180
- },
181
- },
182
- },
183
- };
184
-
185
- const dataSources: Record<string, LocalGraphQLDataSource> = {
186
- a: new LocalGraphQLDataSource(buildSubgraphSchema(serviceA)),
187
- b: new LocalGraphQLDataSource(buildSubgraphSchema(serviceB)),
188
- };
189
-
190
- const gateway = new ApolloGateway({
191
- localServiceList: [serviceA, serviceB],
192
- buildService(service) {
193
- return dataSources[service.name];
194
- },
195
- });
196
-
197
- const server = new ApolloServer({ gateway });
198
- await server.start();
199
-
200
- const query1 = `#graphql
201
- query UserFavoriteColor {
202
- user {
203
- favoriteColor
204
- }
205
- }
206
- `;
207
-
208
- const query2 = `#graphql
209
- query UserFavorites {
210
- user {
211
- favoriteColor
212
- favoriteAnimal
213
- }
214
- }
215
- `;
216
-
217
- const result1 = await server.executeOperation({
218
- query: query1,
219
- });
220
- const result2 = await server.executeOperation({
221
- query: query2,
222
- });
223
- const result3 = await server.executeOperation({
224
- query: query1,
225
- });
226
-
227
- expect(unwrapSingleResultKind(result1).errors).toEqual(undefined);
228
- expect(unwrapSingleResultKind(result2).errors).toEqual(undefined);
229
- expect(unwrapSingleResultKind(result3).errors).toEqual(undefined);
230
- expect(result1).toEqual(result3);
231
- });
@@ -1,101 +0,0 @@
1
- import gql from 'graphql-tag';
2
- import { startSubgraphsAndGateway, Services } from './testUtils'
3
-
4
- let services: Services;
5
-
6
- afterEach(async () => {
7
- if (services) {
8
- await services.stop();
9
- }
10
- });
11
-
12
- describe('`debug.bypassPlannerForSingleSubgraph` config', () => {
13
- const subgraph = {
14
- name: 'A',
15
- url: 'https://A',
16
- typeDefs: gql`
17
- type Query {
18
- a: A
19
- }
20
-
21
- type A {
22
- b: B
23
- }
24
-
25
- type B {
26
- x: Int
27
- y: String
28
- }
29
- `,
30
- resolvers: {
31
- Query: {
32
- a: () => ({
33
- b: {
34
- x: 1,
35
- y: 'foo',
36
- }
37
- }),
38
- }
39
- }
40
- };
41
-
42
- const query = `
43
- {
44
- a {
45
- b {
46
- x
47
- y
48
- }
49
- }
50
- }
51
- `;
52
-
53
- const expectedResult = `
54
- Object {
55
- "data": Object {
56
- "a": Object {
57
- "b": Object {
58
- "x": 1,
59
- "y": "foo",
60
- },
61
- },
62
- },
63
- }
64
- `;
65
-
66
- it('is disabled by default', async () => {
67
- services = await startSubgraphsAndGateway([subgraph]);
68
-
69
- const response = await services.queryGateway(query);
70
- const result = await response.json();
71
- expect(result).toMatchInlineSnapshot(expectedResult);
72
-
73
- const queryPlanner = services.gateway.__testing().queryPlanner!;
74
- // If the query planner is genuinely used, we shoud have evaluated 1 plan.
75
- expect(queryPlanner.lastGeneratedPlanStatistics()?.evaluatedPlanCount).toBe(1);
76
- });
77
-
78
- it('works when enabled', async () => {
79
- services = await startSubgraphsAndGateway(
80
- [subgraph],
81
- {
82
- gatewayConfig: {
83
- queryPlannerConfig: {
84
- debug: {
85
- bypassPlannerForSingleSubgraph: true,
86
- }
87
- }
88
- }
89
- }
90
- );
91
-
92
- const response = await services.queryGateway(query);
93
- const result = await response.json();
94
- expect(result).toMatchInlineSnapshot(expectedResult);
95
-
96
- const queryPlanner = services.gateway.__testing().queryPlanner!;
97
- // The `bypassPlannerForSingleSubgraph` doesn't evaluate anything. It's use is the only case where `evaluatedPlanCount` can be 0.
98
- expect(queryPlanner.lastGeneratedPlanStatistics()?.evaluatedPlanCount).toBe(0);
99
- });
100
- });
101
-