import { describe, it, expect } from 'vitest'; import { decide } from './enforce-branch-switch.mjs'; describe('enforce-branch-switch / decide', () => { it('allows non-Bash tools', () => { expect(decide({ toolName: 'Edit', command: '' }).block).toBe(false); }); it('allows non-git Bash commands', () => { expect(decide({ toolName: 'Bash', command: 'ls -la', actualBranch: 'feat/x', expectedBranch: 'main' }).block).toBe(false); }); it('allows git status / git log (read-only)', () => { expect(decide({ toolName: 'Bash', command: 'git status', actualBranch: 'feat/x', expectedBranch: 'main' }).block).toBe(false); }); it('blocks git commit when actual != expected', () => { const r = decide({ toolName: 'Bash', command: 'git commit -m "x"', actualBranch: 'feat/supplier', expectedBranch: 'main', assistantText: 'some random text', }); expect(r.block).toBe(true); expect(r.message).toMatch(/feat\/supplier.*main/); }); it('blocks git push on wrong branch', () => { const r = decide({ toolName: 'Bash', command: 'LEFTHOOK=0 git push origin main', actualBranch: 'feat/other', expectedBranch: 'main', assistantText: '', }); expect(r.block).toBe(true); }); it('allows when BRANCH-SWITCH-CONFIRMED marker present in assistant text', () => { const r = decide({ toolName: 'Bash', command: 'git commit -m "x"', actualBranch: 'feat/x', expectedBranch: 'main', assistantText: 'BRANCH-SWITCH-CONFIRMED — продолжаю на feat/x по плану', }); expect(r.block).toBe(false); }); it('allows when RECOVERY-INTENT marker present', () => { const r = decide({ toolName: 'Bash', command: 'git cherry-pick abc123', actualBranch: 'main', expectedBranch: 'feat/x', assistantText: 'RECOVERY-INTENT: cherry-pick после смены ветки чужой сессией', }); expect(r.block).toBe(false); }); it('allows when override phrase present', () => { const r = decide({ toolName: 'Bash', command: 'git commit -m "x"', actualBranch: 'feat/x', expectedBranch: 'main', assistantText: '', override: { phrase: 'recovery', suppresses: ['branch-switch'] }, }); expect(r.block).toBe(false); }); it('allows on match', () => { const r = decide({ toolName: 'Bash', command: 'git commit -m "x"', actualBranch: 'main', expectedBranch: 'main', }); expect(r.block).toBe(false); }); it('defaults expected to "main" if unset and matches when on main', () => { expect(decide({ toolName: 'Bash', command: 'git commit', actualBranch: 'main', expectedBranch: '' }).block).toBe(false); }); it('defaults expected to "main" if unset and blocks when on feature branch', () => { const r = decide({ toolName: 'Bash', command: 'git commit', actualBranch: 'feat/x', expectedBranch: '' }); expect(r.block).toBe(true); }); });