Skip to content

Commit 4b5fe49

Browse files
committed
test(webapp): cover unselected billing limit mode and default alerts
1 parent a8b80cc commit 4b5fe49

3 files changed

Lines changed: 73 additions & 0 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
area: webapp
3+
type: improvement
4+
---
5+
6+
The billing limit page no longer pre-selects an option before you've configured a limit, and shows a clear prompt to set one up. The reminder banner is now hidden for members who can't manage billing.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { describe, expect, it } from "vitest";
2+
import { buildDefaultBillingAlerts } from "~/services/billingAlertsDefaults.server";
3+
import { ABSOLUTE_ALERT_BASE_CENTS } from "~/components/billing/billingAlertsFormat";
4+
5+
describe("buildDefaultBillingAlerts", () => {
6+
it("uses the absolute dollar base so alert levels read as dollar thresholds", () => {
7+
expect(buildDefaultBillingAlerts().amount).toBe(ABSOLUTE_ALERT_BASE_CENTS);
8+
expect(buildDefaultBillingAlerts().amount).toBe(100);
9+
});
10+
11+
it("starts with no recipients so the platform falls back to org members", () => {
12+
expect(buildDefaultBillingAlerts().emails).toEqual([]);
13+
});
14+
15+
it("seeds the default dollar alert thresholds", () => {
16+
expect(buildDefaultBillingAlerts().alertLevels).toEqual([5, 100, 500, 1000, 2500]);
17+
});
18+
19+
it("returns a fresh alertLevels array each call (no shared mutable state)", () => {
20+
const first = buildDefaultBillingAlerts();
21+
const second = buildDefaultBillingAlerts();
22+
expect(first.alertLevels).not.toBe(second.alertLevels);
23+
first.alertLevels.push(9999);
24+
expect(second.alertLevels).toEqual([5, 100, 500, 1000, 2500]);
25+
});
26+
});

apps/webapp/test/billingLimitsRoute.test.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,27 @@ describe("isBillingLimitFormDirty", () => {
266266
gracePeriodMs: 86_400_000,
267267
};
268268

269+
it("is not dirty when no mode is selected, regardless of other inputs", () => {
270+
expect(
271+
isBillingLimitFormDirty({
272+
billingLimit: unconfiguredLimit,
273+
mode: "",
274+
customAmount: "999.00",
275+
cancelInProgressRuns: true,
276+
})
277+
).toBe(false);
278+
279+
// Even a configured limit stays clean while the form has no selection.
280+
expect(
281+
isBillingLimitFormDirty({
282+
billingLimit: configuredPlanLimit,
283+
mode: "",
284+
customAmount: "50.00",
285+
cancelInProgressRuns: true,
286+
})
287+
).toBe(false);
288+
});
289+
269290
it("is dirty when billing limit has never been saved", () => {
270291
expect(
271292
isBillingLimitFormDirty({
@@ -277,6 +298,26 @@ describe("isBillingLimitFormDirty", () => {
277298
).toBe(true);
278299
});
279300

301+
it("is dirty when an unconfigured limit picks a real mode (initial save)", () => {
302+
expect(
303+
isBillingLimitFormDirty({
304+
billingLimit: unconfiguredLimit,
305+
mode: "plan",
306+
customAmount: "",
307+
cancelInProgressRuns: false,
308+
})
309+
).toBe(true);
310+
311+
expect(
312+
isBillingLimitFormDirty({
313+
billingLimit: unconfiguredLimit,
314+
mode: "custom",
315+
customAmount: "100.00",
316+
cancelInProgressRuns: false,
317+
})
318+
).toBe(true);
319+
});
320+
280321
it("is clean when configured values match saved state", () => {
281322
expect(
282323
isBillingLimitFormDirty({

0 commit comments

Comments
 (0)