- Add CommandCode usage handler mirroring the official CLI /usage
(whoami → credits/subscriptions → summary) with 5h/weekly/monthly
quota rows, registered in services/usage.js and registry config
- Parse commandcode quota rows in ProviderLimits (remainingPercentage + $ unit)
- Match official CLI request shape: x-command-code-version 1.10.0,
User-Agent cli, and config.environment '${platform}-${arch}, Node.js ${version}'
- Fix connect timeout unit confusion: both profile and provider pages
now use ms with a 1s minimum guard (prevents 60ms footgun)
- Fix fetchT0 ReferenceError in base.js error path and log fetch
diagnostics only on upstream failure
- Quota Tracker defaults to the Active account filter
- Ignore .commandcode/ CLI local state
219 lines
6.2 KiB
JavaScript
219 lines
6.2 KiB
JavaScript
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
|
|
vi.mock("../../open-sse/utils/proxyFetch.js", () => ({
|
|
proxyAwareFetch: vi.fn(),
|
|
}));
|
|
|
|
import { proxyAwareFetch } from "../../open-sse/utils/proxyFetch.js";
|
|
import { getUsageForProvider } from "../../open-sse/services/usage.js";
|
|
import {
|
|
USAGE_SUPPORTED_PROVIDERS,
|
|
USAGE_APIKEY_PROVIDERS,
|
|
} from "../../src/shared/constants/providers.js";
|
|
import { parseQuotaData } from "../../src/app/(dashboard)/dashboard/usage/components/ProviderLimits/utils.js";
|
|
|
|
const BASE = "https://api.commandcode.ai";
|
|
const WHOAMI_URL = `${BASE}/alpha/whoami`;
|
|
const CREDITS_URL = `${BASE}/alpha/billing/credits`;
|
|
const SUBS_URL = `${BASE}/alpha/billing/subscriptions`;
|
|
const SUMMARY_URL = `${BASE}/alpha/usage/summary`;
|
|
|
|
function jsonResponse(body, status = 200) {
|
|
return new Response(JSON.stringify(body), {
|
|
status,
|
|
headers: { "Content-Type": "application/json" },
|
|
});
|
|
}
|
|
|
|
const WHOAMI = { success: true, user: { id: "u1" }, org: null };
|
|
const CREDITS = {
|
|
credits: {
|
|
belowThreshold: false,
|
|
creditThreshold: 0,
|
|
monthlyCredits: 9.9,
|
|
purchasedCredits: 0,
|
|
freeCredits: 0,
|
|
},
|
|
windowLimits: {
|
|
limited: true,
|
|
exceeded: null,
|
|
fiveHour: { used: 0.05, cap: 3, exceeded: false, resetAt: 1785812386064 },
|
|
weekly: { used: 0.1, cap: 6, exceeded: false, resetAt: 1786379982640 },
|
|
},
|
|
};
|
|
const SUBS = {
|
|
success: true,
|
|
data: {
|
|
id: "sub_1",
|
|
status: "active",
|
|
orgId: null,
|
|
planId: "individual-go",
|
|
currentPeriodStart: "2026-08-03T16:38:16.000Z",
|
|
currentPeriodEnd: "2026-09-03T16:38:16.000Z",
|
|
},
|
|
};
|
|
const SUMMARY = {
|
|
totalCount: 61,
|
|
totalCost: 0.1,
|
|
totalCredits: 0.1,
|
|
totalMonthlyCredits: 0.1,
|
|
periodBasis: "billing-period",
|
|
};
|
|
|
|
describe("commandcode registry usage flags", () => {
|
|
it("is listed for apikey quota dashboard", () => {
|
|
expect(USAGE_SUPPORTED_PROVIDERS).toContain("commandcode");
|
|
expect(USAGE_APIKEY_PROVIDERS).toContain("commandcode");
|
|
});
|
|
});
|
|
|
|
describe("getUsageForProvider(commandcode)", () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it("fetches whoami → credits+subs → summary and maps windows + credits", async () => {
|
|
proxyAwareFetch
|
|
.mockResolvedValueOnce(jsonResponse(WHOAMI))
|
|
.mockResolvedValueOnce(jsonResponse(CREDITS))
|
|
.mockResolvedValueOnce(jsonResponse(SUBS))
|
|
.mockResolvedValueOnce(jsonResponse(SUMMARY));
|
|
|
|
const usage = await getUsageForProvider({
|
|
provider: "commandcode",
|
|
apiKey: "user_cc_test",
|
|
});
|
|
|
|
expect(usage.message).toBeUndefined();
|
|
expect(usage.plan).toBe("individual-go");
|
|
expect(usage.periodBasis).toBe("billing-period");
|
|
|
|
expect(proxyAwareFetch).toHaveBeenCalledTimes(4);
|
|
const [whoamiUrl, whoamiOpts] = proxyAwareFetch.mock.calls[0];
|
|
expect(whoamiUrl).toBe(WHOAMI_URL);
|
|
expect(whoamiOpts.headers.Authorization).toBe("Bearer user_cc_test");
|
|
|
|
// No org → credits/subscriptions called without orgId query
|
|
const creditsCall = proxyAwareFetch.mock.calls[1][0];
|
|
expect(creditsCall).toBe(CREDITS_URL);
|
|
|
|
// Summary uses currentPeriodStart as `since`
|
|
const summaryCall = proxyAwareFetch.mock.calls[3][0];
|
|
expect(summaryCall).toBe(
|
|
`${SUMMARY_URL}?since=${encodeURIComponent("2026-08-03T16:38:16.000Z")}`,
|
|
);
|
|
|
|
expect(usage.quotas["5-hour window"]).toMatchObject({
|
|
used: 0.05,
|
|
total: 3,
|
|
resetAt: new Date(1785812386064).toISOString(),
|
|
});
|
|
expect(usage.quotas["Weekly window"]).toMatchObject({
|
|
used: 0.1,
|
|
total: 6,
|
|
resetAt: new Date(1786379982640).toISOString(),
|
|
});
|
|
expect(usage.quotas["Monthly credits"]).toMatchObject({
|
|
used: 0.1,
|
|
total: 9.9,
|
|
});
|
|
});
|
|
|
|
it("adds orgId query when whoami returns an org", async () => {
|
|
proxyAwareFetch
|
|
.mockResolvedValueOnce(
|
|
jsonResponse({ success: true, org: { id: "org_1" } }),
|
|
)
|
|
.mockResolvedValueOnce(jsonResponse(CREDITS))
|
|
.mockResolvedValueOnce(jsonResponse(SUBS))
|
|
.mockResolvedValueOnce(jsonResponse(SUMMARY));
|
|
|
|
await getUsageForProvider({
|
|
provider: "commandcode",
|
|
apiKey: "user_cc_test",
|
|
});
|
|
|
|
expect(proxyAwareFetch.mock.calls[1][0]).toBe(`${CREDITS_URL}?orgId=org_1`);
|
|
expect(proxyAwareFetch.mock.calls[2][0]).toBe(`${SUBS_URL}?orgId=org_1`);
|
|
});
|
|
|
|
it("falls back to first-of-month since when subscription has no period start", async () => {
|
|
proxyAwareFetch
|
|
.mockResolvedValueOnce(jsonResponse(WHOAMI))
|
|
.mockResolvedValueOnce(jsonResponse(CREDITS))
|
|
.mockResolvedValueOnce(
|
|
jsonResponse({ success: true, data: { planId: "individual-go" } }),
|
|
)
|
|
.mockResolvedValueOnce(jsonResponse(SUMMARY));
|
|
|
|
await getUsageForProvider({
|
|
provider: "commandcode",
|
|
apiKey: "user_cc_test",
|
|
});
|
|
|
|
const since = new URL(proxyAwareFetch.mock.calls[3][0]).searchParams.get(
|
|
"since",
|
|
);
|
|
// firstOfMonth() is local-time based; assert the local date is the 1st.
|
|
const localDate = new Date(since);
|
|
expect(localDate.getDate()).toBe(1);
|
|
});
|
|
|
|
it("returns message on missing key / 401 / non-ok whoami", async () => {
|
|
const missing = await getUsageForProvider({ provider: "commandcode" });
|
|
expect(missing.message).toMatch(/credential/i);
|
|
expect(proxyAwareFetch).not.toHaveBeenCalled();
|
|
|
|
proxyAwareFetch.mockResolvedValueOnce(jsonResponse({ error: "no" }, 401));
|
|
const auth = await getUsageForProvider({
|
|
provider: "commandcode",
|
|
apiKey: "bad",
|
|
});
|
|
expect(auth.message).toMatch(/invalid|expired/i);
|
|
|
|
proxyAwareFetch.mockResolvedValueOnce(jsonResponse({ error: "x" }, 500));
|
|
const err = await getUsageForProvider({
|
|
provider: "commandcode",
|
|
apiKey: "bad",
|
|
});
|
|
expect(err.message).toMatch(/whoami/i);
|
|
});
|
|
});
|
|
|
|
describe("parseQuotaData(commandcode)", () => {
|
|
it("forwards remainingPercentage + unit for window/credit rows", () => {
|
|
const rows = parseQuotaData("commandcode", {
|
|
plan: "individual-go",
|
|
quotas: {
|
|
"5-hour window": {
|
|
used: 0.05,
|
|
total: 3,
|
|
remainingPercentage: 98.33,
|
|
resetAt: "2026-08-03T22:59:46.064Z",
|
|
unit: "$",
|
|
},
|
|
"Monthly credits": {
|
|
used: 0.1,
|
|
total: 9.9,
|
|
remainingPercentage: 98.99,
|
|
resetAt: null,
|
|
unit: "$",
|
|
},
|
|
},
|
|
});
|
|
expect(rows[0]).toMatchObject({
|
|
name: "5-hour window",
|
|
used: 0.05,
|
|
total: 3,
|
|
remainingPercentage: 98.33,
|
|
unit: "$",
|
|
});
|
|
expect(rows[1]).toMatchObject({
|
|
name: "Monthly credits",
|
|
used: 0.1,
|
|
total: 9.9,
|
|
remainingPercentage: 98.99,
|
|
});
|
|
});
|
|
});
|