import assert from 'node:assert/strict'; import test from 'node:test'; import { distransAuctionBlock as block } from '../game/distrans-timing'; import { createRicheseAuction, submitRicheseBid } from '../game/richese-auction'; const fresh = () => ({ phase: 3, auction: { cards: ['original-lot'], index: 0, bid: 0, bidder: null as string | null, active: 'a', passed: [] as string[], opener: 0, peekKnown: true, allyPayment: 0 } }); void test('Distrans quotes a virgin physical ordinary lot without rewriting its inspected card or cycle', () => { const g = fresh(), before = structuredClone(g); assert.equal(block(g), null); assert.deepEqual(g, before); assert.equal(block({ ...g, auction: { ...g.auction, cards: ['earlier-sold', 'current'], index: 1 } }), null); assert.equal(block({ phase: 3, auction: null }), null); }); void test('Distrans permits completed ordinary bids and passes while rejecting invalid lots', () => { const g = fresh(); for (const auction of [{ ...g.auction, bid: 1, bidder: 'a' }, { ...g.auction, passed: ['a'] }, { ...g.auction, bid: 2, bidder: 'a', allyPayment: 1 }]) assert.equal(block({ ...g, auction }), null); for (const auction of [ { ...g.auction, bidder: 'a' }, { ...g.auction, allyPayment: 1 }, { ...g.auction, index: -1 }, { ...g.auction, index: 1 }, { ...g.auction, index: 0.5 }, { ...g.auction, cards: [] }, ]) assert.match(block({ ...g, auction })!, /unresolved auction state/); assert.ok(block({ ...g, phase: 4 })); }); function special(method: 'onceAround' | 'silent' | 'normal', source: 'cache' | 'blackMarket' = 'cache') { return createRicheseAuction({ event: 'lot-event', cardId: 'physical-card', source, owner: 'r', method, eligible: ['a', 'r', 'b'], order: ['a', 'r', 'b'], tieOrder: ['r', 'a', 'b'] }); } void test('Distrans can be used provisionally before the first decision in a genuine Richese special lot', () => { for (const method of ['onceAround', 'silent'] as const) for (const source of ['cache', 'blackMarket'] as const) { const lot = special(method, source), before = structuredClone(lot); assert.equal(block({ phase: 3, auction: null, richeseAuction: lot, richeseFunding: {} }), null); assert.deepEqual(lot, before); assert.ok(block({ phase: 4, auction: null, richeseAuction: lot })); assert.ok(block({ ...fresh(), richeseAuction: lot })); } const normal = special('normal', 'blackMarket'), before = structuredClone(normal); assert.equal(block({ phase: 3, auction: null, richeseAuction: normal, richeseFunding: {} }), null); assert.deepEqual(normal, before); }); void test('completed special bids remain available while malformed lots and funding are rejected', () => { const once = special('onceAround'), silent = special('silent'), normal = special('normal', 'blackMarket'); const pass = submitRicheseBid(once, { event: once.event, actor: once.active!, amount: null }, 0); const bid = submitRicheseBid(once, { event: once.event, actor: once.active!, amount: 1 }, 1); const sealed = submitRicheseBid(silent, { event: silent.event, actor: 'a', amount: 0 }, 0); const normalPass = submitRicheseBid(normal, { event: normal.event, actor: normal.active!, amount: null }, 0); const normalBid = submitRicheseBid(normal, { event: normal.event, actor: normal.active!, amount: 1 }, 1); for (const lot of [pass, bid, sealed, normalPass, normalBid]) assert.equal(block({ phase: 3, auction: null, richeseAuction: lot }), null); for (const lot of [ { ...once, event: '' }, { ...once, active: 'b' }, { ...once, cardId: '' }, { ...once, order: ['a', 'a', 'r'] }, { ...once, tieOrder: ['a', 'r', 'r'] }, { ...once, outcome: { kind: 'unbid' as const } }, { ...normal, source: 'cache' as const }, { ...normal, active: 'r' }, { ...silent, active: 'a' }, { ...silent, passed: ['a'] }, { ...silent, acted: ['a'] }, { ...silent, sealed: { a: 0 } }, ]) assert.ok(block({ phase: 3, auction: null, richeseAuction: lot })); assert.ok(block({ phase: 3, auction: null, richeseAuction: once, richeseFunding: { a: { amount: 0 } } })); }); void test('Distrans keeps the existing paid-sale allowance independently of the later income response', () => { const g = fresh(); assert.equal(block({ ...g, auction: { ...g.auction, bid: 2, bidder: 'a' }, currentAuctionSale: { winner: 'a', amount: 2, free: false, origin: 'normal', seller: null } }), null); });