feat(commandcode): quota usage dashboard, CLI-parity request, and connect timeout fixes
- 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
This commit is contained in:
218
tests/unit/commandcode-usage.test.js
Normal file
218
tests/unit/commandcode-usage.test.js
Normal file
@@ -0,0 +1,218 @@
|
||||
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,
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user