/** * @file Covers the quota lines in the Claude Code auth-profile modal: opening * it asks for EVERY saved account's quota, not one row at a time. * * The one-at-a-time version made the user click through their own accounts to * answer the only question the panel exists for — which account still has room. * The other half is that each row fails on its own: an account whose saved * login has been superseded must not stop its neighbours from reporting. * @author Nguyễn Ngọc Trí Vĩ */ import { describe, it, expect, vi, afterEach } from "vitest"; import { render, screen, act } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; const ccConfigMock = vi.hoisted(() => { const r = (value: unknown) => vi.fn().mockResolvedValue(value); const window = (utilization: number) => ({ utilization, resetsAt: "2026-09-18T08:00:00Z", }); return { window, overview: r({ roots: { claudeHome: "/home/.claude", projectClaudeDir: "/repo/.claude", projectRoot: "/repo", }, counts: { skills: { user: 0, project: 0 }, agents: { user: 0, project: 0 }, commands: { user: 0, project: 0 }, outputStyles: { user: 0, project: 0 }, mcpServers: { user: 0, project: 0 }, hooks: {}, plugins: 0, marketplaces: 0, keybindings: 0, settingsFiles: 0, memory: 0, }, }), skills: r({ items: [] }), agents: r({ items: [] }), commands: r({ items: [] }), outputStyles: r({ items: [] }), memory: r({ items: [] }), plugins: r({ manifestPath: "", manifestExists: false, plugins: [] }), marketplaces: r({ marketplaces: [] }), mcp: r({ mcp: [] }), hooks: r({ hooks: [] }), settings: r({ sources: [] }), keybindings: r({ groups: [] }), statusline: r({}), hookScripts: r({ items: [] }), backups: r({ items: [] }), file: r({ ok: true, file: "", size: 0, mtime: 0, truncated: false, text: "" }), pluginsAvailable: r({ installed: [], available: [] }), updateAllStatus: r({ batch: null }), // The modal's own list: two saved accounts, one of them live. profiles: r({ items: [ { name: "work", label: "Work", active: true, accountUuid: "u1", email: "a@b.c" }, { name: "spare", label: "Spare", active: false, accountUuid: "u2", email: "d@e.f" }, ], active: { accountUuid: "u1", email: "a@b.c" }, }), profileUsage: vi.fn().mockImplementation(async (name: string) => { if (name === "spare") { throw new Error("this profile's saved login has been superseded"); } return { name, refreshed: false, fiveHour: window(8), sevenDay: window(70), checkedAt: "2026-09-17T16:00:00Z", }; }), }; }); vi.mock("../../lib/api", async (importOriginal) => { const actual = await importOriginal>(); return { ...actual, api: { ...(actual.api as Record), ccConfig: ccConfigMock }, }; }); vi.mock("../../lib/eventBus", () => ({ eventBus: { subscribe: () => () => {}, publish: () => {}, onConnection: () => () => {}, connected: true, setConnected: () => {}, }, })); import { CcConfig } from "../CcConfig"; async function settle() { await act(async () => { await new Promise((res) => setTimeout(res, 0)); await new Promise((res) => setTimeout(res, 0)); }); } async function openProfiles() { render(); await settle(); await userEvent.click(screen.getByRole("button", { name: /profile/i })); await settle(); await settle(); } afterEach(() => vi.clearAllMocks()); describe("CcConfig — auth profile quotas", () => { it("asks for every saved account's quota when the modal opens", async () => { await openProfiles(); expect(ccConfigMock.profileUsage).toHaveBeenCalledWith("work"); expect(ccConfigMock.profileUsage).toHaveBeenCalledWith("spare"); expect(await screen.findByText("8%")).toBeInTheDocument(); expect(await screen.findByText("70%")).toBeInTheDocument(); }); it("reports the account that failed without costing the others their numbers", async () => { await openProfiles(); expect(await screen.findByText(/saved login has been superseded/i)).toBeInTheDocument(); expect(screen.getByText("8%")).toBeInTheDocument(); }); it("asks once per profile, however many times the panel re-renders", async () => { await openProfiles(); await settle(); await settle(); const asked = ccConfigMock.profileUsage.mock.calls.filter((c) => c[0] === "work"); expect(asked).toHaveLength(1); }); });