-
Notifications
You must be signed in to change notification settings - Fork 36
Expand file tree
/
Copy pathopencode.test.ts
More file actions
142 lines (119 loc) · 4.28 KB
/
opencode.test.ts
File metadata and controls
142 lines (119 loc) · 4.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import { describe, it, expect, vi, beforeEach, afterAll } from 'bun:test';
import { componentRegistry } from '@shipsec/component-sdk';
import * as SDK from '@shipsec/component-sdk'; // Import for spying
import { IsolatedContainerVolume } from '../../../utils/isolated-volume';
import * as utils from '../utils';
import '../opencode'; // Register the component
// Mock IsolatedContainerVolume
vi.mock('../../../utils/isolated-volume', () => {
return {
IsolatedContainerVolume: vi.fn().mockImplementation(() => ({
initialize: vi.fn().mockResolvedValue('mock-volume-name'),
cleanup: vi.fn().mockResolvedValue(undefined),
getVolumeConfig: vi
.fn()
.mockReturnValue({ source: 'mock', target: '/workspace', readOnly: false }),
getVolumeName: vi.fn().mockReturnValue('mock-volume-name'),
})),
};
});
describe('shipsec.opencode.agent', () => {
let runSpy: any;
beforeEach(() => {
vi.clearAllMocks();
// Mock getGatewaySessionToken
// We use spyOn so we can restore it later if needed, but here we just want to ensure it's mocked for this suite.
vi.spyOn(utils, 'getGatewaySessionToken').mockResolvedValue('mock-session-token');
// Spy on runComponentWithRunner
runSpy = vi.spyOn(SDK, 'runComponentWithRunner').mockResolvedValue({
stdout: '# Report\n\nInvestigation complete.',
stderr: '',
exitCode: 0,
results: [],
raw: '',
} as any);
});
afterAll(() => {
vi.restoreAllMocks();
});
it('should be registered', () => {
const component = componentRegistry.get('core.ai.opencode');
expect(component).toBeDefined();
expect(component?.id).toBe('core.ai.opencode');
});
it('should execute with valid inputs', async () => {
const component = componentRegistry.get('core.ai.opencode');
if (!component) throw new Error('Component not found');
const context = {
runId: 'test-run',
componentRef: 'test-ref',
metadata: {
connectedToolNodeIds: ['tool-1'],
organizationId: 'org-1',
},
logger: {
info: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
debug: vi.fn(),
},
emitProgress: vi.fn(),
};
const inputs = {
task: 'Find the bug',
context: { alertId: '123' },
model: { provider: 'openai', modelId: 'gpt-4o', apiKey: 'sk-test' },
};
const params = {
systemPrompt: 'You are a detective.',
autoApprove: true,
};
const result = await component.execute({ inputs, params }, context as any);
expect(result.report).toContain('# Report');
expect(IsolatedContainerVolume).toHaveBeenCalled();
const volumeInstance = (IsolatedContainerVolume as any).mock.results[0].value;
const initCall = volumeInstance.initialize.mock.calls[0][0];
expect(initCall['context.json']).toContain('"alertId": "123"');
expect(initCall['opencode.jsonc']).toContain('shipsec-gateway');
expect(runSpy).toHaveBeenCalled();
const runnerCall = runSpy.mock.calls[0][0];
expect(runnerCall.image).toBe('ghcr.io/shipsecai/opencode:1.1.53');
expect(runnerCall.network).toBe('host');
expect(runnerCall.env.OPENAI_API_KEY).toBe('sk-test');
});
it('should merge providerConfig into opencode.jsonc', async () => {
const component = componentRegistry.get('core.ai.opencode');
if (!component) throw new Error('Component not found');
const context = {
runId: 'test-run-config',
componentRef: 'test-ref-config',
metadata: {
connectedToolNodeIds: [],
organizationId: 'org-1',
},
logger: {
info: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
debug: vi.fn(),
},
emitProgress: vi.fn(),
};
const inputs = {
task: 'Test config merge',
};
const params = {
providerConfig: {
githubToken: 'gh-token',
extraSetting: 123,
},
};
await component.execute({ inputs, params }, context as any);
expect(IsolatedContainerVolume).toHaveBeenCalled();
const volumeInstance = (IsolatedContainerVolume as any).mock.results[0].value;
const initCall = volumeInstance.initialize.mock.calls[0][0];
const config = JSON.parse(initCall['opencode.jsonc']);
expect(config.githubToken).toBe('gh-token');
expect(config.extraSetting).toBe(123);
});
});