Files
thedotmack--claude-mem/tests/worker/dependency-preflight.test.ts
wehub-resource-sync f9447f8e5f
CI / typecheck · build · test · bundle-size (push) Failing after 1s
CI / clean-room dependency closure smoke (push) Failing after 1s
CI / server-runtime e2e (docker · pg + valkey) (push) Failing after 2s
Deploy Install Scripts / deploy (push) Failing after 2s
Windows / build (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:07:03 +08:00

99 lines
3.1 KiB
TypeScript

import { describe, it, expect, beforeEach } from 'bun:test';
import { runWorkerDependencyPreflight } from '../../src/services/worker/dependency-preflight.js';
import {
getDependencyStatus,
recordDependencyStatus,
resetDependencyStatusesForTesting,
} from '../../src/shared/dependency-health.js';
function classifier(error: unknown): { kind: string; message: string } {
return {
kind: error instanceof Error && /Claude executable not found/.test(error.message)
? 'setup_required'
: 'transient',
message: error instanceof Error ? error.message : String(error),
};
}
describe('worker dependency preflight', () => {
beforeEach(() => {
resetDependencyStatusesForTesting();
});
it('records missing uvx using PATH/file checks without checking Claude for Gemini', () => {
let claudeChecked = false;
const snapshot = runWorkerDependencyPreflight({
settings: {
CLAUDE_MEM_PROVIDER: 'gemini',
CLAUDE_MEM_CHROMA_ENABLED: 'true',
},
classifyClaudeError: classifier,
findClaudeExecutable: () => {
claudeChecked = true;
throw new Error('Claude should not be checked for Gemini');
},
env: { PATH: '/tmp/no-uvx' },
platform: 'linux',
homedir: () => '/tmp/home',
pathExists: () => false,
isFile: () => false,
});
expect(claudeChecked).toBe(false);
expect(snapshot.degraded).toBe(true);
expect(getDependencyStatus('uvx')).toMatchObject({
dependency: 'uvx',
kind: 'vector_search_unavailable',
});
expect(getDependencyStatus('uvx')?.remediation).toContain('uv/uvx');
});
it('clears stale Claude CLI setup status when a non-Claude provider is selected', () => {
recordDependencyStatus('claude_cli', 'setup_required', 'old failure');
runWorkerDependencyPreflight({
settings: {
CLAUDE_MEM_PROVIDER: 'openrouter',
CLAUDE_MEM_CHROMA_ENABLED: 'false',
},
classifyClaudeError: classifier,
findClaudeExecutable: () => {
throw new Error('Claude should not be checked for OpenRouter');
},
env: { PATH: '' },
platform: 'linux',
homedir: () => '/tmp/home',
pathExists: () => false,
isFile: () => false,
});
expect(getDependencyStatus('claude_cli')).toBeNull();
});
it('records Claude CLI setup_required when Claude is selected and discovery fails', () => {
runWorkerDependencyPreflight({
settings: {
CLAUDE_MEM_PROVIDER: 'claude',
CLAUDE_MEM_CHROMA_ENABLED: 'false',
},
classifyClaudeError: classifier,
findClaudeExecutable: () => {
throw new Error('Claude executable not found. Please install Claude Code CLI.');
},
env: { PATH: '' },
platform: 'linux',
homedir: () => '/tmp/home',
pathExists: () => false,
isFile: () => false,
});
expect(getDependencyStatus('claude_cli')).toMatchObject({
dependency: 'claude_cli',
kind: 'setup_required',
message: 'Claude executable not found. Please install Claude Code CLI.',
});
expect(getDependencyStatus('claude_cli')?.remediation).toContain('Claude Code CLI');
});
});