Files
Dune/tests/auction-payment-routing.test.ts
T
Quintine 599af2475d
Verify and publish checkpoint container / container (push) Canceled after 0s
Route Advanced Emperor allied auction funding
2026-10-29 02:48:11 +11:00

88 lines
4.9 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { AuctionPaymentRoutingError, routeAuctionPayment, type AuctionPaymentInput } from '../game/auction-payment-routing';
const leg = (payer: string, amount: number, recipient: 'bank' | 'emperor' | 'seller') =>
({payer, amount, recipient});
function invoice(patch: Partial<AuctionPaymentInput> = {}): AuctionPaymentInput {
return {advanced:true, free:false, price:9, buyer:'buyer', emperor:'emperor', seller:null,
contributions:[{payer:'buyer',amount:3}, {payer:'emperor',amount:4}, {payer:'ally',amount:2}], ...patch};
}
void test('Advanced ordinary auction routes Emperor aid to Bank and other actual payer legs to Emperor', () => {
const source = invoice(), before = structuredClone(source);
assert.deepEqual(routeAuctionPayment(source), [
leg('buyer',3,'emperor'), leg('emperor',4,'bank'), leg('ally',2,'emperor'),
]);
assert.deepEqual(source, before);
assert.deepEqual(routeAuctionPayment(invoice({advanced:false})), [
leg('buyer',3,'emperor'), leg('emperor',4,'emperor'), leg('ally',2,'emperor'),
], 'Basic retains the preexisting aggregate income routing.');
});
void test('a direct gift is buyer-owned funding and does not become Emperor aid', () => {
assert.deepEqual(routeAuctionPayment(invoice({price:7, contributions:[
{payer:'buyer',amount:5}, {payer:'ally',amount:2},
]})), [leg('buyer',5,'emperor'), leg('ally',2,'emperor')]);
});
void test('an Emperor buyer or an absent Emperor sends a normal invoice to Bank', () => {
assert.deepEqual(routeAuctionPayment(invoice({buyer:'emperor',price:6,contributions:[
{payer:'emperor',amount:4}, {payer:'ally',amount:2},
]})), [leg('emperor',4,'bank'), leg('ally',2,'bank')]);
assert.deepEqual(routeAuctionPayment(invoice({emperor:null,price:5,contributions:[
{payer:'buyer',amount:3}, {payer:'ally',amount:2},
]})), [leg('buyer',3,'bank'), leg('ally',2,'bank')]);
});
void test('Richese seller, Emperor and other donors retain distinct Advanced special-auction destinations', () => {
const contributions = [{payer:'buyer',amount:3}, {payer:'emperor',amount:2},
{payer:'richese',amount:2}, {payer:'ally',amount:1}];
assert.deepEqual(routeAuctionPayment(invoice({seller:'richese',price:8,contributions})), [
leg('buyer',3,'seller'), leg('emperor',2,'bank'), leg('richese',2,'emperor'), leg('ally',1,'seller'),
]);
assert.deepEqual(routeAuctionPayment(invoice({advanced:false,seller:'richese',price:8,contributions})), [
leg('buyer',3,'seller'), leg('emperor',2,'seller'), leg('richese',2,'seller'), leg('ally',1,'seller'),
]);
assert.deepEqual(routeAuctionPayment(invoice({seller:'richese',emperor:null,price:5,contributions:[
{payer:'buyer',amount:3}, {payer:'richese',amount:2},
]})), [leg('buyer',3,'seller'), leg('richese',2,'bank')]);
});
void test('Emperor buying a Richese card receives Richese aid, while buyer payment goes to the seller', () => {
assert.deepEqual(routeAuctionPayment(invoice({buyer:'emperor',seller:'richese',price:5,contributions:[
{payer:'emperor',amount:3}, {payer:'richese',amount:2},
]})), [leg('emperor',3,'seller'), leg('richese',2,'emperor')]);
});
void test('Richese paid self-retention routes its own price normally and Emperor aid to Bank', () => {
assert.deepEqual(routeAuctionPayment(invoice({buyer:'richese',seller:'richese',price:7,contributions:[
{payer:'richese',amount:3}, {payer:'emperor',amount:4},
]})), [leg('richese',3,'emperor'), leg('emperor',4,'bank')]);
assert.deepEqual(routeAuctionPayment(invoice({buyer:'richese',seller:'richese',emperor:null,price:3,
contributions:[{payer:'richese',amount:3}]})), [leg('richese',3,'bank')]);
});
void test('a Bank-only override reroutes every leg and a free purchase carries no paid legs', () => {
assert.deepEqual(routeAuctionPayment(invoice({seller:'richese',bankOnly:true})), [
leg('buyer',3,'bank'), leg('emperor',4,'bank'), leg('ally',2,'bank'),
]);
assert.deepEqual(routeAuctionPayment(invoice({free:true,contributions:[]})), []);
assert.deepEqual(routeAuctionPayment(invoice({free:false,price:0,contributions:[]})), []);
assert.throws(() => routeAuctionPayment(invoice({free:true})), AuctionPaymentRoutingError);
});
void test('the physical invoice rejects duplicates, phantom legs, unfunded costs and unsafe sums', () => {
for (const patch of [
{contributions:[{payer:'buyer',amount:0}, {payer:'ally',amount:9}]},
{contributions:[{payer:'buyer',amount:4}, {payer:'buyer',amount:5}]},
{contributions:[{payer:'buyer',amount:8}]},
{contributions:[{payer:'buyer',amount:10}]},
{contributions:[{payer:'',amount:9}]},
{price:-1}, {price:1.5}, {price:Number.MAX_SAFE_INTEGER + 1},
{seller:'emperor'}, {bankOnly:'yes'},
{price:Number.MAX_SAFE_INTEGER, contributions:[{payer:'buyer',amount:Number.MAX_SAFE_INTEGER},
{payer:'ally',amount:1}]},
]) assert.throws(() => routeAuctionPayment(invoice(patch as Partial<AuctionPaymentInput>)), AuctionPaymentRoutingError);
});