agent-ecosystem/src/renderer/components/team/dialogs/ProvisioningProviderStatusList.test.ts

152 lines
4.6 KiB
TypeScript

import { OPENCODE_WINDOWS_ACCESS_DENIED_MESSAGE } from '@shared/utils/openCodeWindowsAccessDenied';
import { describe, expect, it } from 'vitest';
import { getProvisioningFailureHint } from './ProvisioningProviderStatusList';
describe('getProvisioningFailureHint', () => {
it('returns the OpenCode Windows permissions hint for OpenCode access-denied details', () => {
expect(
getProvisioningFailureHint(null, [
{
providerId: 'opencode',
status: 'failed',
details: [OPENCODE_WINDOWS_ACCESS_DENIED_MESSAGE],
},
])
).toBe(
'Fix folder permissions or move the project to a user-writable folder. Running as administrator is only a temporary workaround.'
);
});
it('keeps non-OpenCode access-denied details on the generic CLI hint', () => {
expect(
getProvisioningFailureHint(null, [
{
providerId: 'anthropic',
status: 'failed',
details: ['EACCES: permission denied'],
},
])
).toBe(
'Make sure the local Claude CLI binary exists and can be started, then reopen this dialog.'
);
});
it('does not treat a mixed-provider generic access-denied message as OpenCode-specific', () => {
expect(
getProvisioningFailureHint('EACCES: permission denied', [
{
providerId: 'opencode',
status: 'ready',
details: [],
},
{
providerId: 'anthropic',
status: 'failed',
details: ['EACCES: permission denied'],
},
])
).toBe(
'Make sure the local Claude CLI binary exists and can be started, then reopen this dialog.'
);
});
it('does not prefer OpenCode access-denied notes over another provider failure', () => {
expect(
getProvisioningFailureHint(null, [
{
providerId: 'opencode',
status: 'notes',
details: [OPENCODE_WINDOWS_ACCESS_DENIED_MESSAGE],
},
{
providerId: 'anthropic',
status: 'failed',
details: ['EACCES: permission denied'],
},
])
).toBe(
'Make sure the local Claude CLI binary exists and can be started, then reopen this dialog.'
);
});
it('uses a normalized OpenCode access-denied message for a failed mixed-provider check', () => {
expect(
getProvisioningFailureHint(OPENCODE_WINDOWS_ACCESS_DENIED_MESSAGE, [
{
providerId: 'opencode',
status: 'failed',
details: [],
},
{
providerId: 'anthropic',
status: 'ready',
details: [],
},
])
).toBe(
'Fix folder permissions or move the project to a user-writable folder. Running as administrator is only a temporary workaround.'
);
});
it('uses a raw OpenCode access-denied message when no other provider failed', () => {
expect(
getProvisioningFailureHint('EPERM: operation not permitted', [
{
providerId: 'opencode',
status: 'failed',
details: [],
},
{
providerId: 'anthropic',
status: 'ready',
details: [],
},
])
).toBe(
'Fix folder permissions or move the project to a user-writable folder. Running as administrator is only a temporary workaround.'
);
});
it('uses the OpenCode Windows permissions hint for a single OpenCode access-denied message', () => {
expect(
getProvisioningFailureHint('EPERM: operation not permitted', [
{
providerId: 'opencode',
status: 'failed',
details: [],
},
])
).toBe(
'Fix folder permissions or move the project to a user-writable folder. Running as administrator is only a temporary workaround.'
);
});
it('keeps existing OpenCode runtime missing and MCP hints unchanged', () => {
expect(
getProvisioningFailureHint(null, [
{
providerId: 'opencode',
status: 'failed',
details: [
'OpenCode runtime binary is not installed or not reachable by launch preflight.',
],
},
])
).toBe(
'Install or retry OpenCode runtime from the provider status card, then reopen this dialog.'
);
expect(
getProvisioningFailureHint(null, [
{
providerId: 'opencode',
status: 'failed',
details: ['OpenCode app MCP is unreachable. Retry launch to refresh the app MCP bridge.'],
},
])
).toBe(
'Retry launch to refresh the OpenCode app MCP bridge. If it repeats, restart the app and OpenCode runtime.'
);
});
});