51 lines
2.8 KiB
TypeScript
51 lines
2.8 KiB
TypeScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { createElement } from 'react';
|
|
import { renderToStaticMarkup } from 'react-dom/server';
|
|
import { viewGame } from '../game/engine';
|
|
import { RicheseNoFieldControls } from '../components/richese-no-field';
|
|
import {
|
|
createRicheseHomeworldShipmentFixture as fixture,
|
|
actRicheseHomeworldShipment as act,
|
|
commitRicheseHomeworldShipment as commit,
|
|
richeseHomeworldShipmentInventory as inventory,
|
|
richeseHomeworldShipmentPlayer as player,
|
|
} from './fixture-richese-homeworld-shipment';
|
|
|
|
for (const companions of [1, 2]) void test(`original Karama prices marker plus ${companions} paid companions as one rounded group`, () => {
|
|
const f = fixture({ companions });
|
|
const rated = act(f.game, f.holder, { type: 'card', card: f.karama, mode: 'shipment', target: f.owner });
|
|
assert.equal(rated.karamaShipping?.player, f.owner);
|
|
assert.ok(rated.discard.some(card => card.id === f.karama));
|
|
const source = structuredClone(rated), original = player(rated);
|
|
const result = commit(rated, f), done = player(result.game);
|
|
const expected = companions === 1 ? 1 : 2;
|
|
// The only opposing Karama was just spent, so native automatic passes may
|
|
// finish the response during the declaration itself.
|
|
assert.equal(result.requested.pendingShipment ?? null, null);
|
|
assert.equal(original.spice - done.spice, expected);
|
|
assert.equal(original.reserves - done.reserves, companions);
|
|
assert.equal(done.forces[f.location], companions);
|
|
assert.equal(done.noField?.deployed?.tokenId, f.token);
|
|
assert.equal(result.game.karamaShipping, null);
|
|
assert.equal(viewGame(result.game, f.holder).richeseNoField?.private, null);
|
|
assert.deepEqual(rated, source);
|
|
assert.deepEqual(inventory(result.game), f.originalInventory);
|
|
});
|
|
|
|
void test('controlled ally/rate projection shows the full replacement fee after native discount cancellation', () => {
|
|
const f = fixture({ companions: 1 }), view = viewGame(f.game, f.owner);
|
|
// Projection-only UI regression, not an earned Guild alliance/cancellation.
|
|
const owner = view.players.find(p => p.id === f.owner)!, ally = view.players.find(p => p.id === f.holder)!;
|
|
owner.ally = ally.id; ally.ally = owner.id; ally.faction = 'guild';
|
|
const markup = () => renderToStaticMarkup(createElement(RicheseNoFieldControls,
|
|
{ game: view, act() {}, busy: false, destination: 'hagga_basin', sector: 8, allyPayment: '' }));
|
|
view.guildRateCanceled = true;
|
|
assert.match(markup(), /Ship concealed No-Field [035] · 2 spice/);
|
|
view.guildRateCanceled = false;
|
|
assert.match(markup(), /Ship concealed No-Field [035] · 1 spice/);
|
|
view.guildRateCanceled = true;
|
|
view.karamaShipping = { player: f.owner, owner: f.holder };
|
|
assert.match(markup(), /Ship concealed No-Field [035] · 1 spice/);
|
|
});
|