feat: close application architecture gaps
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import { defineEntitlements, defineMeter, definePacks } from "../src/index.ts";
|
||||
|
||||
test("resolves fallback entitlements and features", async () => {
|
||||
const entitlements = defineEntitlements({
|
||||
plans: () => [
|
||||
{ code: "free", name: "Free", features: [], allowance: 10 },
|
||||
{ code: "pro", name: "Pro", features: ["schedule"], allowance: 100 },
|
||||
],
|
||||
subscriptionFor: async () => "pro",
|
||||
fallback: "free",
|
||||
});
|
||||
expect(await entitlements.enabled("u1", "schedule")).toBe(true);
|
||||
expect(await entitlements.allowance("u1")).toBe(100);
|
||||
});
|
||||
|
||||
test("packs are immutable and selected only by code", () => {
|
||||
const packs = definePacks([{ code: "small", units: 100, label: "Small" }]);
|
||||
expect(packs.get("constructor")).toBeUndefined();
|
||||
expect(packs.get("small")?.units).toBe(100);
|
||||
});
|
||||
|
||||
test("meter distinguishes refusals from storage faults", async () => {
|
||||
const meter = defineMeter({
|
||||
store: {
|
||||
balance: async () => 5,
|
||||
reserve: async (_subject, units) => units <= 5,
|
||||
write: async () => {
|
||||
throw new Error("offline");
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(await meter.reserve("u1", 6, "send")).toEqual({
|
||||
ok: false,
|
||||
reason: "insufficient balance",
|
||||
});
|
||||
expect(await meter.grant("u1", 5, "plan")).toEqual({
|
||||
ok: false,
|
||||
reason: "offline",
|
||||
fault: true,
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user