Files
portal/tools/router-prehook.test.mjs
T
Дмитрий c7e02eeac9 feat(router): подключить UTF-8 helper к трём хукам (stage 3 follow-up 1)
router-prehook, router-stop-gate, router-tool-gate теперь читают stdin
через readStdinAsUtf8 (StringDecoder). Русский в промпте корректно
доходит до Anthropic API и в state-файл — никаких mojibake типа
'посмотри'.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 15:36:14 +03:00

58 lines
2.5 KiB
JavaScript

import { describe, it, expect } from 'vitest';
import { buildStateFromClassification, isEnforcementRequired } from './router-prehook.mjs';
describe('buildStateFromClassification', () => {
it('builds full state object', () => {
const cls = { taskType: 'feature', micro: false, recommendedNode: '#19', confidence: 0.9, source: 'regex', recommendedChain: 'L1' };
const s = buildStateFromClassification(cls, { sessionId: 'abc', promptHash: '12345' });
expect(s.sessionId).toBe('abc');
expect(s.promptHash).toBe('12345');
expect(s.classification).toEqual(cls);
expect(s.skillInvokedThisTurn).toBe(false);
expect(s.chainProgress).toEqual([]);
expect(s.enforcementRequired).toBe(true);
expect(s.timestamp).toBeDefined();
});
it('enforcementRequired false on micro', () => {
const s = buildStateFromClassification({ taskType: 'bugfix', micro: true, recommendedNode: null }, { sessionId: 'a', promptHash: 'b' });
expect(s.enforcementRequired).toBe(false);
});
it('enforcementRequired false when no recommendedNode', () => {
const s = buildStateFromClassification({ taskType: 'question', micro: false, recommendedNode: null }, { sessionId: 'a', promptHash: 'b' });
expect(s.enforcementRequired).toBe(false);
});
it('enforcementRequired false on excluded taskType', () => {
const s = buildStateFromClassification({ taskType: 'question', micro: false, recommendedNode: '#60' }, { sessionId: 'a', promptHash: 'b' });
expect(s.enforcementRequired).toBe(false);
});
});
describe('isEnforcementRequired', () => {
it('true on feature with node', () => {
expect(isEnforcementRequired({ taskType: 'feature', micro: false, recommendedNode: '#19' })).toBe(true);
});
it('false on micro', () => {
expect(isEnforcementRequired({ taskType: 'feature', micro: true, recommendedNode: '#19' })).toBe(false);
});
it('false when no node', () => {
expect(isEnforcementRequired({ taskType: 'feature', micro: false, recommendedNode: null })).toBe(false);
});
it('false on question/memory-sync (excluded)', () => {
expect(isEnforcementRequired({ taskType: 'question', micro: false, recommendedNode: '#60' })).toBe(false);
expect(isEnforcementRequired({ taskType: 'memory-sync', micro: false, recommendedNode: '#33' })).toBe(false);
});
});
describe('UTF-8 cyrillic stdin (regression — Stage 3 fix 1)', () => {
it('module loads with UTF-8 helper wired (smoke)', async () => {
const mod = await import('./router-prehook.mjs');
expect(typeof mod.buildStateFromClassification).toBe('function');
});
});