Files
brain/tools/mentor-go-store.test.mjs
T

40 lines
2.2 KiB
JavaScript

import { describe, it, expect } from 'vitest';
import { buildMentorGo, mentorGoValidFor, persistMentorGo, loadMentorGo } from './mentor-go-store.mjs';
const KEY = 'k-test';
describe('mentor-go-store (наставник одобрил этот план — зеркало judge-go-store)', () => {
it('buildMentorGo подписан; mentorGoValidFor true для своего plan_hash + валидной подписи', () => {
const rec = buildMentorGo({ planHash: 'PH1', key: KEY });
expect(mentorGoValidFor(rec, { planHash: 'PH1', key: KEY })).toBe(true);
});
it('чужой plan_hash → false (не одобрение этого плана)', () => {
const rec = buildMentorGo({ planHash: 'PH1', key: KEY });
expect(mentorGoValidFor(rec, { planHash: 'OTHER', key: KEY })).toBe(false);
});
it('битая подпись / чужой ключ → false (fail-closed)', () => {
const rec = buildMentorGo({ planHash: 'PH1', key: KEY });
expect(mentorGoValidFor(rec, { planHash: 'PH1', key: 'wrong' })).toBe(false);
expect(mentorGoValidFor({ ...rec, sig: 'tampered' }, { planHash: 'PH1', key: KEY })).toBe(false);
});
it('null / без approved → false', () => {
expect(mentorGoValidFor(null, { planHash: 'PH1', key: KEY })).toBe(false);
expect(mentorGoValidFor({ plan_hash: 'PH1' }, { planHash: 'PH1', key: KEY })).toBe(false);
});
});
describe('persistMentorGo / loadMentorGo (атомарная запись tmp+rename, mock fs)', () => {
it('persist пишет через tmp+rename; load читает обратно; нет файла → null', () => {
const files = {};
const fsImpl = {
writeFileSync: (p, d) => { files[p] = d; },
renameSync: (a, b) => { files[b] = files[a]; delete files[a]; },
readFileSync: (p) => { if (!(p in files)) { const e = new Error('no'); e.code = 'ENOENT'; throw e; } return files[p]; },
};
const rec = buildMentorGo({ planHash: 'PH1', key: KEY });
expect(loadMentorGo({ sessionId: 'S1', runtimeDir: '/rt', fsImpl })).toBe(null);
persistMentorGo({ record: rec, sessionId: 'S1', runtimeDir: '/rt', fsImpl });
expect(loadMentorGo({ sessionId: 'S1', runtimeDir: '/rt', fsImpl })).toEqual(rec);
});
});