fix(quota): harden dashboard integration
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
import assert from "node:assert/strict"
|
||||
import { describe, it } from "node:test"
|
||||
|
||||
import { registerCommandCodeQuota, type QuotaCommandContext } from "../src/quota-command.ts"
|
||||
import type { CommandCodeQuotaResult } from "../src/quota-types.ts"
|
||||
|
||||
class CommandApiDouble {
|
||||
handler?: (args: string, ctx: QuotaCommandContext) => Promise<void>
|
||||
|
||||
registerCommand(
|
||||
name: string,
|
||||
options: {
|
||||
description: string
|
||||
handler: (args: string, ctx: QuotaCommandContext) => Promise<void>
|
||||
},
|
||||
): void {
|
||||
assert.equal(name, "commandcode-quota")
|
||||
assert.match(options.description, /usage and quota/)
|
||||
this.handler = options.handler
|
||||
}
|
||||
}
|
||||
|
||||
function context(registryKey: string | undefined) {
|
||||
const notifications: Array<{ message: string; type?: "info" | "warning" | "error" }> = []
|
||||
let waited = false
|
||||
const value = {
|
||||
async waitForIdle() {
|
||||
waited = true
|
||||
},
|
||||
modelRegistry: {
|
||||
async getApiKeyForProvider(provider: string) {
|
||||
assert.equal(provider, "commandcode")
|
||||
return registryKey
|
||||
},
|
||||
},
|
||||
ui: {
|
||||
notify(message: string, type?: "info" | "warning" | "error") {
|
||||
notifications.push({ message, type })
|
||||
},
|
||||
},
|
||||
} satisfies QuotaCommandContext
|
||||
return { value, notifications, waited: () => waited }
|
||||
}
|
||||
|
||||
const quotaResult: CommandCodeQuotaResult = {
|
||||
ok: true,
|
||||
quota: {
|
||||
account: { login: "alice", orgId: null },
|
||||
credits: null,
|
||||
subscription: null,
|
||||
summary: { totalCost: 1, totalCount: 2 },
|
||||
},
|
||||
}
|
||||
|
||||
describe("commandcode-quota command", () => {
|
||||
it("registers the command and resolves OMP placeholders through the fallback key", async () => {
|
||||
const pi = new CommandApiDouble()
|
||||
let requestKey = ""
|
||||
let requestBase = ""
|
||||
registerCommandCodeQuota(pi, {
|
||||
apiBase: "https://api.commandcode.ai",
|
||||
getConfiguredKey: () => "fallback-key",
|
||||
fetchQuota: async (options) => {
|
||||
requestKey = options.apiKey
|
||||
requestBase = options.baseUrl ?? ""
|
||||
return quotaResult
|
||||
},
|
||||
})
|
||||
|
||||
assert.ok(pi.handler)
|
||||
const ctx = context("$COMMANDCODE_API_KEY")
|
||||
await pi.handler("", ctx.value)
|
||||
assert.equal(ctx.waited(), true)
|
||||
assert.equal(requestKey, "fallback-key")
|
||||
assert.equal(requestBase, "https://api.commandcode.ai")
|
||||
assert.equal(ctx.notifications.at(-1)?.type, "info")
|
||||
assert.match(ctx.notifications.at(-1)?.message ?? "", /Requests: 2/)
|
||||
})
|
||||
|
||||
it("warns without calling the endpoint when no API key is available", async () => {
|
||||
const pi = new CommandApiDouble()
|
||||
let called = false
|
||||
registerCommandCodeQuota(pi, {
|
||||
apiBase: "https://api.commandcode.ai",
|
||||
getConfiguredKey: () => undefined,
|
||||
fetchQuota: async () => {
|
||||
called = true
|
||||
return quotaResult
|
||||
},
|
||||
})
|
||||
|
||||
assert.ok(pi.handler)
|
||||
const ctx = context(undefined)
|
||||
await pi.handler("", ctx.value)
|
||||
assert.equal(called, false)
|
||||
assert.equal(ctx.notifications.at(-1)?.type, "warning")
|
||||
assert.match(ctx.notifications.at(-1)?.message ?? "", /requires an API key/)
|
||||
})
|
||||
|
||||
it("redacts endpoint failures before notifying the host", async () => {
|
||||
const pi = new CommandApiDouble()
|
||||
registerCommandCodeQuota(pi, {
|
||||
apiBase: "https://api.commandcode.ai",
|
||||
getConfiguredKey: () => "real-key",
|
||||
fetchQuota: async () => ({
|
||||
ok: false,
|
||||
error: { kind: "http", message: "api_key=supersecretvalue123456 failed" },
|
||||
}),
|
||||
})
|
||||
|
||||
assert.ok(pi.handler)
|
||||
const ctx = context("real-key")
|
||||
await pi.handler("", ctx.value)
|
||||
assert.equal(ctx.notifications.at(-1)?.type, "error")
|
||||
assert.doesNotMatch(ctx.notifications.at(-1)?.message ?? "", /supersecret/)
|
||||
})
|
||||
})
|
||||
+30
-8
@@ -8,15 +8,18 @@
|
||||
import assert from "node:assert/strict"
|
||||
import { describe, it } from "node:test"
|
||||
|
||||
import { formatQuota, formatWindowLimits } from "../src/quota-format.ts"
|
||||
import {
|
||||
DEFAULT_API_BASE,
|
||||
fetchCommandCodeQuota,
|
||||
formatQuota,
|
||||
formatWindowLimits,
|
||||
redactValue,
|
||||
windowLimitsFromCredits,
|
||||
} from "../src/quota.ts"
|
||||
import type { CommandCodeQuota, CommandCodeCredits, CommandCodeWindowLimit } from "../src/quota.ts"
|
||||
import type {
|
||||
CommandCodeCredits,
|
||||
CommandCodeQuota,
|
||||
CommandCodeWindowLimit,
|
||||
} from "../src/quota-types.ts"
|
||||
|
||||
function jsonResponse(body: unknown, status = 200): Response {
|
||||
return new Response(JSON.stringify(body), {
|
||||
@@ -71,7 +74,7 @@ describe("Command Code quota", () => {
|
||||
assert.equal(limits[1]?.resetAt, 1_700_000_000)
|
||||
})
|
||||
|
||||
it("renders a zero request count instead of dropping the Requests line", () => {
|
||||
it("renders valid zero usage without claiming an unknown billing period", () => {
|
||||
const quota: CommandCodeQuota = {
|
||||
account: { login: "alice", orgId: null },
|
||||
credits: null,
|
||||
@@ -79,6 +82,8 @@ describe("Command Code quota", () => {
|
||||
summary: { totalCost: 0, totalCount: 0 },
|
||||
}
|
||||
const output = formatQuota(quota, () => 1_700_000_000_000)
|
||||
assert.match(output, /Usage\n/)
|
||||
assert.doesNotMatch(output, /billing period/)
|
||||
assert.match(output, /Requests: 0/)
|
||||
})
|
||||
|
||||
@@ -158,6 +163,20 @@ describe("Command Code quota", () => {
|
||||
}
|
||||
})
|
||||
|
||||
it("rejects unrecognized successful endpoint schemas instead of displaying zero usage", async () => {
|
||||
const fetchImpl = async (input: RequestInfo | URL): Promise<Response> => {
|
||||
const url = String(input)
|
||||
if (url.includes("whoami")) return jsonResponse({ user: { userName: "alice" }, org: null })
|
||||
return jsonResponse({ changed: "schema" })
|
||||
}
|
||||
|
||||
const result = await fetchCommandCodeQuota({ apiKey: "cc_test_key", fetchImpl })
|
||||
assert.equal(result.ok, false)
|
||||
if (result.ok) return
|
||||
assert.equal(result.error.kind, "http")
|
||||
assert.match(result.error.message, /no recognized usage data/i)
|
||||
})
|
||||
|
||||
it("degrades gracefully when individual billing endpoints fail", async () => {
|
||||
const fetchImpl = async (input: RequestInfo | URL): Promise<Response> => {
|
||||
const url = String(input)
|
||||
@@ -174,6 +193,8 @@ describe("Command Code quota", () => {
|
||||
if (!result.ok) return
|
||||
assert.equal(result.quota.credits, null)
|
||||
assert.equal(result.quota.summary?.totalCost, 3.0)
|
||||
assert.deepEqual(result.quota.unavailable, ["credits", "subscription"])
|
||||
assert.match(formatQuota(result.quota), /Unavailable: credits, subscription/)
|
||||
// Optional aggregate tokens are parsed when the summary reports them.
|
||||
assert.equal(result.quota.summary?.totalTokens, undefined)
|
||||
})
|
||||
@@ -194,6 +215,7 @@ describe("Command Code quota", () => {
|
||||
assert.equal(result.quota.credits, null)
|
||||
assert.equal(result.quota.subscription?.planId, "pro")
|
||||
assert.equal(result.quota.summary?.totalCost, 3.0)
|
||||
assert.deepEqual(result.quota.unavailable, ["credits"])
|
||||
})
|
||||
|
||||
it("fails the command when the summary endpoint rejects auth/permission", async () => {
|
||||
@@ -299,8 +321,8 @@ describe("Command Code quota", () => {
|
||||
subscription: {
|
||||
planId: "pro",
|
||||
status: "active",
|
||||
currentPeriodStart: "",
|
||||
currentPeriodEnd: "",
|
||||
currentPeriodStart: "2026-01-01T00:00:00Z",
|
||||
currentPeriodEnd: "2026-02-01T00:00:00Z",
|
||||
},
|
||||
summary: { totalCost: 12.34, totalCount: 1500 },
|
||||
}
|
||||
@@ -312,10 +334,10 @@ describe("Command Code quota", () => {
|
||||
assert.match(output, /Used: \$12\.34/)
|
||||
assert.match(output, /Sources: monthly \$40\.00 \/ purchased \$10\.00 \/ free \$5\.00/)
|
||||
assert.match(output, /Plan: pro \(active\)/)
|
||||
assert.match(output, /Usage \(this month\)/)
|
||||
assert.match(output, /Usage \(billing period\)/)
|
||||
assert.match(output, /Cost: \$12\.34/)
|
||||
assert.match(output, /Requests: 1,500/)
|
||||
assert.match(output, /Username/)
|
||||
assert.match(output, /Account/)
|
||||
assert.match(output, /alice-inc/)
|
||||
assert.match(output, /5-hour: 8\.00 \/ 16\.00 credits/)
|
||||
assert.match(output, /Weekly: 20\.00 \/ 40\.00 credits/)
|
||||
|
||||
Reference in New Issue
Block a user