63 lines
1.6 KiB
TypeScript
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;
|
|
};
|