115 lines
7.9 KiB
TypeScript
115 lines
7.9 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import { test } from 'node:test';
|
|
import { HARASS_WITHDRAW_CARD } from '../game/harass-withdraw';
|
|
import { REINFORCEMENTS_CARD } from '../game/reinforcements';
|
|
import { createIndependentHarkonnenCall, createIndependentIxianPurchase,
|
|
reactionAction, reactionPlayer } from './fixture-classic-independent-nexus-reactions';
|
|
import { advanceClassicIndependentNexus } from './fixture-classic-independent-nexus';
|
|
import { classicDiscoveryNexusClean } from './fixture-discovery-classic-nexus';
|
|
import { settleHarkonnenBetrayalNativeCounters } from './fixture-nexus-harkonnen-betrayal';
|
|
|
|
void test('independent Harass survives a canceled native call and Harkonnen draws the actual Mentat replacement', () => {
|
|
const f = createIndependentHarkonnenCall();
|
|
const frame = f.game.pendingNexusHarkonnenBetrayal!;
|
|
assert.equal(reactionPlayer(f.game, 'atreides').leaders.find(leader => leader.id === f.identity)?.dead, false);
|
|
let game = reactionAction(f.game, 'atreides', { type: 'nexusHarkonnenBetrayalUse', event: frame.source.event });
|
|
assert.equal(game.nexusCards!.cards!.hands.atreides, null);
|
|
assert.deepEqual(game.nexusCards!.cards!.discard, ['harkonnen']);
|
|
assert.equal(reactionPlayer(game, 'harkonnen').traitors.includes(f.identity), false);
|
|
assert.equal(reactionPlayer(game, 'harkonnen').traitors.length, 3);
|
|
assert.equal(game.traitorReserve!.includes(f.identity), true);
|
|
assert.equal(reactionPlayer(game, 'atreides').reserves, reactionPlayer(f.beforeShipment, 'atreides').reserves);
|
|
assert.equal(reactionPlayer(game, 'atreides').tanks, 0);
|
|
assert.equal(reactionPlayer(game, 'atreides').leaders.find(leader => leader.id === f.identity)?.dead, false);
|
|
assert.equal(game.discard.filter(card => card.id === HARASS_WITHDRAW_CARD).length, 1);
|
|
const top = game.traitorReserve![0];
|
|
game = advanceClassicIndependentNexus(game, state => state.phase === 8 && classicDiscoveryNexusClean(state));
|
|
assert.equal(game.pendingNexusHarkonnenReplacement, null);
|
|
assert.equal(game.nexusHarkonnenReplacementHistory!.length, 1);
|
|
assert.equal(game.nexusHarkonnenReplacementHistory![0].drawn, top);
|
|
assert.equal(reactionPlayer(game, 'harkonnen').traitors.length, 4);
|
|
assert.equal(reactionPlayer(game, 'harkonnen').traitors.filter(identity => identity === top).length, 1);
|
|
});
|
|
|
|
void test('all14 independent Harkonnen Pass preserves the actual traitor outcome and cancels Harass', () => {
|
|
const f = createIndependentHarkonnenCall({ advanced: true, skills: true });
|
|
const game = reactionAction(f.game, 'atreides', { type: 'nexusHarkonnenBetrayalPass',
|
|
event: f.game.pendingNexusHarkonnenBetrayal!.source.event });
|
|
assert.equal(game.nexusCards!.cards!.hands.atreides, 'harkonnen');
|
|
assert.deepEqual(game.nexusCards!.cards!.discard, []);
|
|
assert.equal(reactionPlayer(game, 'harkonnen').traitors.includes(f.identity), true);
|
|
assert.equal(reactionPlayer(game, 'harkonnen').traitors.length, 4);
|
|
assert.equal(reactionPlayer(game, 'atreides').leaders.find(leader => leader.id === f.identity)?.dead, true);
|
|
assert.equal(reactionPlayer(game, 'atreides').tanks, 1);
|
|
assert.equal(reactionPlayer(game, 'atreides').reserves, reactionPlayer(f.afterShipment, 'atreides').reserves);
|
|
assert.equal(game.discard.filter(card => card.id === HARASS_WITHDRAW_CARD).length, 1);
|
|
assert.equal(game.pendingNexusHarkonnenReplacement, null);
|
|
assert.deepEqual(game.nexusHarkonnenReplacementHistory, []);
|
|
});
|
|
|
|
void test('all14 printed allied counter precedes independent Harkonnen acknowledgement without Nexus spending', () => {
|
|
const f = createIndependentHarkonnenCall({ advanced: true, skills: true, remote: true });
|
|
assert.equal(f.game.response?.kind, 'harkonnenTraitor');
|
|
assert.equal(f.game.pendingNexusHarkonnenBetrayal, null);
|
|
const game = reactionAction(f.game, 'guild', { type: 'card', card: f.counter, mode: 'cancel' });
|
|
assert.equal(game.pendingNexusHarkonnenBetrayal, null);
|
|
assert.equal(game.pendingNexusHarkonnenReplacement, null);
|
|
assert.equal(game.nexusCards!.cards!.hands.atreides, 'harkonnen');
|
|
assert.deepEqual(game.nexusCards!.cards!.discard, []);
|
|
assert.equal(reactionPlayer(game, 'harkonnen').traitors.includes(f.identity), true);
|
|
assert.equal(reactionPlayer(game, 'atreides').leaders.find(leader => leader.id === f.identity)?.dead, false);
|
|
assert.equal(reactionPlayer(game, 'atreides').reserves, reactionPlayer(f.beforeShipment, 'atreides').reserves);
|
|
assert.equal(game.discard.filter(card => card.id === f.counter).length, 1);
|
|
assert.equal(game.discard.filter(card => card.id === HARASS_WITHDRAW_CARD).length, 1);
|
|
});
|
|
|
|
void test('all14 allowed allied call reaches independent Nexus Use before its original battle and Mentat', () => {
|
|
const f = createIndependentHarkonnenCall({ advanced: true, skills: true, remote: true });
|
|
let game = settleHarkonnenBetrayalNativeCounters(f.game);
|
|
const source = game.pendingNexusHarkonnenBetrayal!.source;
|
|
assert.equal(source.declaration.beneficiary, 'guild');
|
|
game = reactionAction(game, 'atreides', { type: 'nexusHarkonnenBetrayalUse', event: source.event });
|
|
assert.equal(reactionPlayer(game, 'atreides').leaders.find(leader => leader.id === f.identity)?.dead, false);
|
|
assert.equal(reactionPlayer(game, 'atreides').tanks, 0);
|
|
assert.equal(reactionPlayer(game, 'atreides').reserves, reactionPlayer(f.beforeShipment, 'atreides').reserves);
|
|
assert.equal(reactionPlayer(game, 'guild').hand.some(card => card.id === f.counter), true);
|
|
const top = game.traitorReserve![0];
|
|
game = advanceClassicIndependentNexus(game, state => state.phase === 8 && classicDiscoveryNexusClean(state));
|
|
assert.equal(game.nexusHarkonnenReplacementHistory!.length, 1);
|
|
assert.equal(game.nexusHarkonnenReplacementHistory![0].drawn, top);
|
|
assert.equal(reactionPlayer(game, 'harkonnen').traitors.length, 4);
|
|
});
|
|
|
|
void test('all14 Ixian replacement discards the delivered independent lot without repeating its paid invoice', () => {
|
|
const f = createIndependentIxianPurchase({ advanced: true, skills: true });
|
|
const paid = reactionPlayer(f.game, 'atreides'), top = f.game.deck[0];
|
|
assert.equal(paid.spice, reactionPlayer(f.beforePayment, 'atreides').spice - 2);
|
|
assert.equal(paid.hand.some(card => card.id === REINFORCEMENTS_CARD), true);
|
|
const game = reactionAction(f.game, 'atreides', { type: 'nexusIxianReplacementUse',
|
|
event: f.game.pendingNexusIxianReplacement!.event });
|
|
assert.equal(reactionPlayer(game, 'atreides').spice, paid.spice);
|
|
assert.equal(reactionPlayer(game, 'atreides').hand.length, paid.hand.length);
|
|
assert.equal(reactionPlayer(game, 'atreides').hand.some(card => card.id === REINFORCEMENTS_CARD), false);
|
|
assert.deepEqual(reactionPlayer(game, 'atreides').hand.find(card => card.id === top.id), top);
|
|
assert.equal(game.discard.filter(card => card.id === REINFORCEMENTS_CARD).length, 1);
|
|
assert.deepEqual(game.nexusCards!.cards!.discard, ['ixians']);
|
|
assert.equal(game.nexusCards!.cards!.hands.atreides, null);
|
|
assert.equal(game.auction?.index, f.game.auction!.index + 1);
|
|
});
|
|
|
|
void test('Harkonnen keeps the independent purchase and gains one native bonus when passing Ixian replacement', () => {
|
|
const f = createIndependentIxianPurchase({ owner: 'harkonnen' });
|
|
const paid = reactionPlayer(f.game, 'harkonnen'), top = f.game.deck[0];
|
|
const game = reactionAction(f.game, 'harkonnen', { type: 'nexusIxianReplacementPass',
|
|
event: f.game.pendingNexusIxianReplacement!.event });
|
|
const buyer = reactionPlayer(game, 'harkonnen');
|
|
assert.equal(buyer.spice, reactionPlayer(f.beforePayment, 'harkonnen').spice - 2);
|
|
assert.equal(buyer.hand.length, paid.hand.length + 1);
|
|
assert.equal(buyer.hand.some(card => card.id === REINFORCEMENTS_CARD), true);
|
|
assert.deepEqual(buyer.hand.find(card => card.id === top.id), top);
|
|
assert.equal(game.discard.some(card => card.id === REINFORCEMENTS_CARD), false);
|
|
assert.equal(game.nexusCards!.cards!.hands.harkonnen, 'ixians');
|
|
assert.deepEqual(game.nexusCards!.cards!.discard, []);
|
|
assert.equal(game.auction?.index, f.game.auction!.index + 1);
|
|
});
|