1import { describe, expect, it } from "vite-plus/test";
2
3import { applyUsageLimitsUpdate, resolveUsageLimitsAfterProbe } from "./usageLimits.ts";
4
5const checkedAt = "2026-09-03T12:00:00.000Z";
6const session = {
7 id: "five_hour",
8 kind: "session",
9 label: "Session",
10 usedPercent: 40,
11 windowDurationMins: 300,
12 resetsAt: "2026-09-03T14:00:00.000Z",
13} as const;
14const weekly = {
15 id: "seven_day",
16 kind: "weekly",
17 label: "Weekly",
18 usedPercent: 20,
19 windowDurationMins: 10_080,
20} as const;
21const published = { checkedAt, windows: [session, weekly] };
22
23describe("applyUsageLimitsUpdate", () => {
24 it("returns the published object itself when no window moved", () => {
25 const next = applyUsageLimitsUpdate({
26 previous: published,
27 checkedAt: "2026-09-03T12:00:05.000Z",
28 update: {
29 windows: [
30 { ...weekly },
31 { id: "five_hour", kind: "session", label: "Session", usedPercent: 40 },
32 ],
33 },
34 });
35 expect(next).toBe(published);
36 const scoped = { checkedAt, windows: [{ ...weekly, modelIds: ["opencode/a"] }] };
37 const providerScoped = { checkedAt, windows: [{ ...weekly, providerIds: ["opencode"] }] };
38 expect(
39 applyUsageLimitsUpdate({
40 previous: providerScoped,
41 checkedAt,
42 update: { windows: [{ ...weekly, providerIds: ["console-custom"] }] },
43 })?.windows[0]?.providerIds,
44 ).toEqual(["console-custom"]);
45 expect(
46 applyUsageLimitsUpdate({
47 previous: scoped,
48 checkedAt,
49 update: { windows: [{ ...weekly, modelIds: ["opencode/a"] }] },
50 }),
51 ).toBe(scoped);
52 expect(
53 applyUsageLimitsUpdate({
54 previous: scoped,
55 checkedAt,
56 update: { windows: [{ ...weekly, modelIds: ["opencode/b"] }] },
57 })?.windows[0]?.modelIds,
58 ).toEqual(["opencode/b"]);
59 });
60
61 it("upserts by id and keeps the reset a percent-only update omits", () => {
62 const next = applyUsageLimitsUpdate({
63 previous: published,
64 checkedAt: "2026-09-03T12:00:05.000Z",
65 update: {
66 windows: [{ id: "five_hour", kind: "session", label: "Session", usedPercent: 55 }],
67 },
68 });
69 expect(next).not.toBe(published);
70 expect(next).toEqual({
71 checkedAt: "2026-09-03T12:00:05.000Z",
72 windows: [{ ...session, usedPercent: 55 }, weekly],
73 });
74 });
75
76 it("leaves an unsupported account and an empty update alone", () => {
77 const unsupported = { checkedAt, windows: [], unavailable: { reason: "unsupported" as const } };
78 expect(
79 applyUsageLimitsUpdate({ previous: unsupported, checkedAt, update: { windows: [session] } }),
80 ).toBe(unsupported);
81 expect(
82 applyUsageLimitsUpdate({ previous: published, checkedAt, update: { windows: [] } }),
83 ).toBe(published);
84 });
85
86 it("marks a first sparse update as unavailable", () => {
87 expect(
88 applyUsageLimitsUpdate({ previous: undefined, checkedAt, update: { windows: [weekly] } }),
89 ).toEqual({ checkedAt, windows: [weekly], unavailable: { reason: "probeFailed" } });
90 });
91
92 it("preserves reset credits when a streamed window update changes usage", () => {
93 const resetCredits = { availableCount: 2, nextExpiresAt: "2026-10-01T00:00:00.000Z" };
94 const next = applyUsageLimitsUpdate({
95 previous: { ...published, resetCredits },
96 checkedAt: "2026-09-03T12:00:05.000Z",
97 update: { windows: [{ ...session, usedPercent: 55 }] },
98 });
99
100 expect(next).toEqual({
101 checkedAt: "2026-09-03T12:00:05.000Z",
102 windows: [{ ...session, usedPercent: 55 }, weekly],
103 resetCredits,
104 });
105 });
106});
107
108describe("resolveUsageLimitsAfterProbe", () => {
109 it("uses read order for windows while taking metadata from the successful probe", () => {
110 const live = {
111 checkedAt: "2026-09-03T12:00:05.000Z",
112 windows: [
113 { ...session, usedPercent: 95 },
114 { ...weekly, usedPercent: 70 },
115 ],
116 resetCredits: { availableCount: 2 },
117 externalUsage: { label: "Old dashboard", url: "https://example.com/old" },
118 };
119 const probed = {
120 ...published,
121 windows: [{ ...session, usedPercent: 0 }],
122 resetCredits: { availableCount: 1 },
123 externalUsage: { label: "Usage dashboard", url: "https://example.com/usage" },
124 };
125
126 expect(resolveUsageLimitsAfterProbe({ published: live, probed })).toEqual({
127 ...probed,
128 checkedAt: live.checkedAt,
129 windows: live.windows,
130 });
131
132 const sameTime = { ...probed, checkedAt: live.checkedAt };
133 const newer = { ...probed, checkedAt: "2026-09-03T12:00:06.000Z" };
134 expect(resolveUsageLimitsAfterProbe({ published: live, probed: sameTime })).toEqual(sameTime);
135 expect(resolveUsageLimitsAfterProbe({ published: live, probed: newer })).toEqual(newer);
136 });
137
138 it("keeps the last good windows through a failed probe but not an unsupported one", () => {
139 const failed = { checkedAt, windows: [], unavailable: { reason: "probeFailed" as const } };
140 const unsupported = { checkedAt, windows: [], unavailable: { reason: "unsupported" as const } };
141 expect(resolveUsageLimitsAfterProbe({ published, probed: failed })).toBe(published);
142 expect(resolveUsageLimitsAfterProbe({ published, probed: unsupported })).toBe(unsupported);
143 expect(resolveUsageLimitsAfterProbe({ published: undefined, probed: failed })).toBe(failed);
144 });
145});