Files
Dune/tests/public-deals-deferred-income.test.ts

58 lines
3.1 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import assert from 'node:assert/strict';
import test from 'node:test';
import { type Action, type Game } from '../game/engine';
import {
actTruthBribe as act, createTruthBribeFixture as fixture,
truthBribeInventory as inventory, truthBribePlayer as player,
} from './fixture-truth-bribe';
import { enterMentatBribeWithUnpaidPromise as enterMentat, finishMentatBribe as finish } from './fixture-mentat-bribes';
function rejected(game: Game, actor: string, action: Action) {
const before = structuredClone(game);
assert.throws(() => act(game, actor, action));
assert.deepEqual(game, before, 'A rejected action leaves the source state unchanged.');
}
/** This is a genuine public H/A/E Basic source at Collection. Its starting
* deal/auction and Spice cards were selected while unopened; all payments and
* Mentat transitions below are actual native actions, with no purse staging. */
void test('already paid bribe escrow can fund a deferred deal at this turn’s real Mentat opening', () => {
const f = fixture({ phase: 7 }), initial = f.game;
assert.equal(initial.phase, 7);
assert.equal(player(initial, f.asker).spice, 10);
// H spends nine now, then receives an independently completed E→H bribe.
let game = act(initial, f.asker, { type: 'bribe', target: f.opponent, amount: 9 });
game = act(game, f.target, { type: 'bribe', target: f.asker, amount: 3 });
assert.equal(player(game, f.asker).spice, 1);
assert.equal(player(game, f.asker).bribes, 3);
assert.equal(player(game, f.opponent).bribes, 9);
// A has not yet received its own nine either; E's three are already in
// H's native escrow and cannot be spent until this turn's real Mentat.
game = act(game, f.asker, { type: 'dealOffer', target: f.opponent,
terms: 'Pay four after the upcoming Mentat opening.',
payment: { kind: 'deferredBribe', payer: f.asker, recipient: f.opponent, amount: 4, dueTurn: game.turn } });
const id = game.deals!.at(-1)!.id;
game = act(game, f.opponent, { type: 'dealRespond', deal: id, accept: true });
assert.equal(game.deals!.at(-1)!.paymentStatus, 'pending');
assert.equal(player(game, f.asker).spice, 1);
assert.equal(player(game, f.asker).bribes, 3);
rejected(game, f.asker, { type: 'dealPay', deal: id });
rejected(game, f.asker, { type: 'bribe', target: f.target, amount: 1 });
const mentat = enterMentat(game);
assert.equal(mentat.phase, 8); assert.equal(mentat.turn, initial.turn);
assert.equal(player(mentat, f.asker).spice, 4);
assert.equal(player(mentat, f.asker).bribes, 0);
assert.equal(player(mentat, f.opponent).bribes, 0);
const paid = act(mentat, f.asker, { type: 'dealPay', deal: id });
assert.equal(paid.deals!.find(deal => deal.id === id)!.paymentStatus, 'paid');
assert.equal(player(paid, f.asker).spice, 0);
assert.equal(player(paid, f.opponent).bribes, 4,
'A payment after this Mentat opening waits for the next opening.');
const next = finish(paid);
assert.equal(next.turn, initial.turn + 1); assert.equal(next.phase, 0);
assert.equal(player(next, f.opponent).bribes, 4);
assert.deepEqual(inventory(next), f.originalCards);
});