100 lines
3.1 KiB
TypeScript
100 lines
3.1 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import type { BillingLimitResult } from "~/services/billingLimit.schemas";
|
|
import {
|
|
collectOrgIdsNeedingBillingLimitLookup,
|
|
resolveConvergeTargetFromBillingLimit,
|
|
resolveReconcileTargetFromBillingLimit,
|
|
resolveReconcileTargetsForOrgLookups,
|
|
} from "~/v3/services/billingLimit/billingLimitReconciliation.server";
|
|
|
|
const graceLimit: BillingLimitResult = {
|
|
isConfigured: true,
|
|
mode: "custom",
|
|
amountCents: 10_000,
|
|
cancelInProgressRuns: false,
|
|
limitState: {
|
|
status: "grace",
|
|
hitAt: "2026-01-01T00:00:00.000Z",
|
|
graceEndsAt: "2026-01-02T00:00:00.000Z",
|
|
},
|
|
effectiveAmountCents: 10_000,
|
|
gracePeriodMs: 86_400_000,
|
|
};
|
|
|
|
describe("billingLimitReconciliation", () => {
|
|
it("maps grace and rejected limits to converge targets", () => {
|
|
expect(resolveConvergeTargetFromBillingLimit(graceLimit)).toBe("grace");
|
|
expect(
|
|
resolveConvergeTargetFromBillingLimit({
|
|
...graceLimit,
|
|
limitState: {
|
|
status: "rejected",
|
|
hitAt: "2026-01-01T00:00:00.000Z",
|
|
graceEndsAt: "2026-01-02T00:00:00.000Z",
|
|
},
|
|
})
|
|
).toBe("rejected");
|
|
expect(
|
|
resolveConvergeTargetFromBillingLimit({
|
|
...graceLimit,
|
|
limitState: { status: "ok" },
|
|
})
|
|
).toBe("ok");
|
|
expect(resolveConvergeTargetFromBillingLimit(undefined)).toBe("ok");
|
|
expect(
|
|
resolveConvergeTargetFromBillingLimit({ isConfigured: false, gracePeriodMs: 86_400_000 })
|
|
).toBe("ok");
|
|
});
|
|
|
|
it("skips reconcile target when platform lookup returns undefined", () => {
|
|
expect(resolveReconcileTargetFromBillingLimit(undefined)).toBeUndefined();
|
|
expect(
|
|
resolveReconcileTargetFromBillingLimit({ isConfigured: false, gracePeriodMs: 86_400_000 })
|
|
).toBe("ok");
|
|
expect(resolveReconcileTargetFromBillingLimit(graceLimit)).toBe("grace");
|
|
});
|
|
|
|
it("dedupes stale and queued org ids and skips excluded or already-covered orgs", () => {
|
|
expect(
|
|
collectOrgIdsNeedingBillingLimitLookup({
|
|
staleOrgIds: ["org_a", "org_b", "org_c"],
|
|
queuedOrgIds: ["org_b", "org_d", "org_a"],
|
|
excludeOrgIds: new Set(["org_c"]),
|
|
coveredOrgIds: new Set(["org_d"]),
|
|
})
|
|
).toEqual(["org_a", "org_b"]);
|
|
});
|
|
|
|
it("resolves reconcile targets with bounded concurrency and isolates lookup failures", async () => {
|
|
const lookedUpOrgIds: string[] = [];
|
|
|
|
const targets = await resolveReconcileTargetsForOrgLookups(
|
|
["org_ok", "org_fail", "org_grace"],
|
|
{
|
|
concurrency: 2,
|
|
getBillingLimit: async (organizationId) => {
|
|
lookedUpOrgIds.push(organizationId);
|
|
|
|
if (organizationId === "org_fail") {
|
|
throw new Error("platform unavailable");
|
|
}
|
|
|
|
if (organizationId === "org_grace") {
|
|
return graceLimit;
|
|
}
|
|
|
|
return { isConfigured: false, gracePeriodMs: 86_400_000 };
|
|
},
|
|
}
|
|
);
|
|
|
|
expect(targets).toEqual(
|
|
new Map([
|
|
["org_ok", "ok"],
|
|
["org_grace", "grace"],
|
|
])
|
|
);
|
|
expect(new Set(lookedUpOrgIds)).toEqual(new Set(["org_ok", "org_fail", "org_grace"]));
|
|
});
|
|
});
|