@apollo/gateway 0.43.0 → 0.45.0-alpha.0
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.
- package/CHANGELOG.md +14 -2
- package/dist/__generated__/graphqlTypes.d.ts +13 -11
- package/dist/__generated__/graphqlTypes.d.ts.map +1 -1
- package/dist/__generated__/graphqlTypes.js.map +1 -1
- package/dist/config.d.ts +3 -8
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +6 -17
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +33 -33
- package/dist/index.js.map +1 -1
- package/dist/loadSupergraphSdlFromStorage.d.ts +15 -6
- package/dist/loadSupergraphSdlFromStorage.d.ts.map +1 -1
- package/dist/loadSupergraphSdlFromStorage.js +40 -9
- package/dist/loadSupergraphSdlFromStorage.js.map +1 -1
- package/dist/outOfBandReporter.d.ts +10 -12
- package/dist/outOfBandReporter.d.ts.map +1 -1
- package/dist/outOfBandReporter.js +70 -73
- package/dist/outOfBandReporter.js.map +1 -1
- package/package.json +8 -8
- package/src/__generated__/graphqlTypes.ts +13 -11
- package/src/__tests__/gateway/reporting.test.ts +5 -3
- package/src/__tests__/integration/configuration.test.ts +32 -11
- package/src/__tests__/integration/networkRequests.test.ts +44 -32
- package/src/__tests__/integration/nockMocks.ts +42 -8
- package/src/__tests__/loadSupergraphSdlFromStorage.test.ts +129 -375
- package/src/__tests__/nockAssertions.ts +20 -0
- package/src/config.ts +10 -43
- package/src/index.ts +43 -54
- package/src/loadSupergraphSdlFromStorage.ts +61 -12
- package/src/outOfBandReporter.ts +87 -89
- package/dist/legacyLoadServicesFromStorage.d.ts +0 -20
- package/dist/legacyLoadServicesFromStorage.d.ts.map +0 -1
- package/dist/legacyLoadServicesFromStorage.js +0 -62
- package/dist/legacyLoadServicesFromStorage.js.map +0 -1
- package/src/__tests__/integration/legacyNetworkRequests.test.ts +0 -279
- package/src/__tests__/integration/legacyNockMocks.ts +0 -113
- package/src/legacyLoadServicesFromStorage.ts +0 -170
|
@@ -1,352 +1,96 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
loadSupergraphSdlFromStorage,
|
|
3
|
+
loadSupergraphSdlFromUplinks
|
|
4
|
+
} from '../loadSupergraphSdlFromStorage';
|
|
2
5
|
import { getDefaultFetcher } from '../..';
|
|
3
6
|
import {
|
|
4
7
|
graphRef,
|
|
5
8
|
apiKey,
|
|
6
|
-
|
|
7
|
-
|
|
9
|
+
mockCloudConfigUrl1,
|
|
10
|
+
mockCloudConfigUrl2,
|
|
8
11
|
mockOutOfBandReporterUrl,
|
|
12
|
+
mockSupergraphSdlRequest,
|
|
9
13
|
mockOutOfBandReportRequestSuccess,
|
|
10
14
|
mockSupergraphSdlRequestSuccess,
|
|
15
|
+
mockSupergraphSdlRequestIfAfterUnchanged,
|
|
16
|
+
mockSupergraphSdlRequestIfAfter
|
|
11
17
|
} from './integration/nockMocks';
|
|
12
|
-
import
|
|
18
|
+
import { getTestingSupergraphSdl } from "./execution-utils";
|
|
19
|
+
import { nockAfterEach, nockBeforeEach } from './nockAssertions';
|
|
13
20
|
|
|
14
21
|
describe('loadSupergraphSdlFromStorage', () => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
afterAll(async () => {
|
|
18
|
-
if (cleanUp) {
|
|
19
|
-
cleanUp();
|
|
20
|
-
cleanUp = null;
|
|
21
|
-
}
|
|
22
|
-
});
|
|
22
|
+
beforeEach(nockBeforeEach);
|
|
23
|
+
afterEach(nockAfterEach);
|
|
23
24
|
|
|
24
25
|
it('fetches Supergraph SDL as expected', async () => {
|
|
25
26
|
mockSupergraphSdlRequestSuccess();
|
|
26
|
-
|
|
27
27
|
const fetcher = getDefaultFetcher();
|
|
28
28
|
const result = await loadSupergraphSdlFromStorage({
|
|
29
29
|
graphRef,
|
|
30
30
|
apiKey,
|
|
31
|
-
endpoint:
|
|
31
|
+
endpoint: mockCloudConfigUrl1,
|
|
32
|
+
errorReportingEndpoint: undefined,
|
|
32
33
|
fetcher,
|
|
34
|
+
compositionId: null,
|
|
35
|
+
});
|
|
36
|
+
expect(result).toMatchObject({
|
|
37
|
+
id: 'originalId-1234',
|
|
38
|
+
supergraphSdl: getTestingSupergraphSdl(),
|
|
33
39
|
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('Queries alternate Uplink URL if first one fails', async () => {
|
|
43
|
+
mockSupergraphSdlRequest('originalId-1234', mockCloudConfigUrl1).reply(500);
|
|
44
|
+
mockSupergraphSdlRequestIfAfter('originalId-1234', mockCloudConfigUrl2).reply(
|
|
45
|
+
200,
|
|
46
|
+
JSON.stringify({
|
|
47
|
+
data: {
|
|
48
|
+
routerConfig: {
|
|
49
|
+
__typename: 'RouterConfigResult',
|
|
50
|
+
id: 'originalId-1234',
|
|
51
|
+
supergraphSdl: getTestingSupergraphSdl()
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
}),
|
|
55
|
+
);
|
|
34
56
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
directive @join__graph(name: String!, url: String!) on ENUM_VALUE
|
|
52
|
-
|
|
53
|
-
directive @join__owner(graph: join__Graph!) on INTERFACE | OBJECT
|
|
54
|
-
|
|
55
|
-
directive @join__type(graph: join__Graph!, key: join__FieldSet) repeatable on INTERFACE | OBJECT
|
|
56
|
-
|
|
57
|
-
directive @stream on FIELD
|
|
58
|
-
|
|
59
|
-
directive @tag(name: String!) repeatable on FIELD_DEFINITION | INTERFACE | OBJECT | UNION
|
|
60
|
-
|
|
61
|
-
directive @transform(from: String!) on FIELD
|
|
62
|
-
|
|
63
|
-
union AccountType
|
|
64
|
-
@tag(name: \\"from-accounts\\")
|
|
65
|
-
= PasswordAccount | SMSAccount
|
|
66
|
-
|
|
67
|
-
type Amazon {
|
|
68
|
-
referrer: String
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
union Body = Image | Text
|
|
72
|
-
|
|
73
|
-
type Book implements Product
|
|
74
|
-
@join__owner(graph: BOOKS)
|
|
75
|
-
@join__type(graph: BOOKS, key: \\"isbn\\")
|
|
76
|
-
@join__type(graph: INVENTORY, key: \\"isbn\\")
|
|
77
|
-
@join__type(graph: PRODUCT, key: \\"isbn\\")
|
|
78
|
-
@join__type(graph: REVIEWS, key: \\"isbn\\")
|
|
79
|
-
{
|
|
80
|
-
details: ProductDetailsBook @join__field(graph: PRODUCT)
|
|
81
|
-
inStock: Boolean @join__field(graph: INVENTORY)
|
|
82
|
-
isCheckedOut: Boolean @join__field(graph: INVENTORY)
|
|
83
|
-
isbn: String! @join__field(graph: BOOKS)
|
|
84
|
-
metadata: [MetadataOrError] @join__field(graph: BOOKS)
|
|
85
|
-
name(delimeter: String = \\" \\"): String @join__field(graph: PRODUCT, requires: \\"title year\\")
|
|
86
|
-
price: String @join__field(graph: PRODUCT)
|
|
87
|
-
relatedReviews: [Review!]! @join__field(graph: REVIEWS, requires: \\"similarBooks{isbn}\\")
|
|
88
|
-
reviews: [Review] @join__field(graph: REVIEWS)
|
|
89
|
-
similarBooks: [Book]! @join__field(graph: BOOKS)
|
|
90
|
-
sku: String! @join__field(graph: PRODUCT)
|
|
91
|
-
title: String @join__field(graph: BOOKS)
|
|
92
|
-
upc: String! @join__field(graph: PRODUCT)
|
|
93
|
-
year: Int @join__field(graph: BOOKS)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
union Brand = Amazon | Ikea
|
|
97
|
-
|
|
98
|
-
enum CacheControlScope {
|
|
99
|
-
PRIVATE
|
|
100
|
-
PUBLIC
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
type Car implements Vehicle
|
|
104
|
-
@join__owner(graph: PRODUCT)
|
|
105
|
-
@join__type(graph: PRODUCT, key: \\"id\\")
|
|
106
|
-
@join__type(graph: REVIEWS, key: \\"id\\")
|
|
107
|
-
{
|
|
108
|
-
description: String @join__field(graph: PRODUCT)
|
|
109
|
-
id: String! @join__field(graph: PRODUCT)
|
|
110
|
-
price: String @join__field(graph: PRODUCT)
|
|
111
|
-
retailPrice: String @join__field(graph: REVIEWS, requires: \\"price\\")
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
type Error {
|
|
115
|
-
code: Int
|
|
116
|
-
message: String
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
type Furniture implements Product
|
|
120
|
-
@join__owner(graph: PRODUCT)
|
|
121
|
-
@join__type(graph: PRODUCT, key: \\"upc\\")
|
|
122
|
-
@join__type(graph: PRODUCT, key: \\"sku\\")
|
|
123
|
-
@join__type(graph: INVENTORY, key: \\"sku\\")
|
|
124
|
-
@join__type(graph: REVIEWS, key: \\"upc\\")
|
|
125
|
-
{
|
|
126
|
-
brand: Brand @join__field(graph: PRODUCT)
|
|
127
|
-
details: ProductDetailsFurniture @join__field(graph: PRODUCT)
|
|
128
|
-
inStock: Boolean @join__field(graph: INVENTORY)
|
|
129
|
-
isHeavy: Boolean @join__field(graph: INVENTORY)
|
|
130
|
-
metadata: [MetadataOrError] @join__field(graph: PRODUCT)
|
|
131
|
-
name: String @join__field(graph: PRODUCT)
|
|
132
|
-
price: String @join__field(graph: PRODUCT)
|
|
133
|
-
reviews: [Review] @join__field(graph: REVIEWS)
|
|
134
|
-
sku: String! @join__field(graph: PRODUCT)
|
|
135
|
-
upc: String! @join__field(graph: PRODUCT)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
type Ikea {
|
|
139
|
-
asile: Int
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
type Image implements NamedObject {
|
|
143
|
-
attributes: ImageAttributes!
|
|
144
|
-
name: String!
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
type ImageAttributes {
|
|
148
|
-
url: String!
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
scalar JSON @specifiedBy(url: \\"https://json-spec.dev\\")
|
|
152
|
-
|
|
153
|
-
type KeyValue {
|
|
154
|
-
key: String!
|
|
155
|
-
value: String!
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
type Library
|
|
159
|
-
@join__owner(graph: BOOKS)
|
|
160
|
-
@join__type(graph: BOOKS, key: \\"id\\")
|
|
161
|
-
@join__type(graph: ACCOUNTS, key: \\"id\\")
|
|
162
|
-
{
|
|
163
|
-
id: ID! @join__field(graph: BOOKS)
|
|
164
|
-
name: String @join__field(graph: BOOKS)
|
|
165
|
-
userAccount(id: ID! = 1): User @join__field(graph: ACCOUNTS, requires: \\"name\\")
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
union MetadataOrError = Error | KeyValue
|
|
169
|
-
|
|
170
|
-
type Mutation {
|
|
171
|
-
deleteReview(id: ID!): Boolean @join__field(graph: REVIEWS)
|
|
172
|
-
login(password: String!, userId: String @deprecated(reason: \\"Use username instead\\"), username: String!): User @join__field(graph: ACCOUNTS)
|
|
173
|
-
reviewProduct(input: ReviewProduct!): Product @join__field(graph: REVIEWS)
|
|
174
|
-
updateReview(review: UpdateReviewInput!): Review @join__field(graph: REVIEWS)
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
type Name {
|
|
178
|
-
first: String
|
|
179
|
-
last: String
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
interface NamedObject {
|
|
183
|
-
name: String!
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
type PasswordAccount
|
|
187
|
-
@join__owner(graph: ACCOUNTS)
|
|
188
|
-
@join__type(graph: ACCOUNTS, key: \\"email\\")
|
|
189
|
-
{
|
|
190
|
-
email: String! @join__field(graph: ACCOUNTS)
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
interface Product
|
|
194
|
-
@tag(name: \\"from-reviews\\")
|
|
195
|
-
{
|
|
196
|
-
details: ProductDetails
|
|
197
|
-
inStock: Boolean
|
|
198
|
-
name: String
|
|
199
|
-
price: String
|
|
200
|
-
reviews: [Review]
|
|
201
|
-
sku: String!
|
|
202
|
-
upc: String!
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
interface ProductDetails {
|
|
206
|
-
country: String
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
type ProductDetailsBook implements ProductDetails {
|
|
210
|
-
country: String
|
|
211
|
-
pages: Int
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
type ProductDetailsFurniture implements ProductDetails {
|
|
215
|
-
color: String
|
|
216
|
-
country: String
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
type Query {
|
|
220
|
-
body: Body! @join__field(graph: DOCUMENTS)
|
|
221
|
-
book(isbn: String!): Book @join__field(graph: BOOKS)
|
|
222
|
-
books: [Book] @join__field(graph: BOOKS)
|
|
223
|
-
library(id: ID!): Library @join__field(graph: BOOKS)
|
|
224
|
-
me: User @join__field(graph: ACCOUNTS)
|
|
225
|
-
product(upc: String!): Product @join__field(graph: PRODUCT)
|
|
226
|
-
topCars(first: Int = 5): [Car] @join__field(graph: PRODUCT)
|
|
227
|
-
topProducts(first: Int = 5): [Product] @join__field(graph: PRODUCT)
|
|
228
|
-
topReviews(first: Int = 5): [Review] @join__field(graph: REVIEWS)
|
|
229
|
-
user(id: ID!): User @join__field(graph: ACCOUNTS)
|
|
230
|
-
vehicle(id: String!): Vehicle @join__field(graph: PRODUCT)
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
type Review
|
|
234
|
-
@join__owner(graph: REVIEWS)
|
|
235
|
-
@join__type(graph: REVIEWS, key: \\"id\\")
|
|
236
|
-
{
|
|
237
|
-
author: User @join__field(graph: REVIEWS, provides: \\"username\\")
|
|
238
|
-
body(format: Boolean = false): String @join__field(graph: REVIEWS)
|
|
239
|
-
id: ID! @join__field(graph: REVIEWS)
|
|
240
|
-
metadata: [MetadataOrError] @join__field(graph: REVIEWS)
|
|
241
|
-
product: Product @join__field(graph: REVIEWS)
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
input ReviewProduct {
|
|
245
|
-
body: String!
|
|
246
|
-
stars: Int @deprecated(reason: \\"Stars are no longer in use\\")
|
|
247
|
-
upc: String!
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
type SMSAccount
|
|
251
|
-
@join__owner(graph: ACCOUNTS)
|
|
252
|
-
@join__type(graph: ACCOUNTS, key: \\"number\\")
|
|
253
|
-
{
|
|
254
|
-
number: String @join__field(graph: ACCOUNTS)
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
type Text implements NamedObject {
|
|
258
|
-
attributes: TextAttributes!
|
|
259
|
-
name: String!
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
type TextAttributes {
|
|
263
|
-
bold: Boolean
|
|
264
|
-
text: String
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
union Thing = Car | Ikea
|
|
268
|
-
|
|
269
|
-
input UpdateReviewInput {
|
|
270
|
-
body: String
|
|
271
|
-
id: ID!
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
type User
|
|
275
|
-
@join__owner(graph: ACCOUNTS)
|
|
276
|
-
@join__type(graph: ACCOUNTS, key: \\"id\\")
|
|
277
|
-
@join__type(graph: ACCOUNTS, key: \\"username name{first last}\\")
|
|
278
|
-
@join__type(graph: INVENTORY, key: \\"id\\")
|
|
279
|
-
@join__type(graph: PRODUCT, key: \\"id\\")
|
|
280
|
-
@join__type(graph: REVIEWS, key: \\"id\\")
|
|
281
|
-
@tag(name: \\"from-accounts\\")
|
|
282
|
-
@tag(name: \\"from-reviews\\")
|
|
283
|
-
{
|
|
284
|
-
account: AccountType @join__field(graph: ACCOUNTS)
|
|
285
|
-
birthDate(locale: String): String @join__field(graph: ACCOUNTS) @tag(name: \\"admin\\") @tag(name: \\"dev\\")
|
|
286
|
-
goodAddress: Boolean @join__field(graph: REVIEWS, requires: \\"metadata{address}\\")
|
|
287
|
-
goodDescription: Boolean @join__field(graph: INVENTORY, requires: \\"metadata{description}\\")
|
|
288
|
-
id: ID! @join__field(graph: ACCOUNTS) @tag(name: \\"accounts\\") @tag(name: \\"on-external\\")
|
|
289
|
-
metadata: [UserMetadata] @join__field(graph: ACCOUNTS)
|
|
290
|
-
name: Name @join__field(graph: ACCOUNTS)
|
|
291
|
-
numberOfReviews: Int! @join__field(graph: REVIEWS)
|
|
292
|
-
reviews: [Review] @join__field(graph: REVIEWS)
|
|
293
|
-
ssn: String @join__field(graph: ACCOUNTS)
|
|
294
|
-
thing: Thing @join__field(graph: PRODUCT)
|
|
295
|
-
username: String @join__field(graph: ACCOUNTS)
|
|
296
|
-
vehicle: Vehicle @join__field(graph: PRODUCT)
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
type UserMetadata {
|
|
300
|
-
address: String
|
|
301
|
-
description: String
|
|
302
|
-
name: String
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
type Van implements Vehicle
|
|
306
|
-
@join__owner(graph: PRODUCT)
|
|
307
|
-
@join__type(graph: PRODUCT, key: \\"id\\")
|
|
308
|
-
@join__type(graph: REVIEWS, key: \\"id\\")
|
|
309
|
-
{
|
|
310
|
-
description: String @join__field(graph: PRODUCT)
|
|
311
|
-
id: String! @join__field(graph: PRODUCT)
|
|
312
|
-
price: String @join__field(graph: PRODUCT)
|
|
313
|
-
retailPrice: String @join__field(graph: REVIEWS, requires: \\"price\\")
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
interface Vehicle {
|
|
317
|
-
description: String
|
|
318
|
-
id: String!
|
|
319
|
-
price: String
|
|
320
|
-
retailPrice: String
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
enum core__Purpose {
|
|
324
|
-
\\"\\"\\"
|
|
325
|
-
\`EXECUTION\` features provide metadata necessary to for operation execution.
|
|
326
|
-
\\"\\"\\"
|
|
327
|
-
EXECUTION
|
|
328
|
-
|
|
329
|
-
\\"\\"\\"
|
|
330
|
-
\`SECURITY\` features provide metadata necessary to securely resolve fields.
|
|
331
|
-
\\"\\"\\"
|
|
332
|
-
SECURITY
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
scalar join__FieldSet
|
|
336
|
-
|
|
337
|
-
enum join__Graph {
|
|
338
|
-
ACCOUNTS @join__graph(name: \\"accounts\\" url: \\"https://accounts.api.com\\")
|
|
339
|
-
BOOKS @join__graph(name: \\"books\\" url: \\"https://books.api.com\\")
|
|
340
|
-
DOCUMENTS @join__graph(name: \\"documents\\" url: \\"https://documents.api.com\\")
|
|
341
|
-
INVENTORY @join__graph(name: \\"inventory\\" url: \\"https://inventory.api.com\\")
|
|
342
|
-
PRODUCT @join__graph(name: \\"product\\" url: \\"https://product.api.com\\")
|
|
343
|
-
REVIEWS @join__graph(name: \\"reviews\\" url: \\"https://reviews.api.com\\")
|
|
344
|
-
}
|
|
345
|
-
",
|
|
346
|
-
}
|
|
347
|
-
`);
|
|
57
|
+
const fetcher = getDefaultFetcher();
|
|
58
|
+
const result = await loadSupergraphSdlFromUplinks({
|
|
59
|
+
graphRef,
|
|
60
|
+
apiKey,
|
|
61
|
+
endpoints: [mockCloudConfigUrl1, mockCloudConfigUrl2],
|
|
62
|
+
errorReportingEndpoint: undefined,
|
|
63
|
+
fetcher,
|
|
64
|
+
compositionId: "originalId-1234",
|
|
65
|
+
maxRetries: 1
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
expect(result).toMatchObject({
|
|
69
|
+
id: 'originalId-1234',
|
|
70
|
+
supergraphSdl: getTestingSupergraphSdl(),
|
|
71
|
+
});
|
|
348
72
|
});
|
|
349
73
|
|
|
74
|
+
it('Throws error if all Uplink URLs fail', async () => {
|
|
75
|
+
mockSupergraphSdlRequest("originalId-1234", mockCloudConfigUrl1).reply(500);
|
|
76
|
+
mockSupergraphSdlRequestIfAfter("originalId-1234", mockCloudConfigUrl2).reply(500);
|
|
77
|
+
|
|
78
|
+
const fetcher = getDefaultFetcher();
|
|
79
|
+
await expect(
|
|
80
|
+
loadSupergraphSdlFromUplinks({
|
|
81
|
+
graphRef,
|
|
82
|
+
apiKey,
|
|
83
|
+
endpoints: [mockCloudConfigUrl1, mockCloudConfigUrl2],
|
|
84
|
+
errorReportingEndpoint: undefined,
|
|
85
|
+
fetcher,
|
|
86
|
+
compositionId: "originalId-1234",
|
|
87
|
+
maxRetries: 1
|
|
88
|
+
}),
|
|
89
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
90
|
+
`"An error occurred while fetching your schema from Apollo: 500 Internal Server Error"`,
|
|
91
|
+
);
|
|
92
|
+
})
|
|
93
|
+
|
|
350
94
|
describe('errors', () => {
|
|
351
95
|
it('throws on a malformed response', async () => {
|
|
352
96
|
mockSupergraphSdlRequest().reply(200, 'Invalid JSON');
|
|
@@ -356,11 +100,13 @@ describe('loadSupergraphSdlFromStorage', () => {
|
|
|
356
100
|
loadSupergraphSdlFromStorage({
|
|
357
101
|
graphRef,
|
|
358
102
|
apiKey,
|
|
359
|
-
endpoint:
|
|
103
|
+
endpoint: mockCloudConfigUrl1,
|
|
104
|
+
errorReportingEndpoint: mockOutOfBandReporterUrl,
|
|
360
105
|
fetcher,
|
|
106
|
+
compositionId: null,
|
|
361
107
|
}),
|
|
362
108
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
363
|
-
`"An error occurred while fetching your schema from Apollo: 200 invalid json response body at https://
|
|
109
|
+
`"An error occurred while fetching your schema from Apollo: 200 invalid json response body at https://example1.cloud-config-url.com/cloudconfig/ reason: Unexpected token I in JSON at position 0"`,
|
|
364
110
|
);
|
|
365
111
|
});
|
|
366
112
|
|
|
@@ -378,22 +124,27 @@ describe('loadSupergraphSdlFromStorage', () => {
|
|
|
378
124
|
loadSupergraphSdlFromStorage({
|
|
379
125
|
graphRef,
|
|
380
126
|
apiKey,
|
|
381
|
-
endpoint:
|
|
127
|
+
endpoint: mockCloudConfigUrl1,
|
|
128
|
+
errorReportingEndpoint: mockOutOfBandReporterUrl,
|
|
382
129
|
fetcher,
|
|
130
|
+
compositionId: null,
|
|
383
131
|
}),
|
|
384
132
|
).rejects.toThrowError(message);
|
|
385
133
|
});
|
|
386
134
|
|
|
387
135
|
it("throws on non-OK status codes when `errors` isn't present in a JSON response", async () => {
|
|
388
136
|
mockSupergraphSdlRequest().reply(500);
|
|
137
|
+
mockOutOfBandReportRequestSuccess();
|
|
389
138
|
|
|
390
139
|
const fetcher = getDefaultFetcher();
|
|
391
140
|
await expect(
|
|
392
141
|
loadSupergraphSdlFromStorage({
|
|
393
142
|
graphRef,
|
|
394
143
|
apiKey,
|
|
395
|
-
endpoint:
|
|
144
|
+
endpoint: mockCloudConfigUrl1,
|
|
145
|
+
errorReportingEndpoint: mockOutOfBandReporterUrl,
|
|
396
146
|
fetcher,
|
|
147
|
+
compositionId: null,
|
|
397
148
|
}),
|
|
398
149
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
399
150
|
`"An error occurred while fetching your schema from Apollo: 500 Internal Server Error"`,
|
|
@@ -410,40 +161,36 @@ describe('loadSupergraphSdlFromStorage', () => {
|
|
|
410
161
|
loadSupergraphSdlFromStorage({
|
|
411
162
|
graphRef,
|
|
412
163
|
apiKey,
|
|
413
|
-
endpoint:
|
|
164
|
+
endpoint: mockCloudConfigUrl1,
|
|
165
|
+
errorReportingEndpoint: mockOutOfBandReporterUrl,
|
|
414
166
|
fetcher,
|
|
167
|
+
compositionId: null,
|
|
415
168
|
}),
|
|
416
169
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
417
|
-
`"An error occurred while fetching your schema from Apollo: 400 invalid json response body at https://
|
|
170
|
+
`"An error occurred while fetching your schema from Apollo: 400 invalid json response body at https://example1.cloud-config-url.com/cloudconfig/ reason: Unexpected end of JSON input"`,
|
|
418
171
|
);
|
|
419
172
|
});
|
|
420
173
|
|
|
421
|
-
it('throws on 400 status response and
|
|
422
|
-
cleanUp = mockedEnv({
|
|
423
|
-
APOLLO_OUT_OF_BAND_REPORTER_ENDPOINT: mockOutOfBandReporterUrl,
|
|
424
|
-
});
|
|
174
|
+
it('throws on 400 status response and does not submit an out of band error', async () => {
|
|
425
175
|
|
|
426
176
|
mockSupergraphSdlRequest().reply(400);
|
|
427
|
-
mockOutOfBandReportRequestSuccess();
|
|
428
177
|
|
|
429
178
|
const fetcher = getDefaultFetcher();
|
|
430
179
|
await expect(
|
|
431
180
|
loadSupergraphSdlFromStorage({
|
|
432
181
|
graphRef,
|
|
433
182
|
apiKey,
|
|
434
|
-
endpoint:
|
|
183
|
+
endpoint: mockCloudConfigUrl1,
|
|
184
|
+
errorReportingEndpoint: mockOutOfBandReporterUrl,
|
|
435
185
|
fetcher,
|
|
186
|
+
compositionId: null,
|
|
436
187
|
}),
|
|
437
188
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
438
|
-
`"An error occurred while fetching your schema from Apollo: 400 invalid json response body at https://
|
|
189
|
+
`"An error occurred while fetching your schema from Apollo: 400 invalid json response body at https://example1.cloud-config-url.com/cloudconfig/ reason: Unexpected end of JSON input"`,
|
|
439
190
|
);
|
|
440
191
|
});
|
|
441
192
|
|
|
442
193
|
it('throws on 413 status response and successfully submits an out of band error', async () => {
|
|
443
|
-
cleanUp = mockedEnv({
|
|
444
|
-
APOLLO_OUT_OF_BAND_REPORTER_ENDPOINT: mockOutOfBandReporterUrl,
|
|
445
|
-
});
|
|
446
|
-
|
|
447
194
|
mockSupergraphSdlRequest().reply(413);
|
|
448
195
|
mockOutOfBandReportRequestSuccess();
|
|
449
196
|
|
|
@@ -452,8 +199,10 @@ describe('loadSupergraphSdlFromStorage', () => {
|
|
|
452
199
|
loadSupergraphSdlFromStorage({
|
|
453
200
|
graphRef,
|
|
454
201
|
apiKey,
|
|
455
|
-
endpoint:
|
|
202
|
+
endpoint: mockCloudConfigUrl1,
|
|
203
|
+
errorReportingEndpoint: mockOutOfBandReporterUrl,
|
|
456
204
|
fetcher,
|
|
205
|
+
compositionId: null,
|
|
457
206
|
}),
|
|
458
207
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
459
208
|
`"An error occurred while fetching your schema from Apollo: 413 Payload Too Large"`,
|
|
@@ -461,10 +210,6 @@ describe('loadSupergraphSdlFromStorage', () => {
|
|
|
461
210
|
});
|
|
462
211
|
|
|
463
212
|
it('throws on 422 status response and successfully submits an out of band error', async () => {
|
|
464
|
-
cleanUp = mockedEnv({
|
|
465
|
-
APOLLO_OUT_OF_BAND_REPORTER_ENDPOINT: mockOutOfBandReporterUrl,
|
|
466
|
-
});
|
|
467
|
-
|
|
468
213
|
mockSupergraphSdlRequest().reply(422);
|
|
469
214
|
mockOutOfBandReportRequestSuccess();
|
|
470
215
|
|
|
@@ -473,8 +218,10 @@ describe('loadSupergraphSdlFromStorage', () => {
|
|
|
473
218
|
loadSupergraphSdlFromStorage({
|
|
474
219
|
graphRef,
|
|
475
220
|
apiKey,
|
|
476
|
-
endpoint:
|
|
221
|
+
endpoint: mockCloudConfigUrl1,
|
|
222
|
+
errorReportingEndpoint: mockOutOfBandReporterUrl,
|
|
477
223
|
fetcher,
|
|
224
|
+
compositionId: null,
|
|
478
225
|
}),
|
|
479
226
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
480
227
|
`"An error occurred while fetching your schema from Apollo: 422 Unprocessable Entity"`,
|
|
@@ -482,10 +229,6 @@ describe('loadSupergraphSdlFromStorage', () => {
|
|
|
482
229
|
});
|
|
483
230
|
|
|
484
231
|
it('throws on 408 status response and successfully submits an out of band error', async () => {
|
|
485
|
-
cleanUp = mockedEnv({
|
|
486
|
-
APOLLO_OUT_OF_BAND_REPORTER_ENDPOINT: mockOutOfBandReporterUrl,
|
|
487
|
-
});
|
|
488
|
-
|
|
489
232
|
mockSupergraphSdlRequest().reply(408);
|
|
490
233
|
mockOutOfBandReportRequestSuccess();
|
|
491
234
|
|
|
@@ -494,8 +237,10 @@ describe('loadSupergraphSdlFromStorage', () => {
|
|
|
494
237
|
loadSupergraphSdlFromStorage({
|
|
495
238
|
graphRef,
|
|
496
239
|
apiKey,
|
|
497
|
-
endpoint:
|
|
240
|
+
endpoint: mockCloudConfigUrl1,
|
|
241
|
+
errorReportingEndpoint: mockOutOfBandReporterUrl,
|
|
498
242
|
fetcher,
|
|
243
|
+
compositionId: null,
|
|
499
244
|
}),
|
|
500
245
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
501
246
|
`"An error occurred while fetching your schema from Apollo: 408 Request Timeout"`,
|
|
@@ -504,9 +249,6 @@ describe('loadSupergraphSdlFromStorage', () => {
|
|
|
504
249
|
});
|
|
505
250
|
|
|
506
251
|
it('throws on 504 status response and successfully submits an out of band error', async () => {
|
|
507
|
-
cleanUp = mockedEnv({
|
|
508
|
-
APOLLO_OUT_OF_BAND_REPORTER_ENDPOINT: mockOutOfBandReporterUrl,
|
|
509
|
-
});
|
|
510
252
|
|
|
511
253
|
mockSupergraphSdlRequest().reply(504);
|
|
512
254
|
mockOutOfBandReportRequestSuccess();
|
|
@@ -516,8 +258,10 @@ describe('loadSupergraphSdlFromStorage', () => {
|
|
|
516
258
|
loadSupergraphSdlFromStorage({
|
|
517
259
|
graphRef,
|
|
518
260
|
apiKey,
|
|
519
|
-
endpoint:
|
|
261
|
+
endpoint: mockCloudConfigUrl1,
|
|
262
|
+
errorReportingEndpoint: mockOutOfBandReporterUrl,
|
|
520
263
|
fetcher,
|
|
264
|
+
compositionId: null,
|
|
521
265
|
}),
|
|
522
266
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
523
267
|
`"An error occurred while fetching your schema from Apollo: 504 Gateway Timeout"`,
|
|
@@ -525,10 +269,6 @@ describe('loadSupergraphSdlFromStorage', () => {
|
|
|
525
269
|
});
|
|
526
270
|
|
|
527
271
|
it('throws when there is no response and successfully submits an out of band error', async () => {
|
|
528
|
-
cleanUp = mockedEnv({
|
|
529
|
-
APOLLO_OUT_OF_BAND_REPORTER_ENDPOINT: mockOutOfBandReporterUrl,
|
|
530
|
-
});
|
|
531
|
-
|
|
532
272
|
mockSupergraphSdlRequest().replyWithError('no response');
|
|
533
273
|
mockOutOfBandReportRequestSuccess();
|
|
534
274
|
|
|
@@ -537,19 +277,17 @@ describe('loadSupergraphSdlFromStorage', () => {
|
|
|
537
277
|
loadSupergraphSdlFromStorage({
|
|
538
278
|
graphRef,
|
|
539
279
|
apiKey,
|
|
540
|
-
endpoint:
|
|
280
|
+
endpoint: mockCloudConfigUrl1,
|
|
281
|
+
errorReportingEndpoint: mockOutOfBandReporterUrl,
|
|
541
282
|
fetcher,
|
|
283
|
+
compositionId: null,
|
|
542
284
|
}),
|
|
543
285
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
544
|
-
`"An error occurred while fetching your schema from Apollo: request to https://
|
|
286
|
+
`"An error occurred while fetching your schema from Apollo: request to https://example1.cloud-config-url.com/cloudconfig/ failed, reason: no response"`,
|
|
545
287
|
);
|
|
546
288
|
});
|
|
547
289
|
|
|
548
290
|
it('throws on 502 status response and successfully submits an out of band error', async () => {
|
|
549
|
-
cleanUp = mockedEnv({
|
|
550
|
-
APOLLO_OUT_OF_BAND_REPORTER_ENDPOINT: mockOutOfBandReporterUrl,
|
|
551
|
-
});
|
|
552
|
-
|
|
553
291
|
mockSupergraphSdlRequest().reply(502);
|
|
554
292
|
mockOutOfBandReportRequestSuccess();
|
|
555
293
|
|
|
@@ -558,8 +296,10 @@ describe('loadSupergraphSdlFromStorage', () => {
|
|
|
558
296
|
loadSupergraphSdlFromStorage({
|
|
559
297
|
graphRef,
|
|
560
298
|
apiKey,
|
|
561
|
-
endpoint:
|
|
299
|
+
endpoint: mockCloudConfigUrl1,
|
|
300
|
+
errorReportingEndpoint: mockOutOfBandReporterUrl,
|
|
562
301
|
fetcher,
|
|
302
|
+
compositionId: null,
|
|
563
303
|
}),
|
|
564
304
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
565
305
|
`"An error occurred while fetching your schema from Apollo: 502 Bad Gateway"`,
|
|
@@ -567,10 +307,6 @@ describe('loadSupergraphSdlFromStorage', () => {
|
|
|
567
307
|
});
|
|
568
308
|
|
|
569
309
|
it('throws on 503 status response and successfully submits an out of band error', async () => {
|
|
570
|
-
cleanUp = mockedEnv({
|
|
571
|
-
APOLLO_OUT_OF_BAND_REPORTER_ENDPOINT: mockOutOfBandReporterUrl,
|
|
572
|
-
});
|
|
573
|
-
|
|
574
310
|
mockSupergraphSdlRequest().reply(503);
|
|
575
311
|
mockOutOfBandReportRequestSuccess();
|
|
576
312
|
|
|
@@ -579,11 +315,29 @@ describe('loadSupergraphSdlFromStorage', () => {
|
|
|
579
315
|
loadSupergraphSdlFromStorage({
|
|
580
316
|
graphRef,
|
|
581
317
|
apiKey,
|
|
582
|
-
endpoint:
|
|
318
|
+
endpoint: mockCloudConfigUrl1,
|
|
319
|
+
errorReportingEndpoint: mockOutOfBandReporterUrl,
|
|
583
320
|
fetcher,
|
|
321
|
+
compositionId: null,
|
|
584
322
|
}),
|
|
585
323
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
586
324
|
`"An error occurred while fetching your schema from Apollo: 503 Service Unavailable"`,
|
|
587
325
|
);
|
|
588
326
|
});
|
|
327
|
+
|
|
328
|
+
it('successfully responds to SDL unchanged by returning null', async () => {
|
|
329
|
+
mockSupergraphSdlRequestIfAfterUnchanged("id-1234");
|
|
330
|
+
|
|
331
|
+
const fetcher = getDefaultFetcher();
|
|
332
|
+
const result = await loadSupergraphSdlFromStorage({
|
|
333
|
+
graphRef,
|
|
334
|
+
apiKey,
|
|
335
|
+
endpoint: mockCloudConfigUrl1,
|
|
336
|
+
errorReportingEndpoint: mockOutOfBandReporterUrl,
|
|
337
|
+
fetcher,
|
|
338
|
+
compositionId: "id-1234",
|
|
339
|
+
});
|
|
340
|
+
expect(result).toBeNull();
|
|
341
|
+
});
|
|
589
342
|
});
|
|
343
|
+
|