import assert from 'node:assert/strict'; import test from 'node:test'; import { parseKaramaEmperorSpecialSource as parse, windowCardNativeEffect, windowCardOpportunity, type WindowCardGame } from '../game/window-card-play'; const source = (): WindowCardGame => ({ status: 'playing', advanced: true, phase: 4, turn: 2, shieldWallDestroyed: false, players: [{ id: 'h', faction: 'emperor', specialKaramaUsed: false }, { id: 'a', faction: 'atreides', specialKaramaUsed: false }] }); const event = JSON.stringify(['karamaEmperorSpecial', 2, 'h']); void test('Emperor special window is public, turn-bound and independent of private custody', () => { const game = source(), before = structuredClone(game); assert.deepEqual(windowCardOpportunity(game, 'karamaEmperorSpecial'), { effect: 'karamaEmperorSpecial', source: event, turn: 2 }); assert.deepEqual(parse(event), { turn: 2, owner: 'h' }); assert.equal(windowCardNativeEffect('karamaEmperorSpecial'), 'karama'); assert.equal(windowCardOpportunity({ ...game, response: { kind: 'voice' }, decision: { kind: 'other' } }, 'karamaEmperorSpecial')?.source, event); assert.equal(windowCardOpportunity(game, 'karamaEmperorSpecial', event)?.source, event); assert.deepEqual(game, before); }); void test('special opportunity ends with use, turn or phase; malformed sources reject', () => { const game = source(); for (const changes of [{ status: 'lobby' }, { advanced: false }, { phase: 3 }, { turn: 0 }, { players: [{ id: 'h', faction: 'emperor', specialKaramaUsed: true }] }, { players: [{ id: 'h', faction: 'atreides' }] }, { players: [{ id: 'h', faction: 'emperor' }, { id: 'h', faction: 'atreides' }] }, { players: [{ id: 'h', faction: 'emperor' }, { id: 'h2', faction: 'emperor' }] }]) assert.equal(windowCardOpportunity({ ...game, ...changes } as WindowCardGame, 'karamaEmperorSpecial'), null); for (const value of ['', '[]', '["karamaEmperorSpecial",2," h"]', '["karamaEmperorSpecial", 2,"h"]', '["karamaEmperorSpecial",0,"h"]', '["karamaEmperorSpecial",2,"h","extra"]']) assert.equal(parse(value), null); assert.equal(windowCardOpportunity(game, 'karamaEmperorSpecial', JSON.stringify(['karamaEmperorSpecial', 2, 'a'])), null); assert.equal(windowCardOpportunity({ ...game, turn: 3 }, 'karamaEmperorSpecial', event), null); assert.ok(windowCardOpportunity({ ...game, players: [{ id: 'h', faction: 'emperor' }] }, 'karamaEmperorSpecial')); });