@adobe/aio-cli-plugin-api-mesh 1.0.3-beta → 1.1.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/README.md +61 -7
- package/oclif.manifest.json +1 -1
- package/package.json +5 -2
- 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/source/__fixtures__/0.0.1-test-01.json +44 -0
- package/src/commands/api-mesh/source/__fixtures__/0.0.1-test-02.json +44 -0
- package/src/commands/api-mesh/source/__fixtures__/connectors-metadata.json +16 -0
- package/src/commands/api-mesh/source/__tests__/discover.test.js +58 -0
- package/src/commands/api-mesh/source/__tests__/get.test.js +123 -0
- package/src/commands/api-mesh/source/discover.js +70 -0
- package/src/commands/api-mesh/source/get.js +138 -0
- package/src/commands/api-mesh/update.js +54 -26
- package/src/constants.js +21 -0
- package/src/helpers.js +213 -44
- package/src/lib/devConsole.js +746 -0
- package/src/utils.js +18 -1
- package/src/classes/SchemaServiceClient.js +0 -416
package/README.md
CHANGED
|
@@ -29,16 +29,37 @@ aio plugins:link api-mesh
|
|
|
29
29
|
|
|
30
30
|
### Configuration
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
The plugin comes out of the box with configurations for stage and prod. The plugin by default connects to PROD dev console. To connect to STAGE instead:
|
|
33
|
+
|
|
34
|
+
1. Clear your config before switching the env
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
aio config clear
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
2. Switch to stage environment
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
aio config set cli.env stage
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
#### Custom Configuration
|
|
47
|
+
|
|
48
|
+
If you want to have custom configuration instead, please follow the steps below:
|
|
49
|
+
|
|
50
|
+
1. create a config.json file with the following parameters
|
|
33
51
|
|
|
34
52
|
```
|
|
35
53
|
{
|
|
36
54
|
"baseUrl": "<base_url>",
|
|
37
|
-
"apiKey": "<api_key>"
|
|
55
|
+
"apiKey": "<api_key>",
|
|
56
|
+
"sourceRegistry: {
|
|
57
|
+
"path": "<path_to_the_source_registry_storage>"
|
|
58
|
+
}
|
|
38
59
|
}
|
|
39
60
|
```
|
|
40
61
|
|
|
41
|
-
Perform the following command to update the configuration
|
|
62
|
+
2. Perform the following command to update the configuration
|
|
42
63
|
|
|
43
64
|
```
|
|
44
65
|
aio config:set api-mesh.configPath <path_to_json_file>
|
|
@@ -48,9 +69,42 @@ aio config:set api-mesh.configPath <path_to_json_file>
|
|
|
48
69
|
|
|
49
70
|
```
|
|
50
71
|
aio api-mesh:describe
|
|
51
|
-
aio api-mesh:get
|
|
52
|
-
aio api-mesh:get
|
|
72
|
+
aio api-mesh:get
|
|
73
|
+
aio api-mesh:get PATH_OF_FILE_TO_DOWNLOAD_INTO
|
|
53
74
|
aio api-mesh:create PATH_OF_MESH_CONFIG_JSON_FILE
|
|
54
|
-
aio api-mesh:update
|
|
55
|
-
aio api-mesh:delete
|
|
75
|
+
aio api-mesh:update PATH_OF_MESH_CONFIG_JSON_FILE
|
|
76
|
+
aio api-mesh:delete
|
|
56
77
|
```
|
|
78
|
+
|
|
79
|
+
All commands support `-i` or `--ignoreCache` flag that will force the CLI to ignore the cached Org, Project and Workspace details and prompt the user to select new options just for that action.
|
|
80
|
+
|
|
81
|
+
Create, Update and Delete support `-c` or `--autoConfirmAction` flag that will not prompt the user for action confirmation mostly used for testing or scaffolding where user prompt can not be handled. This flag is only to be used in certain situations.
|
|
82
|
+
|
|
83
|
+
# Sources Registry
|
|
84
|
+
|
|
85
|
+
Source registry is a collection of predefined sources (API mesh source configurations) that are created to solve specific use cases. The source can be installed for customer-specific API mesh configuration.
|
|
86
|
+
|
|
87
|
+
To submit a new source, please follow the instructions provided in the [Source Registry](https://github.com/adobe/api-mesh-sources/) repository.
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
## Commands
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
aio api-mesh:source:get
|
|
94
|
+
NAME_OF_THE_SOURCE
|
|
95
|
+
aio api-mesh:source:get NAME_OF_THE_SOURCE@VERSION_OF_THE_SOURCE
|
|
96
|
+
aio api-mesh:source:get -m
|
|
97
|
+
aio api-mesh:source:discover
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The "source:get" command accept multiple sources per one call.
|
|
101
|
+
|
|
102
|
+
Example:
|
|
103
|
+
```
|
|
104
|
+
aio api-mesh:source:get -m <NAME_OF_THE_SOURCE>@<VERSION_OF_THE_SOURC><NAME_OF_THE_SECOND_SOURCE>@<VERSION_OF_THE_SOURC>
|
|
105
|
+
<NAME_OF_THE_THIRD_SOURCE>@<VERSION_OF_THE_SOURC>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
All commands support `-i` or `--ignoreCache` flag that will force the CLI to ignore the cached Org, Project and Workspace details and prompt the user to select new options just for that action.
|
|
109
|
+
|
|
110
|
+
Create, Update and Delete support `-c` or `--autoConfirmAction` flag that will not prompt the user for action confirmation mostly used for testing or scaffolding where user prompt can not be handled. This flag is only to be used in certain situations.
|
package/oclif.manifest.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"1.0
|
|
1
|
+
{"version":"1.1.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}},"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: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}},"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":{},"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 <version>@<source_name>","$ aio api-mesh:source:get <source_name>","$ aio api-mesh:source:get -m"],"flags":{"source":{"name":"source","type":"option","char":"s","description":"Source name"},"multiple":{"name":"multiple","type":"boolean","char":"m","description":"Select multiple sources","allowNo":false}},"args":[]}}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/aio-cli-plugin-api-mesh",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -12,12 +12,16 @@
|
|
|
12
12
|
"@adobe/aio-lib-ims": "^5.0.1",
|
|
13
13
|
"@oclif/command": "^1.6.1",
|
|
14
14
|
"@oclif/config": "^1.15.1",
|
|
15
|
+
"@oclif/core": "^1.14.1",
|
|
15
16
|
"@oclif/errors": "^1.1.2",
|
|
16
17
|
"axios": "^0.23.0",
|
|
18
|
+
"chalk": "^4.1.0",
|
|
17
19
|
"dotenv": "^16.0.1",
|
|
18
20
|
"inquirer": "^8.2.4",
|
|
21
|
+
"node-clipboardy": "^1.0.3",
|
|
19
22
|
"pino": "^7.9.2",
|
|
20
23
|
"pino-pretty": "^7.6.0",
|
|
24
|
+
"source-registry-storage-adapter": "github:devx-services/source-registry-storage-adapter#main",
|
|
21
25
|
"uuid": "^8.3.2"
|
|
22
26
|
},
|
|
23
27
|
"devDependencies": {
|
|
@@ -27,7 +31,6 @@
|
|
|
27
31
|
"@oclif/plugin-help": "2.2.3",
|
|
28
32
|
"@trivago/prettier-plugin-sort-imports": "^3.1.1",
|
|
29
33
|
"acorn": "7.4.1",
|
|
30
|
-
"chalk": "4.1.2",
|
|
31
34
|
"eslint": "7.28.0",
|
|
32
35
|
"eslint-config-oclif": "^3.1.0",
|
|
33
36
|
"eslint-config-prettier": "^8.3.0",
|
|
@@ -12,64 +12,477 @@ governing permissions and limitations under the License.
|
|
|
12
12
|
|
|
13
13
|
const mockConsoleCLIInstance = {};
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
const CreateCommand = require('../create');
|
|
16
|
+
const sampleCreateMeshConfig = require('../../__fixtures__/sample_mesh.json');
|
|
17
|
+
const { initSdk, initRequestId, promptConfirm } = require('../../../helpers');
|
|
18
|
+
const {
|
|
19
|
+
createMesh,
|
|
20
|
+
createAPIMeshCredentials,
|
|
21
|
+
subscribeCredentialToMeshService,
|
|
22
|
+
} = require('../../../lib/devConsole');
|
|
17
23
|
|
|
18
|
-
const orgs = [{ id: '1234', code: 'CODE1234@AdobeOrg', name: 'ORG01', type: 'entp' }];
|
|
19
24
|
const selectedOrg = { id: '1234', code: 'CODE1234@AdobeOrg', name: 'ORG01', type: 'entp' };
|
|
20
25
|
|
|
21
|
-
const projects = [{ id: '5678', title: 'Project01' }];
|
|
22
26
|
const selectedProject = { id: '5678', title: 'Project01' };
|
|
23
27
|
|
|
24
|
-
const workspaces = [{ id: '123456789', title: 'Workspace01' }];
|
|
25
28
|
const selectedWorkspace = { id: '123456789', title: 'Workspace01' };
|
|
26
29
|
|
|
27
|
-
function setDefaultMockConsoleCLI() {
|
|
28
|
-
mockConsoleCLIInstance.getToken = jest.fn().mockReturnValue('test_token');
|
|
29
|
-
mockConsoleCLIInstance.getCliEnv = jest.fn().mockReturnValue('prod');
|
|
30
|
-
|
|
31
|
-
mockConsoleCLIInstance.getOrganizations = jest.fn().mockResolvedValue(orgs);
|
|
32
|
-
mockConsoleCLIInstance.promptForSelectOrganization = jest.fn().mockResolvedValue(selectedOrg);
|
|
33
|
-
|
|
34
|
-
mockConsoleCLIInstance.getProjects = jest.fn().mockResolvedValue(projects);
|
|
35
|
-
mockConsoleCLIInstance.promptForSelectProject = jest.fn().mockResolvedValue(selectedProject);
|
|
36
|
-
|
|
37
|
-
mockConsoleCLIInstance.getWorkspaces = jest.fn().mockResolvedValue(workspaces);
|
|
38
|
-
mockConsoleCLIInstance.promptForSelectWorkspace = jest.fn().mockResolvedValue(selectedWorkspace);
|
|
39
|
-
}
|
|
40
30
|
jest.mock('@adobe/aio-cli-lib-console', () => ({
|
|
41
31
|
init: jest.fn().mockResolvedValue(mockConsoleCLIInstance),
|
|
42
32
|
cleanStdOut: jest.fn(),
|
|
43
33
|
}));
|
|
34
|
+
|
|
35
|
+
jest.mock('axios');
|
|
44
36
|
jest.mock('@adobe/aio-lib-ims');
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
37
|
+
jest.mock('@adobe/aio-lib-env');
|
|
38
|
+
jest.mock('@adobe/aio-cli-lib-console');
|
|
39
|
+
jest.mock('../../../helpers', () => ({
|
|
40
|
+
initSdk: jest.fn().mockResolvedValue({}),
|
|
41
|
+
initRequestId: jest.fn().mockResolvedValue({}),
|
|
42
|
+
promptConfirm: jest.fn().mockResolvedValue(true),
|
|
43
|
+
}));
|
|
44
|
+
jest.mock('../../../lib/devConsole');
|
|
45
|
+
|
|
46
|
+
let logSpy = null;
|
|
47
|
+
let errorLogSpy = null;
|
|
48
|
+
|
|
49
|
+
let parseSpy = null;
|
|
50
|
+
|
|
51
|
+
const mockIgnoreCacheFlag = Promise.resolve(true);
|
|
52
|
+
const mockAutoApproveAction = Promise.resolve(false);
|
|
48
53
|
|
|
49
54
|
describe('create command tests', () => {
|
|
50
55
|
beforeEach(() => {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
56
|
+
initSdk.mockResolvedValue({
|
|
57
|
+
imsOrgId: selectedOrg.id,
|
|
58
|
+
projectId: selectedProject.id,
|
|
59
|
+
workspaceId: selectedWorkspace.id,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
global.requestId = 'dummy_request_id';
|
|
63
|
+
|
|
64
|
+
logSpy = jest.spyOn(CreateCommand.prototype, 'log');
|
|
65
|
+
errorLogSpy = jest.spyOn(CreateCommand.prototype, 'error');
|
|
66
|
+
|
|
67
|
+
createMesh.mockResolvedValue({
|
|
68
|
+
meshId: 'dummy_mesh_id',
|
|
69
|
+
meshConfig: sampleCreateMeshConfig.meshConfig,
|
|
70
|
+
});
|
|
71
|
+
createAPIMeshCredentials.mockResolvedValue({
|
|
72
|
+
apiKey: 'dummy_api_key',
|
|
73
|
+
id: 'dummy_id',
|
|
74
|
+
});
|
|
75
|
+
subscribeCredentialToMeshService.mockResolvedValue(['dummy_service']);
|
|
76
|
+
|
|
77
|
+
parseSpy = jest.spyOn(CreateCommand.prototype, 'parse');
|
|
78
|
+
parseSpy.mockResolvedValue({
|
|
79
|
+
args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
|
|
80
|
+
flags: {
|
|
81
|
+
ignoreCache: mockIgnoreCacheFlag,
|
|
82
|
+
autoConfirmAction: mockAutoApproveAction,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
54
85
|
});
|
|
55
86
|
|
|
56
87
|
afterEach(() => {
|
|
57
88
|
jest.restoreAllMocks();
|
|
58
89
|
});
|
|
59
90
|
|
|
60
|
-
test('
|
|
61
|
-
expect.
|
|
62
|
-
|
|
63
|
-
|
|
91
|
+
test('snapshot create command description', () => {
|
|
92
|
+
expect(CreateCommand.description).toMatchInlineSnapshot(
|
|
93
|
+
`"Create a mesh with the given config."`,
|
|
94
|
+
);
|
|
95
|
+
expect(CreateCommand.args).toMatchInlineSnapshot(`
|
|
96
|
+
Array [
|
|
97
|
+
Object {
|
|
98
|
+
"name": "file",
|
|
99
|
+
},
|
|
100
|
+
]
|
|
101
|
+
`);
|
|
102
|
+
expect(CreateCommand.flags).toMatchInlineSnapshot(`
|
|
103
|
+
Object {
|
|
104
|
+
"autoConfirmAction": Object {
|
|
105
|
+
"allowNo": false,
|
|
106
|
+
"char": "c",
|
|
107
|
+
"default": false,
|
|
108
|
+
"description": "Auto confirm action prompt. CLI will not check for user approval before executing the action.",
|
|
109
|
+
"parse": [Function],
|
|
110
|
+
"type": "boolean",
|
|
111
|
+
},
|
|
112
|
+
"ignoreCache": Object {
|
|
113
|
+
"allowNo": false,
|
|
114
|
+
"char": "i",
|
|
115
|
+
"default": false,
|
|
116
|
+
"description": "Ignore cache and force manual org -> project -> workspace selection",
|
|
117
|
+
"parse": [Function],
|
|
118
|
+
"type": "boolean",
|
|
119
|
+
},
|
|
120
|
+
}
|
|
121
|
+
`);
|
|
122
|
+
expect(CreateCommand.aliases).toMatchInlineSnapshot(`Array []`);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test('should fail if mesh config file arg is missing', async () => {
|
|
126
|
+
parseSpy.mockResolvedValueOnce({
|
|
127
|
+
args: {},
|
|
128
|
+
flags: {
|
|
129
|
+
ignoreCache: mockIgnoreCacheFlag,
|
|
130
|
+
autoConfirmAction: mockAutoApproveAction,
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
const runResult = CreateCommand.run();
|
|
134
|
+
|
|
64
135
|
await expect(runResult).rejects.toEqual(
|
|
65
136
|
new Error('Missing file path. Run aio api-mesh create --help for more info.'),
|
|
66
137
|
);
|
|
138
|
+
expect(logSpy.mock.calls).toMatchInlineSnapshot(`Array []`);
|
|
139
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
|
|
140
|
+
Array [
|
|
141
|
+
Array [
|
|
142
|
+
"Missing file path. Run aio api-mesh create --help for more info.",
|
|
143
|
+
],
|
|
144
|
+
]
|
|
145
|
+
`);
|
|
67
146
|
});
|
|
68
147
|
|
|
69
|
-
test('
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
148
|
+
test('should fail if mesh file is invalid', async () => {
|
|
149
|
+
parseSpy.mockResolvedValueOnce({
|
|
150
|
+
args: { file: 'dummy_file_path' },
|
|
151
|
+
flags: {
|
|
152
|
+
ignoreCache: mockIgnoreCacheFlag,
|
|
153
|
+
autoConfirmAction: mockAutoApproveAction,
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
const runResult = CreateCommand.run();
|
|
157
|
+
|
|
158
|
+
await expect(runResult).rejects.toEqual(
|
|
159
|
+
new Error(
|
|
160
|
+
'Unable to read the mesh configuration file provided. Please check the file and try again.',
|
|
161
|
+
),
|
|
162
|
+
);
|
|
163
|
+
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
164
|
+
Array [
|
|
165
|
+
Array [
|
|
166
|
+
"ENOENT: no such file or directory, open 'dummy_file_path'",
|
|
167
|
+
],
|
|
168
|
+
]
|
|
169
|
+
`);
|
|
170
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
|
|
171
|
+
Array [
|
|
172
|
+
Array [
|
|
173
|
+
"Unable to read the mesh configuration file provided. Please check the file and try again.",
|
|
174
|
+
],
|
|
175
|
+
]
|
|
176
|
+
`);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
test('should fail if create mesh api has failed', async () => {
|
|
180
|
+
createMesh.mockRejectedValueOnce(new Error('create mesh api failed'));
|
|
181
|
+
|
|
182
|
+
const runResult = CreateCommand.run();
|
|
183
|
+
|
|
184
|
+
await expect(runResult).rejects.toEqual(
|
|
185
|
+
new Error(
|
|
186
|
+
'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',
|
|
187
|
+
),
|
|
188
|
+
);
|
|
189
|
+
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
190
|
+
Array [
|
|
191
|
+
Array [
|
|
192
|
+
"create mesh api failed",
|
|
193
|
+
],
|
|
194
|
+
]
|
|
195
|
+
`);
|
|
196
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
|
|
197
|
+
Array [
|
|
198
|
+
Array [
|
|
199
|
+
"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",
|
|
200
|
+
],
|
|
201
|
+
]
|
|
202
|
+
`);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
test('should fail if create api credential api has failed', async () => {
|
|
206
|
+
createAPIMeshCredentials.mockRejectedValueOnce(new Error('create api credential api failed'));
|
|
207
|
+
|
|
208
|
+
const runResult = CreateCommand.run();
|
|
209
|
+
|
|
210
|
+
await expect(runResult).rejects.toEqual(
|
|
211
|
+
new Error(
|
|
212
|
+
'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',
|
|
213
|
+
),
|
|
214
|
+
);
|
|
215
|
+
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
216
|
+
Array [
|
|
217
|
+
Array [
|
|
218
|
+
"Successfully created mesh %s",
|
|
219
|
+
"dummy_mesh_id",
|
|
220
|
+
],
|
|
221
|
+
Array [
|
|
222
|
+
"{
|
|
223
|
+
\\"meshId\\": \\"dummy_mesh_id\\",
|
|
224
|
+
\\"meshConfig\\": {
|
|
225
|
+
\\"sources\\": [
|
|
226
|
+
{
|
|
227
|
+
\\"name\\": \\"<api_name>\\",
|
|
228
|
+
\\"handler\\": {
|
|
229
|
+
\\"graphql\\": {
|
|
230
|
+
\\"endpoint\\": \\"<gql_endpoint>\\"
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
]
|
|
235
|
+
}
|
|
236
|
+
}",
|
|
237
|
+
],
|
|
238
|
+
Array [
|
|
239
|
+
"create api credential api failed",
|
|
240
|
+
],
|
|
241
|
+
]
|
|
242
|
+
`);
|
|
243
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
|
|
244
|
+
Array [
|
|
245
|
+
Array [
|
|
246
|
+
"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",
|
|
247
|
+
],
|
|
248
|
+
]
|
|
249
|
+
`);
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
test('should fail if subscribe credential to mesh service api has failed', async () => {
|
|
253
|
+
subscribeCredentialToMeshService.mockRejectedValueOnce(
|
|
254
|
+
new Error('subscribe credential to mesh service api failed'),
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
const runResult = CreateCommand.run();
|
|
258
|
+
|
|
259
|
+
await expect(runResult).rejects.toEqual(
|
|
260
|
+
new Error(
|
|
261
|
+
'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',
|
|
262
|
+
),
|
|
263
|
+
);
|
|
264
|
+
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
265
|
+
Array [
|
|
266
|
+
Array [
|
|
267
|
+
"Successfully created mesh %s",
|
|
268
|
+
"dummy_mesh_id",
|
|
269
|
+
],
|
|
270
|
+
Array [
|
|
271
|
+
"{
|
|
272
|
+
\\"meshId\\": \\"dummy_mesh_id\\",
|
|
273
|
+
\\"meshConfig\\": {
|
|
274
|
+
\\"sources\\": [
|
|
275
|
+
{
|
|
276
|
+
\\"name\\": \\"<api_name>\\",
|
|
277
|
+
\\"handler\\": {
|
|
278
|
+
\\"graphql\\": {
|
|
279
|
+
\\"endpoint\\": \\"<gql_endpoint>\\"
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
]
|
|
284
|
+
}
|
|
285
|
+
}",
|
|
286
|
+
],
|
|
287
|
+
Array [
|
|
288
|
+
"Successfully created API Key %s",
|
|
289
|
+
"dummy_api_key",
|
|
290
|
+
],
|
|
291
|
+
Array [
|
|
292
|
+
"subscribe credential to mesh service api failed",
|
|
293
|
+
],
|
|
294
|
+
]
|
|
295
|
+
`);
|
|
296
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
|
|
297
|
+
Array [
|
|
298
|
+
Array [
|
|
299
|
+
"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",
|
|
300
|
+
],
|
|
301
|
+
]
|
|
302
|
+
`);
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
test('should create if a valid mesh config file is provided', async () => {
|
|
306
|
+
const runResult = await CreateCommand.run();
|
|
307
|
+
|
|
308
|
+
expect(initRequestId).toHaveBeenCalled();
|
|
309
|
+
expect(createMesh.mock.calls[0]).toMatchInlineSnapshot(`
|
|
310
|
+
Array [
|
|
311
|
+
"1234",
|
|
312
|
+
"5678",
|
|
313
|
+
"123456789",
|
|
314
|
+
Object {
|
|
315
|
+
"meshConfig": Object {
|
|
316
|
+
"sources": Array [
|
|
317
|
+
Object {
|
|
318
|
+
"handler": Object {
|
|
319
|
+
"graphql": Object {
|
|
320
|
+
"endpoint": "<gql_endpoint>",
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
"name": "<api_name>",
|
|
324
|
+
},
|
|
325
|
+
],
|
|
326
|
+
},
|
|
327
|
+
},
|
|
328
|
+
]
|
|
329
|
+
`);
|
|
330
|
+
expect(createAPIMeshCredentials.mock.calls[0]).toMatchInlineSnapshot(`
|
|
331
|
+
Array [
|
|
332
|
+
"1234",
|
|
333
|
+
"5678",
|
|
334
|
+
"123456789",
|
|
335
|
+
]
|
|
336
|
+
`);
|
|
337
|
+
expect(subscribeCredentialToMeshService.mock.calls[0]).toMatchInlineSnapshot(`
|
|
338
|
+
Array [
|
|
339
|
+
"1234",
|
|
340
|
+
"5678",
|
|
341
|
+
"123456789",
|
|
342
|
+
"dummy_id",
|
|
343
|
+
]
|
|
344
|
+
`);
|
|
345
|
+
expect(runResult).toMatchInlineSnapshot(`
|
|
346
|
+
Object {
|
|
347
|
+
"adobeIdIntegrationsForWorkspace": Object {
|
|
348
|
+
"apiKey": "dummy_api_key",
|
|
349
|
+
"id": "dummy_id",
|
|
350
|
+
},
|
|
351
|
+
"mesh": Object {
|
|
352
|
+
"meshConfig": Object {
|
|
353
|
+
"sources": Array [
|
|
354
|
+
Object {
|
|
355
|
+
"handler": Object {
|
|
356
|
+
"graphql": Object {
|
|
357
|
+
"endpoint": "<gql_endpoint>",
|
|
358
|
+
},
|
|
359
|
+
},
|
|
360
|
+
"name": "<api_name>",
|
|
361
|
+
},
|
|
362
|
+
],
|
|
363
|
+
},
|
|
364
|
+
"meshId": "dummy_mesh_id",
|
|
365
|
+
},
|
|
366
|
+
"sdkList": Array [
|
|
367
|
+
"dummy_service",
|
|
368
|
+
],
|
|
369
|
+
}
|
|
370
|
+
`);
|
|
371
|
+
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
372
|
+
Array [
|
|
373
|
+
Array [
|
|
374
|
+
"Successfully created mesh %s",
|
|
375
|
+
"dummy_mesh_id",
|
|
376
|
+
],
|
|
377
|
+
Array [
|
|
378
|
+
"{
|
|
379
|
+
\\"meshId\\": \\"dummy_mesh_id\\",
|
|
380
|
+
\\"meshConfig\\": {
|
|
381
|
+
\\"sources\\": [
|
|
382
|
+
{
|
|
383
|
+
\\"name\\": \\"<api_name>\\",
|
|
384
|
+
\\"handler\\": {
|
|
385
|
+
\\"graphql\\": {
|
|
386
|
+
\\"endpoint\\": \\"<gql_endpoint>\\"
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
]
|
|
391
|
+
}
|
|
392
|
+
}",
|
|
393
|
+
],
|
|
394
|
+
Array [
|
|
395
|
+
"Successfully created API Key %s",
|
|
396
|
+
"dummy_api_key",
|
|
397
|
+
],
|
|
398
|
+
Array [
|
|
399
|
+
"Successfully subscribed API Key %s to API Mesh service",
|
|
400
|
+
"dummy_api_key",
|
|
401
|
+
],
|
|
402
|
+
Array [
|
|
403
|
+
"Mesh Endpoint: %s
|
|
404
|
+
",
|
|
405
|
+
"https://graph.adobe.io/api/dummy_mesh_id/graphql?api_key=dummy_api_key",
|
|
406
|
+
],
|
|
407
|
+
]
|
|
408
|
+
`);
|
|
409
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`Array []`);
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
test('should not ask for confirmation if autoConfirmAction is provided', async () => {
|
|
413
|
+
parseSpy.mockResolvedValueOnce({
|
|
414
|
+
args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
|
|
415
|
+
flags: {
|
|
416
|
+
ignoreCache: mockIgnoreCacheFlag,
|
|
417
|
+
autoConfirmAction: Promise.resolve(true),
|
|
418
|
+
},
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
await CreateCommand.run();
|
|
422
|
+
|
|
423
|
+
expect(initRequestId).toHaveBeenCalled();
|
|
424
|
+
expect(promptConfirm).not.toHaveBeenCalled();
|
|
425
|
+
expect(initSdk).toHaveBeenCalledWith({
|
|
426
|
+
ignoreCache: true,
|
|
427
|
+
});
|
|
428
|
+
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
429
|
+
Array [
|
|
430
|
+
Array [
|
|
431
|
+
"Successfully created mesh %s",
|
|
432
|
+
"dummy_mesh_id",
|
|
433
|
+
],
|
|
434
|
+
Array [
|
|
435
|
+
"{
|
|
436
|
+
\\"meshId\\": \\"dummy_mesh_id\\",
|
|
437
|
+
\\"meshConfig\\": {
|
|
438
|
+
\\"sources\\": [
|
|
439
|
+
{
|
|
440
|
+
\\"name\\": \\"<api_name>\\",
|
|
441
|
+
\\"handler\\": {
|
|
442
|
+
\\"graphql\\": {
|
|
443
|
+
\\"endpoint\\": \\"<gql_endpoint>\\"
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
]
|
|
448
|
+
}
|
|
449
|
+
}",
|
|
450
|
+
],
|
|
451
|
+
Array [
|
|
452
|
+
"Successfully created API Key %s",
|
|
453
|
+
"dummy_api_key",
|
|
454
|
+
],
|
|
455
|
+
Array [
|
|
456
|
+
"Successfully subscribed API Key %s to API Mesh service",
|
|
457
|
+
"dummy_api_key",
|
|
458
|
+
],
|
|
459
|
+
Array [
|
|
460
|
+
"Mesh Endpoint: %s
|
|
461
|
+
",
|
|
462
|
+
"https://graph.adobe.io/api/dummy_mesh_id/graphql?api_key=dummy_api_key",
|
|
463
|
+
],
|
|
464
|
+
]
|
|
465
|
+
`);
|
|
466
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`Array []`);
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
test('should stop creation if user declines confirmation', async () => {
|
|
470
|
+
promptConfirm.mockResolvedValueOnce(false);
|
|
471
|
+
|
|
472
|
+
await CreateCommand.run();
|
|
473
|
+
|
|
474
|
+
expect(initRequestId).toHaveBeenCalled();
|
|
475
|
+
expect(promptConfirm).toHaveBeenCalled();
|
|
476
|
+
expect(initSdk).toHaveBeenCalledWith({
|
|
477
|
+
ignoreCache: true,
|
|
478
|
+
});
|
|
479
|
+
expect(logSpy.mock.calls).toMatchInlineSnapshot(`
|
|
480
|
+
Array [
|
|
481
|
+
Array [
|
|
482
|
+
"Create cancelled",
|
|
483
|
+
],
|
|
484
|
+
]
|
|
485
|
+
`);
|
|
486
|
+
expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`Array []`);
|
|
74
487
|
});
|
|
75
488
|
});
|