| 1 | import assert from "node:assert/strict"; |
| 2 | import { test } from "node:test"; |
| 3 | |
| 4 | import type { FeatureState, LedgerEntry } from "@g1t/contracts"; |
| 5 | |
| 6 | import { planReturnNotice, prepaymentSettled } from "./billing-return.ts"; |
| 7 | |
| 8 | const plan = (on: boolean, status: "active" | "past_due" | null): FeatureState => ({ |
| 9 | plan: { feature: "plan", title: "g1t", monthlyCents: 2000, includes: [], overage: "" }, |
| 10 | subscription: status ? { feature: "plan", status, periodEnd: null, startedBy: "ada", startedAt: "2026-10-01T00:00:00Z" } : null, |
| 11 | on, |
| 12 | }); |
| 13 | |
| 14 | test("a plan that is on says so", () => { |
| 15 | assert.equal(planReturnNotice(plan(true, "active"), "subscribed"), "The g1t plan is on."); |
| 16 | }); |
| 17 | |
| 18 | test("a plan whose payment has not cleared says it is pending, never that it is on", () => { |
| 19 | const notice = planReturnNotice(plan(false, null), "subscribed"); |
| 20 | assert.match(notice, /^Payment pending\. The g1t plan starts once the payment clears/); |
| 21 | assert.match(planReturnNotice(null, "security_on"), /^Payment pending\. Security and quality starts/); |
| 22 | }); |
| 23 | |
| 24 | test("a failed payment points at Update payment method", () => { |
| 25 | assert.match(planReturnNotice(plan(false, "past_due"), "subscribed"), /did not go through.*Update payment method/); |
| 26 | }); |
| 27 | |
| 28 | const topUp = (createdAt: string, amountMicros = 25_000_000): LedgerEntry => ({ |
| 29 | id: "l1", |
| 30 | kind: "top_up", |
| 31 | amountMicros, |
| 32 | description: "Paid in advance", |
| 33 | repo: null, |
| 34 | number: null, |
| 35 | task: null, |
| 36 | model: null, |
| 37 | billedTo: "workspace", |
| 38 | createdBy: "ada", |
| 39 | createdAt, |
| 40 | }); |
| 41 | |
| 42 | test("a prepayment is settled when the balance rose or it was just entered", () => { |
| 43 | const now = Date.parse("2026-10-13T12:00:00Z"); |
| 44 | assert.equal(prepaymentSettled(0, 25_000_000, null, now), true); |
| 45 | assert.equal(prepaymentSettled(25_000_000, 25_000_000, [topUp("2026-10-13T11:55:00Z")], now), true); |
| 46 | }); |
| 47 | |
| 48 | test("a bank transfer still on its way is pending", () => { |
| 49 | const now = Date.parse("2026-10-13T12:00:00Z"); |
| 50 | assert.equal(prepaymentSettled(10, 10, [], now), false); |
| 51 | assert.equal(prepaymentSettled(10, 10, [topUp("2026-10-01T00:00:00Z")], now), false); |
| 52 | assert.equal(prepaymentSettled(null, 10, null, now), false); |
| 53 | }); |