Files
brain/tools/enforce-askuser-answer-parser-floor-escape.test.mjs
T

39 lines
1.7 KiB
JavaScript

// tools/enforce-askuser-answer-parser-floor-escape.test.mjs
import { describe, it, expect } from 'vitest';
import { join } from 'node:path';
import { processEvent } from './enforce-askuser-answer-parser.mjs';
import { verifyFloorEscapeRecord } from './askuser-answer-parser.mjs';
function memFs() {
const s = new Map(); const norm = (p) => String(p).replace(/\\/g, '/');
return { s,
appendFileSync: (p, d) => { const n = norm(p); s.set(n, (s.get(n) || '') + d); },
mkdirSync: () => {} };
}
const DIR = '/rt'; const KEY = 'test-receipt-key';
const ev = (action) => ({
session_id: 's1',
tool_input: { questions: [{ question: 'Q?' }] },
tool_response: { answers: { 'Q?': `да, разрешаю. FLOOR-ESCAPE: ${action}` } },
});
function readLines(fs) {
const raw = fs.s.get(join(DIR, 'askuser-decisions-s1.jsonl').replace(/\\/g, '/')) || '';
return raw.trim().split('\n').filter(Boolean).map((l) => JSON.parse(l));
}
describe('processEvent — key-gated подпись floor_escape', () => {
it('ключ есть → floor_escape несёт валидную подпись', () => {
const fs = memFs();
processEvent(ev('bash:git push --force'), { runtimeDir: DIR, nowMs: 5, keyImpl: () => KEY, fsImpl: fs });
const esc = readLines(fs).find((r) => r.type === 'floor_escape');
expect(esc).toBeTruthy();
expect(verifyFloorEscapeRecord(esc, KEY)).toBe(true);
});
it('ключ null → floor_escape без подписи (как сегодня)', () => {
const fs = memFs();
processEvent(ev('bash:git push --force'), { runtimeDir: DIR, nowMs: 5, keyImpl: () => null, fsImpl: fs });
const esc = readLines(fs).find((r) => r.type === 'floor_escape');
expect(esc.sig).toBeUndefined();
});
});