@adobe/aio-cli-plugin-api-mesh 1.0.3-beta → 1.0.4-beta
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/README.md +28 -6
- package/oclif.manifest.json +1 -1
- package/package.json +2 -1
- package/src/commands/api-mesh/__tests__/create.test.js +446 -33
- package/src/commands/api-mesh/__tests__/delete.test.js +267 -52
- package/src/commands/api-mesh/__tests__/describe.test.js +210 -40
- package/src/commands/api-mesh/__tests__/get.test.js +298 -36
- package/src/commands/api-mesh/__tests__/update.test.js +237 -61
- package/src/commands/api-mesh/create.js +92 -18
- package/src/commands/api-mesh/delete.js +76 -29
- package/src/commands/api-mesh/describe.js +27 -3
- package/src/commands/api-mesh/get.js +46 -26
- package/src/commands/api-mesh/update.js +54 -26
- package/src/constants.js +21 -0
- package/src/helpers.js +162 -44
- package/src/lib/devConsole.js +746 -0
- package/src/utils.js +18 -1
- package/src/classes/SchemaServiceClient.js +0 -416
|
@@ -10,65 +10,327 @@ OF ANY KIND, either express or implied. See the License for the specific languag
|
|
|
10
10
|
governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
jest.mock('axios');
|
|
14
14
|
jest.mock('@adobe/aio-lib-env');
|
|
15
15
|
jest.mock('@adobe/aio-cli-lib-console');
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
jest.mock('fs/promises');
|
|
17
|
+
jest.mock('@adobe/aio-cli-lib-console', () => ({
|
|
18
|
+
init: jest.fn().mockResolvedValue(mockConsoleCLIInstance),
|
|
19
|
+
cleanStdOut: jest.fn(),
|
|
20
|
+
}));
|
|
21
|
+
jest.mock('@adobe/aio-lib-ims');
|
|
22
|
+
jest.mock('../../../helpers', () => ({
|
|
23
|
+
initSdk: jest.fn().mockResolvedValue({}),
|
|
24
|
+
initRequestId: jest.fn().mockResolvedValue({}),
|
|
25
|
+
}));
|
|
26
|
+
jest.mock('../../../lib/devConsole');
|
|
18
27
|
|
|
19
|
-
const
|
|
28
|
+
const mockConsoleCLIInstance = {};
|
|
29
|
+
const selectedOrg = { id: '1234', code: 'CODE1234@AdobeOrg', name: 'ORG01', type: 'entp' };
|
|
20
30
|
const selectedProject = { id: '5678', title: 'Project01' };
|
|
21
|
-
|
|
22
|
-
const workspaces = [{ id: '123456789', title: 'Workspace01' }];
|
|
23
31
|
const selectedWorkspace = { id: '123456789', title: 'Workspace01' };
|
|
24
32
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
33
|
+
const { writeFile } = require('fs/promises');
|
|
34
|
+
const { initSdk, initRequestId } = require('../../../helpers');
|
|
35
|
+
const GetCommand = require('../get');
|
|
36
|
+
const mockGetMeshConfig = require('../../__fixtures__/sample_mesh.json');
|
|
37
|
+
const { getMeshId, getMesh } = require('../../../lib/devConsole');
|
|
28
38
|
|
|
29
|
-
|
|
30
|
-
|
|
39
|
+
let logSpy = null;
|
|
40
|
+
let errorLogSpy = null;
|
|
31
41
|
|
|
32
|
-
|
|
33
|
-
mockConsoleCLIInstance.promptForSelectProject = jest.fn().mockResolvedValue(selectedProject);
|
|
42
|
+
let parseSpy = null;
|
|
34
43
|
|
|
35
|
-
|
|
36
|
-
mockConsoleCLIInstance.promptForSelectWorkspace = jest.fn().mockResolvedValue(selectedWorkspace);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
jest.mock('@adobe/aio-cli-lib-console', () => ({
|
|
40
|
-
init: jest.fn().mockResolvedValue(mockConsoleCLIInstance),
|
|
41
|
-
cleanStdOut: jest.fn(),
|
|
42
|
-
}));
|
|
43
|
-
jest.mock('@adobe/aio-lib-ims');
|
|
44
|
-
const GetCommand = require('../get');
|
|
45
|
-
const { SchemaServiceClient } = require('../../../classes/SchemaServiceClient');
|
|
46
|
-
const mockGetMesh = require('../../__fixtures__/sample_mesh.json');
|
|
44
|
+
const mockIgnoreCacheFlag = Promise.resolve(true);
|
|
47
45
|
|
|
48
46
|
describe('get command tests', () => {
|
|
49
47
|
beforeEach(() => {
|
|
50
|
-
|
|
48
|
+
initSdk.mockResolvedValue({
|
|
49
|
+
imsOrgId: selectedOrg.id,
|
|
50
|
+
projectId: selectedProject.id,
|
|
51
|
+
workspaceId: selectedWorkspace.id,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
global.requestId = 'dummy_request_id';
|
|
55
|
+
|
|
56
|
+
logSpy = jest.spyOn(GetCommand.prototype, 'log');
|
|
57
|
+
errorLogSpy = jest.spyOn(GetCommand.prototype, 'error');
|
|
58
|
+
|
|
59
|
+
writeFile.mockResolvedValue(true);
|
|
60
|
+
|
|
61
|
+
getMeshId.mockResolvedValue('dummy_meshId');
|
|
62
|
+
getMesh.mockResolvedValue({
|
|
63
|
+
meshId: 'dummy_meshId',
|
|
64
|
+
mesh: mockGetMeshConfig,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
parseSpy = jest.spyOn(GetCommand.prototype, 'parse');
|
|
68
|
+
parseSpy.mockResolvedValue({
|
|
69
|
+
args: { file: 'mesh.json' },
|
|
70
|
+
flags: {
|
|
71
|
+
ignoreCache: mockIgnoreCacheFlag,
|
|
72
|
+
},
|
|
73
|
+
});
|
|
51
74
|
});
|
|
75
|
+
|
|
52
76
|
afterEach(() => {
|
|
53
77
|
jest.restoreAllMocks();
|
|
54
78
|
});
|
|
55
79
|
|
|
80
|
+
test('snapshot get command', () => {
|
|
81
|
+
expect(GetCommand.description).toMatchInlineSnapshot(`"Get the config of a given mesh"`);
|
|
82
|
+
expect(GetCommand.args).toMatchInlineSnapshot(`
|
|
83
|
+
Array [
|
|
84
|
+
Object {
|
|
85
|
+
"name": "file",
|
|
86
|
+
},
|
|
87
|
+
]
|
|
88
|
+
`);
|
|
89
|
+
expect(GetCommand.flags).toMatchInlineSnapshot(`
|
|
90
|
+
Object {
|
|
91
|
+
"ignoreCache": Object {
|
|
92
|
+
"allowNo": false,
|
|
93
|
+
"char": "i",
|
|
94
|
+
"default": false,
|
|
95
|
+
"description": "Ignore cache and force manual org -> project -> workspace selection",
|
|
96
|
+
"parse": [Function],
|
|
97
|
+
"type": "boolean",
|
|
98
|
+
},
|
|
99
|
+
}
|
|
100
|
+
`);
|
|
101
|
+
expect(GetCommand.aliases).toMatchInlineSnapshot(`Array []`);
|
|
102
|
+
});
|
|
103
|
+
|
|
56
104
|
test('should fail if mesh id is missing', async () => {
|
|
57
|
-
|
|
105
|
+
getMeshId.mockResolvedValue(null);
|
|
106
|
+
const runResult = GetCommand.run();
|
|
107
|
+
|
|
108
|
+
return runResult.catch(err => {
|
|
109
|
+
expect(err.message).toMatchInlineSnapshot(
|
|
110
|
+
`"Unable to get mesh config. No mesh found for Org(1234) -> Project(5678) -> Workspace(123456789). Please check the details and try again."`,
|
|
111
|
+
);
|
|
112
|
+
expect(logSpy.mock.calls).toMatchInlineSnapshot(`Array []`);
|
|
113
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
|
|
114
|
+
Array [
|
|
115
|
+
Array [
|
|
116
|
+
"Unable to get mesh config. No mesh found for Org(1234) -> Project(5678) -> Workspace(123456789). Please check the details and try again.",
|
|
117
|
+
],
|
|
118
|
+
]
|
|
119
|
+
`);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test('should fail if getMeshId failed', async () => {
|
|
124
|
+
getMeshId.mockRejectedValue(new Error('getMeshId failed'));
|
|
125
|
+
const runResult = GetCommand.run();
|
|
58
126
|
|
|
59
127
|
return runResult.catch(err => {
|
|
60
|
-
expect(err).
|
|
61
|
-
|
|
62
|
-
expect.stringMatching(/^Missing Mesh ID. Run aio api-mesh get --help for more info./),
|
|
128
|
+
expect(err.message).toMatchInlineSnapshot(
|
|
129
|
+
`"Unable to get mesh ID. Please check the details and try again. RequestId: dummy_request_id"`,
|
|
63
130
|
);
|
|
131
|
+
expect(logSpy.mock.calls).toMatchInlineSnapshot(`Array []`);
|
|
132
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
|
|
133
|
+
Array [
|
|
134
|
+
Array [
|
|
135
|
+
"Unable to get mesh ID. Please check the details and try again. RequestId: dummy_request_id",
|
|
136
|
+
],
|
|
137
|
+
]
|
|
138
|
+
`);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test('should fail if mesh id is not found', async () => {
|
|
143
|
+
getMesh.mockResolvedValueOnce(null);
|
|
144
|
+
|
|
145
|
+
const runResult = await GetCommand.run();
|
|
146
|
+
|
|
147
|
+
expect(runResult).toMatchInlineSnapshot(`undefined`);
|
|
148
|
+
expect(logSpy.mock.calls).toMatchInlineSnapshot(`Array []`);
|
|
149
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
|
|
150
|
+
Array [
|
|
151
|
+
Array [
|
|
152
|
+
"Unable to get mesh with the ID dummy_meshId. Please check the mesh ID and try again. RequestId: dummy_request_id",
|
|
153
|
+
Object {
|
|
154
|
+
"exit": false,
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
]
|
|
158
|
+
`);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
test('should fail if get mesh method failed', async () => {
|
|
162
|
+
getMesh.mockRejectedValueOnce(new Error('get mesh failed'));
|
|
163
|
+
|
|
164
|
+
const runResult = GetCommand.run();
|
|
165
|
+
|
|
166
|
+
await expect(runResult).rejects.toEqual(
|
|
167
|
+
new Error(
|
|
168
|
+
'Unable to get mesh. Please check the details and try again. If the error persists please contact support. RequestId: dummy_request_id',
|
|
169
|
+
),
|
|
170
|
+
);
|
|
171
|
+
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
172
|
+
Array [
|
|
173
|
+
Array [
|
|
174
|
+
"get mesh failed",
|
|
175
|
+
],
|
|
176
|
+
]
|
|
177
|
+
`);
|
|
178
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
|
|
179
|
+
Array [
|
|
180
|
+
Array [
|
|
181
|
+
"Unable to get mesh. Please check the details and try again. If the error persists please contact support. RequestId: dummy_request_id",
|
|
182
|
+
],
|
|
183
|
+
]
|
|
184
|
+
`);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
test('should pass if mesh id is valid', async () => {
|
|
188
|
+
const meshId = 'dummy_meshId';
|
|
189
|
+
getMeshId.mockResolvedValueOnce(meshId);
|
|
190
|
+
const runResult = await GetCommand.run();
|
|
191
|
+
|
|
192
|
+
expect(initSdk).toHaveBeenCalledWith({
|
|
193
|
+
ignoreCache: true,
|
|
194
|
+
});
|
|
195
|
+
expect(initRequestId).toHaveBeenCalled();
|
|
196
|
+
expect(runResult).toEqual({ meshId: 'dummy_meshId', mesh: mockGetMeshConfig });
|
|
197
|
+
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
198
|
+
Array [
|
|
199
|
+
Array [
|
|
200
|
+
"Successfully retrieved mesh %s",
|
|
201
|
+
"{
|
|
202
|
+
\\"meshId\\": \\"dummy_meshId\\",
|
|
203
|
+
\\"mesh\\": {
|
|
204
|
+
\\"meshConfig\\": {
|
|
205
|
+
\\"sources\\": [
|
|
206
|
+
{
|
|
207
|
+
\\"name\\": \\"<api_name>\\",
|
|
208
|
+
\\"handler\\": {
|
|
209
|
+
\\"graphql\\": {
|
|
210
|
+
\\"endpoint\\": \\"<gql_endpoint>\\"
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
]
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}",
|
|
218
|
+
],
|
|
219
|
+
Array [
|
|
220
|
+
"Successfully wrote mesh to file %s",
|
|
221
|
+
"mesh.json",
|
|
222
|
+
],
|
|
223
|
+
]
|
|
224
|
+
`);
|
|
225
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`Array []`);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
test('should write to file if file argument is provided', async () => {
|
|
229
|
+
writeFile.mockResolvedValueOnce(true);
|
|
230
|
+
|
|
231
|
+
const file = './mesh.json';
|
|
232
|
+
parseSpy.mockResolvedValueOnce({
|
|
233
|
+
args: {
|
|
234
|
+
file,
|
|
235
|
+
},
|
|
236
|
+
flags: {
|
|
237
|
+
ignoreCache: mockIgnoreCacheFlag,
|
|
238
|
+
},
|
|
64
239
|
});
|
|
240
|
+
|
|
241
|
+
const runResult = await GetCommand.run();
|
|
242
|
+
|
|
243
|
+
expect(runResult).toEqual({ meshId: 'dummy_meshId', mesh: mockGetMeshConfig });
|
|
244
|
+
expect(writeFile.mock.calls).toMatchInlineSnapshot(`
|
|
245
|
+
Array [
|
|
246
|
+
Array [
|
|
247
|
+
"./mesh.json",
|
|
248
|
+
"{}",
|
|
249
|
+
],
|
|
250
|
+
]
|
|
251
|
+
`);
|
|
252
|
+
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
253
|
+
Array [
|
|
254
|
+
Array [
|
|
255
|
+
"Successfully retrieved mesh %s",
|
|
256
|
+
"{
|
|
257
|
+
\\"meshId\\": \\"dummy_meshId\\",
|
|
258
|
+
\\"mesh\\": {
|
|
259
|
+
\\"meshConfig\\": {
|
|
260
|
+
\\"sources\\": [
|
|
261
|
+
{
|
|
262
|
+
\\"name\\": \\"<api_name>\\",
|
|
263
|
+
\\"handler\\": {
|
|
264
|
+
\\"graphql\\": {
|
|
265
|
+
\\"endpoint\\": \\"<gql_endpoint>\\"
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
]
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}",
|
|
273
|
+
],
|
|
274
|
+
Array [
|
|
275
|
+
"Successfully wrote mesh to file %s",
|
|
276
|
+
"./mesh.json",
|
|
277
|
+
],
|
|
278
|
+
]
|
|
279
|
+
`);
|
|
280
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`Array []`);
|
|
65
281
|
});
|
|
66
282
|
|
|
67
|
-
test('should
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
283
|
+
test('should log error if failed to write to file', async () => {
|
|
284
|
+
writeFile.mockRejectedValueOnce(false);
|
|
285
|
+
|
|
286
|
+
const file = './mesh.json';
|
|
287
|
+
parseSpy.mockResolvedValueOnce({
|
|
288
|
+
args: {
|
|
289
|
+
file,
|
|
290
|
+
},
|
|
291
|
+
flags: {
|
|
292
|
+
ignoreCache: mockIgnoreCacheFlag,
|
|
293
|
+
},
|
|
294
|
+
});
|
|
295
|
+
const runResult = await GetCommand.run();
|
|
296
|
+
|
|
297
|
+
expect(runResult).toEqual({ meshId: 'dummy_meshId', mesh: mockGetMeshConfig });
|
|
298
|
+
expect(writeFile.mock.calls).toMatchInlineSnapshot(`
|
|
299
|
+
Array [
|
|
300
|
+
Array [
|
|
301
|
+
"./mesh.json",
|
|
302
|
+
"{}",
|
|
303
|
+
],
|
|
304
|
+
]
|
|
305
|
+
`);
|
|
306
|
+
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
307
|
+
Array [
|
|
308
|
+
Array [
|
|
309
|
+
"Successfully retrieved mesh %s",
|
|
310
|
+
"{
|
|
311
|
+
\\"meshId\\": \\"dummy_meshId\\",
|
|
312
|
+
\\"mesh\\": {
|
|
313
|
+
\\"meshConfig\\": {
|
|
314
|
+
\\"sources\\": [
|
|
315
|
+
{
|
|
316
|
+
\\"name\\": \\"<api_name>\\",
|
|
317
|
+
\\"handler\\": {
|
|
318
|
+
\\"graphql\\": {
|
|
319
|
+
\\"endpoint\\": \\"<gql_endpoint>\\"
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
]
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}",
|
|
327
|
+
],
|
|
328
|
+
Array [
|
|
329
|
+
"Unable to write mesh to file %s",
|
|
330
|
+
"./mesh.json",
|
|
331
|
+
],
|
|
332
|
+
]
|
|
333
|
+
`);
|
|
334
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`Array []`);
|
|
73
335
|
});
|
|
74
336
|
});
|