From 816ffb9379e31c5ed8240665df3b2ea1eebfb62c Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 13 Mar 2026 23:59:31 +0000 Subject: [PATCH] test: extract provider usage load coverage --- src/infra/provider-usage.load.test.ts | 136 ++++++++++++++++++++++++++ src/infra/provider-usage.test.ts | 116 +--------------------- 2 files changed, 137 insertions(+), 115 deletions(-) create mode 100644 src/infra/provider-usage.load.test.ts diff --git a/src/infra/provider-usage.load.test.ts b/src/infra/provider-usage.load.test.ts new file mode 100644 index 00000000000..1a91b87a56b --- /dev/null +++ b/src/infra/provider-usage.load.test.ts @@ -0,0 +1,136 @@ +import { describe, expect, it, vi } from "vitest"; +import { createProviderUsageFetch, makeResponse } from "../test-utils/provider-usage-fetch.js"; +import { loadProviderUsageSummary } from "./provider-usage.load.js"; +import { ignoredErrors } from "./provider-usage.shared.js"; + +const usageNow = Date.UTC(2026, 0, 7, 0, 0, 0); + +type ProviderAuth = NonNullable< + NonNullable[0]>["auth"] +>[number]; + +async function loadUsageWithAuth( + auth: ProviderAuth[], + mockFetch: ReturnType, +) { + return await loadProviderUsageSummary({ + now: usageNow, + auth, + fetch: mockFetch as unknown as typeof fetch, + }); +} + +describe("provider-usage.load", () => { + it("loads snapshots for copilot gemini codex and xiaomi", async () => { + const mockFetch = createProviderUsageFetch(async (url) => { + if (url.includes("api.github.com/copilot_internal/user")) { + return makeResponse(200, { + quota_snapshots: { chat: { percent_remaining: 80 } }, + copilot_plan: "Copilot Pro", + }); + } + if (url.includes("cloudcode-pa.googleapis.com/v1internal:fetchAvailableModels")) { + return makeResponse(200, { + models: { + "gemini-2.5-pro": { + quotaInfo: { remainingFraction: 0.4, resetTime: "2026-01-08T01:00:00Z" }, + }, + }, + }); + } + if (url.includes("cloudcode-pa.googleapis.com/v1internal:retrieveUserQuota")) { + return makeResponse(200, { + buckets: [{ modelId: "gemini-2.5-pro", remainingFraction: 0.6 }], + }); + } + if (url.includes("chatgpt.com/backend-api/wham/usage")) { + return makeResponse(200, { + rate_limit: { primary_window: { used_percent: 12, limit_window_seconds: 10800 } }, + plan_type: "Plus", + }); + } + return makeResponse(404, "not found"); + }); + + const summary = await loadUsageWithAuth( + [ + { provider: "github-copilot", token: "copilot-token" }, + { provider: "google-gemini-cli", token: "gemini-token" }, + { provider: "openai-codex", token: "codex-token", accountId: "acc-1" }, + { provider: "xiaomi", token: "xiaomi-token" }, + ], + mockFetch, + ); + + expect(summary.providers.map((provider) => provider.provider)).toEqual([ + "github-copilot", + "google-gemini-cli", + "openai-codex", + "xiaomi", + ]); + expect( + summary.providers.find((provider) => provider.provider === "github-copilot")?.windows, + ).toEqual([{ label: "Chat", usedPercent: 20 }]); + expect( + summary.providers.find((provider) => provider.provider === "google-gemini-cli")?.windows[0] + ?.label, + ).toBe("Pro"); + expect( + summary.providers.find((provider) => provider.provider === "openai-codex")?.windows[0]?.label, + ).toBe("3h"); + expect(summary.providers.find((provider) => provider.provider === "xiaomi")?.windows).toEqual( + [], + ); + }); + + it("returns empty provider list when auth resolves to none", async () => { + const mockFetch = createProviderUsageFetch(async () => makeResponse(404, "not found")); + const summary = await loadUsageWithAuth([], mockFetch); + expect(summary).toEqual({ updatedAt: usageNow, providers: [] }); + }); + + it("returns unsupported provider snapshots for unknown provider ids", async () => { + const mockFetch = createProviderUsageFetch(async () => makeResponse(404, "not found")); + const summary = await loadUsageWithAuth( + [{ provider: "unsupported-provider", token: "token-u" }] as unknown as ProviderAuth[], + mockFetch, + ); + expect(summary.providers).toHaveLength(1); + expect(summary.providers[0]?.error).toBe("Unsupported provider"); + }); + + it("filters errors that are marked as ignored", async () => { + const mockFetch = createProviderUsageFetch(async (url) => { + if (url.includes("api.anthropic.com/api/oauth/usage")) { + return makeResponse(500, "boom"); + } + return makeResponse(404, "not found"); + }); + ignoredErrors.add("HTTP 500"); + try { + const summary = await loadUsageWithAuth( + [{ provider: "anthropic", token: "token-a" }], + mockFetch, + ); + expect(summary.providers).toEqual([]); + } finally { + ignoredErrors.delete("HTTP 500"); + } + }); + + it("throws when fetch is unavailable", async () => { + const previousFetch = globalThis.fetch; + vi.stubGlobal("fetch", undefined); + try { + await expect( + loadProviderUsageSummary({ + now: usageNow, + auth: [{ provider: "xiaomi", token: "token-x" }], + fetch: undefined, + }), + ).rejects.toThrow("fetch is not available"); + } finally { + vi.stubGlobal("fetch", previousFetch); + } + }); +}); diff --git a/src/infra/provider-usage.test.ts b/src/infra/provider-usage.test.ts index d8f94d04646..2e45a2ee9dc 100644 --- a/src/infra/provider-usage.test.ts +++ b/src/infra/provider-usage.test.ts @@ -1,6 +1,6 @@ import fs from "node:fs"; import path from "node:path"; -import { describe, expect, it, vi } from "vitest"; +import { describe, expect, it } from "vitest"; import { withTempHome } from "../../test/helpers/temp-home.js"; import { ensureAuthProfileStore, listProfilesForProvider } from "../agents/auth-profiles.js"; import { withEnvAsync } from "../test-utils/env.js"; @@ -11,7 +11,6 @@ import { loadProviderUsageSummary, type UsageSummary, } from "./provider-usage.js"; -import { ignoredErrors } from "./provider-usage.shared.js"; const minimaxRemainsEndpoint = "api.minimaxi.com/v1/api/openplatform/coding_plan/remains"; const usageNow = Date.UTC(2026, 0, 7, 0, 0, 0); @@ -354,117 +353,4 @@ describe("provider usage loading", () => { expect(claude?.windows.some((w) => w.label === "Week")).toBe(true); }); }); - - it("loads snapshots for copilot gemini codex and xiaomi", async () => { - const mockFetch = createProviderUsageFetch(async (url) => { - if (url.includes("api.github.com/copilot_internal/user")) { - return makeResponse(200, { - quota_snapshots: { chat: { percent_remaining: 80 } }, - copilot_plan: "Copilot Pro", - }); - } - if (url.includes("cloudcode-pa.googleapis.com/v1internal:fetchAvailableModels")) { - return makeResponse(200, { - models: { - "gemini-2.5-pro": { - quotaInfo: { remainingFraction: 0.4, resetTime: "2026-01-08T01:00:00Z" }, - }, - }, - }); - } - if (url.includes("cloudcode-pa.googleapis.com/v1internal:retrieveUserQuota")) { - return makeResponse(200, { - buckets: [{ modelId: "gemini-2.5-pro", remainingFraction: 0.6 }], - }); - } - if (url.includes("chatgpt.com/backend-api/wham/usage")) { - return makeResponse(200, { - rate_limit: { primary_window: { used_percent: 12, limit_window_seconds: 10800 } }, - plan_type: "Plus", - }); - } - return makeResponse(404, "not found"); - }); - - const summary = await loadUsageWithAuth( - [ - { provider: "github-copilot", token: "copilot-token" }, - { provider: "google-gemini-cli", token: "gemini-token" }, - { provider: "openai-codex", token: "codex-token", accountId: "acc-1" }, - { provider: "xiaomi", token: "xiaomi-token" }, - ], - mockFetch, - ); - - expect(summary.providers.map((provider) => provider.provider)).toEqual([ - "github-copilot", - "google-gemini-cli", - "openai-codex", - "xiaomi", - ]); - expect( - summary.providers.find((provider) => provider.provider === "github-copilot")?.windows, - ).toEqual([{ label: "Chat", usedPercent: 20 }]); - expect( - summary.providers.find((provider) => provider.provider === "google-gemini-cli")?.windows[0] - ?.label, - ).toBe("Pro"); - expect( - summary.providers.find((provider) => provider.provider === "openai-codex")?.windows[0]?.label, - ).toBe("3h"); - expect(summary.providers.find((provider) => provider.provider === "xiaomi")?.windows).toEqual( - [], - ); - }); - - it("returns empty provider list when auth resolves to none", async () => { - const mockFetch = createProviderUsageFetch(async () => makeResponse(404, "not found")); - const summary = await loadUsageWithAuth([], mockFetch); - expect(summary).toEqual({ updatedAt: usageNow, providers: [] }); - }); - - it("returns unsupported provider snapshots for unknown provider ids", async () => { - const mockFetch = createProviderUsageFetch(async () => makeResponse(404, "not found")); - const summary = await loadUsageWithAuth( - [{ provider: "unsupported-provider", token: "token-u" }] as unknown as ProviderAuth[], - mockFetch, - ); - expect(summary.providers).toHaveLength(1); - expect(summary.providers[0]?.error).toBe("Unsupported provider"); - }); - - it("filters errors that are marked as ignored", async () => { - const mockFetch = createProviderUsageFetch(async (url) => { - if (url.includes("api.anthropic.com/api/oauth/usage")) { - return makeResponse(500, "boom"); - } - return makeResponse(404, "not found"); - }); - ignoredErrors.add("HTTP 500"); - try { - const summary = await loadUsageWithAuth( - [{ provider: "anthropic", token: "token-a" }], - mockFetch, - ); - expect(summary.providers).toEqual([]); - } finally { - ignoredErrors.delete("HTTP 500"); - } - }); - - it("throws when fetch is unavailable", async () => { - const previousFetch = globalThis.fetch; - vi.stubGlobal("fetch", undefined); - try { - await expect( - loadProviderUsageSummary({ - now: usageNow, - auth: [{ provider: "xiaomi", token: "token-x" }], - fetch: undefined, - }), - ).rejects.toThrow("fetch is not available"); - } finally { - vi.stubGlobal("fetch", previousFetch); - } - }); });