Files
Dune/tests/duke-public-revival-uncertainty.test.ts
T
Quintine 59cb336c80
Verify and publish checkpoint container / container (push) Canceled after 0s
Resolve Duke uncertainty on public events
2026-10-29 19:30:00 +11:00

66 lines
3.6 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { applyAction, createGame, newPlayer } from '../game/engine';
import { baseDeck } from '../game/cards';
import { createDukeVidal, DUKE_VIDAL_ID } from '../game/duke-vidal';
import { newRevivalRules } from '../game/revival';
import { actDukeAmbassador, createDukeAmbassadorFixture } from './fixture-duke-ambassador';
/** Stage the public dead Duke and capture marker in an Advanced roster; the
* actual return uses the native action. */
function revivalSource(legacy = false) {
const game = createGame('DUKEPUBLICREVIVAL', newPlayer('ec', 'Ecaz', 'ecaz'), true, ['ecaz']);
game.players.push(newPlayer('m', 'Moritani', 'moritani'), newPlayer('g', 'Guild', 'guild'));
Object.assign(game, { status: 'playing', turn: 3, phase: 4, order: ['ec', 'm', 'g'],
revivalRules: newRevivalRules() });
game.dukeVidal = createDukeVidal();
Object.assign(game.dukeVidal.leader, { dead: true, deaths: 1 });
game.players[0].spice = 10;
game.players[0].leaders.slice(0, 4).forEach(leader => Object.assign(leader, { dead: true, deaths: 1 }));
game.deck = baseDeck();
if (legacy) delete game.dukeCaptureUncertain;
else game.dukeCaptureUncertain = true;
return game;
}
for (const legacy of [false, true]) {
void test(`public paid Duke revival clears ${legacy ? 'legacy' : 'uncertain'} capture history`, () => {
const source = revivalSource(legacy), initial = structuredClone(source), before = source.players[0].spice;
assert.throws(() => applyAction(source, 'ec', { type: 'reviveLeader', leader: 'not-a-leader' }));
assert.deepEqual(source, initial, 'Rejected action does not clear uncertainty or spend spice');
const done = applyAction(source, 'ec', { type: 'reviveLeader', leader: DUKE_VIDAL_ID });
assert.equal(done.dukeCaptureUncertain, false);
assert.equal(done.dukeVidal!.leader.dead, false);
assert.equal(done.dukeVidal!.controller, null);
assert.equal(done.players[0].spice, before - 5);
assert.ok(done.log.some(entry => entry.text.includes('revived Duke Prad Vidal')));
});
void test(`public Ghola Duke revival clears ${legacy ? 'legacy' : 'uncertain'} capture history`, () => {
const source = revivalSource(legacy);
const index = source.deck.findIndex(card => card.effect === 'ghola'); assert.ok(index >= 0);
const card = source.deck.splice(index, 1)[0]; source.players[0].hand.push(card);
const done = applyAction(source, 'ec', { type: 'card', card: card.id, leader: DUKE_VIDAL_ID });
assert.equal(done.dukeCaptureUncertain, false);
assert.equal(done.dukeVidal!.leader.dead, false);
assert.equal(done.dukeVidal!.controller, null);
assert.ok(done.log.some(entry => entry.text.includes('revived Duke Prad Vidal with Ghola')));
assert.ok(done.discard.some(item => item.id === card.id));
});
}
void test('public Tleilaxu Ambassador Duke return clears uncertainty, but decline does not', () => {
const f = createDukeAmbassadorFixture(), source = structuredClone(f.currentGrant);
source.dukeCaptureUncertain = true;
const declined = actDukeAmbassador(structuredClone(source), f.owner,
{ type: 'decision', event: f.event, decline: true });
assert.equal(declined.dukeCaptureUncertain, true);
assert.equal(declined.dukeVidal!.leader.dead, true);
const done = actDukeAmbassador(source, f.owner,
{ type: 'decision', event: f.event, leader: DUKE_VIDAL_ID });
assert.equal(done.dukeCaptureUncertain, false);
assert.equal(done.dukeVidal!.leader.dead, false);
assert.equal(done.dukeVidal!.controller, null);
assert.ok(done.log.some(entry => entry.text.includes('revived Duke Prad Vidal for free through the Tleilaxu Ambassador')));
});