// Characterization for reorderParticipants correct usage. // replay-combat.js calls it with wrong signature (swallowed by try/catch), // so real behavior untested. Lock what it actually does. const shared = require('@ttrpg/shared'); const { makeParticipant, startEncounter, nextTurn, reorderParticipants } = shared; function p(id, init, extra = {}) { return makeParticipant({ id, name: id, type: 'monster', initiative: init, maxHp: 100, currentHp: 100, ...extra, }); } function enc(ps) { return { name:'t', participants:ps, isStarted:false, isPaused:false, round:0, currentTurnParticipantId:null, turnOrderIds:[] }; } describe('reorderParticipants', () => { test('drag before target (1-list model)', () => { const ps = [p('a', 10), p('b', 20), p('c', 20)]; // b,c tie let e = enc(ps); e = { ...e, ...startEncounter(e).patch }; // initial order: b,c,a (init 20,20,10) expect(e.turnOrderIds).toEqual(['b', 'c', 'a']); const r = reorderParticipants(e, 'c', 'b'); // drag c before b: remove c → [b,a], insert before b → [c,b,a] expect(r.patch.participants.map(p => p.id)).toEqual(['c', 'b', 'a']); }); test('cross-init drag allowed (1-list, DM override)', () => { const ps = [p('a', 10), p('b', 20)]; let e = enc(ps); e = { ...e, ...startEncounter(e).patch }; // [b,a] const r = reorderParticipants(e, 'a', 'b'); expect(r.patch.participants.map(p => p.id)).toEqual(['a', 'b']); }); test('throws if id not found', () => { const ps = [p('a', 10), p('b', 20)]; let e = enc(ps); e = { ...e, ...startEncounter(e).patch }; expect(() => reorderParticipants(e, 'a', 'zzz')).toThrow(); }); test('syncs turnOrderIds = participants order (1-list, fixes BUG-6)', () => { const ps = [p('a', 10), p('b', 20), p('c', 20)]; let e = enc(ps); e = { ...e, ...startEncounter(e).patch }; const r = reorderParticipants(e, 'c', 'b'); expect(r.patch.turnOrderIds).toEqual(['c', 'b', 'a']); expect(r.patch.turnOrderIds).toEqual(r.patch.participants.map(p => p.id)); }); // BUG-6 candidate: reorder should affect turnOrderIds so mid-combat // drag-drop changes who goes next within same-initiative tie. // Currently RED (turnOrderIds not in patch). test('reorder updates turnOrderIds to reflect new participant order', () => { const ps = [p('a', 10), p('b', 20), p('c', 20)]; let e = enc(ps); e = { ...e, ...startEncounter(e).patch }; // order: b,c,a e = { ...e, ...reorderParticipants(e, 'c', 'b').patch }; expect(e.turnOrderIds).toEqual(['c', 'b', 'a']); }); });