Protect Sapho priority at the Testing Station
Verify and publish checkpoint container / container (push) Successful in 11m16s
Verify and publish checkpoint container / container (push) Successful in 11m16s
This commit is contained in:
1 parent
f73a6e0a9c
commit
a6be17fc5d
12 files changed
+391
-9
No files matched your search
@@ -0,0 +1,73 @@
|
||||
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 { SaphoStationPriority, type SaphoStationPriorityProps } from '../components/sapho-station-priority';
|
||||
|
||||
function props(): SaphoStationPriorityProps & { sent: Action[] } {
|
||||
const sent: Action[] = [];
|
||||
return {game: {saphoStationPriority: {event:'station-event', canPass:true, waiting:false}},
|
||||
busy:false, sent, act(action) { sent.push(action); }};
|
||||
}
|
||||
const render = (input: SaphoStationPriorityProps) =>
|
||||
renderToStaticMarkup(createElement(SaphoStationPriority, input));
|
||||
|
||||
/** Invoke the actual rendered Button callback, without mounting a browser. */
|
||||
function pass(input: SaphoStationPriorityProps) {
|
||||
const section = SaphoStationPriority(input); assert.ok(section);
|
||||
const button = Children.toArray(section.props.children).find(child =>
|
||||
isValidElement(child) && (child.props as {'data-testid'?: string})['data-testid'] === 'sapho-station-priority-pass');
|
||||
assert.ok(isValidElement<{onClick: () => void; disabled: boolean}>(button));
|
||||
return button;
|
||||
}
|
||||
|
||||
void test('a neutral Testing Station opportunity stays visible and passes its exact event', () => {
|
||||
const input = props(), html = render(input);
|
||||
assert.match(html, /Testing Station priority/);
|
||||
assert.match(html, /Continue without changing the order/);
|
||||
assert.match(html, /Already completed choices stay finished/);
|
||||
assert.equal(pass(input).props.disabled, false);
|
||||
pass(input).props.onClick();
|
||||
assert.deepEqual(input.sent, [{type:'saphoStationPass', event:'station-event'}]);
|
||||
});
|
||||
|
||||
void test('busy and invalid events disable Continue without sending an action', () => {
|
||||
for (const change of ['busy', 'empty-event'] as const) {
|
||||
const input = props();
|
||||
if (change === 'busy') input.busy = true;
|
||||
else input.game.saphoStationPriority!.event = '';
|
||||
assert.match(render(input), /disabled=""/);
|
||||
const button = pass(input); assert.equal(button.props.disabled, true);
|
||||
button.props.onClick();
|
||||
assert.deepEqual(input.sent, []);
|
||||
}
|
||||
});
|
||||
|
||||
void test('waiting and completed viewers see no Continue button or hidden card data', () => {
|
||||
for (const waiting of [true, false]) {
|
||||
const input = props();
|
||||
input.game.saphoStationPriority = {event:'station-event', canPass:false, waiting};
|
||||
// Only the server-supplied public opportunity is rendered, even when a
|
||||
// surrounding object contains unrelated private fields.
|
||||
Object.assign(input.game, {hiddenCard:'private-sapho-card-id'});
|
||||
const html = render(input);
|
||||
assert.doesNotMatch(html, /sapho-station-priority-pass|private-sapho-card-id/);
|
||||
assert.match(html, waiting ? /Waiting for the other players/ : /Your response has been recorded/);
|
||||
assert.deepEqual(input.sent, []);
|
||||
}
|
||||
const input = props(); input.game.saphoStationPriority = null;
|
||||
assert.equal(render(input), '');
|
||||
});
|
||||
|
||||
void test('stale event, consumed response and replaced priority callbacks do not send', () => {
|
||||
for (const change of ['event', 'pass', 'replace', 'close'] as const) {
|
||||
const input = props(), button = pass(input), view = input.game.saphoStationPriority!;
|
||||
if (change === 'event') view.event = 'new-event';
|
||||
else if (change === 'pass') view.canPass = false;
|
||||
else if (change === 'replace') input.game.saphoStationPriority = {...view};
|
||||
else input.game.saphoStationPriority = null;
|
||||
button.props.onClick();
|
||||
assert.deepEqual(input.sent, []);
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user