Connect Tleilaxu Nexus free leader and paid force revival
This commit is contained in:
1 parent
4bf6cfc875
commit
72e37a8978
22 files changed
+1589
-80
No files matched your search
@@ -1,9 +1,6 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { createElement } from 'react';
|
||||
import { renderToStaticMarkup } from 'react-dom/server';
|
||||
import { createGame, newPlayer, viewGame, type GameView } from '../game/engine';
|
||||
import { NexusTleilaxu } from '../components/nexus-tleilaxu';
|
||||
import { nexusFaceDancersAction } from '../game/nexus-tleilaxu-options';
|
||||
|
||||
/** Explicit projected offers isolate presentation/consumer validation. These
|
||||
@@ -36,31 +33,10 @@ function fixture(): GameView {
|
||||
};
|
||||
v.nexusTleilaxu = {
|
||||
cunning: { event: 'dancer-event', count: 2, blocked: null },
|
||||
secretAlly: null,
|
||||
};
|
||||
return v;
|
||||
}
|
||||
function html(game: GameView, busy = false) {
|
||||
return renderToStaticMarkup(
|
||||
createElement(NexusTleilaxu, { game, busy, act() {} }),
|
||||
);
|
||||
}
|
||||
|
||||
void test('Cunning explains the ordered complete replacement and submits no selection or extra confirmation', () => {
|
||||
const v = fixture();
|
||||
const before = structuredClone(v);
|
||||
assert.deepEqual(nexusFaceDancersAction(v, 'dancer-event'), {
|
||||
type: 'nexusFaceDancers',
|
||||
event: 'dancer-event',
|
||||
});
|
||||
const text = html(v);
|
||||
assert.match(text, /secretly draw their replacements/);
|
||||
assert.match(text, /Then shuffle the set-aside cards/);
|
||||
assert.match(text, /unrevealed Face Dancers stay in your hand/);
|
||||
assert.match(text, /Replace 2 revealed Face Dancers/);
|
||||
assert.doesNotMatch(text, /type="checkbox"|<select|Confirm|disabled=""/);
|
||||
assert.deepEqual(v, before);
|
||||
assert.match(html(v, true), /disabled=""/);
|
||||
});
|
||||
|
||||
void test('Cunning binds owner, held card, event and server block while preserving anytime decision access', () => {
|
||||
const v = fixture();
|
||||
@@ -70,8 +46,6 @@ void test('Cunning binds owner, held card, event and server block while preservi
|
||||
assert.equal(nexusFaceDancersAction(v, 'stale'), null);
|
||||
v.nexusTleilaxu!.cunning!.blocked = 'Finish the current Nexus return first.';
|
||||
assert.equal(nexusFaceDancersAction(v, 'dancer-event'), null);
|
||||
assert.match(html(v), /Finish the current Nexus return first/);
|
||||
assert.match(html(v), /disabled=""/);
|
||||
v.nexusTleilaxu!.cunning!.blocked = null;
|
||||
v.nexusCards!.card = 'harkonnen';
|
||||
assert.equal(nexusFaceDancersAction(v, 'dancer-event'), null);
|
||||
@@ -93,7 +67,6 @@ void test('Cunning controls honor Truth and exchange priority and never inspect
|
||||
},
|
||||
});
|
||||
assert.ok(nexusFaceDancersAction(v, 'dancer-event'));
|
||||
assert.match(html(v), /Replace 2/);
|
||||
v.truthtrance = { stage: 'priority', queue: [], passed: [], question: null };
|
||||
assert.equal(nexusFaceDancersAction(v, 'dancer-event'), null);
|
||||
v.truthtrance = null;
|
||||
@@ -117,17 +90,5 @@ void test('Cunning controls honor Truth and exchange priority and never inspect
|
||||
assert.equal(nexusFaceDancersAction(v, 'dancer-event'), null);
|
||||
}
|
||||
v.nexusTleilaxu = null;
|
||||
assert.equal(html(v), '');
|
||||
});
|
||||
|
||||
void test('unavailable Tleilaxu modes are explained only from the viewer’s own held Nexus card', () => {
|
||||
const v = fixture();
|
||||
v.nexusTleilaxu = { cunning: null };
|
||||
v.me = 'a';
|
||||
assert.match(html(v), /Betrayal is unavailable while its private response timing is pending/);
|
||||
v.players = v.players.filter((player) => player.faction !== 'tleilaxu');
|
||||
assert.match(html(v), /Secret Ally revival is unavailable while its revival-limit ruling is pending/);
|
||||
assert.doesNotMatch(html(v), /<button/);
|
||||
v.nexusCards!.card = null;
|
||||
assert.equal(html(v), '');
|
||||
});
|
||||
Reference in new issue
Block a user