Skip to content

Commit 1be10f1

Browse files
committed
test(cli): add unit tests for utils modules
Add comprehensive test coverage for: - utils/coana/spawn.mts: Coana CLI spawning functionality - utils/git/gitlab-provider.mts: GitLab MR provider implementation - utils/telemetry/integration.mts: Telemetry integration helpers - utils/update/checker.mts: Update checking functionality
1 parent 448ea99 commit 1be10f1

File tree

4 files changed

+1440
-136
lines changed

4 files changed

+1440
-136
lines changed
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/**
2+
* Unit tests for Coana spawn utilities.
3+
*
4+
* Purpose:
5+
* Tests the Coana CLI spawning functionality.
6+
*
7+
* Test Coverage:
8+
* - spawnCoana function export
9+
* - Environment variable handling
10+
* - Error handling
11+
*
12+
* Related Files:
13+
* - utils/coana/spawn.mts (implementation)
14+
*/
15+
16+
import { beforeEach, describe, expect, it, vi } from 'vitest'
17+
18+
// Mock dependencies.
19+
const mockSpawnNode = vi.hoisted(() => vi.fn())
20+
const mockDlxPackage = vi.hoisted(() => vi.fn())
21+
const mockGetDefaultOrgSlug = vi.hoisted(() => vi.fn())
22+
const mockGetCliVersion = vi.hoisted(() => vi.fn())
23+
const mockGetCoanaVersion = vi.hoisted(() => vi.fn())
24+
const mockGetDefaultApiToken = vi.hoisted(() => vi.fn())
25+
const mockGetDefaultProxyUrl = vi.hoisted(() => vi.fn())
26+
const mockGetErrorCause = vi.hoisted(() => vi.fn())
27+
28+
vi.mock('@socketsecurity/lib/dlx/package', () => ({
29+
dlxPackage: mockDlxPackage,
30+
}))
31+
32+
vi.mock('../../../../src/commands/ci/fetch-default-org-slug.mts', () => ({
33+
getDefaultOrgSlug: mockGetDefaultOrgSlug,
34+
}))
35+
36+
vi.mock('../../../../src/env/cli-version.mts', () => ({
37+
getCliVersion: mockGetCliVersion,
38+
}))
39+
40+
vi.mock('../../../../src/env/coana-version.mts', () => ({
41+
getCoanaVersion: mockGetCoanaVersion,
42+
}))
43+
44+
vi.mock('../../../../src/env/socket-cli-coana-local-path.mts', () => ({
45+
SOCKET_CLI_COANA_LOCAL_PATH: null,
46+
}))
47+
48+
vi.mock('../../../../src/utils/socket/sdk.mts', () => ({
49+
getDefaultApiToken: mockGetDefaultApiToken,
50+
getDefaultProxyUrl: mockGetDefaultProxyUrl,
51+
}))
52+
53+
vi.mock('../../../../src/utils/error/errors.mts', () => ({
54+
getErrorCause: mockGetErrorCause,
55+
}))
56+
57+
vi.mock('../../../../src/utils/spawn/spawn-node.mjs', () => ({
58+
spawnNode: mockSpawnNode,
59+
}))
60+
61+
import { spawnCoana } from '../../../../src/utils/coana/spawn.mts'
62+
63+
describe('coana/spawn', () => {
64+
beforeEach(() => {
65+
vi.clearAllMocks()
66+
67+
// Default mock implementations.
68+
mockGetCliVersion.mockReturnValue('1.0.0')
69+
mockGetCoanaVersion.mockReturnValue('1.0.0')
70+
mockGetDefaultApiToken.mockReturnValue(null)
71+
mockGetDefaultProxyUrl.mockReturnValue(null)
72+
mockGetDefaultOrgSlug.mockResolvedValue({ ok: false })
73+
mockGetErrorCause.mockReturnValue('Unknown error')
74+
75+
mockDlxPackage.mockResolvedValue({
76+
spawnPromise: Promise.resolve({ stdout: 'success', code: 0 }),
77+
})
78+
})
79+
80+
describe('spawnCoana', () => {
81+
it('exports spawnCoana function', () => {
82+
expect(typeof spawnCoana).toBe('function')
83+
})
84+
85+
it('spawns coana with dlxPackage when no local path set', async () => {
86+
const result = await spawnCoana(['--version'])
87+
88+
expect(result.ok).toBe(true)
89+
expect(mockDlxPackage).toHaveBeenCalled()
90+
})
91+
92+
it('passes environment variables to coana', async () => {
93+
mockGetDefaultApiToken.mockReturnValue('test-token')
94+
mockGetDefaultProxyUrl.mockReturnValue('http://proxy.example.com')
95+
96+
await spawnCoana(['--version'])
97+
98+
const call = mockDlxPackage.mock.calls[0]
99+
const spawnOptions = call[1].spawnOptions
100+
expect(spawnOptions.env.SOCKET_CLI_API_TOKEN).toBe('test-token')
101+
expect(spawnOptions.env.SOCKET_CLI_API_PROXY).toBe(
102+
'http://proxy.example.com',
103+
)
104+
})
105+
106+
it('includes org slug in environment when provided', async () => {
107+
await spawnCoana(['--version'], 'my-org')
108+
109+
const call = mockDlxPackage.mock.calls[0]
110+
const spawnOptions = call[1].spawnOptions
111+
expect(spawnOptions.env.SOCKET_ORG_SLUG).toBe('my-org')
112+
})
113+
114+
it('fetches default org slug when not provided', async () => {
115+
mockGetDefaultOrgSlug.mockResolvedValue({ ok: true, data: 'default-org' })
116+
117+
await spawnCoana(['--version'])
118+
119+
expect(mockGetDefaultOrgSlug).toHaveBeenCalled()
120+
const call = mockDlxPackage.mock.calls[0]
121+
const spawnOptions = call[1].spawnOptions
122+
expect(spawnOptions.env.SOCKET_ORG_SLUG).toBe('default-org')
123+
})
124+
125+
it('handles errors gracefully', async () => {
126+
mockDlxPackage.mockRejectedValue(new Error('Spawn failed'))
127+
mockGetErrorCause.mockReturnValue('Spawn failed')
128+
129+
const result = await spawnCoana(['--version'])
130+
131+
expect(result.ok).toBe(false)
132+
expect(result.message).toBe('Spawn failed')
133+
})
134+
135+
it('uses force:true for dlxPackage', async () => {
136+
await spawnCoana(['--version'])
137+
138+
const call = mockDlxPackage.mock.calls[0]
139+
expect(call[1].force).toBe(true)
140+
})
141+
142+
it('passes CLI version to environment', async () => {
143+
mockGetCliVersion.mockReturnValue('2.0.0')
144+
145+
await spawnCoana(['--version'])
146+
147+
const call = mockDlxPackage.mock.calls[0]
148+
const spawnOptions = call[1].spawnOptions
149+
expect(spawnOptions.env.SOCKET_CLI_VERSION).toBe('2.0.0')
150+
})
151+
})
152+
})

0 commit comments

Comments
 (0)