48 lines
2.4 KiB
TypeScript
48 lines
2.4 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, type CoalitionNexusView } from '../components/coalition-nexus';
|
|
import type { CoalitionGroup } from '../game/coalition-alliance';
|
|
|
|
const players = ['a', 'b', 'c', 'd'].map(id => ({id, name:id.toUpperCase()}));
|
|
const group: CoalitionGroup = {id:'group', members:['a','b','c'], formedTurn:1, edges:[
|
|
{members:['a','b'], formedTurn:1}, {members:['a','c'], formedTurn:1},
|
|
{members:['b','c'], formedTurn:1},
|
|
]};
|
|
const view = (me:string, admissionBlocked = false): CoalitionNexusView => ({
|
|
me, players, groups:[group], proposal:null, revision:3, variant:'unlimited', admissionBlocked,
|
|
});
|
|
const render = (value:CoalitionNexusView) => renderToStaticMarkup(createElement(CoalitionNexus, {
|
|
view:value, onIntent() {},
|
|
}));
|
|
|
|
void test('a live bribe commitment hides new invitations while retaining the owned leave control', () => {
|
|
const member = view('a', true), choices = coalitionNexusOptions(member), html = render(member);
|
|
assert.deepEqual(choices.invitations, []);
|
|
assert.equal(choices.mayLeave, true);
|
|
assert.match(html, /Invitations are unavailable while a bribe commitment remains unresolved/);
|
|
assert.match(html, /Leave A, B, C/);
|
|
assert.doesNotMatch(html, /Invite D to/);
|
|
|
|
const entrant = view('d', true);
|
|
assert.deepEqual(coalitionNexusOptions(entrant).invitations, []);
|
|
assert.equal(coalitionNexusOptions(entrant).mayLeave, false);
|
|
assert.doesNotMatch(render(entrant), /Ask to join/);
|
|
});
|
|
|
|
void test('invitations return after the block clears; a blocked pending offer can be declined', () => {
|
|
const member = view('a');
|
|
assert.deepEqual(coalitionNexusOptions(member).invitations.map(row => row.entrant), ['d']);
|
|
assert.match(render(member), /Invite D to A, B, C/);
|
|
assert.doesNotMatch(render(member), /bribe commitment remains unresolved/);
|
|
|
|
const pending = view('d', true);
|
|
pending.proposal = {event:'event', nexus:'nexus', turn:2, groupId:group.id,
|
|
original:group, entrant:'d', proposer:'a', approvals:['a']};
|
|
assert.equal(coalitionNexusOptions(pending).mayAccept, false);
|
|
assert.equal(coalitionNexusOptions(pending).mayDecline, true);
|
|
assert.doesNotMatch(render(pending), /Accept invitation/);
|
|
assert.match(render(pending), /may decline this invitation/);
|
|
});
|