Files
Dune/tests/truth-traitor-decision-controls.test.tsx
T

42 lines
2.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import assert from 'node:assert/strict';
import test from 'node:test';
import { createElement, type ReactElement } from 'react';
import { renderToStaticMarkup } from 'react-dom/server';
import { Truthtrance } from '../components/truthtrance';
import { TraitorDecisionAnswers, TraitorDecisionPromises } from '../components/traitor-decision-promises';
import { viewGame, type Action } from '../game/engine';
import { createTruthTraitorDecisionFixture as fixture, actTruthTraitorDecision as act,
askTruthTraitorDecision as ask } from './fixture-truth-traitor-decision';
function callbacks(node: unknown): (() => void)[] {
if (Array.isArray(node)) return node.flatMap(callbacks);
if (!node || typeof node !== 'object' || !('props' in node)) return [];
const props = (node as ReactElement<{ children?: unknown; onClick?: () => void }>).props;
return [...(props.onClick ? [props.onClick] : []), ...callbacks(props.children)];
}
void test('actual current-decision answer controls and persistent declaration notice explain later prevention', () => {
const f = fixture(); let g = ask(f.game, f.asker, f.truth, f.target);
const html = renderToStaticMarkup(createElement(Truthtrance,
{ game: viewGame(g, f.target), busy: false, act() {} }));
assert.match(html, /Answer Yes/); assert.match(html, /Answer No/);
assert.match(html, /later Karama or betrayal response/);
const actions: Action[] = [], props = { game: viewGame(g, f.target), busy: false, act: (action: Action) => { actions.push(action); } };
callbacks(TraitorDecisionAnswers(props))[1]();
assert.deepEqual(actions, [{ type: 'truthAnswer', answer: 'yes' }]);
callbacks(TraitorDecisionAnswers({ ...props, busy: true }))[1](); assert.equal(actions.length, 1);
g = act(g, f.target, actions[0]);
const notice = renderToStaticMarkup(createElement(TraitorDecisionPromises, { game: viewGame(g, f.target) }));
assert.match(notice, /requires Reveal traitor/);
assert.match(notice, /original declaration fulfills your answer/);
assert.equal(TraitorDecisionPromises({ game: viewGame(g, f.asker) }), null);
});
void test('only the current declared battle has the new question authoring choice', () => {
const f = fixture(); let g = act(f.game, f.asker, { type: 'card', card: f.truth });
for (const p of g.players) if (!g.truthtrance!.passed.includes(p.id)) g = act(g, p.id, { type: 'truthPass' });
const html = renderToStaticMarkup(createElement(Truthtrance, { game: viewGame(g, f.asker), busy: false, act() {} }));
assert.match(html, /Bind this battle’s Traitor declaration/);
assert.ok(viewGame(g, f.asker).truthTraitorTargets.includes(f.target));
});