fix: update the quota tracker for user role

This commit is contained in:
2026-07-18 13:23:02 +07:00
parent c77127aaf3
commit 8f6e57dfc6
11 changed files with 516 additions and 155 deletions
+16 -68
View File
@@ -2,9 +2,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
const requireAdminUser = vi.fn();
const getUserById = vi.fn();
const getUserTokenLimits = vi.fn();
const getUserProviderTokenUsageSince = vi.fn();
const getUserTokenLimitWindowStart = vi.fn();
const getUserTokenQuota = vi.fn();
vi.mock("next/server", () => ({
NextResponse: {
@@ -19,53 +17,36 @@ vi.mock("next/server", () => ({
vi.mock("@/lib/auth/currentUser.js", () => ({ requireAdminUser }));
vi.mock("@/lib/db/index.js", () => ({
getUserById,
getUserTokenLimits,
getUserProviderTokenUsageSince,
}));
vi.mock("@/lib/tokenLimitEnforcer.js", () => ({ getUserTokenLimitWindowStart }));
vi.mock("@/lib/userTokenQuota.js", () => ({ getUserTokenQuota }));
const { GET } = await import("@/app/api/users/[userId]/token-usage/route.js");
const context = (userId = "user-1") => ({ params: Promise.resolve({ userId }) });
const request = new Request("https://9router.local/api/users/user-1/token-usage");
const sessionStart = new Date("2026-07-17T05:00:00.000Z");
const weeklyStart = new Date("2026-07-13T17:00:00.000Z");
const limits = {
"orbit-provider": { session: 100, weekly: 1000 },
codex: { session: 0, weekly: 500 },
const quota = {
"orbit-provider": {
session: { limit: 100, used: 25, remaining: 75, remainingPercentage: 75, isUnlimited: false, windowStart: "2026-07-17T05:00:00.000Z" },
weekly: { limit: 1000, used: 1200, remaining: 0, remainingPercentage: 0, isUnlimited: false, windowStart: "2026-07-13T17:00:00.000Z" },
},
codex: {
session: { limit: 0, used: 12, remaining: null, remainingPercentage: null, isUnlimited: true, windowStart: "2026-07-17T05:00:00.000Z" },
weekly: { limit: 500, used: 400, remaining: 100, remainingPercentage: 20, isUnlimited: false, windowStart: "2026-07-13T17:00:00.000Z" },
},
};
function usageKey(provider, since) {
return `${provider}|${since.toISOString()}`;
}
describe("/api/users/[userId]/token-usage", () => {
beforeEach(() => {
requireAdminUser.mockReset();
getUserById.mockReset();
getUserTokenLimits.mockReset();
getUserProviderTokenUsageSince.mockReset();
getUserTokenLimitWindowStart.mockReset();
getUserTokenQuota.mockReset();
requireAdminUser.mockResolvedValue({ id: "admin-1", role: "admin" });
getUserById.mockResolvedValue({ id: "user-1", role: "user", isActive: true });
getUserTokenLimits.mockResolvedValue(limits);
getUserTokenLimitWindowStart.mockImplementation((windowType) => (
windowType === "session" ? sessionStart : weeklyStart
));
const usage = new Map([
[usageKey("orbit-provider", sessionStart), 25],
[usageKey("orbit-provider", weeklyStart), 1200],
[usageKey("codex", sessionStart), 12],
[usageKey("codex", weeklyStart), 400],
]);
getUserProviderTokenUsageSince.mockImplementation(async (_userId, provider, since) => (
usage.get(usageKey(provider, since)) || 0
));
getUserTokenQuota.mockResolvedValue(quota);
});
it("returns usage and remaining headroom for every provider window", async () => {
it("returns the shared usage and remaining headroom snapshot", async () => {
const response = await GET(request, context());
const payload = await response.json();
@@ -73,43 +54,10 @@ describe("/api/users/[userId]/token-usage", () => {
expect(response.headers.get("Cache-Control")).toBe("no-store");
expect(payload).toMatchObject({
userId: "user-1",
providers: {
"orbit-provider": {
session: {
limit: 100,
used: 25,
remaining: 75,
remainingPercentage: 75,
windowStart: sessionStart.toISOString(),
},
weekly: {
limit: 1000,
used: 1200,
remaining: 0,
remainingPercentage: 0,
windowStart: weeklyStart.toISOString(),
},
},
codex: {
session: {
limit: 0,
used: 12,
remaining: null,
remainingPercentage: null,
windowStart: sessionStart.toISOString(),
},
weekly: {
limit: 500,
used: 400,
remaining: 100,
remainingPercentage: 20,
windowStart: weeklyStart.toISOString(),
},
},
},
providers: quota,
});
expect(payload.updatedAt).toEqual(expect.any(String));
expect(getUserProviderTokenUsageSince).toHaveBeenCalledTimes(4);
expect(getUserTokenQuota).toHaveBeenCalledWith("user-1", expect.any(Date));
});
it("requires an administrator and an existing regular user", async () => {