eleven / ocho Public

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

Plain git — no account needed to clone.

Download

Download this file

1// Tests for the pricing picker's pure helpers. node home/test/fx.test.mjs
2import assert from "node:assert/strict";
3import { BANDS, bandName, bandsOffered, tierForBand, regionCurrency, approxLocal, capNote } from "../web/static/fx.js";
4
5let failures = 0;
6async function test(name, fn) {
7 try {
8 await fn();
9 console.log("PASS " + name);
10 } catch (e) {
11 console.log("FAIL " + name + " — " + (e && e.message));
12 failures++;
13 }
14}
15
16const tiers = [
17 { key: "family", name: "Family", label: "€5/year", eur: 5 },
18 { key: "friends", name: "Friends", label: "€4/month", eur: 4,
19 bands: { reduced: { label: "€2/month", eur: 2 }, supporter: { label: "€5.50/month", eur: 5.5 } } },
20];
21
22await test("band vocabulary is the doc's four, in display order", () => {
23 assert.deepEqual(BANDS.map((b) => b.key), ["supporter", "base", "reduced", "solidarity"]);
24 assert.equal(bandName("base"), "Standard");
25 // The messaging rules: aggregate cross-subsidy only, never "discount"/"eligible".
26 for (const b of BANDS) {
27 assert.ok(!/discount|eligible/i.test(b.line), b.key + " line breaks the messaging rules");
28 }
29});
30
31await test("bandsOffered: base always; others once any tier defines them", () => {
32 assert.deepEqual(bandsOffered([tiers[0]]), ["base"]);
33 assert.deepEqual(bandsOffered(tiers), ["supporter", "base", "reduced"]);
34 assert.deepEqual(bandsOffered([]), ["base"]);
35});
36
37await test("tierForBand: band label when offered, base flagged when not", () => {
38 assert.deepEqual(tierForBand(tiers[1], "reduced"), { label: "€2/month", eur: 2, band: "reduced", offered: true });
39 assert.deepEqual(tierForBand(tiers[1], "base"), { label: "€4/month", eur: 4, band: "base", offered: true });
40 // family has no bands: a reduced selection falls back to base, UNOFFERED —
41 // the UI says "standard price" instead of implying a reduction.
42 assert.deepEqual(tierForBand(tiers[0], "reduced"), { label: "€5/year", eur: 5, band: "base", offered: false });
43});
44
45await test("regionCurrency: locale region → ECB currency; euro area and unknown → none", () => {
46 assert.equal(regionCurrency("en-US"), "USD");
47 assert.equal(regionCurrency("en-GB"), "GBP");
48 assert.equal(regionCurrency("ja"), "JPY"); // maximize() infers the region
49 assert.equal(regionCurrency("de-DE"), ""); // euro area: billed in EUR already
50 assert.equal(regionCurrency("fr"), "");
51 assert.equal(regionCurrency(""), "");
52 assert.equal(regionCurrency("not a locale"), "");
53});
54
55await test("approxLocal: converts and formats; silent when it can't be honest", () => {
56 const rates = { USD: 1.1, JPY: 170 };
57 assert.equal(approxLocal(5, "USD", rates, "en"), "≈ $5.50");
58 // Larger amounts drop the cents (an estimate pretending precision reads wrong).
59 assert.equal(approxLocal(999, "USD", rates, "en"), "≈ $1,099");
60 // Unknown currency / missing rate / zero amount → no figure at all.
61 assert.equal(approxLocal(5, "CHF", rates, "en"), "");
62 assert.equal(approxLocal(0, "USD", rates, "en"), "");
63 assert.equal(approxLocal(5, "", rates, "en"), "");
64 assert.equal(approxLocal(5, "USD", null, "en"), "");
65});
66
67await test("capNote: the 15% promise in euros, not percent", () => {
68 assert.equal(capNote(5, "en"), "never more than €0.75 more at renewal without your say-so");
69 assert.equal(capNote(0, "en"), "");
70});
71
72console.log(failures === 0 ? "\nALL PASSED" : `\n${failures} FAILED`);
73process.exit(failures === 0 ? 0 : 1);
74