@adobe/aio-cli-plugin-api-mesh 2.0.0 → 2.2.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/oclif.manifest.json +1 -1
- package/package.json +4 -3
- package/src/commands/__fixtures__/env_invalid +8 -0
- package/src/commands/__fixtures__/env_valid +3 -0
- package/src/commands/__fixtures__/sample_mesh_with_placeholder +17 -0
- package/src/commands/api-mesh/__tests__/create.test.js +351 -131
- package/src/commands/api-mesh/__tests__/delete.test.js +3 -3
- package/src/commands/api-mesh/__tests__/update.test.js +128 -128
- package/src/commands/api-mesh/create.js +69 -5
- package/src/commands/api-mesh/update.js +69 -5
- package/src/helpers.js +110 -0
- package/src/meshInterpolation.js +120 -0
- package/src/utils.js +8 -2
package/oclif.manifest.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"2.
|
|
1
|
+
{"version":"2.2.0","commands":{"PLUGINNAME":{"id":"PLUGINNAME","description":"Your description here","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"examples":["$ aio PLUGINNAME:some_command"],"flags":{"someflag":{"name":"someflag","type":"option","char":"f","description":"this is some flag"}},"args":[]},"api-mesh:create":{"id":"api-mesh:create","description":"Create a mesh with the given config.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false},"autoConfirmAction":{"name":"autoConfirmAction","type":"boolean","char":"c","description":"Auto confirm action prompt. CLI will not check for user approval before executing the action.","allowNo":false},"json":{"name":"json","type":"boolean","description":"Output JSON","allowNo":false},"env":{"name":"env","type":"option","char":"e","description":"Path to env file"}},"args":[{"name":"file"}]},"api-mesh:delete":{"id":"api-mesh:delete","description":"Delete the config of a given mesh","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false},"autoConfirmAction":{"name":"autoConfirmAction","type":"boolean","char":"c","description":"Auto confirm action prompt. CLI will not check for user approval before executing the action.","allowNo":false}},"args":[]},"api-mesh:describe":{"id":"api-mesh:describe","description":"Get details of a mesh","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false}},"args":[]},"api-mesh:get":{"id":"api-mesh:get","description":"Get the config of a given mesh","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false}},"args":[{"name":"file"}]},"api-mesh:status":{"id":"api-mesh:status","description":"Get a mesh status with a given meshid.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false}},"args":[]},"api-mesh:update":{"id":"api-mesh:update","description":"Update a mesh with the given config.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false},"autoConfirmAction":{"name":"autoConfirmAction","type":"boolean","char":"c","description":"Auto confirm action prompt. CLI will not check for user approval before executing the action.","allowNo":false},"env":{"name":"env","type":"option","char":"e","description":"Path to env file"}},"args":[{"name":"file"}]},"api-mesh:source:discover":{"id":"api-mesh:source:discover","description":"Return the list of avaliable sources","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"confirm":{"name":"confirm","type":"boolean","char":"c","description":"Auto confirm install action prompt. CLI will not check ask user to install source.","allowNo":false}},"args":[]},"api-mesh:source:get":{"id":"api-mesh:source:get","description":"Command returns the content of a specific source.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"examples":["$ aio api-mesh:source:get -s=<version>@<source_name>","$ aio api-mesh:source:get -s<source_name>","$ aio api-mesh:source:get -m"],"flags":{"confirm":{"name":"confirm","type":"boolean","char":"c","description":"Auto confirm print action prompt. CLI will not check ask user to print source.","allowNo":false},"source":{"name":"source","type":"option","char":"s","description":"Source name"},"multiple":{"name":"multiple","type":"boolean","char":"m","description":"Select multiple sources","allowNo":false}},"args":[]},"api-mesh:source:install":{"id":"api-mesh:source:install","description":"Command to install the source to your API mesh.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"examples":["$ aio api-mesh:source:install <version>@<source_name>","$ aio api-mesh:source:install <source_name> -v <variable_name>=<variable_value>","$ aio api-mesh:source:install <source_name> -f <path_to_variables_file>"],"flags":{"source":{"name":"source","type":"option","char":"s","description":"Source name"},"confirm":{"name":"confirm","type":"boolean","char":"c","description":"Auto confirm override action prompt. CLI will not check ask user to override source.","allowNo":false},"variable":{"name":"variable","type":"option","char":"v","description":"Variables required for the source"},"variable-file":{"name":"variable-file","type":"option","char":"f","description":"Variables file path"},"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false}},"args":[{"name":"source"}]}}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/aio-cli-plugin-api-mesh",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -16,13 +16,14 @@
|
|
|
16
16
|
"@oclif/errors": "^1.1.2",
|
|
17
17
|
"axios": "^1.2.0",
|
|
18
18
|
"chalk": "^4.1.0",
|
|
19
|
-
"dotenv": "^16.0.
|
|
19
|
+
"dotenv": "^16.0.3",
|
|
20
20
|
"fs-extra": "^11.1.0",
|
|
21
21
|
"inquirer": "^8.2.4",
|
|
22
22
|
"json-interpolate": "^1.0.3",
|
|
23
23
|
"node-clipboardy": "^1.0.3",
|
|
24
24
|
"pino": "^7.9.2",
|
|
25
25
|
"pino-pretty": "^7.6.0",
|
|
26
|
+
"pupa": "^3.1.0",
|
|
26
27
|
"source-registry-storage-adapter": "github:devx-services/source-registry-storage-adapter#main",
|
|
27
28
|
"uuid": "^8.3.2"
|
|
28
29
|
},
|
|
@@ -51,7 +52,7 @@
|
|
|
51
52
|
},
|
|
52
53
|
"engines": {
|
|
53
54
|
"npm": ">=8.0.0",
|
|
54
|
-
"node": ">=18.0.0"
|
|
55
|
+
"node": "^16.13 || >=18.0.0"
|
|
55
56
|
},
|
|
56
57
|
"files": [
|
|
57
58
|
"/oclif.manifest.json",
|
|
@@ -21,6 +21,8 @@ const {
|
|
|
21
21
|
subscribeCredentialToMeshService,
|
|
22
22
|
} = require('../../../lib/devConsole');
|
|
23
23
|
|
|
24
|
+
const meshInterpolation = require('../../../meshInterpolation');
|
|
25
|
+
|
|
24
26
|
const selectedOrg = { id: '1234', code: 'CODE1234@AdobeOrg', name: 'ORG01', type: 'entp' };
|
|
25
27
|
|
|
26
28
|
const selectedProject = { id: '5678', title: 'Project01' };
|
|
@@ -40,6 +42,7 @@ jest.mock('../../../helpers', () => ({
|
|
|
40
42
|
initSdk: jest.fn().mockResolvedValue({}),
|
|
41
43
|
initRequestId: jest.fn().mockResolvedValue({}),
|
|
42
44
|
promptConfirm: jest.fn().mockResolvedValue(true),
|
|
45
|
+
getname: jest.fn().mockResolvedValue({}),
|
|
43
46
|
}));
|
|
44
47
|
jest.mock('../../../lib/devConsole');
|
|
45
48
|
|
|
@@ -84,8 +87,20 @@ describe('create command tests', () => {
|
|
|
84
87
|
});
|
|
85
88
|
});
|
|
86
89
|
|
|
87
|
-
|
|
88
|
-
|
|
90
|
+
test('must return proper object structure used by adobe/generator-app-api-mesh', async () => {
|
|
91
|
+
parseSpy.mockResolvedValueOnce({
|
|
92
|
+
args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
|
|
93
|
+
flags: {
|
|
94
|
+
json: Promise.resolve(true),
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
const output = await CreateCommand.run();
|
|
98
|
+
expect(output).toHaveProperty('mesh');
|
|
99
|
+
expect(output).toHaveProperty('adobeIdIntegrationsForWorkspace');
|
|
100
|
+
expect(output.mesh).toEqual(expect.objectContaining({ meshId: 'dummy_mesh_id' }));
|
|
101
|
+
expect(output.adobeIdIntegrationsForWorkspace).toEqual(
|
|
102
|
+
expect.objectContaining({ apiKey: 'dummy_api_key' }),
|
|
103
|
+
);
|
|
89
104
|
});
|
|
90
105
|
|
|
91
106
|
test('snapshot create command description', () => {
|
|
@@ -99,6 +114,7 @@ describe('create command tests', () => {
|
|
|
99
114
|
},
|
|
100
115
|
]
|
|
101
116
|
`);
|
|
117
|
+
|
|
102
118
|
expect(CreateCommand.flags).toMatchInlineSnapshot(`
|
|
103
119
|
{
|
|
104
120
|
"autoConfirmAction": {
|
|
@@ -109,6 +125,14 @@ describe('create command tests', () => {
|
|
|
109
125
|
"parse": [Function],
|
|
110
126
|
"type": "boolean",
|
|
111
127
|
},
|
|
128
|
+
"env": {
|
|
129
|
+
"char": "e",
|
|
130
|
+
"description": "Path to env file",
|
|
131
|
+
"input": [],
|
|
132
|
+
"multiple": false,
|
|
133
|
+
"parse": [Function],
|
|
134
|
+
"type": "option",
|
|
135
|
+
},
|
|
112
136
|
"ignoreCache": {
|
|
113
137
|
"allowNo": false,
|
|
114
138
|
"char": "i",
|
|
@@ -128,6 +152,131 @@ describe('create command tests', () => {
|
|
|
128
152
|
`);
|
|
129
153
|
expect(CreateCommand.aliases).toMatchInlineSnapshot(`[]`);
|
|
130
154
|
});
|
|
155
|
+
test('should fail if create mesh api has failed', async () => {
|
|
156
|
+
createMesh.mockRejectedValueOnce(new Error('create mesh api failed'));
|
|
157
|
+
|
|
158
|
+
const runResult = CreateCommand.run();
|
|
159
|
+
await expect(runResult).rejects.toEqual(
|
|
160
|
+
new Error(
|
|
161
|
+
'Unable to create a mesh. Please check the mesh configuration file and try again. If the error persists please contact support. RequestId: dummy_request_id',
|
|
162
|
+
),
|
|
163
|
+
);
|
|
164
|
+
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
165
|
+
[
|
|
166
|
+
[
|
|
167
|
+
"create mesh api failed",
|
|
168
|
+
],
|
|
169
|
+
]
|
|
170
|
+
`);
|
|
171
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
|
|
172
|
+
[
|
|
173
|
+
[
|
|
174
|
+
"Unable to create a mesh. Please check the mesh configuration file and try again. If the error persists please contact support. RequestId: dummy_request_id",
|
|
175
|
+
],
|
|
176
|
+
]
|
|
177
|
+
`);
|
|
178
|
+
});
|
|
179
|
+
test('should create if a valid mesh config file is provided', async () => {
|
|
180
|
+
const runResult = await CreateCommand.run();
|
|
181
|
+
|
|
182
|
+
expect(initRequestId).toHaveBeenCalled();
|
|
183
|
+
expect(createMesh.mock.calls[0]).toMatchInlineSnapshot(`
|
|
184
|
+
[
|
|
185
|
+
"1234",
|
|
186
|
+
"5678",
|
|
187
|
+
"123456789",
|
|
188
|
+
{
|
|
189
|
+
"meshConfig": {
|
|
190
|
+
"sources": [
|
|
191
|
+
{
|
|
192
|
+
"handler": {
|
|
193
|
+
"graphql": {
|
|
194
|
+
"endpoint": "<gql_endpoint>",
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
"name": "<api_name>",
|
|
198
|
+
},
|
|
199
|
+
],
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
]
|
|
203
|
+
`);
|
|
204
|
+
expect(createAPIMeshCredentials.mock.calls[0]).toMatchInlineSnapshot(`
|
|
205
|
+
[
|
|
206
|
+
"1234",
|
|
207
|
+
"5678",
|
|
208
|
+
"123456789",
|
|
209
|
+
]
|
|
210
|
+
`);
|
|
211
|
+
expect(subscribeCredentialToMeshService.mock.calls[0]).toMatchInlineSnapshot(`
|
|
212
|
+
[
|
|
213
|
+
"1234",
|
|
214
|
+
"5678",
|
|
215
|
+
"123456789",
|
|
216
|
+
"dummy_id",
|
|
217
|
+
]
|
|
218
|
+
`);
|
|
219
|
+
expect(runResult).toMatchInlineSnapshot(`
|
|
220
|
+
{
|
|
221
|
+
"adobeIdIntegrationsForWorkspace": {
|
|
222
|
+
"apiKey": "dummy_api_key",
|
|
223
|
+
"id": "dummy_id",
|
|
224
|
+
},
|
|
225
|
+
"mesh": {
|
|
226
|
+
"meshConfig": {
|
|
227
|
+
"sources": [
|
|
228
|
+
{
|
|
229
|
+
"handler": {
|
|
230
|
+
"graphql": {
|
|
231
|
+
"endpoint": "<gql_endpoint>",
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
"name": "<api_name>",
|
|
235
|
+
},
|
|
236
|
+
],
|
|
237
|
+
},
|
|
238
|
+
"meshId": "dummy_mesh_id",
|
|
239
|
+
},
|
|
240
|
+
"sdkList": [
|
|
241
|
+
"dummy_service",
|
|
242
|
+
],
|
|
243
|
+
}
|
|
244
|
+
`);
|
|
245
|
+
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
246
|
+
[
|
|
247
|
+
[
|
|
248
|
+
"******************************************************************************************************",
|
|
249
|
+
],
|
|
250
|
+
[
|
|
251
|
+
"Your mesh is being provisioned. Wait a few minutes before checking the status of your mesh %s",
|
|
252
|
+
"dummy_mesh_id",
|
|
253
|
+
],
|
|
254
|
+
[
|
|
255
|
+
"To check the status of your mesh, run:",
|
|
256
|
+
],
|
|
257
|
+
[
|
|
258
|
+
"aio api-mesh:status",
|
|
259
|
+
],
|
|
260
|
+
[
|
|
261
|
+
"******************************************************************************************************",
|
|
262
|
+
],
|
|
263
|
+
[
|
|
264
|
+
"Successfully created API Key %s",
|
|
265
|
+
"dummy_api_key",
|
|
266
|
+
],
|
|
267
|
+
[
|
|
268
|
+
"Successfully subscribed API Key %s to API Mesh service",
|
|
269
|
+
"dummy_api_key",
|
|
270
|
+
],
|
|
271
|
+
[
|
|
272
|
+
"Mesh Endpoint: %s
|
|
273
|
+
",
|
|
274
|
+
"https://graph.adobe.io/api/dummy_mesh_id/graphql?api_key=dummy_api_key",
|
|
275
|
+
],
|
|
276
|
+
]
|
|
277
|
+
`);
|
|
278
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`[]`);
|
|
279
|
+
});
|
|
131
280
|
|
|
132
281
|
test('should fail if mesh config file arg is missing', async () => {
|
|
133
282
|
parseSpy.mockResolvedValueOnce({
|
|
@@ -183,34 +332,8 @@ describe('create command tests', () => {
|
|
|
183
332
|
`);
|
|
184
333
|
});
|
|
185
334
|
|
|
186
|
-
test('should fail if create mesh api has failed', async () => {
|
|
187
|
-
createMesh.mockRejectedValueOnce(new Error('create mesh api failed'));
|
|
188
|
-
|
|
189
|
-
const runResult = CreateCommand.run();
|
|
190
|
-
|
|
191
|
-
await expect(runResult).rejects.toEqual(
|
|
192
|
-
new Error(
|
|
193
|
-
'Unable to create a mesh. Please check the mesh configuration file and try again. If the error persists please contact support. RequestId: dummy_request_id',
|
|
194
|
-
),
|
|
195
|
-
);
|
|
196
|
-
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
197
|
-
[
|
|
198
|
-
[
|
|
199
|
-
"create mesh api failed",
|
|
200
|
-
],
|
|
201
|
-
]
|
|
202
|
-
`);
|
|
203
|
-
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
|
|
204
|
-
[
|
|
205
|
-
[
|
|
206
|
-
"Unable to create a mesh. Please check the mesh configuration file and try again. If the error persists please contact support. RequestId: dummy_request_id",
|
|
207
|
-
],
|
|
208
|
-
]
|
|
209
|
-
`);
|
|
210
|
-
});
|
|
211
|
-
|
|
212
335
|
test('should fail if create api credential api has failed', async () => {
|
|
213
|
-
createAPIMeshCredentials.
|
|
336
|
+
createAPIMeshCredentials.mockRejectedValue(new Error('create api credential api failed'));
|
|
214
337
|
|
|
215
338
|
const runResult = CreateCommand.run();
|
|
216
339
|
|
|
@@ -299,108 +422,6 @@ describe('create command tests', () => {
|
|
|
299
422
|
`);
|
|
300
423
|
});
|
|
301
424
|
|
|
302
|
-
test('should create if a valid mesh config file is provided', async () => {
|
|
303
|
-
const runResult = await CreateCommand.run();
|
|
304
|
-
|
|
305
|
-
expect(initRequestId).toHaveBeenCalled();
|
|
306
|
-
expect(createMesh.mock.calls[0]).toMatchInlineSnapshot(`
|
|
307
|
-
[
|
|
308
|
-
"1234",
|
|
309
|
-
"5678",
|
|
310
|
-
"123456789",
|
|
311
|
-
{
|
|
312
|
-
"meshConfig": {
|
|
313
|
-
"sources": [
|
|
314
|
-
{
|
|
315
|
-
"handler": {
|
|
316
|
-
"graphql": {
|
|
317
|
-
"endpoint": "<gql_endpoint>",
|
|
318
|
-
},
|
|
319
|
-
},
|
|
320
|
-
"name": "<api_name>",
|
|
321
|
-
},
|
|
322
|
-
],
|
|
323
|
-
},
|
|
324
|
-
},
|
|
325
|
-
]
|
|
326
|
-
`);
|
|
327
|
-
expect(createAPIMeshCredentials.mock.calls[0]).toMatchInlineSnapshot(`
|
|
328
|
-
[
|
|
329
|
-
"1234",
|
|
330
|
-
"5678",
|
|
331
|
-
"123456789",
|
|
332
|
-
]
|
|
333
|
-
`);
|
|
334
|
-
expect(subscribeCredentialToMeshService.mock.calls[0]).toMatchInlineSnapshot(`
|
|
335
|
-
[
|
|
336
|
-
"1234",
|
|
337
|
-
"5678",
|
|
338
|
-
"123456789",
|
|
339
|
-
"dummy_id",
|
|
340
|
-
]
|
|
341
|
-
`);
|
|
342
|
-
expect(runResult).toMatchInlineSnapshot(`
|
|
343
|
-
{
|
|
344
|
-
"adobeIdIntegrationsForWorkspace": {
|
|
345
|
-
"apiKey": "dummy_api_key",
|
|
346
|
-
"id": "dummy_id",
|
|
347
|
-
},
|
|
348
|
-
"mesh": {
|
|
349
|
-
"meshConfig": {
|
|
350
|
-
"sources": [
|
|
351
|
-
{
|
|
352
|
-
"handler": {
|
|
353
|
-
"graphql": {
|
|
354
|
-
"endpoint": "<gql_endpoint>",
|
|
355
|
-
},
|
|
356
|
-
},
|
|
357
|
-
"name": "<api_name>",
|
|
358
|
-
},
|
|
359
|
-
],
|
|
360
|
-
},
|
|
361
|
-
"meshId": "dummy_mesh_id",
|
|
362
|
-
},
|
|
363
|
-
"sdkList": [
|
|
364
|
-
"dummy_service",
|
|
365
|
-
],
|
|
366
|
-
}
|
|
367
|
-
`);
|
|
368
|
-
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
369
|
-
[
|
|
370
|
-
[
|
|
371
|
-
"******************************************************************************************************",
|
|
372
|
-
],
|
|
373
|
-
[
|
|
374
|
-
"Your mesh is being provisioned. Wait a few minutes before checking the status of your mesh %s",
|
|
375
|
-
"dummy_mesh_id",
|
|
376
|
-
],
|
|
377
|
-
[
|
|
378
|
-
"To check the status of your mesh, run:",
|
|
379
|
-
],
|
|
380
|
-
[
|
|
381
|
-
"aio api-mesh:status",
|
|
382
|
-
],
|
|
383
|
-
[
|
|
384
|
-
"******************************************************************************************************",
|
|
385
|
-
],
|
|
386
|
-
[
|
|
387
|
-
"Successfully created API Key %s",
|
|
388
|
-
"dummy_api_key",
|
|
389
|
-
],
|
|
390
|
-
[
|
|
391
|
-
"Successfully subscribed API Key %s to API Mesh service",
|
|
392
|
-
"dummy_api_key",
|
|
393
|
-
],
|
|
394
|
-
[
|
|
395
|
-
"Mesh Endpoint: %s
|
|
396
|
-
",
|
|
397
|
-
"https://graph.adobe.io/api/dummy_mesh_id/graphql?api_key=dummy_api_key",
|
|
398
|
-
],
|
|
399
|
-
]
|
|
400
|
-
`);
|
|
401
|
-
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`[]`);
|
|
402
|
-
});
|
|
403
|
-
|
|
404
425
|
test('should not ask for confirmation if autoConfirmAction is provided', async () => {
|
|
405
426
|
parseSpy.mockResolvedValueOnce({
|
|
406
427
|
args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
|
|
@@ -488,4 +509,203 @@ describe('create command tests', () => {
|
|
|
488
509
|
expect.objectContaining({ apiKey: 'dummy_api_key' }),
|
|
489
510
|
);
|
|
490
511
|
});
|
|
512
|
+
|
|
513
|
+
test('should return error if the env file provided using --env flag is not found', async () => {
|
|
514
|
+
parseSpy.mockResolvedValueOnce({
|
|
515
|
+
args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
|
|
516
|
+
flags: {
|
|
517
|
+
ignoreCache: mockIgnoreCacheFlag,
|
|
518
|
+
autoConfirmAction: Promise.resolve(true),
|
|
519
|
+
env: 'src/commands/__fixtures__/.env_nonExisting',
|
|
520
|
+
},
|
|
521
|
+
});
|
|
522
|
+
const runResult = CreateCommand.run();
|
|
523
|
+
|
|
524
|
+
await expect(runResult).rejects.toEqual(
|
|
525
|
+
new Error('Unable to read the env file provided. Please check the file and try again.'),
|
|
526
|
+
);
|
|
527
|
+
|
|
528
|
+
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
529
|
+
[
|
|
530
|
+
[
|
|
531
|
+
"ENOENT: no such file or directory, open 'src/commands/__fixtures__/.env_nonExisting'",
|
|
532
|
+
],
|
|
533
|
+
]
|
|
534
|
+
`);
|
|
535
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
|
|
536
|
+
[
|
|
537
|
+
[
|
|
538
|
+
"Unable to read the env file provided. Please check the file and try again.",
|
|
539
|
+
],
|
|
540
|
+
]
|
|
541
|
+
`);
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
test('should return error if the provided env file is invalid', async () => {
|
|
545
|
+
parseSpy.mockResolvedValueOnce({
|
|
546
|
+
args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
|
|
547
|
+
flags: {
|
|
548
|
+
ignoreCache: mockIgnoreCacheFlag,
|
|
549
|
+
autoConfirmAction: Promise.resolve(true),
|
|
550
|
+
env: 'src/commands/__fixtures__/env_invalid',
|
|
551
|
+
},
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
const runResult = CreateCommand.run();
|
|
555
|
+
|
|
556
|
+
await expect(runResult).rejects.toEqual(
|
|
557
|
+
new Error(
|
|
558
|
+
"Issue in src/commands/__fixtures__/env_invalid file - Duplicate key << key1 >> on line 3,Invalid format for key/value << key2=='value3' >> on line 5,Invalid format << key3 >> on line 6,Invalid format for key/value << key4='value4 >> on line 7",
|
|
559
|
+
),
|
|
560
|
+
);
|
|
561
|
+
|
|
562
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
|
|
563
|
+
[
|
|
564
|
+
[
|
|
565
|
+
"Issue in src/commands/__fixtures__/env_invalid file - Duplicate key << key1 >> on line 3,Invalid format for key/value << key2=='value3' >> on line 5,Invalid format << key3 >> on line 6,Invalid format for key/value << key4='value4 >> on line 7",
|
|
566
|
+
],
|
|
567
|
+
]
|
|
568
|
+
`);
|
|
569
|
+
});
|
|
570
|
+
|
|
571
|
+
test('should return error if the provided env file is valid but there are missing keys found in mesh interpolation', async () => {
|
|
572
|
+
parseSpy.mockResolvedValueOnce({
|
|
573
|
+
args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
|
|
574
|
+
flags: {
|
|
575
|
+
ignoreCache: mockIgnoreCacheFlag,
|
|
576
|
+
autoConfirmAction: Promise.resolve(true),
|
|
577
|
+
env: 'src/commands/__fixtures__/env_valid',
|
|
578
|
+
},
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
const interpolateMeshFunc = jest.spyOn(meshInterpolation, 'interpolateMesh');
|
|
582
|
+
interpolateMeshFunc.mockResolvedValueOnce({
|
|
583
|
+
interpolationStatus: 'failed',
|
|
584
|
+
missingKeys: ['newKey1', 'newKey2', 'newKey1'],
|
|
585
|
+
interpolatedMesh: '',
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
const runResult = CreateCommand.run();
|
|
589
|
+
await expect(runResult).rejects.toEqual(
|
|
590
|
+
new Error('The mesh file cannot be interpolated due to missing keys : newKey1,newKey2'),
|
|
591
|
+
);
|
|
592
|
+
|
|
593
|
+
await expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
|
|
594
|
+
[
|
|
595
|
+
[
|
|
596
|
+
"The mesh file cannot be interpolated due to missing keys : newKey1,newKey2",
|
|
597
|
+
],
|
|
598
|
+
]
|
|
599
|
+
`);
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
test('should return error if the provided env file is valid and mesh interpolation is successful but interpolated mesh is not a valid JSON', async () => {
|
|
603
|
+
parseSpy.mockResolvedValueOnce({
|
|
604
|
+
args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
|
|
605
|
+
flags: {
|
|
606
|
+
ignoreCache: mockIgnoreCacheFlag,
|
|
607
|
+
autoConfirmAction: Promise.resolve(true),
|
|
608
|
+
env: 'src/commands/__fixtures__/env_valid',
|
|
609
|
+
},
|
|
610
|
+
});
|
|
611
|
+
|
|
612
|
+
//sampleInterpolated mesh where value of responseConfig.includeHTTPDetails is invalid i.e. non-boolean
|
|
613
|
+
const sampleInterpolatedMesh =
|
|
614
|
+
'{"meshConfig":{"sources":[{"name":"<api-name>","handler":{"graphql":{"endpoint":"<api-url>"}}}],"responseConfig":{"includeHTTPDetails":sample}}}';
|
|
615
|
+
|
|
616
|
+
const interpolateMeshFunc = jest.spyOn(meshInterpolation, 'interpolateMesh');
|
|
617
|
+
interpolateMeshFunc.mockResolvedValueOnce({
|
|
618
|
+
interpolationStatus: 'success',
|
|
619
|
+
missingKeys: [],
|
|
620
|
+
interpolatedMeshData: sampleInterpolatedMesh,
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
const runResult = CreateCommand.run();
|
|
624
|
+
await expect(runResult).rejects.toEqual(
|
|
625
|
+
new Error('Interpolated mesh is not a valid JSON. Please check the generated json file.'),
|
|
626
|
+
);
|
|
627
|
+
|
|
628
|
+
await expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
|
|
629
|
+
[
|
|
630
|
+
[
|
|
631
|
+
"Interpolated mesh is not a valid JSON. Please check the generated json file.",
|
|
632
|
+
],
|
|
633
|
+
]
|
|
634
|
+
`);
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
test('should successfully create a mesh if provided env file is valid, mesh interpolation is successful and interpolated mesh is a valid JSON', async () => {
|
|
638
|
+
parseSpy.mockResolvedValue({
|
|
639
|
+
args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
|
|
640
|
+
flags: {
|
|
641
|
+
ignoreCache: mockIgnoreCacheFlag,
|
|
642
|
+
autoConfirmAction: mockAutoApproveAction,
|
|
643
|
+
env: 'src/commands/__fixtures__/env_valid',
|
|
644
|
+
},
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
//sampleInterpolated mesh where the mesh string is a valid JSON
|
|
648
|
+
const sampleInterpolatedMesh =
|
|
649
|
+
'{"meshConfig":{"sources":[{"name":"<api-name>","handler":{"graphql":{"endpoint":"<api-url>"}}}],"responseConfig":{"includeHTTPDetails":true}}}';
|
|
650
|
+
|
|
651
|
+
const interpolateMeshFunc = jest.spyOn(meshInterpolation, 'interpolateMesh');
|
|
652
|
+
interpolateMeshFunc.mockResolvedValueOnce({
|
|
653
|
+
interpolationStatus: 'success',
|
|
654
|
+
missingKeys: [],
|
|
655
|
+
interpolatedMeshData: sampleInterpolatedMesh,
|
|
656
|
+
});
|
|
657
|
+
|
|
658
|
+
const runResult = await CreateCommand.run();
|
|
659
|
+
|
|
660
|
+
expect(promptConfirm).toHaveBeenCalledWith('Are you sure you want to create a mesh?');
|
|
661
|
+
expect(runResult).toMatchInlineSnapshot(`
|
|
662
|
+
{
|
|
663
|
+
"adobeIdIntegrationsForWorkspace": {
|
|
664
|
+
"apiKey": "dummy_api_key",
|
|
665
|
+
"id": "dummy_id",
|
|
666
|
+
},
|
|
667
|
+
"mesh": {
|
|
668
|
+
"meshConfig": {
|
|
669
|
+
"sources": [
|
|
670
|
+
{
|
|
671
|
+
"handler": {
|
|
672
|
+
"graphql": {
|
|
673
|
+
"endpoint": "<gql_endpoint>",
|
|
674
|
+
},
|
|
675
|
+
},
|
|
676
|
+
"name": "<api_name>",
|
|
677
|
+
},
|
|
678
|
+
],
|
|
679
|
+
},
|
|
680
|
+
"meshId": "dummy_mesh_id",
|
|
681
|
+
},
|
|
682
|
+
"sdkList": [
|
|
683
|
+
"dummy_service",
|
|
684
|
+
],
|
|
685
|
+
}
|
|
686
|
+
`);
|
|
687
|
+
});
|
|
688
|
+
|
|
689
|
+
test('should return error if inputMesh is not a valid JSON', async () => {
|
|
690
|
+
parseSpy.mockResolvedValue({
|
|
691
|
+
args: { file: 'src/commands/__fixtures__/sample_mesh_with_placeholder' },
|
|
692
|
+
flags: {
|
|
693
|
+
ignoreCache: mockIgnoreCacheFlag,
|
|
694
|
+
autoConfirmAction: mockAutoApproveAction,
|
|
695
|
+
},
|
|
696
|
+
});
|
|
697
|
+
|
|
698
|
+
const runResult = CreateCommand.run();
|
|
699
|
+
await expect(runResult).rejects.toEqual(
|
|
700
|
+
new Error('Input mesh file is not a valid JSON. Please check the file provided.'),
|
|
701
|
+
);
|
|
702
|
+
|
|
703
|
+
await expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
|
|
704
|
+
[
|
|
705
|
+
[
|
|
706
|
+
"Input mesh file is not a valid JSON. Please check the file provided.",
|
|
707
|
+
],
|
|
708
|
+
]
|
|
709
|
+
`);
|
|
710
|
+
});
|
|
491
711
|
});
|
|
@@ -81,9 +81,9 @@ describe('delete command tests', () => {
|
|
|
81
81
|
});
|
|
82
82
|
});
|
|
83
83
|
|
|
84
|
-
afterEach(() => {
|
|
85
|
-
|
|
86
|
-
});
|
|
84
|
+
// afterEach(() => {
|
|
85
|
+
// jest.restoreAllMocks();
|
|
86
|
+
// });
|
|
87
87
|
|
|
88
88
|
test('snapshot delete command description', () => {
|
|
89
89
|
expect(DeleteCommand.description).toMatchInlineSnapshot(`"Delete the config of a given mesh"`);
|