import { describe, expect, it } from "vitest"; // The documented `GET /api/billing/plans` response, copied from getpaseo/hub docs/public-api.md. import documentedResponse from "./hub-plans.fixture.json" with { type: "json" }; import { getTranslator } from "./i18n"; import { formatPlanPrice, parseHubPlansResponse, planPriceQualifier } from "./hub-plans"; describe("parseHubPlansResponse", () => { it("reads Free and Pro, their monthly prices, and the figures each includes", () => { const plans = parseHubPlansResponse(documentedResponse); expect(plans.free.name).toBe("Free"); expect(plans.free.included).toEqual({ seats: 1, executionsPerMonth: 50 }); expect(plans.free.price.unitAmount).toBe(0); expect(plans.free.features).toEqual([ { key: "daemon-location", label: "Daemons run on your machines", tooltip: null }, ]); expect(plans.paid.slug).toBe("hosted"); expect(plans.paid.name).toBe("Pro"); expect(plans.paid.included).toEqual({ seats: null, executionsPerMonth: null }); expect(plans.paid.price.unitAmount).toBe(1500); expect(plans.paid.price.currency).toBe("usd"); expect(plans.paid.billing.unit.label).toBe("seat"); }); it("rejects a catalog that omits the free plan", () => { const withoutFree = { plans: documentedResponse.plans.filter((plan) => plan.slug !== "free"), }; expect(() => parseHubPlansResponse(withoutFree)).toThrow('Hub plan "free" is unavailable'); }); it("rejects the pre-included plan shape instead of rendering a plan with no figures", () => { const withoutIncluded = { plans: documentedResponse.plans.map(({ included: _included, ...plan }) => plan), }; expect(() => parseHubPlansResponse(withoutIncluded)).toThrow( "Invalid Hub plan included figures", ); }); it("rejects a plan that has no monthly price", () => { const annualOnly = structuredClone(documentedResponse); for (const plan of annualOnly.plans) { if (plan.slug !== "hosted") continue; for (const price of plan.prices) price.interval = "annual"; } expect(() => parseHubPlansResponse(annualOnly)).toThrow( 'Hub plan "hosted" has no monthly price', ); }); }); describe("plan price copy", () => { it("shows Free as $0 a month and Pro as $15 per seat a month", () => { const plans = parseHubPlansResponse(documentedResponse); const t = getTranslator("en"); expect(formatPlanPrice(plans.free.price, "en")).toBe("$0"); expect(planPriceQualifier(plans.free, t)).toBe("/ month"); expect(formatPlanPrice(plans.paid.price, "en")).toBe("$15"); expect(planPriceQualifier(plans.paid, t)).toBe("per seat / month"); }); it("describes the same prices in Chinese around the catalog's unit label", () => { const plans = parseHubPlansResponse(documentedResponse); const t = getTranslator("zh-CN"); expect(formatPlanPrice(plans.paid.price, "zh-CN")).toBe("US$15"); expect(planPriceQualifier(plans.free, t)).toBe("/ 月"); expect(planPriceQualifier(plans.paid, t)).toBe("每席位 / 月"); }); });