70 lines
3.2 KiB
TypeScript
70 lines
3.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, type CoalitionNexusView } from '../components/coalition-nexus';
|
|
import type { CoalitionGroup } from '../game/coalition-alliance';
|
|
|
|
const players = ['a', 'b', 'c', 'd', 'e'].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): CoalitionNexusView => ({
|
|
me, players, groups: [group], proposal: null, revision: 3, variant: 'unlimited',
|
|
});
|
|
const render = (value: CoalitionNexusView) => renderToStaticMarkup(createElement(CoalitionNexus, {
|
|
view: value, onIntent() {},
|
|
}));
|
|
|
|
void test('only the specified group and entrant invitation is blocked', () => {
|
|
const member = view('a');
|
|
member.blockedInvitations = [{groupId: 'group', entrant: 'd'}, {groupId: 'other', entrant: 'e'}];
|
|
const choices = coalitionNexusOptions(member);
|
|
assert.deepEqual(choices.invitations.map(row => row.entrant), ['e']);
|
|
assert.equal(choices.mayLeave, true);
|
|
const html = render(member);
|
|
assert.doesNotMatch(html, /Invite D to/);
|
|
assert.match(html, /Invite E to A, B, C/);
|
|
assert.match(html, /conflict with your commitments/);
|
|
assert.match(html, /Leave A, B, C/);
|
|
|
|
const entrant = view('d');
|
|
entrant.blockedInvitations = [{groupId: 'group', entrant: 'e'}];
|
|
assert.match(render(entrant), /Ask to join A, B, C/);
|
|
entrant.blockedInvitations = [{groupId: 'group', entrant: 'd'}];
|
|
assert.doesNotMatch(render(entrant), /Ask to join/);
|
|
});
|
|
|
|
void test('a blocked pending acceptance can still be declined or withdrawn', () => {
|
|
const pending = view('d');
|
|
pending.proposal = {event: 'event', nexus: 'nexus', turn: 2, groupId: group.id,
|
|
original: group, entrant: 'd', proposer: 'a', approvals: ['a', 'b']};
|
|
pending.acceptBlocked = true;
|
|
assert.equal(coalitionNexusOptions(pending).mayAccept, false);
|
|
assert.equal(coalitionNexusOptions(pending).mayDecline, true);
|
|
assert.doesNotMatch(render(pending), /Accept invitation/);
|
|
assert.match(render(pending), /conflict with your commitments/);
|
|
assert.match(render(pending), /Decline and cancel invitation/);
|
|
|
|
pending.me = 'b';
|
|
assert.match(render(pending), /Withdraw approval and cancel invitation/);
|
|
pending.me = 'd';
|
|
pending.acceptBlocked = false;
|
|
assert.equal(coalitionNexusOptions(pending).mayAccept, true);
|
|
assert.match(render(pending), /Accept invitation/);
|
|
});
|
|
|
|
void test('legacy admissionBlocked still blocks all invitations and acceptance', () => {
|
|
const member = view('a');
|
|
member.admissionBlocked = true;
|
|
assert.deepEqual(coalitionNexusOptions(member).invitations, []);
|
|
assert.equal(coalitionNexusOptions(member).mayLeave, true);
|
|
const pending = view('d');
|
|
pending.admissionBlocked = 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);
|
|
});
|