58 lines
3.0 KiB
TypeScript
58 lines
3.0 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import { Children, createElement, isValidElement } from 'react';
|
|
import { renderToStaticMarkup } from 'react-dom/server';
|
|
import type { Action } from '../game/engine';
|
|
import { EmperorExtortionPriority, type EmperorExtortionPriorityProps } from '../components/emperor-extortion-priority';
|
|
|
|
function props(): EmperorExtortionPriorityProps & { sent: Action[] } {
|
|
const sent: Action[] = [];
|
|
return {game:{emperorExtortionPriority:{event:'extortion-event',recipient:'ally',canContinue:true},
|
|
players:[{id:'ally',name:'Ally'}]}, busy:false, sent, act(action) {sent.push(action);}};
|
|
}
|
|
const render = (input: EmperorExtortionPriorityProps) => renderToStaticMarkup(createElement(EmperorExtortionPriority, input));
|
|
function button(input: EmperorExtortionPriorityProps) {
|
|
const section = EmperorExtortionPriority(input); assert.ok(section);
|
|
const match = Children.toArray(section.props.children).find(child => isValidElement(child) &&
|
|
(child.props as {'data-testid'?: string})['data-testid'] === 'emperor-extortion-continue');
|
|
assert.ok(isValidElement<{onClick:() => void; disabled:boolean}>(match));
|
|
return match;
|
|
}
|
|
|
|
void test('the Emperor sees a persistent, event-bound Extortion opportunity', () => {
|
|
const input = props(), html = render(input);
|
|
assert.match(html, /Before Ally makes the Extortion choice/);
|
|
assert.match(html, /Continue to Extortion/);
|
|
assert.equal(button(input).props.disabled, false);
|
|
button(input).props.onClick();
|
|
assert.deepEqual(input.sent, [{type:'emperorExtortionContinue',event:'extortion-event'}]);
|
|
});
|
|
|
|
void test('other viewers see the same neutral opportunity without a Continue control or private data', () => {
|
|
const input = props();
|
|
input.game.emperorExtortionPriority!.canContinue = false;
|
|
Object.assign(input.game, {privateSpice:19, privateCard:'secret-card'});
|
|
const html = render(input);
|
|
assert.match(html, /Waiting for the Emperor/);
|
|
assert.doesNotMatch(html, /emperor-extortion-continue|secret-card|19/);
|
|
assert.deepEqual(input.sent, []);
|
|
input.game.emperorExtortionPriority = null;
|
|
assert.equal(render(input), '');
|
|
});
|
|
|
|
void test('busy, invalid, stale or consumed opportunities cannot submit', () => {
|
|
for (const change of ['busy','empty','event','permission','replace','close'] as const) {
|
|
const input = props();
|
|
if (change === 'busy') input.busy = true;
|
|
if (change === 'empty') input.game.emperorExtortionPriority!.event = '';
|
|
const control = button(input);
|
|
if (change === 'busy' || change === 'empty') assert.equal(control.props.disabled, true);
|
|
if (change === 'event') input.game.emperorExtortionPriority!.event = 'other';
|
|
if (change === 'permission') input.game.emperorExtortionPriority!.canContinue = false;
|
|
if (change === 'replace') input.game.emperorExtortionPriority = {...input.game.emperorExtortionPriority!};
|
|
if (change === 'close') input.game.emperorExtortionPriority = null;
|
|
control.props.onClick();
|
|
assert.deepEqual(input.sent, [], change);
|
|
}
|
|
});
|