@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.
Files changed (32) hide show
  1. package/oclif.manifest.json +1 -1
  2. package/package.json +5 -3
  3. package/src/commands/__fixtures__/env_invalid +8 -0
  4. package/src/commands/__fixtures__/env_valid +3 -0
  5. package/src/commands/__fixtures__/files/requestParams.json +3 -0
  6. package/src/commands/__fixtures__/openapi-schema.json +4 -0
  7. package/src/commands/__fixtures__/requestParams.json +3 -0
  8. package/src/commands/__fixtures__/sample_fully_qualified_mesh.json +29 -0
  9. package/src/commands/__fixtures__/sample_invalid_mesh.txt +17 -0
  10. package/src/commands/__fixtures__/sample_mesh_files.json +23 -0
  11. package/src/commands/__fixtures__/sample_mesh_invalid_file_content.json +14 -0
  12. package/src/commands/__fixtures__/sample_mesh_invalid_file_name.json +27 -0
  13. package/src/commands/__fixtures__/sample_mesh_invalid_paths.json +23 -0
  14. package/src/commands/__fixtures__/sample_mesh_invalid_type.json +27 -0
  15. package/src/commands/__fixtures__/sample_mesh_mismatching_path.json +29 -0
  16. package/src/commands/__fixtures__/sample_mesh_outside_workspace_dir.json +23 -0
  17. package/src/commands/__fixtures__/sample_mesh_path_from_home.json +14 -0
  18. package/src/commands/__fixtures__/sample_mesh_subdirectory.json +23 -0
  19. package/src/commands/__fixtures__/sample_mesh_with_files_array.json +29 -0
  20. package/src/commands/__fixtures__/sample_mesh_with_placeholder +17 -0
  21. package/src/commands/api-mesh/__tests__/create.test.js +1334 -140
  22. package/src/commands/api-mesh/__tests__/delete.test.js +3 -3
  23. package/src/commands/api-mesh/__tests__/init.test.js +390 -0
  24. package/src/commands/api-mesh/__tests__/update.test.js +524 -109
  25. package/src/commands/api-mesh/create.js +47 -14
  26. package/src/commands/api-mesh/init.js +168 -0
  27. package/src/commands/api-mesh/update.js +49 -17
  28. package/src/helpers.js +254 -3
  29. package/src/lib/devConsole.js +1 -2
  30. package/src/templates/gitignore +1 -0
  31. package/src/templates/package.json +38 -0
  32. 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(true);
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
- afterEach(() => {
77
- jest.restoreAllMocks();
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 fail if updateMesh method failed', async () => {
179
- updateMesh.mockRejectedValueOnce(new Error('dummy_error'));
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
- const runResult = UpdateCommand.run();
538
+ parseSpy.mockResolvedValue({
539
+ args: { file: 'src/commands/__fixtures__/sample_mesh_files.json' },
540
+ flags: {
541
+ autoConfirmAction: mockAutoApproveAction,
542
+ },
543
+ });
182
544
 
183
- await expect(runResult).rejects.toEqual(
184
- new Error(
185
- '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',
186
- ),
187
- );
188
- expect(logSpy.mock.calls).toMatchInlineSnapshot(`
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
- "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",
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
- test('should pass with valid args', async () => {
205
- const runResult = await UpdateCommand.run();
206
-
207
- expect(runResult).toMatchInlineSnapshot(`
590
+ expect(output).toMatchInlineSnapshot(`
208
591
  {
209
- "status": "success",
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 pass with valid args and ignoreCache flag', async () => {
240
- parseSpy.mockResolvedValueOnce({
241
- args: { file: 'valid_file_name' },
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: Promise.resolve(true),
653
+ ignoreCache: mockIgnoreCacheFlag,
244
654
  autoConfirmAction: mockAutoApproveAction,
245
655
  },
246
656
  });
247
657
 
248
- const runResult = await UpdateCommand.run();
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 pass with valid args if autoConfirmAction flag is set', async () => {
283
- parseSpy.mockResolvedValueOnce({
284
- args: { file: 'valid_file_name' },
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: Promise.resolve(true),
709
+ autoConfirmAction: mockAutoApproveAction,
288
710
  },
289
711
  });
290
712
 
291
- const runResult = await UpdateCommand.run();
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
  });