| author | |
| committer | |
| log | f1a08116f9c6f98d933d53fa897be3d8e3ac1e03 |
| tree | 3d649c6796626fa2e6a7d71f38f55469c950f528 |
| parent | 9c96ac25804de9f38cd19c57976fe73573efa005 |
| signature | Signed by PGP key B5690EEEBB952194 |
2 files changed, 19 insertions(+), 1 deletions(-)
apps/server/src/provider/providerUsageLimits.test.ts+15| ... | ... | @@ -61,6 +61,21 @@ describe("applyUsageLimitsUpdate", () => { |
| 61 | 61 | applyUsageLimitsUpdate({ previous: published, checkedAt, update: { windows: [] } }), |
| 62 | 62 | ).toBe(published); |
| 63 | 63 | }); |
| 64 | ||
| 65 | it("preserves reset credits when a streamed window update changes usage", () => { | |
| 66 | const resetCredits = { availableCount: 2, nextExpiresAt: "2026-10-01T00:00:00.000Z" }; | |
| 67 | const next = applyUsageLimitsUpdate({ | |
| 68 | previous: { ...published, resetCredits }, | |
| 69 | checkedAt: "2026-09-03T12:00:05.000Z", | |
| 70 | update: { windows: [{ ...session, usedPercent: 55 }] }, | |
| 71 | }); | |
| 72 | ||
| 73 | expect(next).toEqual({ | |
| 74 | checkedAt: "2026-09-03T12:00:05.000Z", | |
| 75 | windows: [{ ...session, usedPercent: 55 }, weekly], | |
| 76 | resetCredits, | |
| 77 | }); | |
| 78 | }); | |
| 64 | 79 | }); |
| 65 | 80 | |
| 66 | 81 | describe("resolveUsageLimitsAfterProbe", () => { |
apps/server/src/provider/providerUsageLimits.ts+4-1| ... | ... | @@ -91,7 +91,10 @@ export function applyUsageLimitsUpdate(input: { |
| 91 | 91 | if (!changed && previous !== undefined && previous.unavailable === undefined) { |
| 92 | 92 | return previous; |
| 93 | 93 | } |
| 94 | return makeUsageLimits({ checkedAt: input.checkedAt, windows: merged.values() }); | |
| 94 | return { | |
| 95 | ...makeUsageLimits({ checkedAt: input.checkedAt, windows: merged.values() }), | |
| 96 | ...(previous?.resetCredits !== undefined ? { resetCredits: previous.resetCredits } : {}), | |
| 97 | }; | |
| 95 | 98 | } |
| 96 | 99 | |
| 97 | 100 | function usageWindowEquals(a: ServerProviderUsageWindow, b: ServerProviderUsageWindow): boolean { |