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