@apollo/gateway 2.4.5 → 2.4.6

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 (64) 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/package.json +4 -4
  6. package/src/__generated__/graphqlTypes.ts +33 -2
  7. package/src/__mocks__/tsconfig.json +0 -7
  8. package/src/__tests__/.gitkeep +0 -0
  9. package/src/__tests__/CucumberREADME.md +0 -96
  10. package/src/__tests__/build-query-plan.feature +0 -1471
  11. package/src/__tests__/buildQueryPlan.test.ts +0 -1225
  12. package/src/__tests__/executeQueryPlan.conditions.test.ts +0 -1488
  13. package/src/__tests__/executeQueryPlan.introspection.test.ts +0 -140
  14. package/src/__tests__/executeQueryPlan.test.ts +0 -6140
  15. package/src/__tests__/execution-utils.ts +0 -124
  16. package/src/__tests__/gateway/__snapshots__/opentelemetry.test.ts.snap +0 -195
  17. package/src/__tests__/gateway/buildService.test.ts +0 -249
  18. package/src/__tests__/gateway/endToEnd.test.ts +0 -486
  19. package/src/__tests__/gateway/executor.test.ts +0 -96
  20. package/src/__tests__/gateway/extensions.test.ts +0 -37
  21. package/src/__tests__/gateway/lifecycle-hooks.test.ts +0 -239
  22. package/src/__tests__/gateway/opentelemetry.test.ts +0 -123
  23. package/src/__tests__/gateway/queryPlanCache.test.ts +0 -231
  24. package/src/__tests__/gateway/queryPlannerConfig.test.ts +0 -101
  25. package/src/__tests__/gateway/reporting.test.ts +0 -616
  26. package/src/__tests__/gateway/supergraphSdl.test.ts +0 -396
  27. package/src/__tests__/gateway/testUtils.ts +0 -89
  28. package/src/__tests__/integration/abstract-types.test.ts +0 -1861
  29. package/src/__tests__/integration/aliases.test.ts +0 -180
  30. package/src/__tests__/integration/boolean.test.ts +0 -279
  31. package/src/__tests__/integration/complex-key.test.ts +0 -197
  32. package/src/__tests__/integration/configuration.test.ts +0 -404
  33. package/src/__tests__/integration/custom-directives.test.ts +0 -174
  34. package/src/__tests__/integration/execution-style.test.ts +0 -35
  35. package/src/__tests__/integration/fragments.test.ts +0 -237
  36. package/src/__tests__/integration/list-key.test.ts +0 -128
  37. package/src/__tests__/integration/logger.test.ts +0 -122
  38. package/src/__tests__/integration/managed.test.ts +0 -319
  39. package/src/__tests__/integration/merge-arrays.test.ts +0 -34
  40. package/src/__tests__/integration/multiple-key.test.ts +0 -327
  41. package/src/__tests__/integration/mutations.test.ts +0 -287
  42. package/src/__tests__/integration/networkRequests.test.ts +0 -542
  43. package/src/__tests__/integration/nockMocks.ts +0 -157
  44. package/src/__tests__/integration/provides.test.ts +0 -77
  45. package/src/__tests__/integration/requires.test.ts +0 -359
  46. package/src/__tests__/integration/scope.test.ts +0 -557
  47. package/src/__tests__/integration/single-service.test.ts +0 -119
  48. package/src/__tests__/integration/unions.test.ts +0 -79
  49. package/src/__tests__/integration/value-types.test.ts +0 -382
  50. package/src/__tests__/integration/variables.test.ts +0 -120
  51. package/src/__tests__/nockAssertions.ts +0 -20
  52. package/src/__tests__/queryPlanCucumber.test.ts +0 -55
  53. package/src/__tests__/resultShaping.test.ts +0 -605
  54. package/src/__tests__/testSetup.ts +0 -1
  55. package/src/__tests__/tsconfig.json +0 -8
  56. package/src/core/__tests__/core.test.ts +0 -412
  57. package/src/datasources/__tests__/LocalGraphQLDataSource.test.ts +0 -51
  58. package/src/datasources/__tests__/RemoteGraphQLDataSource.test.ts +0 -574
  59. package/src/schema-helper/__tests__/addExtensions.test.ts +0 -70
  60. package/src/supergraphManagers/IntrospectAndCompose/__tests__/IntrospectAndCompose.test.ts +0 -364
  61. package/src/supergraphManagers/IntrospectAndCompose/__tests__/loadServicesFromRemoteEndpoint.test.ts +0 -40
  62. package/src/supergraphManagers/UplinkSupergraphManager/__tests__/UplinkSupergraphManager.test.ts +0 -65
  63. package/src/supergraphManagers/UplinkSupergraphManager/__tests__/loadSupergraphSdlFromStorage.test.ts +0 -511
  64. 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
-