import { describe, it, expect } from 'vitest'; import { buildArbitrationCard, ARBITRATION_OPTIONS } from './arbitration-card.mjs'; describe('buildArbitrationCard', () => { const base = { side: 'mentor', level: 'L1', round: 3, objectionVerbatim: 'Шаг 2 склеен: чтение и правка в одном пункте — разбей.', controllerPositionVerbatim: 'Не согласен: шаг 2 атомарен, чтение нужно ровно для этой правки.', }; it('цитаты переданы ДОСЛОВНО (без перефраза)', () => { const c = buildArbitrationCard(base); expect(c.objection).toBe(base.objectionVerbatim); expect(c.position).toBe(base.controllerPositionVerbatim); }); it('три варианта выбора в фиксированном порядке', () => { const c = buildArbitrationCard(base); expect(c.options.map((o) => o.key)).toEqual(['hold', 'accept', 'own']); expect(ARBITRATION_OPTIONS).toEqual(['hold', 'accept', 'own']); }); it('каждый вариант несёт нейтральную строку «что меняет выбор»', () => { const c = buildArbitrationCard(base); for (const o of c.options) expect(typeof o.whatChanges === 'string' && o.whatChanges.length > 0).toBe(true); }); it('есть аффорданс «объясни подробнее»', () => { expect(buildArbitrationCard(base).explainAffordance).toBe(true); }); it('сторона судьи меняет заголовок, не ломает форму', () => { const c = buildArbitrationCard({ ...base, side: 'judge', level: 'L2' }); expect(c.title).toMatch(/судь/i); expect(c.options.map((o) => o.key)).toEqual(['hold', 'accept', 'own']); }); it('пустые/нестроковые цитаты не роняют (fail-safe → пустая строка)', () => { const c = buildArbitrationCard({ ...base, objectionVerbatim: null, controllerPositionVerbatim: undefined }); expect(c.objection).toBe(''); expect(c.position).toBe(''); }); it('SP3-c: sealAction передан → card.sealAction + hold-текст несёт точную escape-строку', () => { const c = buildArbitrationCard({ ...base, sealAction: 'owner-seal:abc123' }); expect(c.sealAction).toBe('owner-seal:abc123'); const hold = c.options.find((o) => o.key === 'hold'); expect(hold.whatChanges).toContain('FLOOR-ESCAPE: owner-seal:abc123'); }); it('SP3-c: sealAction не передан → null, прежний hold-текст, форма цела', () => { const c = buildArbitrationCard(base); expect(c.sealAction).toBe(null); const hold = c.options.find((o) => o.key === 'hold'); expect(hold.whatChanges).not.toContain('FLOOR-ESCAPE'); expect(typeof hold.whatChanges).toBe('string'); expect(hold.whatChanges.length).toBeGreaterThan(0); }); });