Files
Dune/tests/public-deals-future-turn-action-runtime.test.ts
T
Quintine 1e81ce8ad8
Verify and publish checkpoint container / container (push) Successful in 11m8s
Support scheduled travel agreements
2026-10-29 08:19:52 +11:00

57 lines
3.3 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { viewGame, type Action, type Game } from '../game/engine';
import {
actTruthTurnAction as act, advanceTruthTurnAction as advance, bindTruthTurnAction as bind,
createTruthTurnActionFixture as fixture, finishTruthTurnAction as finish,
settleTruthTurnAction as settle, truthTurnActionClean as clean,
truthTurnActionInventory as inventory, truthTurnActionPlayer as player,
truthTurnActionPromise as promise, truthTurnActionShip as ship,
} from './fixture-truth-turn-action';
function reject(game: Game, actor: string, action: Action) {
const before = structuredClone(game);
assert.throws(() => act(game, actor, action));
assert.deepEqual(game, before, 'Rejected actions preserve both original receipts.');
}
/** Real Basic three-seat game, actual dealt Truthtrance and native movement
* window. This schedules the later public obligation first; it then asks and
* fulfills a distinct genuine whole-turn Truthtrance shipment in turn one. */
void test('a completed earlier whole-turn Truthtrance receipt preserves a scheduled future travel deal through rollover', () => {
const f = fixture(), dueTurn = f.game.turn + 1, originalCards = inventory(f.game);
let game = act(f.game, f.asker, {type:'dealOffer', target:f.target, terms:'Ship to Polar Sink next turn.',
travel:{kind:'ship', territory:'polar_sink', minimum:1, answer:true, dueTurn}});
const deal = game.deals?.at(-1); assert.ok(deal);
game = act(game, f.target, {type:'dealRespond', deal:deal.id, accept:true});
assert.equal(viewGame(game, f.target).dealTravelStatus[deal.id], 'scheduled');
const scheduled = game.travelPromises?.find(row => row.sourceDeal === deal.id); assert.ok(scheduled);
assert.equal(scheduled.turn, dueTurn); assert.equal(scheduled.player, f.target);
assert.equal(scheduled.fulfilled, false); assert.equal(scheduled.released, false);
game = bind(f, 'yes', ship(), game).game;
const truth = game.turnActionPromises?.at(-1); assert.ok(truth);
assert.equal(truth.turn, f.game.turn); assert.equal(truth.player, f.target);
assert.equal(viewGame(game, f.target).dealTravelStatus[deal.id], 'scheduled');
reject(game, f.target, f.end);
game = settle(act(game, f.target, f.shipment));
assert.equal(promise(game, f.target).fulfilled, true);
assert.equal(viewGame(game, f.target).dealTravelStatus[deal.id], 'scheduled');
assert.equal(game.travelPromises?.find(row => row.sourceDeal === deal.id)?.fulfilled, false);
const firstForces = player(game, f.target).forces['polar_sink:0'];
game = settle(act(game, f.target, f.end));
game = finish(game);
assert.equal(game.turn, dueTurn);
assert.equal(viewGame(game, f.target).dealTravelStatus[deal.id], 'pending');
assert.equal(promise(game, f.target).fulfilled, true);
game = advance(game, state => state.turn === dueTurn && state.phase === 5 &&
state.active === f.target && clean(state) && !state.pendingShipment, [], true);
reject(game, f.target, f.end);
game = settle(act(game, f.target, f.shipment));
assert.equal(viewGame(game, f.target).dealTravelStatus[deal.id], 'fulfilled');
assert.equal(player(game, f.target).forces['polar_sink:0'], firstForces + 1);
assert.equal(promise(game, f.target).fulfilled, true);
assert.deepEqual(inventory(game), originalCards);
});