Files
Dune/tests/coalition-advanced-nexus-runtime.test.tsx
T
Quintine 3ba9087405
Verify and publish checkpoint container / container (push) Successful in 10m53s
Connect staged Advanced classic group alliances
2026-10-29 02:37:23 +11:00

72 lines
4.2 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { createElement } from 'react';
import { renderToStaticMarkup } from 'react-dom/server';
import { CoalitionNexus, coalitionNexusOptions } from '../components/coalition-nexus';
import { botActions } from '../game/bots';
import { DIFFICULTIES } from '../game/bot-profiles';
import { coalitionOf, emptyCoalitionState } from '../game/coalition-alliance';
import { applyAction, viewGame, type Game } from '../game/engine';
import { createTruthAllianceFixture } from './fixture-truth-alliance';
/** Public Advanced Harkonnen/Atreides/Emperor setup, genuine first turn and
* ordinary worm Nexus. The fixture selects only unopened original deals,
* auction and Spice positions and scalar lotteries. The optional group's
* empty unexposed ledger is inserted at the real Nexus, before any offer. */
function pair(variant: 'three-short' | 'unlimited') {
const source = createTruthAllianceFixture({advanced:true, consent:'none'});
let game = structuredClone(source.game);
assert.equal(game.advanced, true);
assert.equal(game.nexus, true);
assert.ok(game.players.every(player => !player.ally));
game.coalitionState = emptyCoalitionState(variant);
game = applyAction(game, source.asker, {type:'alliance', target:source.opponent});
game = applyAction(game, source.opponent, {type:'alliance', target:source.asker});
return {game, source};
}
function answer(game: Game, player: string): Game {
const proposal = game.coalitionState!.proposal; assert.ok(proposal);
return applyAction(game, player, {type:'coalitionAnswer', event:proposal.event, nexus:proposal.nexus,
turn:proposal.turn, accept:true, expectedRevision:game.coalitionState!.revision});
}
for (const variant of ['three-short', 'unlimited'] as const) {
void test(`Advanced ${variant} genuine Nexus forms a three-player group with legal bot and human consent`, () => {
const {game, source} = pair(variant);
const group = coalitionOf(game.players, game.coalitionState, source.asker); assert.ok(group);
assert.deepEqual(new Set(group.members), new Set([source.asker, source.opponent]));
const controls = viewGame(game, source.target).coalitionNexus; assert.ok(controls);
assert.equal(controls.variant, variant);
assert.deepEqual(coalitionNexusOptions(controls).invitations.map(row => row.entrant), [source.target]);
const html = renderToStaticMarkup(createElement(CoalitionNexus, {view:controls, onIntent(){}}));
assert.match(html, /Ask to join/);
for (const difficulty of DIFFICULTIES) {
const view = viewGame(game, source.target);
view.players.find(seat => seat.id === source.target)!.bot = difficulty;
const propose = botActions(view).find(action => action.type === 'coalitionPropose');
assert.ok(propose, difficulty);
let pending = applyAction(game, source.target, propose);
assert.deepEqual(pending.coalitionState!.proposal!.approvals, [source.target]);
const projected = viewGame(pending, source.opponent).coalitionNexus; assert.ok(projected);
assert.equal(projected.proposal!.entrant, source.target);
assert.equal(coalitionNexusOptions(projected).mayAccept, true);
assert.match(renderToStaticMarkup(createElement(CoalitionNexus, {view:projected, onIntent(){}})), /Accept invitation/);
pending = answer(pending, source.asker);
assert.deepEqual(new Set(coalitionOf(pending.players, pending.coalitionState, source.asker)!.members),
new Set([source.asker, source.opponent]));
const approvalView = viewGame(pending, source.opponent);
approvalView.players.find(seat => seat.id === source.opponent)!.bot = difficulty;
const approval = botActions(approvalView).find(action => action.type === 'coalitionAnswer');
assert.ok(approval, difficulty);
assert.equal(approval.accept, true);
pending = applyAction(pending, source.opponent, approval);
assert.equal(pending.coalitionState!.proposal, null);
assert.deepEqual(new Set(coalitionOf(pending.players, pending.coalitionState, source.asker)!.members),
new Set([source.asker, source.opponent, source.target]));
assert.equal(viewGame(pending, source.target).coalitionNexus!.variant, variant);
}
});
}