/** * @file Tests for PoolAccountSettings — Settings → AI tools → Pool account: * hidden in local mode and with no usable account; one select per tool that * starts on the user's choice (or Automatic) and saves a pick through * `PUT /api/me/pool-accounts`; locked when an admin pinned the user. * @author Nguyễn Ngọc Trí Vĩ */ import { describe, it, expect, vi, beforeEach } from "vitest"; import { render, screen, act } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import "../../../i18n"; import { PoolAccountSettings } from "../PoolAccountSettings"; const perms = vi.hoisted(() => ({ local: false })); vi.mock("../../AuthGate", () => ({ usePermissions: () => perms })); const m = vi.hoisted(() => ({ poolAccounts: vi.fn(), choosePoolAccount: vi.fn() })); vi.mock("../../../lib/api", () => ({ api: { me: m, aiTools: { iconUrl: (id: string) => `/icons/${id}.png` } }, })); const account = (name: string) => ({ name, kind: "login", email: `${name}@x.io`, expired: false, quotaPercent: 20, full: false, }); async function show() { render(); await act(async () => { await new Promise((res) => setTimeout(res, 0)); }); } beforeEach(() => { perms.local = false; m.poolAccounts.mockReset(); m.choosePoolAccount.mockReset(); }); describe("PoolAccountSettings", () => { it("renders nothing in local mode or with no account to choose", async () => { perms.local = true; await show(); expect(m.poolAccounts).not.toHaveBeenCalled(); expect(screen.queryByRole("combobox")).toBeNull(); perms.local = false; m.poolAccounts.mockResolvedValue({ tools: [] }); await show(); expect(screen.queryByRole("combobox")).toBeNull(); }); it("starts on the user's choice and saves a new pick", async () => { m.poolAccounts.mockResolvedValue({ tools: [ { tool: "claude", pin: null, choice: "two", accounts: [account("one"), account("two")] }, ], }); m.choosePoolAccount.mockResolvedValue({ tool: "claude", choice: "one", switched: "switched" }); await show(); const select = screen.getByRole("combobox") as HTMLSelectElement; expect(select.value).toBe("two"); await userEvent.selectOptions(select, "one"); expect(m.choosePoolAccount).toHaveBeenCalledWith("claude", "one"); await userEvent.selectOptions(select, ""); expect(m.choosePoolAccount).toHaveBeenLastCalledWith("claude", null); }); it("is locked on an admin's pin", async () => { m.poolAccounts.mockResolvedValue({ tools: [ { tool: "codex", pin: "one", choice: null, accounts: [account("one"), account("two")] }, ], }); await show(); const select = screen.getByRole("combobox") as HTMLSelectElement; expect(select.disabled).toBe(true); expect(select.value).toBe("one"); expect(screen.getByText(/one/, { selector: "span" })).toBeTruthy(); }); });