test(runtime-provider-management): cover project-aware opencode flow
This commit is contained in:
parent
2eba377be2
commit
825cfc00d1
3 changed files with 98 additions and 1 deletions
|
|
@ -3,6 +3,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
const buildProviderAwareCliEnvMock = vi.fn();
|
const buildProviderAwareCliEnvMock = vi.fn();
|
||||||
const resolveBinaryMock = vi.fn();
|
const resolveBinaryMock = vi.fn();
|
||||||
const execCliMock = vi.fn();
|
const execCliMock = vi.fn();
|
||||||
|
const spawnCliMock = vi.fn();
|
||||||
const resolveInteractiveShellEnvMock = vi.fn();
|
const resolveInteractiveShellEnvMock = vi.fn();
|
||||||
|
|
||||||
vi.mock('@main/services/runtime/providerAwareCliEnv', () => ({
|
vi.mock('@main/services/runtime/providerAwareCliEnv', () => ({
|
||||||
|
|
@ -17,7 +18,7 @@ vi.mock('@main/services/team/ClaudeBinaryResolver', () => ({
|
||||||
|
|
||||||
vi.mock('@main/utils/childProcess', () => ({
|
vi.mock('@main/utils/childProcess', () => ({
|
||||||
execCli: (...args: unknown[]) => execCliMock(...args),
|
execCli: (...args: unknown[]) => execCliMock(...args),
|
||||||
spawnCli: vi.fn(),
|
spawnCli: (...args: unknown[]) => spawnCliMock(...args),
|
||||||
killProcessTree: vi.fn(),
|
killProcessTree: vi.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
@ -86,4 +87,41 @@ describe('AgentTeamsRuntimeProviderManagementCliClient', () => {
|
||||||
'Provider opencode must be connected before testing a model'
|
'Provider opencode must be connected before testing a model'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('passes project path as cwd and CLI flag for project-aware provider management', async () => {
|
||||||
|
execCliMock.mockResolvedValue({
|
||||||
|
stdout: JSON.stringify({
|
||||||
|
schemaVersion: 1,
|
||||||
|
runtimeId: 'opencode',
|
||||||
|
view: {
|
||||||
|
runtimeId: 'opencode',
|
||||||
|
title: 'OpenCode',
|
||||||
|
runtime: {
|
||||||
|
state: 'ready',
|
||||||
|
cliPath: '/opt/homebrew/bin/opencode',
|
||||||
|
version: '1.0.0',
|
||||||
|
managedProfile: 'active',
|
||||||
|
localAuth: 'synced',
|
||||||
|
},
|
||||||
|
providers: [],
|
||||||
|
defaultModel: null,
|
||||||
|
fallbackModel: null,
|
||||||
|
diagnostics: [],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
stderr: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const client = new AgentTeamsRuntimeProviderManagementCliClient();
|
||||||
|
await client.loadView({
|
||||||
|
runtimeId: 'opencode',
|
||||||
|
projectPath: '/Users/test/project',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(execCliMock).toHaveBeenCalledWith(
|
||||||
|
'/repo/cli-dev',
|
||||||
|
expect.arrayContaining(['--project-path', '/Users/test/project']),
|
||||||
|
expect.objectContaining({ cwd: '/Users/test/project' })
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -67,10 +67,12 @@ vi.mock('@features/runtime-provider-management/renderer', () => ({
|
||||||
runtimeId,
|
runtimeId,
|
||||||
open,
|
open,
|
||||||
disabled,
|
disabled,
|
||||||
|
projectPath,
|
||||||
}: {
|
}: {
|
||||||
runtimeId: string;
|
runtimeId: string;
|
||||||
open: boolean;
|
open: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
projectPath?: string | null;
|
||||||
}) =>
|
}) =>
|
||||||
React.createElement(
|
React.createElement(
|
||||||
'section',
|
'section',
|
||||||
|
|
@ -79,6 +81,7 @@ vi.mock('@features/runtime-provider-management/renderer', () => ({
|
||||||
'data-runtime-id': runtimeId,
|
'data-runtime-id': runtimeId,
|
||||||
'data-open': String(open),
|
'data-open': String(open),
|
||||||
'data-disabled': String(Boolean(disabled)),
|
'data-disabled': String(Boolean(disabled)),
|
||||||
|
'data-project-path': projectPath ?? '',
|
||||||
},
|
},
|
||||||
`Runtime provider management: ${runtimeId}`
|
`Runtime provider management: ${runtimeId}`
|
||||||
),
|
),
|
||||||
|
|
@ -1453,6 +1456,7 @@ describe('ProviderRuntimeSettingsDialog', () => {
|
||||||
onOpenChange: vi.fn(),
|
onOpenChange: vi.fn(),
|
||||||
providers: [createOpenCodeProvider()],
|
providers: [createOpenCodeProvider()],
|
||||||
initialProviderId: 'opencode',
|
initialProviderId: 'opencode',
|
||||||
|
projectPath: '/tmp/project-a',
|
||||||
onSelectBackend: vi.fn(),
|
onSelectBackend: vi.fn(),
|
||||||
onRefreshProvider: vi.fn(() => Promise.resolve(undefined)),
|
onRefreshProvider: vi.fn(() => Promise.resolve(undefined)),
|
||||||
})
|
})
|
||||||
|
|
@ -1464,6 +1468,7 @@ describe('ProviderRuntimeSettingsDialog', () => {
|
||||||
expect(panel).not.toBeNull();
|
expect(panel).not.toBeNull();
|
||||||
expect(panel?.getAttribute('data-runtime-id')).toBe('opencode');
|
expect(panel?.getAttribute('data-runtime-id')).toBe('opencode');
|
||||||
expect(panel?.getAttribute('data-open')).toBe('true');
|
expect(panel?.getAttribute('data-open')).toBe('true');
|
||||||
|
expect(panel?.getAttribute('data-project-path')).toBe('/tmp/project-a');
|
||||||
expect(host.textContent).toContain('Runtime provider management: opencode');
|
expect(host.textContent).toContain('Runtime provider management: opencode');
|
||||||
expect(host.textContent).not.toContain('Desktop currently exposes status only.');
|
expect(host.textContent).not.toContain('Desktop currently exposes status only.');
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,17 @@ describe('useRuntimeProviderManagement', () => {
|
||||||
return React.createElement('div');
|
return React.createElement('div');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function EnabledHarness(props: { projectPath?: string | null }): React.ReactElement {
|
||||||
|
const hook = useRuntimeProviderManagement({
|
||||||
|
runtimeId: 'opencode',
|
||||||
|
enabled: true,
|
||||||
|
projectPath: props.projectPath,
|
||||||
|
});
|
||||||
|
state = hook[0];
|
||||||
|
actions = hook[1];
|
||||||
|
return React.createElement('div');
|
||||||
|
}
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.stubGlobal('IS_REACT_ACT_ENVIRONMENT', true);
|
vi.stubGlobal('IS_REACT_ACT_ENVIRONMENT', true);
|
||||||
host = document.createElement('div');
|
host = document.createElement('div');
|
||||||
|
|
@ -74,6 +85,49 @@ describe('useRuntimeProviderManagement', () => {
|
||||||
expect(getStoredCreateTeamModel('opencode')).toBe(modelId);
|
expect(getStoredCreateTeamModel('opencode')).toBe(modelId);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('passes projectPath to the runtime provider management API', async () => {
|
||||||
|
const loadView = vi.fn(() =>
|
||||||
|
Promise.resolve({
|
||||||
|
schemaVersion: 1,
|
||||||
|
runtimeId: 'opencode',
|
||||||
|
view: {
|
||||||
|
runtimeId: 'opencode',
|
||||||
|
title: 'OpenCode',
|
||||||
|
runtime: {
|
||||||
|
state: 'ready',
|
||||||
|
cliPath: '/opt/homebrew/bin/opencode',
|
||||||
|
version: '1.0.0',
|
||||||
|
managedProfile: 'active',
|
||||||
|
localAuth: 'synced',
|
||||||
|
},
|
||||||
|
providers: [],
|
||||||
|
defaultModel: null,
|
||||||
|
fallbackModel: null,
|
||||||
|
diagnostics: [],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
Object.defineProperty(window, 'electronAPI', {
|
||||||
|
configurable: true,
|
||||||
|
value: {
|
||||||
|
runtimeProviderManagement: {
|
||||||
|
loadView,
|
||||||
|
},
|
||||||
|
} as unknown as ElectronAPI,
|
||||||
|
});
|
||||||
|
|
||||||
|
const root = createRoot(host);
|
||||||
|
await act(async () => {
|
||||||
|
root.render(React.createElement(EnabledHarness, { projectPath: '/tmp/project-a' }));
|
||||||
|
await Promise.resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(loadView).toHaveBeenCalledWith({
|
||||||
|
runtimeId: 'opencode',
|
||||||
|
projectPath: '/tmp/project-a',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('keeps failed model probes scoped to the model result instead of a global success banner', async () => {
|
it('keeps failed model probes scoped to the model result instead of a global success banner', async () => {
|
||||||
const modelId = 'openrouter/anthropic/claude-3.5-haiku';
|
const modelId = 'openrouter/anthropic/claude-3.5-haiku';
|
||||||
const message =
|
const message =
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue