@apollo/gateway 2.4.4 → 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 (176) hide show
  1. package/dist/__generated__/graphqlTypes.d.ts +178 -0
  2. package/dist/__generated__/graphqlTypes.d.ts.map +1 -0
  3. package/dist/__generated__/graphqlTypes.js +31 -0
  4. package/dist/__generated__/graphqlTypes.js.map +1 -0
  5. package/dist/config.d.ts +138 -0
  6. package/dist/config.d.ts.map +1 -0
  7. package/dist/config.js +60 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/dataRewrites.d.ts +5 -0
  10. package/dist/dataRewrites.d.ts.map +1 -0
  11. package/dist/dataRewrites.js +103 -0
  12. package/dist/dataRewrites.js.map +1 -0
  13. package/dist/datasources/LocalGraphQLDataSource.d.ts +10 -0
  14. package/dist/datasources/LocalGraphQLDataSource.d.ts.map +1 -0
  15. package/dist/datasources/LocalGraphQLDataSource.js +31 -0
  16. package/dist/datasources/LocalGraphQLDataSource.js.map +1 -0
  17. package/dist/datasources/RemoteGraphQLDataSource.d.ts +24 -0
  18. package/dist/datasources/RemoteGraphQLDataSource.d.ts.map +1 -0
  19. package/dist/datasources/RemoteGraphQLDataSource.js +180 -0
  20. package/dist/datasources/RemoteGraphQLDataSource.js.map +1 -0
  21. package/dist/datasources/index.d.ts +4 -0
  22. package/dist/datasources/index.d.ts.map +1 -0
  23. package/dist/datasources/index.js +8 -0
  24. package/dist/datasources/index.js.map +1 -0
  25. package/dist/datasources/parseCacheControlHeader.d.ts +2 -0
  26. package/dist/datasources/parseCacheControlHeader.d.ts.map +1 -0
  27. package/dist/datasources/parseCacheControlHeader.js +16 -0
  28. package/dist/datasources/parseCacheControlHeader.js.map +1 -0
  29. package/dist/datasources/types.d.ts +23 -0
  30. package/dist/datasources/types.d.ts.map +1 -0
  31. package/dist/datasources/types.js +10 -0
  32. package/dist/datasources/types.js.map +1 -0
  33. package/dist/executeQueryPlan.d.ts +15 -0
  34. package/dist/executeQueryPlan.d.ts.map +1 -0
  35. package/dist/executeQueryPlan.js +539 -0
  36. package/dist/executeQueryPlan.js.map +1 -0
  37. package/dist/index.d.ts +113 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +590 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/logger.d.ts +3 -0
  42. package/dist/logger.d.ts.map +1 -0
  43. package/dist/logger.js +15 -0
  44. package/dist/logger.js.map +1 -0
  45. package/dist/operationContext.d.ts +17 -0
  46. package/dist/operationContext.d.ts.map +1 -0
  47. package/dist/operationContext.js +38 -0
  48. package/dist/operationContext.js.map +1 -0
  49. package/dist/resultShaping.d.ts +12 -0
  50. package/dist/resultShaping.d.ts.map +1 -0
  51. package/dist/resultShaping.js +229 -0
  52. package/dist/resultShaping.js.map +1 -0
  53. package/dist/schema-helper/addExtensions.d.ts +3 -0
  54. package/dist/schema-helper/addExtensions.d.ts.map +1 -0
  55. package/dist/schema-helper/addExtensions.js +23 -0
  56. package/dist/schema-helper/addExtensions.js.map +1 -0
  57. package/dist/supergraphManagers/IntrospectAndCompose/index.d.ts +31 -0
  58. package/dist/supergraphManagers/IntrospectAndCompose/index.d.ts.map +1 -0
  59. package/dist/supergraphManagers/IntrospectAndCompose/index.js +112 -0
  60. package/dist/supergraphManagers/IntrospectAndCompose/index.js.map +1 -0
  61. package/dist/supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.d.ts +12 -0
  62. package/dist/supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.d.ts.map +1 -0
  63. package/dist/supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.js +57 -0
  64. package/dist/supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.js.map +1 -0
  65. package/dist/supergraphManagers/LegacyFetcher/index.d.ts +33 -0
  66. package/dist/supergraphManagers/LegacyFetcher/index.d.ts.map +1 -0
  67. package/dist/supergraphManagers/LegacyFetcher/index.js +149 -0
  68. package/dist/supergraphManagers/LegacyFetcher/index.js.map +1 -0
  69. package/dist/supergraphManagers/LocalCompose/index.d.ts +19 -0
  70. package/dist/supergraphManagers/LocalCompose/index.d.ts.map +1 -0
  71. package/dist/supergraphManagers/LocalCompose/index.js +55 -0
  72. package/dist/supergraphManagers/LocalCompose/index.js.map +1 -0
  73. package/dist/supergraphManagers/UplinkSupergraphManager/index.d.ts +63 -0
  74. package/dist/supergraphManagers/UplinkSupergraphManager/index.d.ts.map +1 -0
  75. package/dist/supergraphManagers/UplinkSupergraphManager/index.js +210 -0
  76. package/dist/supergraphManagers/UplinkSupergraphManager/index.js.map +1 -0
  77. package/dist/supergraphManagers/UplinkSupergraphManager/loadSupergraphSdlFromStorage.d.ts +30 -0
  78. package/dist/supergraphManagers/UplinkSupergraphManager/loadSupergraphSdlFromStorage.d.ts.map +1 -0
  79. package/dist/supergraphManagers/UplinkSupergraphManager/loadSupergraphSdlFromStorage.js +145 -0
  80. package/dist/supergraphManagers/UplinkSupergraphManager/loadSupergraphSdlFromStorage.js.map +1 -0
  81. package/dist/supergraphManagers/UplinkSupergraphManager/outOfBandReporter.d.ts +14 -0
  82. package/dist/supergraphManagers/UplinkSupergraphManager/outOfBandReporter.d.ts.map +1 -0
  83. package/dist/supergraphManagers/UplinkSupergraphManager/outOfBandReporter.js +85 -0
  84. package/dist/supergraphManagers/UplinkSupergraphManager/outOfBandReporter.js.map +1 -0
  85. package/dist/supergraphManagers/index.d.ts +6 -0
  86. package/dist/supergraphManagers/index.d.ts.map +1 -0
  87. package/dist/supergraphManagers/index.js +27 -0
  88. package/dist/supergraphManagers/index.js.map +1 -0
  89. package/dist/typings/graphql.d.ts +11 -0
  90. package/dist/typings/graphql.d.ts.map +1 -0
  91. package/dist/typings/graphql.js +3 -0
  92. package/dist/typings/graphql.js.map +1 -0
  93. package/dist/utilities/array.d.ts +5 -0
  94. package/dist/utilities/array.d.ts.map +1 -0
  95. package/dist/utilities/array.js +46 -0
  96. package/dist/utilities/array.js.map +1 -0
  97. package/dist/utilities/assert.d.ts +2 -0
  98. package/dist/utilities/assert.d.ts.map +1 -0
  99. package/dist/utilities/assert.js +10 -0
  100. package/dist/utilities/assert.js.map +1 -0
  101. package/dist/utilities/deepMerge.d.ts +2 -0
  102. package/dist/utilities/deepMerge.d.ts.map +1 -0
  103. package/dist/utilities/deepMerge.js +34 -0
  104. package/dist/utilities/deepMerge.js.map +1 -0
  105. package/dist/utilities/graphql.d.ts +5 -0
  106. package/dist/utilities/graphql.d.ts.map +1 -0
  107. package/dist/utilities/graphql.js +28 -0
  108. package/dist/utilities/graphql.js.map +1 -0
  109. package/dist/utilities/opentelemetry.d.ts +10 -0
  110. package/dist/utilities/opentelemetry.d.ts.map +1 -0
  111. package/dist/utilities/opentelemetry.js +19 -0
  112. package/dist/utilities/opentelemetry.js.map +1 -0
  113. package/dist/utilities/predicates.d.ts +2 -0
  114. package/dist/utilities/predicates.d.ts.map +1 -0
  115. package/dist/utilities/predicates.js +11 -0
  116. package/dist/utilities/predicates.js.map +1 -0
  117. package/package.json +4 -4
  118. package/src/__generated__/graphqlTypes.ts +33 -2
  119. package/src/__mocks__/tsconfig.json +0 -7
  120. package/src/__tests__/.gitkeep +0 -0
  121. package/src/__tests__/CucumberREADME.md +0 -96
  122. package/src/__tests__/build-query-plan.feature +0 -1471
  123. package/src/__tests__/buildQueryPlan.test.ts +0 -1225
  124. package/src/__tests__/executeQueryPlan.conditions.test.ts +0 -1488
  125. package/src/__tests__/executeQueryPlan.introspection.test.ts +0 -140
  126. package/src/__tests__/executeQueryPlan.test.ts +0 -6140
  127. package/src/__tests__/execution-utils.ts +0 -124
  128. package/src/__tests__/gateway/__snapshots__/opentelemetry.test.ts.snap +0 -195
  129. package/src/__tests__/gateway/buildService.test.ts +0 -249
  130. package/src/__tests__/gateway/endToEnd.test.ts +0 -486
  131. package/src/__tests__/gateway/executor.test.ts +0 -96
  132. package/src/__tests__/gateway/extensions.test.ts +0 -37
  133. package/src/__tests__/gateway/lifecycle-hooks.test.ts +0 -239
  134. package/src/__tests__/gateway/opentelemetry.test.ts +0 -123
  135. package/src/__tests__/gateway/queryPlanCache.test.ts +0 -231
  136. package/src/__tests__/gateway/queryPlannerConfig.test.ts +0 -101
  137. package/src/__tests__/gateway/reporting.test.ts +0 -616
  138. package/src/__tests__/gateway/supergraphSdl.test.ts +0 -396
  139. package/src/__tests__/gateway/testUtils.ts +0 -89
  140. package/src/__tests__/integration/abstract-types.test.ts +0 -1861
  141. package/src/__tests__/integration/aliases.test.ts +0 -180
  142. package/src/__tests__/integration/boolean.test.ts +0 -279
  143. package/src/__tests__/integration/complex-key.test.ts +0 -197
  144. package/src/__tests__/integration/configuration.test.ts +0 -404
  145. package/src/__tests__/integration/custom-directives.test.ts +0 -174
  146. package/src/__tests__/integration/execution-style.test.ts +0 -35
  147. package/src/__tests__/integration/fragments.test.ts +0 -237
  148. package/src/__tests__/integration/list-key.test.ts +0 -128
  149. package/src/__tests__/integration/logger.test.ts +0 -122
  150. package/src/__tests__/integration/managed.test.ts +0 -319
  151. package/src/__tests__/integration/merge-arrays.test.ts +0 -34
  152. package/src/__tests__/integration/multiple-key.test.ts +0 -327
  153. package/src/__tests__/integration/mutations.test.ts +0 -287
  154. package/src/__tests__/integration/networkRequests.test.ts +0 -542
  155. package/src/__tests__/integration/nockMocks.ts +0 -157
  156. package/src/__tests__/integration/provides.test.ts +0 -77
  157. package/src/__tests__/integration/requires.test.ts +0 -359
  158. package/src/__tests__/integration/scope.test.ts +0 -557
  159. package/src/__tests__/integration/single-service.test.ts +0 -119
  160. package/src/__tests__/integration/unions.test.ts +0 -79
  161. package/src/__tests__/integration/value-types.test.ts +0 -382
  162. package/src/__tests__/integration/variables.test.ts +0 -120
  163. package/src/__tests__/nockAssertions.ts +0 -20
  164. package/src/__tests__/queryPlanCucumber.test.ts +0 -55
  165. package/src/__tests__/resultShaping.test.ts +0 -605
  166. package/src/__tests__/testSetup.ts +0 -1
  167. package/src/__tests__/tsconfig.json +0 -8
  168. package/src/core/__tests__/core.test.ts +0 -412
  169. package/src/datasources/__tests__/LocalGraphQLDataSource.test.ts +0 -51
  170. package/src/datasources/__tests__/RemoteGraphQLDataSource.test.ts +0 -574
  171. package/src/schema-helper/__tests__/addExtensions.test.ts +0 -70
  172. package/src/supergraphManagers/IntrospectAndCompose/__tests__/IntrospectAndCompose.test.ts +0 -364
  173. package/src/supergraphManagers/IntrospectAndCompose/__tests__/loadServicesFromRemoteEndpoint.test.ts +0 -40
  174. package/src/supergraphManagers/UplinkSupergraphManager/__tests__/UplinkSupergraphManager.test.ts +0 -65
  175. package/src/supergraphManagers/UplinkSupergraphManager/__tests__/loadSupergraphSdlFromStorage.test.ts +0 -511
  176. package/src/utilities/__tests__/deepMerge.test.ts +0 -77
@@ -1,364 +0,0 @@
1
- import nock from 'nock';
2
- import {
3
- fixtures,
4
- fixturesWithUpdate,
5
- } from 'apollo-federation-integration-testsuite';
6
- import { nockBeforeEach, nockAfterEach } from '../../../__tests__/nockAssertions';
7
- import { RemoteGraphQLDataSource, ServiceEndpointDefinition } from '../../..';
8
- import { IntrospectAndCompose } from '..';
9
- import { mockAllServicesSdlQuerySuccess } from '../../../__tests__/integration/nockMocks';
10
- import { getTestingSupergraphSdl, wait } from '../../../__tests__/execution-utils';
11
- import resolvable from '@josephg/resolvable';
12
- import type { Logger } from '@apollo/utils.logger';
13
-
14
- describe('IntrospectAndCompose', () => {
15
- beforeEach(nockBeforeEach);
16
- afterEach(nockAfterEach);
17
-
18
- it('constructs', () => {
19
- expect(
20
- () =>
21
- new IntrospectAndCompose({
22
- subgraphs: fixtures,
23
- }),
24
- ).not.toThrow();
25
- });
26
-
27
- it('has an `initialize` property which is callable (simulating the gateway calling it)', async () => {
28
- mockAllServicesSdlQuerySuccess();
29
- const instance = new IntrospectAndCompose({ subgraphs: fixtures });
30
- await expect(
31
- instance.initialize({
32
- update() {},
33
- async healthCheck() {},
34
- getDataSource({ url }) {
35
- return new RemoteGraphQLDataSource({ url });
36
- },
37
- }),
38
- ).resolves.toBeTruthy();
39
- });
40
-
41
- it('uses `GraphQLDataSource`s provided by the `buildService` function', async () => {
42
- mockAllServicesSdlQuerySuccess();
43
-
44
- const processSpies: jest.SpyInstance[] = [];
45
- function getDataSourceSpy(definition: ServiceEndpointDefinition) {
46
- const datasource = new RemoteGraphQLDataSource({
47
- url: definition.url,
48
- });
49
- const processSpy = jest.spyOn(datasource, 'process');
50
- processSpies.push(processSpy);
51
- return datasource;
52
- }
53
-
54
- const instance = new IntrospectAndCompose({
55
- subgraphs: fixtures,
56
- });
57
-
58
- await instance.initialize({
59
- update() {},
60
- async healthCheck() {},
61
- getDataSource: getDataSourceSpy,
62
- });
63
-
64
- expect(processSpies.length).toBe(fixtures.length);
65
- for (const processSpy of processSpies) {
66
- expect(processSpy).toHaveBeenCalledTimes(1);
67
- }
68
- });
69
-
70
- it('polls services when a `pollInterval` is set and stops when `cleanup` is called', async () => {
71
- // This is mocked 4 times to include the initial load (followed by 3 polls)
72
- // We need to alternate schemas, else the update will be ignored
73
- mockAllServicesSdlQuerySuccess();
74
- mockAllServicesSdlQuerySuccess(fixturesWithUpdate);
75
- mockAllServicesSdlQuerySuccess();
76
- mockAllServicesSdlQuerySuccess(fixturesWithUpdate);
77
-
78
- const p1 = resolvable();
79
- const p2 = resolvable();
80
- const p3 = resolvable();
81
-
82
- // `update` (below) is called each time we poll (and there's an update to
83
- // the supergraph), so this is a reasonable hook into "when" the poll
84
- // happens and drives this test cleanly with `Promise`s.
85
- const updateSpy = jest
86
- .fn()
87
- .mockImplementationOnce(() => p1.resolve())
88
- .mockImplementationOnce(() => p2.resolve())
89
- .mockImplementationOnce(() => p3.resolve());
90
-
91
- const instance = new IntrospectAndCompose({
92
- subgraphs: fixtures,
93
- pollIntervalInMs: 10,
94
- });
95
-
96
- const { cleanup } = await instance.initialize({
97
- update(supergraphSdl) {
98
- updateSpy(supergraphSdl);
99
- },
100
- async healthCheck() {},
101
- getDataSource({ url }) {
102
- return new RemoteGraphQLDataSource({ url });
103
- },
104
- });
105
-
106
- await Promise.all([p1, p2, p3]);
107
-
108
- expect(updateSpy).toHaveBeenCalledTimes(3);
109
-
110
- // stop polling
111
- await cleanup!();
112
-
113
- expect(updateSpy).toHaveBeenCalledTimes(3);
114
-
115
- // ensure we cancelled the timer
116
- // @ts-ignore
117
- expect(instance.timerRef).toBe(null);
118
- });
119
-
120
- // TODO: useFakeTimers (though I'm struggling to get this to work as expected)
121
- it("doesn't call `update` when there's no change to the supergraph", async () => {
122
- // mock for initial load and a few polls against an unchanging schema
123
- mockAllServicesSdlQuerySuccess();
124
- mockAllServicesSdlQuerySuccess();
125
- mockAllServicesSdlQuerySuccess();
126
- mockAllServicesSdlQuerySuccess();
127
-
128
- const instance = new IntrospectAndCompose({
129
- subgraphs: fixtures,
130
- pollIntervalInMs: 100,
131
- });
132
-
133
- const updateSpy = jest.fn();
134
- const { cleanup } = await instance.initialize({
135
- update(supergraphSdl) {
136
- updateSpy(supergraphSdl);
137
- },
138
- async healthCheck() {},
139
- getDataSource({ url }) {
140
- return new RemoteGraphQLDataSource({
141
- url,
142
- });
143
- },
144
- });
145
-
146
- // let the instance poll through all the active mocks
147
- // wouldn't need to do this if I could get fakeTimers working as expected
148
- while (nock.activeMocks().length > 0) {
149
- await wait(0);
150
- }
151
-
152
- await cleanup!();
153
-
154
- expect(updateSpy).not.toHaveBeenCalled();
155
- });
156
-
157
- it('issues subgraph health checks when enabled (and polling)', async () => {
158
- mockAllServicesSdlQuerySuccess();
159
- mockAllServicesSdlQuerySuccess(fixturesWithUpdate);
160
-
161
- const healthCheckPromiseOnLoad = resolvable();
162
- const healthCheckPromiseOnUpdate = resolvable();
163
-
164
- const healthCheckSpy = jest
165
- .fn()
166
- .mockImplementationOnce(() => healthCheckPromiseOnLoad.resolve())
167
- .mockImplementationOnce(() => healthCheckPromiseOnUpdate.resolve());
168
-
169
- const instance = new IntrospectAndCompose({
170
- subgraphs: fixtures,
171
- pollIntervalInMs: 10,
172
- subgraphHealthCheck: true,
173
- });
174
-
175
- const { cleanup } = await instance.initialize({
176
- update() {},
177
- async healthCheck(supergraphSdl) {
178
- healthCheckSpy(supergraphSdl);
179
- },
180
- getDataSource({ url }) {
181
- return new RemoteGraphQLDataSource({ url });
182
- },
183
- });
184
-
185
- await Promise.all([
186
- healthCheckPromiseOnLoad,
187
- healthCheckPromiseOnUpdate,
188
- ]);
189
-
190
- expect(healthCheckSpy).toHaveBeenNthCalledWith(
191
- 1,
192
- getTestingSupergraphSdl(fixtures),
193
- );
194
- expect(healthCheckSpy).toHaveBeenNthCalledWith(
195
- 2,
196
- getTestingSupergraphSdl(fixturesWithUpdate),
197
- );
198
-
199
- // stop polling
200
- await cleanup!();
201
- });
202
-
203
- describe('errors', () => {
204
- it('logs an error when `update` function throws', async () => {
205
- const errorLoggedPromise = resolvable();
206
-
207
- const errorSpy = jest.fn(() => {
208
- errorLoggedPromise.resolve();
209
- });
210
- const logger: Logger = {
211
- error: errorSpy,
212
- debug() {},
213
- info() {},
214
- warn() {},
215
- };
216
-
217
- // mock successful initial load
218
- mockAllServicesSdlQuerySuccess();
219
-
220
- // mock first update
221
- mockAllServicesSdlQuerySuccess(fixturesWithUpdate);
222
-
223
- const instance = new IntrospectAndCompose({
224
- subgraphs: fixtures,
225
- pollIntervalInMs: 1000,
226
- logger,
227
- });
228
-
229
- const thrownErrorMessage = 'invalid supergraph';
230
- // simulate gateway throwing an error when `update` is called
231
- const updateSpy = jest.fn().mockImplementationOnce(() => {
232
- throw new Error(thrownErrorMessage);
233
- });
234
-
235
- const { cleanup } = await instance.initialize({
236
- update: updateSpy,
237
- async healthCheck() {},
238
- getDataSource({ url }) {
239
- return new RemoteGraphQLDataSource({ url });
240
- },
241
- });
242
-
243
- await errorLoggedPromise;
244
- // stop polling
245
- await cleanup!();
246
-
247
- expect(updateSpy).toHaveBeenCalledTimes(1);
248
- expect(logger.error).toHaveBeenCalledTimes(1);
249
- expect(logger.error).toHaveBeenCalledWith(
250
- `IntrospectAndCompose failed to update supergraph with the following error: ${thrownErrorMessage}`,
251
- );
252
- });
253
-
254
- it('fails to load when `healthCheck` function throws on startup', async () => {
255
- mockAllServicesSdlQuerySuccess();
256
-
257
- const expectedErrorMsg = 'error reaching subgraph';
258
- const errorLoggedPromise = resolvable();
259
- const errorSpy = jest.fn(() => {
260
- errorLoggedPromise.resolve();
261
- });
262
- const logger: Logger = {
263
- error: errorSpy,
264
- debug() {},
265
- info() {},
266
- warn() {},
267
- };
268
-
269
- const updateSpy = jest.fn();
270
-
271
- const instance = new IntrospectAndCompose({
272
- subgraphs: fixtures,
273
- pollIntervalInMs: 10,
274
- subgraphHealthCheck: true,
275
- logger,
276
- });
277
-
278
- await expect(
279
- instance.initialize({
280
- update() {
281
- updateSpy();
282
- },
283
- async healthCheck() {
284
- throw new Error(expectedErrorMsg);
285
- },
286
- getDataSource({ url }) {
287
- return new RemoteGraphQLDataSource({ url });
288
- },
289
- }),
290
- ).rejects.toThrowErrorMatchingInlineSnapshot(`"error reaching subgraph"`);
291
-
292
- await errorLoggedPromise;
293
-
294
- expect(errorSpy).toHaveBeenCalledWith(
295
- `IntrospectAndCompose failed to update supergraph with the following error: ${expectedErrorMsg}`,
296
- );
297
- expect(updateSpy).not.toHaveBeenCalled();
298
- });
299
-
300
- it('does not attempt to update when `healthCheck` function throws', async () => {
301
- mockAllServicesSdlQuerySuccess();
302
- mockAllServicesSdlQuerySuccess(fixturesWithUpdate);
303
-
304
- const expectedErrorMsg = 'error reaching subgraph';
305
- const errorLoggedPromise = resolvable();
306
- const errorSpy = jest.fn(() => {
307
- errorLoggedPromise.resolve();
308
- });
309
- const logger: Logger = {
310
- error: errorSpy,
311
- debug() {},
312
- info() {},
313
- warn() {},
314
- };
315
-
316
- const healthCheckPromiseOnLoad = resolvable();
317
- const healthCheckPromiseOnUpdate = resolvable();
318
- const healthCheckSpyWhichEventuallyThrows = jest
319
- .fn()
320
- .mockImplementationOnce(() => healthCheckPromiseOnLoad.resolve())
321
- .mockImplementationOnce(() => {
322
- healthCheckPromiseOnUpdate.resolve();
323
- throw new Error(expectedErrorMsg);
324
- });
325
-
326
- const updateSpy = jest.fn();
327
-
328
- const instance = new IntrospectAndCompose({
329
- subgraphs: fixtures,
330
- pollIntervalInMs: 10,
331
- subgraphHealthCheck: true,
332
- logger,
333
- });
334
-
335
- const { cleanup } = await instance.initialize({
336
- update() {
337
- updateSpy();
338
- },
339
- async healthCheck(supergraphSdl) {
340
- healthCheckSpyWhichEventuallyThrows(supergraphSdl);
341
- },
342
- getDataSource({ url }) {
343
- return new RemoteGraphQLDataSource({ url });
344
- },
345
- });
346
-
347
- await Promise.all([
348
- healthCheckPromiseOnLoad,
349
- healthCheckPromiseOnUpdate,
350
- errorLoggedPromise,
351
- ]);
352
-
353
- expect(errorSpy).toHaveBeenCalledWith(
354
- `IntrospectAndCompose failed to update supergraph with the following error: ${expectedErrorMsg}`,
355
- );
356
- expect(healthCheckSpyWhichEventuallyThrows).toHaveBeenCalledTimes(2);
357
- // update isn't called on load so this shouldn't be called even once
358
- expect(updateSpy).not.toHaveBeenCalled();
359
-
360
- // stop polling
361
- await cleanup!();
362
- });
363
- });
364
- });
@@ -1,40 +0,0 @@
1
- import { loadServicesFromRemoteEndpoint } from '../loadServicesFromRemoteEndpoint';
2
- import { RemoteGraphQLDataSource } from '../../../datasources';
3
-
4
- describe('loadServicesFromRemoteEndpoint', () => {
5
- it('errors when no URL was specified', async () => {
6
- const serviceSdlCache = new Map<string, string>();
7
- const dataSource = new RemoteGraphQLDataSource({ url: '' });
8
- const serviceList = [{ name: 'test', dataSource }];
9
- await expect(
10
- loadServicesFromRemoteEndpoint({
11
- serviceList,
12
- serviceSdlCache,
13
- getServiceIntrospectionHeaders: async () => ({})
14
- }),
15
- ).rejects.toThrowError(
16
- "Tried to load schema for 'test' but no 'url' was specified.",
17
- );
18
- });
19
-
20
- it('throws when the downstream service returns errors', async () => {
21
- const serviceSdlCache = new Map<string, string>();
22
- const host = 'http://host-which-better-not-resolve.invalid';
23
- const url = host + '/graphql';
24
-
25
- const dataSource = new RemoteGraphQLDataSource({ url });
26
- const serviceList = [{ name: 'test', url, dataSource }];
27
- // Depending on the OS's resolver, the error may result in an error
28
- // of `EAI_AGAIN` or `ENOTFOUND`. This `toThrowError` uses a Regex
29
- // to match either case.
30
- await expect(
31
- loadServicesFromRemoteEndpoint({
32
- serviceList,
33
- serviceSdlCache,
34
- getServiceIntrospectionHeaders: async () => ({}),
35
- }),
36
- ).rejects.toThrowError(
37
- /^Couldn't load service definitions for "test" at http:\/\/host-which-better-not-resolve.invalid\/graphql: request to http:\/\/host-which-better-not-resolve.invalid\/graphql failed, reason: getaddrinfo (ENOTFOUND|EAI_AGAIN)/,
38
- );
39
- });
40
- });
@@ -1,65 +0,0 @@
1
- import mockedEnv from 'mocked-env';
2
-
3
- import { UplinkSupergraphManager } from '@apollo/gateway';
4
-
5
- let cleanUp: (() => void) | undefined;
6
-
7
- const logger = {
8
- warn: jest.fn(),
9
- debug: jest.fn(),
10
- error: jest.fn(),
11
- info: jest.fn(),
12
- };
13
- const apiKey = 'OU812';
14
- const graphRef = 'graph@ref';
15
-
16
- afterEach(async () => {
17
- if (cleanUp) {
18
- cleanUp();
19
- cleanUp = undefined;
20
- }
21
- });
22
-
23
- describe('UplinkSupergraphManager', () => {
24
- it('can be minimally constructed', () => {
25
- new UplinkSupergraphManager({ apiKey, graphRef });
26
- });
27
-
28
- describe('setting uplink URLs', () => {
29
- it('uses default uplink URLs', async () => {
30
- const manager = new UplinkSupergraphManager({ apiKey, graphRef, logger });
31
-
32
- expect(manager.uplinkEndpoints).toEqual(UplinkSupergraphManager.DEFAULT_UPLINK_ENDPOINTS);
33
- });
34
-
35
- it('can set uplink URLs via config', async () => {
36
- cleanUp = mockedEnv({
37
- APOLLO_SCHEMA_CONFIG_DELIVERY_ENDPOINT: 'https://env-delivery.com',
38
- });
39
- const uplinkEndpoints = [
40
- 'https://config-delivery1.com',
41
- 'https://config-delivery2.com',
42
- ];
43
-
44
- const manager = new UplinkSupergraphManager({
45
- apiKey,
46
- graphRef,
47
- uplinkEndpoints,
48
- logger,
49
- });
50
-
51
- expect(manager.uplinkEndpoints).toEqual(uplinkEndpoints);
52
- });
53
-
54
- it('can set uplink URLs via environment variable', async () => {
55
- const uplinkUrl = 'https://env-delivery.com';
56
- cleanUp = mockedEnv({
57
- APOLLO_SCHEMA_CONFIG_DELIVERY_ENDPOINT: uplinkUrl,
58
- });
59
-
60
- const manager = new UplinkSupergraphManager({ apiKey, graphRef, logger });
61
-
62
- expect(manager.uplinkEndpoints).toEqual([uplinkUrl]);
63
- });
64
- });
65
- });