@adobe/aio-cli-plugin-api-mesh 2.0.0 → 2.2.0-beta.1
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/oclif.manifest.json +1 -1
- package/package.json +5 -3
- package/src/commands/__fixtures__/env_invalid +8 -0
- package/src/commands/__fixtures__/env_valid +3 -0
- package/src/commands/__fixtures__/files/requestParams.json +3 -0
- package/src/commands/__fixtures__/openapi-schema.json +4 -0
- package/src/commands/__fixtures__/requestParams.json +3 -0
- package/src/commands/__fixtures__/sample_fully_qualified_mesh.json +29 -0
- package/src/commands/__fixtures__/sample_invalid_mesh.txt +17 -0
- package/src/commands/__fixtures__/sample_mesh_files.json +23 -0
- package/src/commands/__fixtures__/sample_mesh_invalid_file_content.json +14 -0
- package/src/commands/__fixtures__/sample_mesh_invalid_file_name.json +27 -0
- package/src/commands/__fixtures__/sample_mesh_invalid_paths.json +23 -0
- package/src/commands/__fixtures__/sample_mesh_invalid_type.json +27 -0
- package/src/commands/__fixtures__/sample_mesh_mismatching_path.json +29 -0
- package/src/commands/__fixtures__/sample_mesh_outside_workspace_dir.json +23 -0
- package/src/commands/__fixtures__/sample_mesh_path_from_home.json +14 -0
- package/src/commands/__fixtures__/sample_mesh_subdirectory.json +23 -0
- package/src/commands/__fixtures__/sample_mesh_with_files_array.json +29 -0
- package/src/commands/__fixtures__/sample_mesh_with_placeholder +17 -0
- package/src/commands/api-mesh/__tests__/create.test.js +1334 -140
- package/src/commands/api-mesh/__tests__/delete.test.js +3 -3
- package/src/commands/api-mesh/__tests__/init.test.js +390 -0
- package/src/commands/api-mesh/__tests__/update.test.js +524 -109
- package/src/commands/api-mesh/create.js +47 -14
- package/src/commands/api-mesh/init.js +168 -0
- package/src/commands/api-mesh/update.js +49 -17
- package/src/helpers.js +254 -3
- package/src/lib/devConsole.js +1 -2
- package/src/templates/gitignore +1 -0
- package/src/templates/package.json +38 -0
- package/src/utils.js +337 -33
|
@@ -17,6 +17,7 @@ jest.mock('../../../helpers', () => ({
|
|
|
17
17
|
initSdk: jest.fn().mockResolvedValue({}),
|
|
18
18
|
initRequestId: jest.fn().mockResolvedValue({}),
|
|
19
19
|
promptConfirm: jest.fn().mockResolvedValue(true),
|
|
20
|
+
importFiles: jest.fn().mockResolvedValue(),
|
|
20
21
|
}));
|
|
21
22
|
jest.mock('@adobe/aio-cli-lib-console', () => ({
|
|
22
23
|
init: jest.fn().mockResolvedValue(mockConsoleCLIInstance),
|
|
@@ -34,7 +35,7 @@ const selectedWorkspace = { id: '123456789', title: 'Workspace01' };
|
|
|
34
35
|
const { readFile } = require('fs/promises');
|
|
35
36
|
|
|
36
37
|
const UpdateCommand = require('../update');
|
|
37
|
-
const { initSdk, initRequestId, promptConfirm } = require('../../../helpers');
|
|
38
|
+
const { initSdk, initRequestId, promptConfirm, importFiles } = require('../../../helpers');
|
|
38
39
|
const { getMeshId, updateMesh } = require('../../../lib/devConsole');
|
|
39
40
|
|
|
40
41
|
let logSpy = null;
|
|
@@ -58,7 +59,7 @@ describe('update command tests', () => {
|
|
|
58
59
|
logSpy = jest.spyOn(UpdateCommand.prototype, 'log');
|
|
59
60
|
errorLogSpy = jest.spyOn(UpdateCommand.prototype, 'error');
|
|
60
61
|
|
|
61
|
-
readFile.mockResolvedValue(
|
|
62
|
+
readFile.mockResolvedValue('{}');
|
|
62
63
|
|
|
63
64
|
getMeshId.mockResolvedValue('mesh_id');
|
|
64
65
|
updateMesh.mockResolvedValue({ status: 'success' });
|
|
@@ -73,11 +74,209 @@ describe('update command tests', () => {
|
|
|
73
74
|
});
|
|
74
75
|
});
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
test('should pass with valid args', async () => {
|
|
78
|
+
let sampleMesh = {
|
|
79
|
+
meshConfig: {
|
|
80
|
+
sources: [
|
|
81
|
+
{
|
|
82
|
+
name: '<api_name>',
|
|
83
|
+
handler: {
|
|
84
|
+
graphql: {
|
|
85
|
+
endpoint: '<gql_endpoint>',
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
readFile.mockResolvedValue(JSON.stringify(sampleMesh));
|
|
93
|
+
|
|
94
|
+
parseSpy.mockResolvedValueOnce({
|
|
95
|
+
args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
|
|
96
|
+
flags: {
|
|
97
|
+
ignoreCache: mockIgnoreCacheFlag,
|
|
98
|
+
autoConfirmAction: mockAutoApproveAction,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const runResult = await UpdateCommand.run();
|
|
103
|
+
|
|
104
|
+
expect(runResult).toMatchInlineSnapshot(`
|
|
105
|
+
{
|
|
106
|
+
"status": "success",
|
|
107
|
+
}
|
|
108
|
+
`);
|
|
109
|
+
expect(initRequestId).toHaveBeenCalled();
|
|
110
|
+
expect(initSdk).toHaveBeenCalledWith({
|
|
111
|
+
ignoreCache: true,
|
|
112
|
+
});
|
|
113
|
+
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
114
|
+
[
|
|
115
|
+
[
|
|
116
|
+
"******************************************************************************************************",
|
|
117
|
+
],
|
|
118
|
+
[
|
|
119
|
+
"Your mesh is being provisioned. Wait a few minutes before checking the status of your mesh %s",
|
|
120
|
+
"mesh_id",
|
|
121
|
+
],
|
|
122
|
+
[
|
|
123
|
+
"To check the status of your mesh, run:",
|
|
124
|
+
],
|
|
125
|
+
[
|
|
126
|
+
"aio api-mesh:status",
|
|
127
|
+
],
|
|
128
|
+
[
|
|
129
|
+
"******************************************************************************************************",
|
|
130
|
+
],
|
|
131
|
+
]
|
|
132
|
+
`);
|
|
133
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`[]`);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test('should pass with valid args and ignoreCache flag', async () => {
|
|
137
|
+
let sampleMesh = {
|
|
138
|
+
meshConfig: {
|
|
139
|
+
sources: [
|
|
140
|
+
{
|
|
141
|
+
name: '<api_name>',
|
|
142
|
+
handler: {
|
|
143
|
+
graphql: {
|
|
144
|
+
endpoint: '<gql_endpoint>',
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
readFile.mockResolvedValue(JSON.stringify(sampleMesh));
|
|
152
|
+
|
|
153
|
+
parseSpy.mockResolvedValueOnce({
|
|
154
|
+
args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
|
|
155
|
+
flags: {
|
|
156
|
+
ignoreCache: Promise.resolve(true),
|
|
157
|
+
autoConfirmAction: mockAutoApproveAction,
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
const runResult = await UpdateCommand.run();
|
|
162
|
+
|
|
163
|
+
expect(runResult).toMatchInlineSnapshot(`
|
|
164
|
+
{
|
|
165
|
+
"status": "success",
|
|
166
|
+
}
|
|
167
|
+
`);
|
|
168
|
+
expect(initRequestId).toHaveBeenCalled();
|
|
169
|
+
expect(initSdk).toHaveBeenCalledWith({
|
|
170
|
+
ignoreCache: true,
|
|
171
|
+
});
|
|
172
|
+
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
173
|
+
[
|
|
174
|
+
[
|
|
175
|
+
"******************************************************************************************************",
|
|
176
|
+
],
|
|
177
|
+
[
|
|
178
|
+
"Your mesh is being provisioned. Wait a few minutes before checking the status of your mesh %s",
|
|
179
|
+
"mesh_id",
|
|
180
|
+
],
|
|
181
|
+
[
|
|
182
|
+
"To check the status of your mesh, run:",
|
|
183
|
+
],
|
|
184
|
+
[
|
|
185
|
+
"aio api-mesh:status",
|
|
186
|
+
],
|
|
187
|
+
[
|
|
188
|
+
"******************************************************************************************************",
|
|
189
|
+
],
|
|
190
|
+
]
|
|
191
|
+
`);
|
|
192
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`[]`);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
test('should pass with valid args if autoConfirmAction flag is set', async () => {
|
|
196
|
+
let sampleMesh = {
|
|
197
|
+
meshConfig: {
|
|
198
|
+
sources: [
|
|
199
|
+
{
|
|
200
|
+
name: '<api_name>',
|
|
201
|
+
handler: {
|
|
202
|
+
graphql: {
|
|
203
|
+
endpoint: '<gql_endpoint>',
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
],
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
readFile.mockResolvedValue(JSON.stringify(sampleMesh));
|
|
211
|
+
|
|
212
|
+
parseSpy.mockResolvedValueOnce({
|
|
213
|
+
args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
|
|
214
|
+
flags: {
|
|
215
|
+
ignoreCache: mockIgnoreCacheFlag,
|
|
216
|
+
autoConfirmAction: Promise.resolve(true),
|
|
217
|
+
},
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
const runResult = await UpdateCommand.run();
|
|
221
|
+
|
|
222
|
+
expect(runResult).toMatchInlineSnapshot(`
|
|
223
|
+
{
|
|
224
|
+
"status": "success",
|
|
225
|
+
}
|
|
226
|
+
`);
|
|
227
|
+
expect(initRequestId).toHaveBeenCalled();
|
|
228
|
+
expect(promptConfirm).not.toHaveBeenCalled();
|
|
229
|
+
expect(initSdk).toHaveBeenCalledWith({
|
|
230
|
+
ignoreCache: true,
|
|
231
|
+
});
|
|
232
|
+
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
233
|
+
[
|
|
234
|
+
[
|
|
235
|
+
"******************************************************************************************************",
|
|
236
|
+
],
|
|
237
|
+
[
|
|
238
|
+
"Your mesh is being provisioned. Wait a few minutes before checking the status of your mesh %s",
|
|
239
|
+
"mesh_id",
|
|
240
|
+
],
|
|
241
|
+
[
|
|
242
|
+
"To check the status of your mesh, run:",
|
|
243
|
+
],
|
|
244
|
+
[
|
|
245
|
+
"aio api-mesh:status",
|
|
246
|
+
],
|
|
247
|
+
[
|
|
248
|
+
"******************************************************************************************************",
|
|
249
|
+
],
|
|
250
|
+
]
|
|
251
|
+
`);
|
|
252
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`[]`);
|
|
78
253
|
});
|
|
79
254
|
|
|
80
255
|
test('should fail if mesh id is missing', async () => {
|
|
256
|
+
let sampleMesh = {
|
|
257
|
+
meshConfig: {
|
|
258
|
+
sources: [
|
|
259
|
+
{
|
|
260
|
+
name: '<api_name>',
|
|
261
|
+
handler: {
|
|
262
|
+
graphql: {
|
|
263
|
+
endpoint: '<gql_endpoint>',
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
],
|
|
268
|
+
},
|
|
269
|
+
};
|
|
270
|
+
readFile.mockResolvedValue(JSON.stringify(sampleMesh));
|
|
271
|
+
|
|
272
|
+
parseSpy.mockResolvedValueOnce({
|
|
273
|
+
args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
|
|
274
|
+
flags: {
|
|
275
|
+
ignoreCache: mockIgnoreCacheFlag,
|
|
276
|
+
autoConfirmAction: mockAutoApproveAction,
|
|
277
|
+
},
|
|
278
|
+
});
|
|
279
|
+
|
|
81
280
|
getMeshId.mockResolvedValue(null);
|
|
82
281
|
const runResult = UpdateCommand.run();
|
|
83
282
|
|
|
@@ -95,6 +294,30 @@ describe('update command tests', () => {
|
|
|
95
294
|
});
|
|
96
295
|
|
|
97
296
|
test('should fail if getMeshId api failed', async () => {
|
|
297
|
+
let sampleMesh = {
|
|
298
|
+
meshConfig: {
|
|
299
|
+
sources: [
|
|
300
|
+
{
|
|
301
|
+
name: '<api_name>',
|
|
302
|
+
handler: {
|
|
303
|
+
graphql: {
|
|
304
|
+
endpoint: '<gql_endpoint>',
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
],
|
|
309
|
+
},
|
|
310
|
+
};
|
|
311
|
+
readFile.mockResolvedValue(JSON.stringify(sampleMesh));
|
|
312
|
+
|
|
313
|
+
parseSpy.mockResolvedValueOnce({
|
|
314
|
+
args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
|
|
315
|
+
flags: {
|
|
316
|
+
ignoreCache: mockIgnoreCacheFlag,
|
|
317
|
+
autoConfirmAction: mockAutoApproveAction,
|
|
318
|
+
},
|
|
319
|
+
});
|
|
320
|
+
|
|
98
321
|
getMeshId.mockRejectedValue(new Error('getMeshId api failed'));
|
|
99
322
|
const runResult = UpdateCommand.run();
|
|
100
323
|
|
|
@@ -111,6 +334,60 @@ describe('update command tests', () => {
|
|
|
111
334
|
`);
|
|
112
335
|
});
|
|
113
336
|
|
|
337
|
+
test('should fail if updateMesh method failed', async () => {
|
|
338
|
+
let sampleMesh = {
|
|
339
|
+
meshConfig: {
|
|
340
|
+
sources: [
|
|
341
|
+
{
|
|
342
|
+
name: '<api_name>',
|
|
343
|
+
handler: {
|
|
344
|
+
graphql: {
|
|
345
|
+
endpoint: '<gql_endpoint>',
|
|
346
|
+
},
|
|
347
|
+
},
|
|
348
|
+
},
|
|
349
|
+
],
|
|
350
|
+
},
|
|
351
|
+
};
|
|
352
|
+
readFile.mockResolvedValue(JSON.stringify(sampleMesh));
|
|
353
|
+
|
|
354
|
+
parseSpy.mockResolvedValueOnce({
|
|
355
|
+
args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
|
|
356
|
+
flags: {
|
|
357
|
+
ignoreCache: mockIgnoreCacheFlag,
|
|
358
|
+
autoConfirmAction: mockAutoApproveAction,
|
|
359
|
+
},
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
updateMesh.mockRejectedValueOnce(new Error('dummy_error'));
|
|
363
|
+
|
|
364
|
+
const runResult = UpdateCommand.run();
|
|
365
|
+
|
|
366
|
+
// await expect(runResult).rejects.toEqual(
|
|
367
|
+
// new Error(
|
|
368
|
+
// 'Unable to update the mesh. Please check the mesh configuration file and try again. If the error persists please contact support. RequestId: dummy_request_id',
|
|
369
|
+
// ),
|
|
370
|
+
// );
|
|
371
|
+
|
|
372
|
+
await expect(runResult).rejects.toMatchInlineSnapshot(
|
|
373
|
+
`[Error: Unable to update the mesh. Please check the mesh configuration file and try again. If the error persists please contact support. RequestId: dummy_request_id]`,
|
|
374
|
+
);
|
|
375
|
+
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
376
|
+
[
|
|
377
|
+
[
|
|
378
|
+
"dummy_error",
|
|
379
|
+
],
|
|
380
|
+
]
|
|
381
|
+
`);
|
|
382
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
|
|
383
|
+
[
|
|
384
|
+
[
|
|
385
|
+
"Unable to update the mesh. Please check the mesh configuration file and try again. If the error persists please contact support. RequestId: dummy_request_id",
|
|
386
|
+
],
|
|
387
|
+
]
|
|
388
|
+
`);
|
|
389
|
+
});
|
|
390
|
+
|
|
114
391
|
test('should fail if update file path is missing', async () => {
|
|
115
392
|
parseSpy.mockResolvedValueOnce({
|
|
116
393
|
args: { file: null },
|
|
@@ -160,6 +437,30 @@ describe('update command tests', () => {
|
|
|
160
437
|
});
|
|
161
438
|
|
|
162
439
|
test('should not update if user prompt returns false', async () => {
|
|
440
|
+
let sampleMesh = {
|
|
441
|
+
meshConfig: {
|
|
442
|
+
sources: [
|
|
443
|
+
{
|
|
444
|
+
name: '<api_name>',
|
|
445
|
+
handler: {
|
|
446
|
+
graphql: {
|
|
447
|
+
endpoint: '<gql_endpoint>',
|
|
448
|
+
},
|
|
449
|
+
},
|
|
450
|
+
},
|
|
451
|
+
],
|
|
452
|
+
},
|
|
453
|
+
};
|
|
454
|
+
readFile.mockResolvedValue(JSON.stringify(sampleMesh));
|
|
455
|
+
|
|
456
|
+
parseSpy.mockResolvedValueOnce({
|
|
457
|
+
args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
|
|
458
|
+
flags: {
|
|
459
|
+
ignoreCache: mockIgnoreCacheFlag,
|
|
460
|
+
autoConfirmAction: mockAutoApproveAction,
|
|
461
|
+
},
|
|
462
|
+
});
|
|
463
|
+
|
|
163
464
|
promptConfirm.mockResolvedValueOnce(false);
|
|
164
465
|
|
|
165
466
|
const runResult = await UpdateCommand.run();
|
|
@@ -175,151 +476,265 @@ describe('update command tests', () => {
|
|
|
175
476
|
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`[]`);
|
|
176
477
|
});
|
|
177
478
|
|
|
178
|
-
test('should
|
|
179
|
-
|
|
479
|
+
test('should pass if there are local files in meshConfig i.e., the file is appended in files array', async () => {
|
|
480
|
+
let sampleMesh = {
|
|
481
|
+
meshConfig: {
|
|
482
|
+
sources: [
|
|
483
|
+
{
|
|
484
|
+
name: '<json_source_name>',
|
|
485
|
+
handler: {
|
|
486
|
+
JsonSchema: {
|
|
487
|
+
baseUrl: '<json_source__baseurl>',
|
|
488
|
+
operations: [
|
|
489
|
+
{
|
|
490
|
+
type: 'Query',
|
|
491
|
+
field: '<query>',
|
|
492
|
+
path: '<query_path>',
|
|
493
|
+
method: 'POST',
|
|
494
|
+
requestSchema: './requestParams.json',
|
|
495
|
+
},
|
|
496
|
+
],
|
|
497
|
+
},
|
|
498
|
+
},
|
|
499
|
+
},
|
|
500
|
+
],
|
|
501
|
+
},
|
|
502
|
+
};
|
|
503
|
+
readFile.mockResolvedValue(JSON.stringify(sampleMesh));
|
|
504
|
+
|
|
505
|
+
let meshConfig = {
|
|
506
|
+
sources: [
|
|
507
|
+
{
|
|
508
|
+
name: '<json_source_name>',
|
|
509
|
+
handler: {
|
|
510
|
+
JsonSchema: {
|
|
511
|
+
baseUrl: '<json_source__baseurl>',
|
|
512
|
+
operations: [
|
|
513
|
+
{
|
|
514
|
+
type: 'Query',
|
|
515
|
+
field: '<query>',
|
|
516
|
+
path: '<query_path>',
|
|
517
|
+
method: 'POST',
|
|
518
|
+
requestSchema: './requestParams.json',
|
|
519
|
+
},
|
|
520
|
+
],
|
|
521
|
+
},
|
|
522
|
+
},
|
|
523
|
+
},
|
|
524
|
+
],
|
|
525
|
+
files: [
|
|
526
|
+
{
|
|
527
|
+
path: './requestParams.json',
|
|
528
|
+
content: '{"type":"updatedContent"}',
|
|
529
|
+
},
|
|
530
|
+
],
|
|
531
|
+
};
|
|
532
|
+
|
|
533
|
+
updateMesh.mockResolvedValue({
|
|
534
|
+
meshId: 'dummy_mesh_id',
|
|
535
|
+
meshConfig: meshConfig,
|
|
536
|
+
});
|
|
180
537
|
|
|
181
|
-
|
|
538
|
+
parseSpy.mockResolvedValue({
|
|
539
|
+
args: { file: 'src/commands/__fixtures__/sample_mesh_files.json' },
|
|
540
|
+
flags: {
|
|
541
|
+
autoConfirmAction: mockAutoApproveAction,
|
|
542
|
+
},
|
|
543
|
+
});
|
|
182
544
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
);
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
"dummy_error",
|
|
192
|
-
],
|
|
193
|
-
]
|
|
194
|
-
`);
|
|
195
|
-
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
|
|
545
|
+
importFiles.mockResolvedValueOnce({
|
|
546
|
+
meshConfig,
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
const output = await UpdateCommand.run();
|
|
550
|
+
|
|
551
|
+
expect(initRequestId).toHaveBeenCalled();
|
|
552
|
+
expect(updateMesh.mock.calls[0]).toMatchInlineSnapshot(`
|
|
196
553
|
[
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
554
|
+
"1234",
|
|
555
|
+
"5678",
|
|
556
|
+
"123456789",
|
|
557
|
+
"mesh_id",
|
|
558
|
+
{
|
|
559
|
+
"meshConfig": {
|
|
560
|
+
"files": [
|
|
561
|
+
{
|
|
562
|
+
"content": "{"type":"updatedContent"}",
|
|
563
|
+
"path": "./requestParams.json",
|
|
564
|
+
},
|
|
565
|
+
],
|
|
566
|
+
"sources": [
|
|
567
|
+
{
|
|
568
|
+
"handler": {
|
|
569
|
+
"JsonSchema": {
|
|
570
|
+
"baseUrl": "<json_source__baseurl>",
|
|
571
|
+
"operations": [
|
|
572
|
+
{
|
|
573
|
+
"field": "<query>",
|
|
574
|
+
"method": "POST",
|
|
575
|
+
"path": "<query_path>",
|
|
576
|
+
"requestSchema": "./requestParams.json",
|
|
577
|
+
"type": "Query",
|
|
578
|
+
},
|
|
579
|
+
],
|
|
580
|
+
},
|
|
581
|
+
},
|
|
582
|
+
"name": "<json_source_name>",
|
|
583
|
+
},
|
|
584
|
+
],
|
|
585
|
+
},
|
|
586
|
+
},
|
|
200
587
|
]
|
|
201
588
|
`);
|
|
202
|
-
});
|
|
203
589
|
|
|
204
|
-
|
|
205
|
-
const runResult = await UpdateCommand.run();
|
|
206
|
-
|
|
207
|
-
expect(runResult).toMatchInlineSnapshot(`
|
|
590
|
+
expect(output).toMatchInlineSnapshot(`
|
|
208
591
|
{
|
|
209
|
-
"
|
|
592
|
+
"meshConfig": {
|
|
593
|
+
"files": [
|
|
594
|
+
{
|
|
595
|
+
"content": "{"type":"updatedContent"}",
|
|
596
|
+
"path": "./requestParams.json",
|
|
597
|
+
},
|
|
598
|
+
],
|
|
599
|
+
"sources": [
|
|
600
|
+
{
|
|
601
|
+
"handler": {
|
|
602
|
+
"JsonSchema": {
|
|
603
|
+
"baseUrl": "<json_source__baseurl>",
|
|
604
|
+
"operations": [
|
|
605
|
+
{
|
|
606
|
+
"field": "<query>",
|
|
607
|
+
"method": "POST",
|
|
608
|
+
"path": "<query_path>",
|
|
609
|
+
"requestSchema": "./requestParams.json",
|
|
610
|
+
"type": "Query",
|
|
611
|
+
},
|
|
612
|
+
],
|
|
613
|
+
},
|
|
614
|
+
},
|
|
615
|
+
"name": "<json_source_name>",
|
|
616
|
+
},
|
|
617
|
+
],
|
|
618
|
+
},
|
|
619
|
+
"meshId": "dummy_mesh_id",
|
|
210
620
|
}
|
|
211
621
|
`);
|
|
212
|
-
expect(initRequestId).toHaveBeenCalled();
|
|
213
|
-
expect(initSdk).toHaveBeenCalledWith({
|
|
214
|
-
ignoreCache: true,
|
|
215
|
-
});
|
|
216
|
-
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
217
|
-
[
|
|
218
|
-
[
|
|
219
|
-
"******************************************************************************************************",
|
|
220
|
-
],
|
|
221
|
-
[
|
|
222
|
-
"Your mesh is being provisioned. Wait a few minutes before checking the status of your mesh %s",
|
|
223
|
-
"mesh_id",
|
|
224
|
-
],
|
|
225
|
-
[
|
|
226
|
-
"To check the status of your mesh, run:",
|
|
227
|
-
],
|
|
228
|
-
[
|
|
229
|
-
"aio api-mesh:status",
|
|
230
|
-
],
|
|
231
|
-
[
|
|
232
|
-
"******************************************************************************************************",
|
|
233
|
-
],
|
|
234
|
-
]
|
|
235
|
-
`);
|
|
236
|
-
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`[]`);
|
|
237
622
|
});
|
|
238
623
|
|
|
239
|
-
test('should
|
|
240
|
-
|
|
241
|
-
|
|
624
|
+
test('should fail if the input mesh config file is inavlid i.e., file name has more than 25 characters', async () => {
|
|
625
|
+
let sampleMesh = {
|
|
626
|
+
meshConfig: {
|
|
627
|
+
sources: [
|
|
628
|
+
{
|
|
629
|
+
name: '<json_source_name>',
|
|
630
|
+
handler: {
|
|
631
|
+
JsonSchema: {
|
|
632
|
+
baseUrl: '<json_source__baseurl>',
|
|
633
|
+
operations: [
|
|
634
|
+
{
|
|
635
|
+
type: 'Query',
|
|
636
|
+
field: '<query>',
|
|
637
|
+
path: '<query_path>',
|
|
638
|
+
method: 'POST',
|
|
639
|
+
requestSchema: './requestJSONParameters.json',
|
|
640
|
+
},
|
|
641
|
+
],
|
|
642
|
+
},
|
|
643
|
+
},
|
|
644
|
+
},
|
|
645
|
+
],
|
|
646
|
+
},
|
|
647
|
+
};
|
|
648
|
+
readFile.mockResolvedValue(JSON.stringify(sampleMesh));
|
|
649
|
+
|
|
650
|
+
parseSpy.mockResolvedValue({
|
|
651
|
+
args: { file: 'src/commands/__fixtures__/sample_mesh_invalid_file_name.json' },
|
|
242
652
|
flags: {
|
|
243
|
-
ignoreCache:
|
|
653
|
+
ignoreCache: mockIgnoreCacheFlag,
|
|
244
654
|
autoConfirmAction: mockAutoApproveAction,
|
|
245
655
|
},
|
|
246
656
|
});
|
|
247
657
|
|
|
248
|
-
const
|
|
658
|
+
const output = UpdateCommand.run();
|
|
659
|
+
|
|
660
|
+
await expect(output).rejects.toEqual(new Error('Input mesh config is not valid.'));
|
|
249
661
|
|
|
250
|
-
expect(runResult).toMatchInlineSnapshot(`
|
|
251
|
-
{
|
|
252
|
-
"status": "success",
|
|
253
|
-
}
|
|
254
|
-
`);
|
|
255
|
-
expect(initRequestId).toHaveBeenCalled();
|
|
256
|
-
expect(initSdk).toHaveBeenCalledWith({
|
|
257
|
-
ignoreCache: true,
|
|
258
|
-
});
|
|
259
662
|
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
260
663
|
[
|
|
261
664
|
[
|
|
262
|
-
"
|
|
263
|
-
],
|
|
264
|
-
[
|
|
265
|
-
"Your mesh is being provisioned. Wait a few minutes before checking the status of your mesh %s",
|
|
266
|
-
"mesh_id",
|
|
267
|
-
],
|
|
268
|
-
[
|
|
269
|
-
"To check the status of your mesh, run:",
|
|
270
|
-
],
|
|
271
|
-
[
|
|
272
|
-
"aio api-mesh:status",
|
|
665
|
+
"Mesh file names must be less than 25 characters. The following file(s) are invalid: requestJSONParameters.json.",
|
|
273
666
|
],
|
|
667
|
+
]
|
|
668
|
+
`);
|
|
669
|
+
|
|
670
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
|
|
671
|
+
[
|
|
274
672
|
[
|
|
275
|
-
"
|
|
673
|
+
"Input mesh config is not valid.",
|
|
276
674
|
],
|
|
277
675
|
]
|
|
278
676
|
`);
|
|
279
|
-
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`[]`);
|
|
280
677
|
});
|
|
281
678
|
|
|
282
|
-
test('should
|
|
283
|
-
|
|
284
|
-
|
|
679
|
+
test('should fail if the import files function fails', async () => {
|
|
680
|
+
let sampleMesh = {
|
|
681
|
+
meshConfig: {
|
|
682
|
+
sources: [
|
|
683
|
+
{
|
|
684
|
+
name: '<json_source_name>',
|
|
685
|
+
handler: {
|
|
686
|
+
JsonSchema: {
|
|
687
|
+
baseUrl: '<json_source__baseurl>',
|
|
688
|
+
operations: [
|
|
689
|
+
{
|
|
690
|
+
type: 'Query',
|
|
691
|
+
field: '<query>',
|
|
692
|
+
path: '<query_path>',
|
|
693
|
+
method: 'POST',
|
|
694
|
+
requestSchema: './requestParams.json',
|
|
695
|
+
},
|
|
696
|
+
],
|
|
697
|
+
},
|
|
698
|
+
},
|
|
699
|
+
},
|
|
700
|
+
],
|
|
701
|
+
},
|
|
702
|
+
};
|
|
703
|
+
readFile.mockResolvedValue(JSON.stringify(sampleMesh));
|
|
704
|
+
|
|
705
|
+
parseSpy.mockResolvedValue({
|
|
706
|
+
args: { file: 'src/commands/__fixtures__/sample_mesh_files.json' },
|
|
285
707
|
flags: {
|
|
286
708
|
ignoreCache: mockIgnoreCacheFlag,
|
|
287
|
-
autoConfirmAction:
|
|
709
|
+
autoConfirmAction: mockAutoApproveAction,
|
|
288
710
|
},
|
|
289
711
|
});
|
|
290
712
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
expect(runResult).toMatchInlineSnapshot(`
|
|
294
|
-
{
|
|
295
|
-
"status": "success",
|
|
296
|
-
}
|
|
297
|
-
`);
|
|
298
|
-
expect(initRequestId).toHaveBeenCalled();
|
|
299
|
-
expect(promptConfirm).not.toHaveBeenCalled();
|
|
300
|
-
expect(initSdk).toHaveBeenCalledWith({
|
|
301
|
-
ignoreCache: true,
|
|
713
|
+
importFiles.mockImplementation(() => {
|
|
714
|
+
throw new Error('Error reading the file.');
|
|
302
715
|
});
|
|
716
|
+
|
|
717
|
+
const output = UpdateCommand.run();
|
|
718
|
+
await expect(output).rejects.toEqual(
|
|
719
|
+
new Error(
|
|
720
|
+
'Unable to import the files in the mesh config. Please check the file and try again.',
|
|
721
|
+
),
|
|
722
|
+
);
|
|
723
|
+
|
|
303
724
|
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
304
725
|
[
|
|
305
726
|
[
|
|
306
|
-
"
|
|
307
|
-
],
|
|
308
|
-
[
|
|
309
|
-
"Your mesh is being provisioned. Wait a few minutes before checking the status of your mesh %s",
|
|
310
|
-
"mesh_id",
|
|
311
|
-
],
|
|
312
|
-
[
|
|
313
|
-
"To check the status of your mesh, run:",
|
|
314
|
-
],
|
|
315
|
-
[
|
|
316
|
-
"aio api-mesh:status",
|
|
727
|
+
"Error reading the file.",
|
|
317
728
|
],
|
|
729
|
+
]
|
|
730
|
+
`);
|
|
731
|
+
|
|
732
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
|
|
733
|
+
[
|
|
318
734
|
[
|
|
319
|
-
"
|
|
735
|
+
"Unable to import the files in the mesh config. Please check the file and try again.",
|
|
320
736
|
],
|
|
321
737
|
]
|
|
322
738
|
`);
|
|
323
|
-
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`[]`);
|
|
324
739
|
});
|
|
325
740
|
});
|