eleven / messenger Public

Clone
git clone https://amadan.net/eleven/messenger

Plain git — no account needed to clone.

Download

Download this file

1// Tests for the band-price minting tool's pure parts — the committed table
2// must stay the doc's matrix. node test/stripe-band-prices.test.mjs
3import assert from "node:assert/strict";
4import { BAND_TABLE, priceLabel, netEURYear } from "../tools/stripe-band-prices.mjs";
5
6let failures = 0;
7async function test(name, fn) {
8 try {
9 await fn();
10 console.log("PASS " + name);
11 } catch (e) {
12 console.log("FAIL " + name + " — " + (e && e.message));
13 failures++;
14 }
15}
16
17await test("the table is the elevens ladder — 11 prices in all", () => {
18 // 3 base + 8 band prices: nominally 3 × 4, minus Business's solidarity
19 // (deliberately absent — a hardship price aimed at businesses never
20 // parsed; Reduced at €5.50/person covers nonprofits/education).
21 const tiers = Object.keys(BAND_TABLE);
22 assert.deepEqual(tiers, ["family", "community", "business"]);
23 const bandCount = tiers.reduce((n, t) => n + Object.keys(BAND_TABLE[t].bands).length, 0);
24 assert.equal(tiers.length + bandCount, 11);
25 assert.ok(!BAND_TABLE.business.bands.solidarity, "business must not offer solidarity");
26 // Spot-pin the ladder's load-bearing figures (decimal cents).
27 assert.equal(BAND_TABLE.family.base, "550");
28 assert.equal(BAND_TABLE.community.base, "11");
29 assert.equal(BAND_TABLE.business.base, "1100");
30 assert.equal(BAND_TABLE.business.bands.supporter, "1500");
31 assert.equal(BAND_TABLE.business.bands.reduced, "550");
32 // The included-members identity: €0.11 × the 100-member floor = the €11
33 // minimum, and every band scales it (supporter €15, reduced €5.50).
34 assert.equal(BAND_TABLE.community.minSeats, 100);
35 assert.equal(Number(BAND_TABLE.community.base) * BAND_TABLE.community.minSeats, 1100);
36 // Bands only ever use the fixed vocabulary; per-unit tiers name their unit.
37 for (const t of tiers) {
38 for (const b of Object.keys(BAND_TABLE[t].bands)) {
39 assert.ok(["supporter", "reduced", "solidarity"].includes(b), `${t}: unknown band ${b}`);
40 }
41 assert.ok([null, "member", "seat"].includes(BAND_TABLE[t].unit));
42 }
43});
44
45await test("priceLabel: whole euros bare, cents as a pair, sub-cent to three places", () => {
46 assert.equal(priceLabel("550", null), "€5.50/year");
47 assert.equal(priceLabel("1100", "seat"), "€11/seat/year");
48 assert.equal(priceLabel("11", "member"), "€0.11/member/year");
49 assert.equal(priceLabel("5.5", "member"), "€0.055/member/year");
50 assert.equal(priceLabel("139900", null), "€1,399/year");
51});
52
53await test("netEURYear: the EEA fee model — flat absorbs the fixed fee, per-unit doesn't", () => {
54 // Flat annual: one charge — €5.50 → 5.50 − 0.0825 − 0.25 = 5.168.
55 assert.equal(netEURYear("550", null), 5.168);
56 // Per-unit rates only carry the percentage; the €0.25 lands once per space.
57 assert.equal(netEURYear("1100", "seat"), 10.835);
58 assert.equal(netEURYear("11", "member"), 0.108);
59});
60
61console.log(failures === 0 ? "\nALL PASSED" : `\n${failures} FAILED`);
62process.exit(failures === 0 ? 0 : 1);
63