test(worktree-isolation): add worktree detection tests

This commit is contained in:
Hibryda 2026-03-11 03:23:58 +01:00
parent 0da53e7390
commit 643ab0a6b6
8 changed files with 125 additions and 2 deletions

View file

@ -205,6 +205,7 @@ import {
isSidecarAlive,
setSidecarAlive,
waitForPendingPersistence,
detectWorktreeFromCwd,
} from './agent-dispatcher';
// Stop any previous dispatcher between tests so `unlistenMsg` is null and start works
@ -622,4 +623,71 @@ describe('agent-dispatcher', () => {
await expect(waitForPendingPersistence()).resolves.toBeUndefined();
});
});
describe('detectWorktreeFromCwd', () => {
it('detects Claude Code worktree path', () => {
const result = detectWorktreeFromCwd('/home/user/project/.claude/worktrees/my-session');
expect(result).toBe('/.claude/worktrees/my-session');
});
it('detects Codex worktree path', () => {
const result = detectWorktreeFromCwd('/home/user/project/.codex/worktrees/task-1');
expect(result).toBe('/.codex/worktrees/task-1');
});
it('detects Cursor worktree path', () => {
const result = detectWorktreeFromCwd('/home/user/project/.cursor/worktrees/feature-x');
expect(result).toBe('/.cursor/worktrees/feature-x');
});
it('returns null for non-worktree CWD', () => {
expect(detectWorktreeFromCwd('/home/user/project')).toBeNull();
expect(detectWorktreeFromCwd('/tmp/work')).toBeNull();
});
it('returns null for empty string', () => {
expect(detectWorktreeFromCwd('')).toBeNull();
});
});
describe('init event CWD worktree detection', () => {
beforeEach(async () => {
await startAgentDispatcher();
});
it('calls setSessionWorktree when init CWD contains worktree path', async () => {
const { setSessionWorktree } = await import('./stores/conflicts.svelte');
// Override the mock adapter to return init with worktree CWD
const { adaptMessage } = await import('./adapters/message-adapters');
(adaptMessage as ReturnType<typeof vi.fn>).mockReturnValueOnce([{
id: 'msg-wt',
type: 'init',
content: { sessionId: 'sdk-wt', model: 'claude-sonnet-4-20250514', cwd: '/home/user/repo/.claude/worktrees/my-session', tools: [] },
timestamp: Date.now(),
}]);
capturedCallbacks.msg!({
type: 'agent_event',
sessionId: 'sess-wt',
event: { type: 'system', subtype: 'init' },
});
expect(setSessionWorktree).toHaveBeenCalledWith('sess-wt', '/.claude/worktrees/my-session');
});
it('does not call setSessionWorktree for non-worktree CWD', async () => {
const { setSessionWorktree } = await import('./stores/conflicts.svelte');
(setSessionWorktree as ReturnType<typeof vi.fn>).mockClear();
capturedCallbacks.msg!({
type: 'agent_event',
sessionId: 'sess-normal',
event: { type: 'system', subtype: 'init' },
});
// The default mock returns cwd: '/tmp' which is not a worktree
expect(setSessionWorktree).not.toHaveBeenCalled();
});
});
});