Files
Dune/tests/public-deals-deferred-insolvent-selection.test.ts
T

46 lines
2.5 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { viewGame, type Game } from '../game/engine';
import {
actMentatBribe as act, createMentatBribeFixture as fixture,
mentatBribeInventory as inventory, mentatBribePlayer as player,
} from './fixture-mentat-bribes';
function agree(game: Game, proposer: string, payer: string) {
const offered = act(game, proposer, { type: 'dealOffer', target: payer, terms: 'Pay this turn.',
payment: { kind: 'deferredBribe', payer, recipient: proposer, amount: 4, dueTurn: game.turn } });
const id = offered.deals!.at(-1)!.id;
return { game: act(offered, payer, { type: 'dealRespond', deal: id, accept: true }), id };
}
const spice = (game: Game) => game.players.reduce((sum, seat) => sum + seat.spice + seat.bribes, 0);
for (const pick of ['first', 'second'] as const) {
void test(`external shortage preserves both individually payable deals until payer chooses ${pick}`, () => {
// The fixture reaches actual Basic Mentat with Emperor's original ten
// spice. Both independent agreements are really offered and accepted.
const f = fixture(), first = agree(f.game, f.asker, f.target);
const second = agree(first.game, f.asker, f.target);
const staged = structuredClone(second.game), target = player(staged, f.target), other = player(staged, f.opponent);
const originalSpice = spice(staged);
// Model an external loss: transfer five existing spice, not create or
// destroy it. Each four-spice payment is now possible on its own.
target.spice -= 5; other.spice += 5;
const waiting = act(staged, f.opponent, { type: 'ready' });
assert.equal(waiting.deals!.find(row => row.id === first.id)!.paymentStatus, 'pending');
assert.equal(waiting.deals!.find(row => row.id === second.id)!.paymentStatus, 'pending');
const options = viewGame(waiting, f.target).deferredDealPaymentOptions;
assert.equal(options[first.id]?.blocked, null);
assert.equal(options[second.id]?.blocked, null);
const chosen = pick === 'first' ? first.id : second.id;
const unchosen = pick === 'first' ? second.id : first.id;
const paid = act(waiting, f.target, { type: 'dealPay', deal: chosen });
assert.equal(paid.deals!.find(row => row.id === chosen)!.paymentStatus, 'paid');
assert.equal(paid.deals!.find(row => row.id === unchosen)!.paymentStatus, 'void');
assert.equal(player(paid, f.target).spice, 1);
assert.equal(player(paid, f.asker).bribes, 4);
assert.equal(spice(paid), originalSpice);
assert.deepEqual(inventory(paid), f.originalCards);
});
}