bbk-cli 1.0.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/.claude/bitbucket-config.local.md.example +58 -0
- package/.eslintcache +1 -0
- package/.github/dependabot.yml +15 -0
- package/.github/workflows/convetional-commit.yml +24 -0
- package/.github/workflows/publish-on-tag.yml +47 -0
- package/.github/workflows/release-please.yml +21 -0
- package/.github/workflows/run-tests.yml +75 -0
- package/.nvmrc +1 -0
- package/.prettierignore +2 -0
- package/.prettierrc.cjs +17 -0
- package/.release-please-manifest.json +3 -0
- package/CHANGELOG.md +21 -0
- package/LICENSE +202 -0
- package/README.md +381 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/wrapper.d.ts +38 -0
- package/dist/cli/wrapper.d.ts.map +1 -0
- package/dist/cli/wrapper.js +326 -0
- package/dist/cli/wrapper.js.map +1 -0
- package/dist/commands/helpers.d.ts +11 -0
- package/dist/commands/helpers.d.ts.map +1 -0
- package/dist/commands/helpers.js +40 -0
- package/dist/commands/helpers.js.map +1 -0
- package/dist/commands/index.d.ts +3 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +3 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/runner.d.ts +7 -0
- package/dist/commands/runner.d.ts.map +1 -0
- package/dist/commands/runner.js +126 -0
- package/dist/commands/runner.js.map +1 -0
- package/dist/config/constants.d.ts +16 -0
- package/dist/config/constants.d.ts.map +1 -0
- package/dist/config/constants.js +171 -0
- package/dist/config/constants.js.map +1 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +2 -0
- package/dist/config/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/arg-parser.d.ts +7 -0
- package/dist/utils/arg-parser.d.ts.map +1 -0
- package/dist/utils/arg-parser.js +67 -0
- package/dist/utils/arg-parser.js.map +1 -0
- package/dist/utils/bitbucket-client.d.ts +122 -0
- package/dist/utils/bitbucket-client.d.ts.map +1 -0
- package/dist/utils/bitbucket-client.js +182 -0
- package/dist/utils/bitbucket-client.js.map +1 -0
- package/dist/utils/bitbucket-utils.d.ts +110 -0
- package/dist/utils/bitbucket-utils.d.ts.map +1 -0
- package/dist/utils/bitbucket-utils.js +491 -0
- package/dist/utils/bitbucket-utils.js.map +1 -0
- package/dist/utils/config-loader.d.ts +41 -0
- package/dist/utils/config-loader.d.ts.map +1 -0
- package/dist/utils/config-loader.js +76 -0
- package/dist/utils/config-loader.js.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/eslint.config.ts +15 -0
- package/package.json +62 -0
- package/release-please-config.json +33 -0
- package/tests/integration/cli-integration.test.ts +528 -0
- package/tests/unit/cli/wrapper.test.ts +727 -0
- package/tests/unit/commands/helpers.test.ts +268 -0
- package/tests/unit/commands/runner.test.ts +758 -0
- package/tests/unit/utils/arg-parser.test.ts +350 -0
- package/tests/unit/utils/config-loader.test.ts +158 -0
- package/vitest.config.ts +22 -0
|
@@ -0,0 +1,758 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { runCommand } from '../../../src/commands/runner.js';
|
|
4
|
+
|
|
5
|
+
// Mock the utils module
|
|
6
|
+
vi.mock('../../../src/utils/index.js', () => ({
|
|
7
|
+
listRepositories: vi.fn(),
|
|
8
|
+
getRepository: vi.fn(),
|
|
9
|
+
listPullRequests: vi.fn(),
|
|
10
|
+
getPullRequest: vi.fn(),
|
|
11
|
+
createPullRequest: vi.fn(),
|
|
12
|
+
listBranches: vi.fn(),
|
|
13
|
+
listCommits: vi.fn(),
|
|
14
|
+
listIssues: vi.fn(),
|
|
15
|
+
getIssue: vi.fn(),
|
|
16
|
+
createIssue: vi.fn(),
|
|
17
|
+
listPipelines: vi.fn(),
|
|
18
|
+
getUser: vi.fn(),
|
|
19
|
+
testConnection: vi.fn(),
|
|
20
|
+
loadConfig: vi.fn(),
|
|
21
|
+
clearClients: vi.fn(),
|
|
22
|
+
}));
|
|
23
|
+
|
|
24
|
+
// Mock process.env
|
|
25
|
+
const originalEnv = process.env;
|
|
26
|
+
|
|
27
|
+
describe('commands/runner', () => {
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
vi.clearAllMocks();
|
|
30
|
+
process.env = { ...originalEnv };
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
afterEach(() => {
|
|
34
|
+
process.env = originalEnv;
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe('runCommand', () => {
|
|
38
|
+
it('should execute list-repositories command', async () => {
|
|
39
|
+
const { listRepositories, loadConfig, clearClients } = await import('../../../src/utils/index.js');
|
|
40
|
+
loadConfig.mockReturnValue({
|
|
41
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
42
|
+
defaultProfile: 'cloud',
|
|
43
|
+
defaultFormat: 'json',
|
|
44
|
+
});
|
|
45
|
+
listRepositories.mockResolvedValue({ success: true, result: '{"repositories": []}' });
|
|
46
|
+
|
|
47
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
48
|
+
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
49
|
+
const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
50
|
+
|
|
51
|
+
await runCommand('list-repositories', '{"workspace":"myworkspace"}', null);
|
|
52
|
+
|
|
53
|
+
expect(loadConfig).toHaveBeenCalled();
|
|
54
|
+
expect(listRepositories).toHaveBeenCalledWith('cloud', 'myworkspace', 'json');
|
|
55
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('{"repositories": []}');
|
|
56
|
+
expect(clearClients).toHaveBeenCalled();
|
|
57
|
+
expect(exitSpy).toHaveBeenCalledWith(0);
|
|
58
|
+
|
|
59
|
+
exitSpy.mockRestore();
|
|
60
|
+
consoleLogSpy.mockRestore();
|
|
61
|
+
consoleErrorSpy.mockRestore();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('should execute list-repositories with custom profile and format', async () => {
|
|
65
|
+
const { listRepositories, loadConfig } = await import('../../../src/utils/index.js');
|
|
66
|
+
loadConfig.mockReturnValue({
|
|
67
|
+
profiles: {
|
|
68
|
+
cloud: { username: 'test@test.com', password: 'password123' },
|
|
69
|
+
staging: { username: 'staging@test.com', password: 'staging-password' },
|
|
70
|
+
},
|
|
71
|
+
defaultProfile: 'cloud',
|
|
72
|
+
defaultFormat: 'json',
|
|
73
|
+
});
|
|
74
|
+
listRepositories.mockResolvedValue({ success: true, result: '{"repositories": []}' });
|
|
75
|
+
|
|
76
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
77
|
+
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
78
|
+
|
|
79
|
+
await runCommand('list-repositories', '{"workspace":"myworkspace","profile":"staging","format":"toon"}', null);
|
|
80
|
+
|
|
81
|
+
expect(listRepositories).toHaveBeenCalledWith('staging', 'myworkspace', 'toon');
|
|
82
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('{"repositories": []}');
|
|
83
|
+
expect(exitSpy).toHaveBeenCalledWith(0);
|
|
84
|
+
|
|
85
|
+
exitSpy.mockRestore();
|
|
86
|
+
consoleLogSpy.mockRestore();
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('should execute get-repository command with workspace and repoSlug', async () => {
|
|
90
|
+
const { getRepository, loadConfig } = await import('../../../src/utils/index.js');
|
|
91
|
+
loadConfig.mockReturnValue({
|
|
92
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
93
|
+
defaultProfile: 'cloud',
|
|
94
|
+
defaultFormat: 'json',
|
|
95
|
+
});
|
|
96
|
+
getRepository.mockResolvedValue({ success: true, result: '{"name":"my-repo"}' });
|
|
97
|
+
|
|
98
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
99
|
+
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
100
|
+
const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
101
|
+
|
|
102
|
+
await runCommand('get-repository', '{"workspace":"myworkspace","repoSlug":"my-repo"}', null);
|
|
103
|
+
|
|
104
|
+
expect(getRepository).toHaveBeenCalledWith('cloud', 'myworkspace', 'my-repo', 'json');
|
|
105
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('{"name":"my-repo"}');
|
|
106
|
+
expect(consoleErrorSpy).not.toHaveBeenCalled();
|
|
107
|
+
expect(exitSpy).toHaveBeenCalledWith(0);
|
|
108
|
+
|
|
109
|
+
exitSpy.mockRestore();
|
|
110
|
+
consoleLogSpy.mockRestore();
|
|
111
|
+
consoleErrorSpy.mockRestore();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('should exit with error if get-repository missing parameters', async () => {
|
|
115
|
+
const { loadConfig } = await import('../../../src/utils/index.js');
|
|
116
|
+
loadConfig.mockReturnValue({
|
|
117
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
118
|
+
defaultProfile: 'cloud',
|
|
119
|
+
defaultFormat: 'json',
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
123
|
+
const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
124
|
+
|
|
125
|
+
await runCommand('get-repository', '{}', null);
|
|
126
|
+
|
|
127
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith('ERROR: "workspace" and "repoSlug" parameters are required');
|
|
128
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
129
|
+
|
|
130
|
+
exitSpy.mockRestore();
|
|
131
|
+
consoleErrorSpy.mockRestore();
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('should execute list-pullrequests command with all parameters', async () => {
|
|
135
|
+
const { listPullRequests, loadConfig } = await import('../../../src/utils/index.js');
|
|
136
|
+
loadConfig.mockReturnValue({
|
|
137
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
138
|
+
defaultProfile: 'cloud',
|
|
139
|
+
defaultFormat: 'json',
|
|
140
|
+
});
|
|
141
|
+
listPullRequests.mockResolvedValue({ success: true, result: '{"pullrequests": []}' });
|
|
142
|
+
|
|
143
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
144
|
+
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
145
|
+
|
|
146
|
+
await runCommand('list-pullrequests', '{"workspace":"myworkspace","repoSlug":"my-repo","state":"OPEN"}', null);
|
|
147
|
+
|
|
148
|
+
expect(listPullRequests).toHaveBeenCalledWith('cloud', 'myworkspace', 'my-repo', 'OPEN', 'json');
|
|
149
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('{"pullrequests": []}');
|
|
150
|
+
expect(exitSpy).toHaveBeenCalledWith(0);
|
|
151
|
+
|
|
152
|
+
exitSpy.mockRestore();
|
|
153
|
+
consoleLogSpy.mockRestore();
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('should execute list-pullrequests with minimal parameters', async () => {
|
|
157
|
+
const { listPullRequests, loadConfig } = await import('../../../src/utils/index.js');
|
|
158
|
+
loadConfig.mockReturnValue({
|
|
159
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
160
|
+
defaultProfile: 'cloud',
|
|
161
|
+
defaultFormat: 'json',
|
|
162
|
+
});
|
|
163
|
+
listPullRequests.mockResolvedValue({ success: true, result: '{"pullrequests": []}' });
|
|
164
|
+
|
|
165
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
166
|
+
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
167
|
+
|
|
168
|
+
await runCommand('list-pullrequests', '{"workspace":"myworkspace","repoSlug":"my-repo"}', null);
|
|
169
|
+
|
|
170
|
+
expect(listPullRequests).toHaveBeenCalledWith('cloud', 'myworkspace', 'my-repo', undefined, 'json');
|
|
171
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('{"pullrequests": []}');
|
|
172
|
+
expect(exitSpy).toHaveBeenCalledWith(0);
|
|
173
|
+
|
|
174
|
+
exitSpy.mockRestore();
|
|
175
|
+
consoleLogSpy.mockRestore();
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it('should execute get-pullrequest command', async () => {
|
|
179
|
+
const { getPullRequest, loadConfig } = await import('../../../src/utils/index.js');
|
|
180
|
+
loadConfig.mockReturnValue({
|
|
181
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
182
|
+
defaultProfile: 'cloud',
|
|
183
|
+
defaultFormat: 'json',
|
|
184
|
+
});
|
|
185
|
+
getPullRequest.mockResolvedValue({ success: true, result: '{"id":"123","title":"Test PR"}' });
|
|
186
|
+
|
|
187
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
188
|
+
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
189
|
+
|
|
190
|
+
await runCommand(
|
|
191
|
+
'get-pullrequest',
|
|
192
|
+
'{"workspace":"myworkspace","repoSlug":"my-repo","pullRequestId":"123"}',
|
|
193
|
+
null
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
expect(getPullRequest).toHaveBeenCalledWith('cloud', 'myworkspace', 'my-repo', '123', 'json');
|
|
197
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('{"id":"123","title":"Test PR"}');
|
|
198
|
+
expect(exitSpy).toHaveBeenCalledWith(0);
|
|
199
|
+
|
|
200
|
+
exitSpy.mockRestore();
|
|
201
|
+
consoleLogSpy.mockRestore();
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it('should exit with error if get-pullrequest missing parameters', async () => {
|
|
205
|
+
const { loadConfig } = await import('../../../src/utils/index.js');
|
|
206
|
+
loadConfig.mockReturnValue({
|
|
207
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
208
|
+
defaultProfile: 'cloud',
|
|
209
|
+
defaultFormat: 'json',
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
213
|
+
const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
214
|
+
|
|
215
|
+
await runCommand('get-pullrequest', '{}', null);
|
|
216
|
+
|
|
217
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
218
|
+
'ERROR: "workspace", "repoSlug", and "pullRequestId" parameters are required'
|
|
219
|
+
);
|
|
220
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
221
|
+
|
|
222
|
+
exitSpy.mockRestore();
|
|
223
|
+
consoleErrorSpy.mockRestore();
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it('should execute create-pullrequest command', async () => {
|
|
227
|
+
const { createPullRequest, loadConfig } = await import('../../../src/utils/index.js');
|
|
228
|
+
loadConfig.mockReturnValue({
|
|
229
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
230
|
+
defaultProfile: 'cloud',
|
|
231
|
+
defaultFormat: 'json',
|
|
232
|
+
});
|
|
233
|
+
createPullRequest.mockResolvedValue({ success: true, result: '{"id":"456","title":"New PR"}' });
|
|
234
|
+
|
|
235
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
236
|
+
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
237
|
+
|
|
238
|
+
await runCommand(
|
|
239
|
+
'create-pullrequest',
|
|
240
|
+
'{"workspace":"myworkspace","repoSlug":"my-repo","title":"New PR","sourceBranch":"feature","destinationBranch":"main"}',
|
|
241
|
+
null
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
expect(createPullRequest).toHaveBeenCalledWith(
|
|
245
|
+
'cloud',
|
|
246
|
+
'myworkspace',
|
|
247
|
+
'my-repo',
|
|
248
|
+
'New PR',
|
|
249
|
+
'feature',
|
|
250
|
+
'main',
|
|
251
|
+
undefined,
|
|
252
|
+
'json'
|
|
253
|
+
);
|
|
254
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('{"id":"456","title":"New PR"}');
|
|
255
|
+
expect(exitSpy).toHaveBeenCalledWith(0);
|
|
256
|
+
|
|
257
|
+
exitSpy.mockRestore();
|
|
258
|
+
consoleLogSpy.mockRestore();
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
it('should execute create-pullrequest with description', async () => {
|
|
262
|
+
const { createPullRequest, loadConfig } = await import('../../../src/utils/index.js');
|
|
263
|
+
loadConfig.mockReturnValue({
|
|
264
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
265
|
+
defaultProfile: 'cloud',
|
|
266
|
+
defaultFormat: 'json',
|
|
267
|
+
});
|
|
268
|
+
createPullRequest.mockResolvedValue({ success: true, result: '{"id":"456","title":"New PR"}' });
|
|
269
|
+
|
|
270
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
271
|
+
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
272
|
+
|
|
273
|
+
await runCommand(
|
|
274
|
+
'create-pullrequest',
|
|
275
|
+
'{"workspace":"myworkspace","repoSlug":"my-repo","title":"New PR","sourceBranch":"feature","destinationBranch":"main","description":"Test description"}',
|
|
276
|
+
null
|
|
277
|
+
);
|
|
278
|
+
|
|
279
|
+
expect(createPullRequest).toHaveBeenCalledWith(
|
|
280
|
+
'cloud',
|
|
281
|
+
'myworkspace',
|
|
282
|
+
'my-repo',
|
|
283
|
+
'New PR',
|
|
284
|
+
'feature',
|
|
285
|
+
'main',
|
|
286
|
+
'Test description',
|
|
287
|
+
'json'
|
|
288
|
+
);
|
|
289
|
+
expect(exitSpy).toHaveBeenCalledWith(0);
|
|
290
|
+
|
|
291
|
+
exitSpy.mockRestore();
|
|
292
|
+
consoleLogSpy.mockRestore();
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
it('should exit with error if create-pullrequest missing required parameters', async () => {
|
|
296
|
+
const { loadConfig } = await import('../../../src/utils/index.js');
|
|
297
|
+
loadConfig.mockReturnValue({
|
|
298
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
299
|
+
defaultProfile: 'cloud',
|
|
300
|
+
defaultFormat: 'json',
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
304
|
+
const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
305
|
+
|
|
306
|
+
await runCommand('create-pullrequest', '{"workspace":"myworkspace"}', null);
|
|
307
|
+
|
|
308
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
309
|
+
'ERROR: "workspace", "repoSlug", "title", "sourceBranch", and "destinationBranch" parameters are required'
|
|
310
|
+
);
|
|
311
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
312
|
+
|
|
313
|
+
exitSpy.mockRestore();
|
|
314
|
+
consoleErrorSpy.mockRestore();
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
it('should execute list-branches command', async () => {
|
|
318
|
+
const { listBranches, loadConfig } = await import('../../../src/utils/index.js');
|
|
319
|
+
loadConfig.mockReturnValue({
|
|
320
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
321
|
+
defaultProfile: 'cloud',
|
|
322
|
+
defaultFormat: 'json',
|
|
323
|
+
});
|
|
324
|
+
listBranches.mockResolvedValue({ success: true, result: '{"branches": []}' });
|
|
325
|
+
|
|
326
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
327
|
+
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
328
|
+
|
|
329
|
+
await runCommand('list-branches', '{"workspace":"myworkspace","repoSlug":"my-repo"}', null);
|
|
330
|
+
|
|
331
|
+
expect(listBranches).toHaveBeenCalledWith('cloud', 'myworkspace', 'my-repo', undefined, undefined, 'json');
|
|
332
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('{"branches": []}');
|
|
333
|
+
expect(exitSpy).toHaveBeenCalledWith(0);
|
|
334
|
+
|
|
335
|
+
exitSpy.mockRestore();
|
|
336
|
+
consoleLogSpy.mockRestore();
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
it('should execute list-commits command', async () => {
|
|
340
|
+
const { listCommits, loadConfig } = await import('../../../src/utils/index.js');
|
|
341
|
+
loadConfig.mockReturnValue({
|
|
342
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
343
|
+
defaultProfile: 'cloud',
|
|
344
|
+
defaultFormat: 'json',
|
|
345
|
+
});
|
|
346
|
+
listCommits.mockResolvedValue({ success: true, result: '{"commits": []}' });
|
|
347
|
+
|
|
348
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
349
|
+
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
350
|
+
|
|
351
|
+
await runCommand('list-commits', '{"workspace":"myworkspace","repoSlug":"my-repo"}', null);
|
|
352
|
+
|
|
353
|
+
expect(listCommits).toHaveBeenCalledWith('cloud', 'myworkspace', 'my-repo', undefined, 'json');
|
|
354
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('{"commits": []}');
|
|
355
|
+
expect(exitSpy).toHaveBeenCalledWith(0);
|
|
356
|
+
|
|
357
|
+
exitSpy.mockRestore();
|
|
358
|
+
consoleLogSpy.mockRestore();
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
it('should execute list-issues command', async () => {
|
|
362
|
+
const { listIssues, loadConfig } = await import('../../../src/utils/index.js');
|
|
363
|
+
loadConfig.mockReturnValue({
|
|
364
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
365
|
+
defaultProfile: 'cloud',
|
|
366
|
+
defaultFormat: 'json',
|
|
367
|
+
});
|
|
368
|
+
listIssues.mockResolvedValue({ success: true, result: '{"issues": []}' });
|
|
369
|
+
|
|
370
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
371
|
+
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
372
|
+
|
|
373
|
+
await runCommand('list-issues', '{"workspace":"myworkspace","repoSlug":"my-repo"}', null);
|
|
374
|
+
|
|
375
|
+
expect(listIssues).toHaveBeenCalledWith('cloud', 'myworkspace', 'my-repo', 'json');
|
|
376
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('{"issues": []}');
|
|
377
|
+
expect(exitSpy).toHaveBeenCalledWith(0);
|
|
378
|
+
|
|
379
|
+
exitSpy.mockRestore();
|
|
380
|
+
consoleLogSpy.mockRestore();
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
it('should execute get-issue command', async () => {
|
|
384
|
+
const { getIssue, loadConfig } = await import('../../../src/utils/index.js');
|
|
385
|
+
loadConfig.mockReturnValue({
|
|
386
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
387
|
+
defaultProfile: 'cloud',
|
|
388
|
+
defaultFormat: 'json',
|
|
389
|
+
});
|
|
390
|
+
getIssue.mockResolvedValue({ success: true, result: '{"id":"123","title":"Test Issue"}' });
|
|
391
|
+
|
|
392
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
393
|
+
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
394
|
+
|
|
395
|
+
await runCommand('get-issue', '{"workspace":"myworkspace","repoSlug":"my-repo","issueId":"123"}', null);
|
|
396
|
+
|
|
397
|
+
expect(getIssue).toHaveBeenCalledWith('cloud', 'myworkspace', 'my-repo', '123', 'json');
|
|
398
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('{"id":"123","title":"Test Issue"}');
|
|
399
|
+
expect(exitSpy).toHaveBeenCalledWith(0);
|
|
400
|
+
|
|
401
|
+
exitSpy.mockRestore();
|
|
402
|
+
consoleLogSpy.mockRestore();
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
it('should exit with error if get-issue missing parameters', async () => {
|
|
406
|
+
const { loadConfig } = await import('../../../src/utils/index.js');
|
|
407
|
+
loadConfig.mockReturnValue({
|
|
408
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
409
|
+
defaultProfile: 'cloud',
|
|
410
|
+
defaultFormat: 'json',
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
414
|
+
const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
415
|
+
|
|
416
|
+
await runCommand('get-issue', '{}', null);
|
|
417
|
+
|
|
418
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
419
|
+
'ERROR: "workspace", "repoSlug", and "issueId" parameters are required'
|
|
420
|
+
);
|
|
421
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
422
|
+
|
|
423
|
+
exitSpy.mockRestore();
|
|
424
|
+
consoleErrorSpy.mockRestore();
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
it('should execute create-issue command', async () => {
|
|
428
|
+
const { createIssue, loadConfig } = await import('../../../src/utils/index.js');
|
|
429
|
+
loadConfig.mockReturnValue({
|
|
430
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
431
|
+
defaultProfile: 'cloud',
|
|
432
|
+
defaultFormat: 'json',
|
|
433
|
+
});
|
|
434
|
+
createIssue.mockResolvedValue({ success: true, result: '{"id":"456","title":"New Issue"}' });
|
|
435
|
+
|
|
436
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
437
|
+
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
438
|
+
|
|
439
|
+
await runCommand('create-issue', '{"workspace":"myworkspace","repoSlug":"my-repo","title":"New Issue"}', null);
|
|
440
|
+
|
|
441
|
+
expect(createIssue).toHaveBeenCalledWith(
|
|
442
|
+
'cloud',
|
|
443
|
+
'myworkspace',
|
|
444
|
+
'my-repo',
|
|
445
|
+
'New Issue',
|
|
446
|
+
undefined,
|
|
447
|
+
undefined,
|
|
448
|
+
undefined,
|
|
449
|
+
'json'
|
|
450
|
+
);
|
|
451
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('{"id":"456","title":"New Issue"}');
|
|
452
|
+
expect(exitSpy).toHaveBeenCalledWith(0);
|
|
453
|
+
|
|
454
|
+
exitSpy.mockRestore();
|
|
455
|
+
consoleLogSpy.mockRestore();
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
it('should execute create-issue with optional parameters', async () => {
|
|
459
|
+
const { createIssue, loadConfig } = await import('../../../src/utils/index.js');
|
|
460
|
+
loadConfig.mockReturnValue({
|
|
461
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
462
|
+
defaultProfile: 'cloud',
|
|
463
|
+
defaultFormat: 'json',
|
|
464
|
+
});
|
|
465
|
+
createIssue.mockResolvedValue({ success: true, result: '{"id":"789"}' });
|
|
466
|
+
|
|
467
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
468
|
+
|
|
469
|
+
await runCommand(
|
|
470
|
+
'create-issue',
|
|
471
|
+
'{"workspace":"myworkspace","repoSlug":"my-repo","title":"Bug report","content":"Details here","kind":"bug","priority":"major"}',
|
|
472
|
+
null
|
|
473
|
+
);
|
|
474
|
+
|
|
475
|
+
expect(createIssue).toHaveBeenCalledWith(
|
|
476
|
+
'cloud',
|
|
477
|
+
'myworkspace',
|
|
478
|
+
'my-repo',
|
|
479
|
+
'Bug report',
|
|
480
|
+
'Details here',
|
|
481
|
+
'bug',
|
|
482
|
+
'major',
|
|
483
|
+
'json'
|
|
484
|
+
);
|
|
485
|
+
expect(exitSpy).toHaveBeenCalledWith(0);
|
|
486
|
+
|
|
487
|
+
exitSpy.mockRestore();
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
it('should exit with error if create-issue missing required parameters', async () => {
|
|
491
|
+
const { loadConfig } = await import('../../../src/utils/index.js');
|
|
492
|
+
loadConfig.mockReturnValue({
|
|
493
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
494
|
+
defaultProfile: 'cloud',
|
|
495
|
+
defaultFormat: 'json',
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
499
|
+
const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
500
|
+
|
|
501
|
+
await runCommand('create-issue', '{"workspace":"myworkspace"}', null);
|
|
502
|
+
|
|
503
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
504
|
+
'ERROR: "workspace", "repoSlug", and "title" parameters are required'
|
|
505
|
+
);
|
|
506
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
507
|
+
|
|
508
|
+
exitSpy.mockRestore();
|
|
509
|
+
consoleErrorSpy.mockRestore();
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
it('should execute list-pipelines command', async () => {
|
|
513
|
+
const { listPipelines, loadConfig } = await import('../../../src/utils/index.js');
|
|
514
|
+
loadConfig.mockReturnValue({
|
|
515
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
516
|
+
defaultProfile: 'cloud',
|
|
517
|
+
defaultFormat: 'json',
|
|
518
|
+
});
|
|
519
|
+
listPipelines.mockResolvedValue({ success: true, result: '{"pipelines": []}' });
|
|
520
|
+
|
|
521
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
522
|
+
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
523
|
+
|
|
524
|
+
await runCommand('list-pipelines', '{"workspace":"myworkspace","repoSlug":"my-repo"}', null);
|
|
525
|
+
|
|
526
|
+
expect(listPipelines).toHaveBeenCalledWith('cloud', 'myworkspace', 'my-repo', 'json');
|
|
527
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('{"pipelines": []}');
|
|
528
|
+
expect(exitSpy).toHaveBeenCalledWith(0);
|
|
529
|
+
|
|
530
|
+
exitSpy.mockRestore();
|
|
531
|
+
consoleLogSpy.mockRestore();
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
it('should execute get-user with username', async () => {
|
|
535
|
+
const { getUser, loadConfig } = await import('../../../src/utils/index.js');
|
|
536
|
+
loadConfig.mockReturnValue({
|
|
537
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
538
|
+
defaultProfile: 'cloud',
|
|
539
|
+
defaultFormat: 'json',
|
|
540
|
+
});
|
|
541
|
+
getUser.mockResolvedValue({ success: true, result: '{"displayName":"User"}' });
|
|
542
|
+
|
|
543
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
544
|
+
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
545
|
+
|
|
546
|
+
await runCommand('get-user', '{"username":"testuser"}', null);
|
|
547
|
+
|
|
548
|
+
expect(getUser).toHaveBeenCalledWith('cloud', 'testuser', 'json');
|
|
549
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('{"displayName":"User"}');
|
|
550
|
+
expect(exitSpy).toHaveBeenCalledWith(0);
|
|
551
|
+
|
|
552
|
+
exitSpy.mockRestore();
|
|
553
|
+
consoleLogSpy.mockRestore();
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
it('should execute get-user without parameters (current user)', async () => {
|
|
557
|
+
const { getUser, loadConfig } = await import('../../../src/utils/index.js');
|
|
558
|
+
loadConfig.mockReturnValue({
|
|
559
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
560
|
+
defaultProfile: 'cloud',
|
|
561
|
+
defaultFormat: 'json',
|
|
562
|
+
});
|
|
563
|
+
getUser.mockResolvedValue({ success: true, result: '{"displayName":"Current User"}' });
|
|
564
|
+
|
|
565
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
566
|
+
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
567
|
+
|
|
568
|
+
await runCommand('get-user', null, null);
|
|
569
|
+
|
|
570
|
+
expect(getUser).toHaveBeenCalledWith('cloud', undefined, 'json');
|
|
571
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('{"displayName":"Current User"}');
|
|
572
|
+
expect(exitSpy).toHaveBeenCalledWith(0);
|
|
573
|
+
|
|
574
|
+
exitSpy.mockRestore();
|
|
575
|
+
consoleLogSpy.mockRestore();
|
|
576
|
+
});
|
|
577
|
+
|
|
578
|
+
it('should execute test-connection command', async () => {
|
|
579
|
+
const { testConnection, loadConfig } = await import('../../../src/utils/index.js');
|
|
580
|
+
loadConfig.mockReturnValue({
|
|
581
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
582
|
+
defaultProfile: 'cloud',
|
|
583
|
+
defaultFormat: 'json',
|
|
584
|
+
});
|
|
585
|
+
testConnection.mockResolvedValue({ success: true, result: 'Connected successfully' });
|
|
586
|
+
|
|
587
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
588
|
+
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
589
|
+
|
|
590
|
+
await runCommand('test-connection', null, null);
|
|
591
|
+
|
|
592
|
+
expect(testConnection).toHaveBeenCalledWith('cloud');
|
|
593
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('Connected successfully');
|
|
594
|
+
expect(exitSpy).toHaveBeenCalledWith(0);
|
|
595
|
+
|
|
596
|
+
exitSpy.mockRestore();
|
|
597
|
+
consoleLogSpy.mockRestore();
|
|
598
|
+
});
|
|
599
|
+
|
|
600
|
+
it('should handle command failure', async () => {
|
|
601
|
+
const { getRepository, loadConfig } = await import('../../../src/utils/index.js');
|
|
602
|
+
loadConfig.mockReturnValue({
|
|
603
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
604
|
+
defaultProfile: 'cloud',
|
|
605
|
+
defaultFormat: 'json',
|
|
606
|
+
});
|
|
607
|
+
getRepository.mockResolvedValue({ success: false, error: 'Repository not found' });
|
|
608
|
+
|
|
609
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
610
|
+
const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
611
|
+
|
|
612
|
+
await runCommand('get-repository', '{"workspace":"myworkspace","repoSlug":"invalid"}', null);
|
|
613
|
+
|
|
614
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith('Repository not found');
|
|
615
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
616
|
+
|
|
617
|
+
exitSpy.mockRestore();
|
|
618
|
+
consoleErrorSpy.mockRestore();
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
it('should handle unknown command', async () => {
|
|
622
|
+
const { loadConfig } = await import('../../../src/utils/index.js');
|
|
623
|
+
loadConfig.mockReturnValue({
|
|
624
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
625
|
+
defaultProfile: 'cloud',
|
|
626
|
+
defaultFormat: 'json',
|
|
627
|
+
});
|
|
628
|
+
|
|
629
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
630
|
+
const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
631
|
+
|
|
632
|
+
await runCommand('unknown-command', '{}', null);
|
|
633
|
+
|
|
634
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith('Unknown command: unknown-command');
|
|
635
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
636
|
+
|
|
637
|
+
exitSpy.mockRestore();
|
|
638
|
+
consoleErrorSpy.mockRestore();
|
|
639
|
+
});
|
|
640
|
+
|
|
641
|
+
it('should handle JSON parse error in arguments', async () => {
|
|
642
|
+
const { loadConfig, clearClients } = await import('../../../src/utils/index.js');
|
|
643
|
+
loadConfig.mockReturnValue({
|
|
644
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
645
|
+
defaultProfile: 'cloud',
|
|
646
|
+
defaultFormat: 'json',
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
650
|
+
const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
651
|
+
|
|
652
|
+
await runCommand('list-repositories', 'invalid json', null);
|
|
653
|
+
|
|
654
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
655
|
+
'Error executing command:',
|
|
656
|
+
expect.stringContaining('not valid JSON')
|
|
657
|
+
);
|
|
658
|
+
expect(clearClients).toHaveBeenCalled();
|
|
659
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
660
|
+
|
|
661
|
+
exitSpy.mockRestore();
|
|
662
|
+
consoleErrorSpy.mockRestore();
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
it('should use CLAUDE_PROJECT_ROOT from environment if set', async () => {
|
|
666
|
+
process.env.CLAUDE_PROJECT_ROOT = '/custom/project/root';
|
|
667
|
+
const { loadConfig, listRepositories } = await import('../../../src/utils/index.js');
|
|
668
|
+
loadConfig.mockReturnValue({
|
|
669
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
670
|
+
defaultProfile: 'cloud',
|
|
671
|
+
defaultFormat: 'json',
|
|
672
|
+
});
|
|
673
|
+
listRepositories.mockResolvedValue({ success: true, result: '{"repositories": []}' });
|
|
674
|
+
|
|
675
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
676
|
+
|
|
677
|
+
await runCommand('list-repositories', '{"workspace":"myworkspace"}', null);
|
|
678
|
+
|
|
679
|
+
expect(loadConfig).toHaveBeenCalledWith('/custom/project/root');
|
|
680
|
+
|
|
681
|
+
exitSpy.mockRestore();
|
|
682
|
+
});
|
|
683
|
+
|
|
684
|
+
it('should use current directory if CLAUDE_PROJECT_ROOT not set', async () => {
|
|
685
|
+
delete process.env.CLAUDE_PROJECT_ROOT;
|
|
686
|
+
const { loadConfig, listRepositories } = await import('../../../src/utils/index.js');
|
|
687
|
+
loadConfig.mockReturnValue({
|
|
688
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
689
|
+
defaultProfile: 'cloud',
|
|
690
|
+
defaultFormat: 'json',
|
|
691
|
+
});
|
|
692
|
+
listRepositories.mockResolvedValue({ success: true, result: '{"repositories": []}' });
|
|
693
|
+
|
|
694
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
695
|
+
|
|
696
|
+
await runCommand('list-repositories', '{"workspace":"myworkspace"}', null);
|
|
697
|
+
|
|
698
|
+
expect(loadConfig).toHaveBeenCalledWith(process.cwd());
|
|
699
|
+
|
|
700
|
+
exitSpy.mockRestore();
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
it('should clear clients on successful execution', async () => {
|
|
704
|
+
const { listRepositories, loadConfig, clearClients } = await import('../../../src/utils/index.js');
|
|
705
|
+
loadConfig.mockReturnValue({
|
|
706
|
+
profiles: { cloud: { username: 'test@test.com', password: 'password123' } },
|
|
707
|
+
defaultProfile: 'cloud',
|
|
708
|
+
defaultFormat: 'json',
|
|
709
|
+
});
|
|
710
|
+
listRepositories.mockResolvedValue({ success: true, result: '{}' });
|
|
711
|
+
|
|
712
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
713
|
+
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
714
|
+
|
|
715
|
+
await runCommand('list-repositories', '{"workspace":"myworkspace"}', null);
|
|
716
|
+
|
|
717
|
+
expect(clearClients).toHaveBeenCalled();
|
|
718
|
+
|
|
719
|
+
exitSpy.mockRestore();
|
|
720
|
+
consoleLogSpy.mockRestore();
|
|
721
|
+
});
|
|
722
|
+
|
|
723
|
+
it('should clear clients on error', async () => {
|
|
724
|
+
const { loadConfig, clearClients } = await import('../../../src/utils/index.js');
|
|
725
|
+
loadConfig.mockImplementation(() => {
|
|
726
|
+
throw new Error('Config error');
|
|
727
|
+
});
|
|
728
|
+
|
|
729
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
730
|
+
const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
731
|
+
|
|
732
|
+
await runCommand('list-repositories', '{"workspace":"myworkspace"}', null);
|
|
733
|
+
|
|
734
|
+
expect(clearClients).toHaveBeenCalled();
|
|
735
|
+
|
|
736
|
+
exitSpy.mockRestore();
|
|
737
|
+
consoleErrorSpy.mockRestore();
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
it('should handle exceptions and display error message', async () => {
|
|
741
|
+
const { loadConfig } = await import('../../../src/utils/index.js');
|
|
742
|
+
loadConfig.mockImplementation(() => {
|
|
743
|
+
throw new Error('Configuration load failed');
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {});
|
|
747
|
+
const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
748
|
+
|
|
749
|
+
await runCommand('list-repositories', '{"workspace":"myworkspace"}', null);
|
|
750
|
+
|
|
751
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith('Error executing command:', 'Configuration load failed');
|
|
752
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
753
|
+
|
|
754
|
+
exitSpy.mockRestore();
|
|
755
|
+
consoleErrorSpy.mockRestore();
|
|
756
|
+
});
|
|
757
|
+
});
|
|
758
|
+
});
|