Files
cfw-autumn/server/tests/integration/billing/utils/expectPreviewNextCycleCorrect.ts
2026-01-15 15:04:37 +00:00

63 lines
1.6 KiB
TypeScript

import { expect } from "bun:test";
import { type BillingPreviewResponse, formatMs } from "@autumn/shared";
const ONE_DAY_MS = 24 * 60 * 60 * 1000;
/**
* Verify a billing preview's next_cycle field has the expected values.
* Used to check when trial ends and what charge will be.
*
* @param startsAt - Expected starts_at as absolute Unix timestamp (ms).
* Use `advancedTo + ms.days(X)` for test clock scenarios.
*/
export const expectPreviewNextCycleCorrect = ({
preview,
expectDefined = true,
startsAt,
total,
toleranceMs = ONE_DAY_MS,
}: {
preview: BillingPreviewResponse;
/** Whether next_cycle should be defined (default: true) */
expectDefined?: boolean;
/** Expected starts_at as absolute Unix timestamp (ms) */
startsAt?: number;
/** Expected total amount (in dollars) */
total?: number;
/** Tolerance in ms (default: 1 day) */
toleranceMs?: number;
}) => {
if (!expectDefined) {
expect(
preview.next_cycle,
"Preview next_cycle should not be defined",
).toBeUndefined();
return;
}
expect(
preview.next_cycle,
"Preview next_cycle should be defined",
).toBeDefined();
const nextCycle = preview.next_cycle!;
if (startsAt !== undefined) {
const diff = Math.abs(nextCycle.starts_at - startsAt);
expect(
diff < toleranceMs,
`Preview next_cycle.starts_at (${formatMs(nextCycle.starts_at)}) should be within ${toleranceMs}ms of ${formatMs(startsAt)}, but diff is ${diff}ms`,
).toBe(true);
}
if (total !== undefined) {
expect(
nextCycle.total,
`Preview next_cycle.total should be ${total}`,
).toEqual(total);
}
return nextCycle;
};