import assert from 'node:assert/strict'; import test from 'node:test'; import { parseKaramaTleilaxuSpecialSource 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: 'tleilaxu', specialKaramaUsed: false }, { id: 'a', faction: 'atreides', specialKaramaUsed: false }] }); const event = JSON.stringify(['karamaTleilaxuSpecial', 2, 'h']); void test('Tleilaxu special window is public, turn-bound and independent of private custody', () => { const game = source(), before = structuredClone(game); assert.deepEqual(windowCardOpportunity(game, 'karamaTleilaxuSpecial'), { effect: 'karamaTleilaxuSpecial', source: event, turn: 2 }); assert.deepEqual(parse(event), { turn: 2, owner: 'h' }); assert.equal(windowCardNativeEffect('karamaTleilaxuSpecial'), 'karama'); assert.equal(windowCardOpportunity({ ...game, response: { kind: 'voice' }, decision: { kind: 'other' } }, 'karamaTleilaxuSpecial')?.source, event); assert.equal(windowCardOpportunity(game, 'karamaTleilaxuSpecial', 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: 'tleilaxu', specialKaramaUsed: true }] }, { players: [{ id: 'h', faction: 'atreides' }] }, { players: [{ id: 'h', faction: 'tleilaxu' }, { id: 'h', faction: 'atreides' }] }, { players: [{ id: 'h', faction: 'tleilaxu' }, { id: 'h2', faction: 'tleilaxu' }] }]) assert.equal(windowCardOpportunity({ ...game, ...changes } as WindowCardGame, 'karamaTleilaxuSpecial'), null); for (const value of ['', '[]', '["karamaTleilaxuSpecial",2," h"]', '["karamaTleilaxuSpecial", 2,"h"]', '["karamaTleilaxuSpecial",0,"h"]', '["karamaTleilaxuSpecial",2,"h","extra"]']) assert.equal(parse(value), null); assert.equal(windowCardOpportunity(game, 'karamaTleilaxuSpecial', JSON.stringify(['karamaTleilaxuSpecial', 2, 'a'])), null); assert.equal(windowCardOpportunity({ ...game, turn: 3 }, 'karamaTleilaxuSpecial', event), null); assert.ok(windowCardOpportunity({ ...game, players: [{ id: 'h', faction: 'tleilaxu' }] }, 'karamaTleilaxuSpecial')); });