Files
triggerdotdev--trigger.dev/apps/webapp/test/billingLimitEnvCreatePause.test.ts
Katia Bulatova b1987dc090 feat(webapp): billing limits — pause, reject, recovery, and settings UI (#3996)
## Summary

Adds Billing Limits to the webapp.

Customers can set a monthly spend cap. When usage crosses the limit,
billable environments enter a grace period. If the limit is not resolved
before grace expires, new triggers are rejected until the organization
increases or removes the limit.
2026-06-26 17:12:53 +02:00

79 lines
2.5 KiB
TypeScript

import { EnvironmentPauseSource } from "@trigger.dev/database";
import { describe, expect, it } from "vitest";
import type { BillingLimitResult } from "~/services/billingLimit.schemas";
import { getInitialEnvPauseStateForBillingLimit } from "~/v3/services/billingLimit/getInitialEnvPauseStateForBillingLimit.server";
function configuredLimit(status: "grace" | "rejected" | "ok"): BillingLimitResult {
const hitAt = "2026-06-16T12:00:00.000Z";
const graceEndsAt = "2026-06-17T12:00:00.000Z";
return {
isConfigured: true,
mode: "custom",
amountCents: 50_000,
cancelInProgressRuns: false,
effectiveAmountCents: 50_000,
gracePeriodMs: 86_400_000,
limitState: status === "ok" ? { status: "ok" } : { status, hitAt, graceEndsAt },
};
}
describe("getInitialEnvPauseStateForBillingLimit", () => {
it("pauses billable environments when org is in grace", async () => {
const result = await getInitialEnvPauseStateForBillingLimit("org_123", "PRODUCTION", {
getBillingLimit: async () => configuredLimit("grace"),
});
expect(result).toEqual({
paused: true,
pauseSource: EnvironmentPauseSource.BILLING_LIMIT,
});
});
it("pauses billable environments when org is rejected", async () => {
const result = await getInitialEnvPauseStateForBillingLimit("org_123", "STAGING", {
getBillingLimit: async () => configuredLimit("rejected"),
});
expect(result).toEqual({
paused: true,
pauseSource: EnvironmentPauseSource.BILLING_LIMIT,
});
});
it("does not pause development environments", async () => {
const result = await getInitialEnvPauseStateForBillingLimit("org_123", "DEVELOPMENT", {
getBillingLimit: async () => configuredLimit("rejected"),
});
expect(result).toEqual({
paused: false,
pauseSource: null,
});
});
it("does not pause when billing limit lookup fails", async () => {
const result = await getInitialEnvPauseStateForBillingLimit("org_123", "PRODUCTION", {
getBillingLimit: async () => {
throw new Error("billing platform unavailable");
},
});
expect(result).toEqual({
paused: false,
pauseSource: null,
});
});
it("does not pause when billing limit is ok", async () => {
const result = await getInitialEnvPauseStateForBillingLimit("org_123", "PRODUCTION", {
getBillingLimit: async () => configuredLimit("ok"),
});
expect(result).toEqual({
paused: false,
pauseSource: null,
});
});
});