/** * @file AccountPoolCard.test.tsx * @description The Users page's account pool card: lists the Claude and Codex * accounts with their live panes and quota, says what an empty pool means, an * admin adds an account only with their own password typed (the token goes * in once and is not shown back) — a saved login moved in (the server's own * included), or a setup-token — and removes one the same way, and an analyst * sees no add or remove control. * @author Nguyễn Ngọc Trí Vĩ */ import { beforeEach, describe, expect, it, vi } from "vitest"; import { render, screen, waitFor } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import type { AccountPool } from "../../../lib/api"; const accountPool = vi.hoisted(() => ({ list: vi.fn(), add: vi.fn(), remove: vi.fn(), profiles: vi.fn(), })); vi.mock("../../../lib/api", async (importOriginal) => { const actual = await importOriginal>(); return { ...actual, api: { accountPool } }; }); import { AccountPoolCard } from "../AccountPoolCard"; const POOL: AccountPool = { accounts: [ { name: "team-1", kind: "login", email: "team1@example.com", refreshError: null, addedAt: "2026-10-01T00:00:00Z", expiresAt: null, expired: false, livePanes: 2, spend5h: 1.5, spend7d: 12, quotaPercent: 42, full: false, }, ], codex: [ { name: "cx-1", kind: "apikey", addedAt: "2026-10-02T00:00:00Z", livePanes: 0, spend5h: 0, spend7d: 0, quotaPercent: null, full: false, }, ], blockPercent: 90, }; beforeEach(() => { for (const fn of Object.values(accountPool)) fn.mockReset(); accountPool.list.mockResolvedValue(POOL); accountPool.profiles.mockResolvedValue({ profiles: [ { name: "work", label: "Work", email: "w@example.com", subscriptionType: "max", active: false, }, { name: "me", label: "Me", email: "me@example.com", subscriptionType: "pro", active: true }, ], }); }); describe("AccountPoolCard", () => { it("lists every account, and explains an empty pool", async () => { const { unmount } = render(); expect(await screen.findByText("team-1")).toBeInTheDocument(); expect(screen.getByText("cx-1")).toBeInTheDocument(); expect(screen.getByText("42%")).toBeInTheDocument(); expect(screen.getByText("team1@example.com")).toBeInTheDocument(); expect(screen.queryByRole("button", { name: /add account/i })).toBeNull(); expect(screen.queryByRole("button", { name: /remove/i })).toBeNull(); unmount(); accountPool.list.mockResolvedValue({ accounts: [], codex: [], blockPercent: 90 }); render(); expect(await screen.findByText(/no accounts yet/i)).toBeInTheDocument(); }); it("moves a saved login in, the server's own included", async () => { accountPool.add.mockResolvedValue({ account: { name: "work" } }); const user = userEvent.setup(); render(); await screen.findByText("team-1"); await user.click(screen.getByRole("button", { name: /add account/i })); const dialog = await screen.findByRole("dialog"); const select = await screen.findByLabelText("Profile"); await waitFor(() => expect(screen.getByRole("option", { name: /Work/ })).toBeInTheDocument()); expect(screen.getByRole("option", { name: /Me/ })).toBeEnabled(); await user.selectOptions(select, "work"); const confirm = Array.from(dialog.querySelectorAll("button")).find( (b) => b.textContent === "Add account" )!; expect(confirm).toBeDisabled(); await user.type(screen.getByLabelText("Your password"), "boss-pass"); await user.click(confirm); await waitFor(() => expect(accountPool.add).toHaveBeenCalledWith( { tool: "claude", name: "work", profile: "work" }, "boss-pass" ) ); }); it("adds a setup-token only with the admin's own password", async () => { accountPool.add.mockResolvedValue({ account: { name: "team-2" } }); const user = userEvent.setup(); render(); await screen.findByText("team-1"); await user.click(screen.getByRole("button", { name: /add account/i })); const dialog = await screen.findByRole("dialog"); await user.selectOptions(screen.getByLabelText("From"), "token"); await user.type(screen.getByLabelText("Name"), "team-2"); await user.type(screen.getByLabelText("Token"), "sk-ant-oat01-xyz"); const confirm = Array.from(dialog.querySelectorAll("button")).find( (b) => b.textContent === "Add account" )!; expect(confirm).toBeDisabled(); await user.type(screen.getByLabelText("Your password"), "boss-pass"); expect(confirm).toBeEnabled(); await user.click(confirm); await waitFor(() => expect(accountPool.add).toHaveBeenCalledWith( { tool: "claude", name: "team-2", token: "sk-ant-oat01-xyz" }, "boss-pass" ) ); }); it("removes an account with the admin's own password", async () => { accountPool.remove.mockResolvedValue({ ok: true }); const user = userEvent.setup(); render(); await user.click(await screen.findByRole("button", { name: "Remove cx-1" })); await user.type(await screen.findByLabelText("Your password"), "boss-pass"); await user.click(screen.getByRole("button", { name: "Remove" })); await waitFor(() => expect(accountPool.remove).toHaveBeenCalledWith("codex", "cx-1", "boss-pass") ); }); });