179 lines · 6.3 KB · TypeScript
RawDownload
import { EnvironmentId, ProviderInstanceId, USAGE_CONTRACT_VERSION } from "@t3tools/contracts";import { mergeUsage } from "@t3tools/shared/usageMerge";import { act } from "react";import { create, type ReactTestRenderer } from "react-test-renderer";import { afterEach, beforeEach, expect, it, vi } from "vite-plus/test"; const state = vi.hoisted(() => ({  presentations: new Map(),  refreshProviders: vi.fn(async () => undefined),}));vi.mock("@effect/atom-react", () => ({ useAtomValue: () => state.presentations }));vi.mock("../../state/presentation", () => ({  environmentPresentations: { presentationsAtom: null },}));vi.mock("../../state/server", () => ({ serverEnvironment: { refreshProviders: null } }));vi.mock("../../state/use-atom-command", () => ({ useAtomCommand: () => state.refreshProviders }));vi.mock("../../env", () => ({ isElectron: false }));vi.mock("../../hooks/useSettings", () => ({ usePrimarySettings: () => "24h" }));vi.mock("../../state/usage", () => ({  useUsage: () => ({    merged: mergeUsage([], USAGE_CONTRACT_VERSION),    environments: [      {        environmentId: EnvironmentId.make("test"),        label: "Test",        isPending: false,        error: null,        summary: null,      },    ],    selectedEnvironments: [      {        environmentId: EnvironmentId.make("test"),        label: "Test",        isPending: false,        error: null,        summary: null,      },    ],    isPending: false,    isPartial: false,    refresh: async () => undefined,  }),}));vi.mock("./usagePagePreferences", () => ({  readUsagePagePreferences: () => ({ metric: "limits", windowDays: 30 }),  saveUsagePagePreferences: vi.fn(),}));vi.mock("../ui/button", () => ({ Button: "button" }));vi.mock("../ui/scroll-area", () => ({ ScrollArea: "div" }));vi.mock("../ui/select", () => ({  Select: "select",  SelectItem: "option",  SelectPopup: "div",  SelectTrigger: "div",  SelectValue: "span",}));vi.mock("../ui/sidebar", () => ({ SidebarInset: "div" }));vi.mock("../ui/toggle-group", () => ({ Toggle: "button", ToggleGroup: "div" }));vi.mock("../ui/tooltip", () => ({ Tooltip: "div", TooltipPopup: "div", TooltipTrigger: "div" }));vi.mock("../ui/popover", () => ({ Popover: "div", PopoverPopup: "div", PopoverTrigger: "div" }));vi.mock("../ui/menu", () => ({  Menu: "div",  MenuCheckboxItem: "div",  MenuItem: "div",  MenuPopup: "div",  MenuSeparator: "hr",  MenuTrigger: "div",}));vi.mock("../WorkspaceBreadcrumb", () => ({  WorkspaceBreadcrumb: "div",  WorkspaceBreadcrumbItem: "div",  WorkspaceBreadcrumbSeparator: "span",}));vi.mock("../WorkspacePageContainer", () => ({ WorkspacePageContainer: "main" }));vi.mock("../WorkspacePageHeader", () => ({ WorkspacePageHeader: "header" }));vi.mock("./UsageProviderChart", () => ({ UsageProviderChart: "div" }));vi.mock("./UsagePriceOverrides", () => ({ UsagePriceOverrides: () => null }));vi.mock("../chat/ProviderInstanceIcon", () => ({ ProviderInstanceIcon: () => null }));vi.mock("../settings/RedactedSensitiveText", () => ({ RedactedSensitiveText: "span" }));vi.mock("../settings/providerDriverMeta", () => ({ getDriverOption: () => ({ label: "Codex" }) })); import { UsagePage } from "./UsagePage"; let renderer: ReactTestRenderer;beforeEach(() => {  vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true);  vi.spyOn(Date, "now").mockReturnValue(Date.parse("2026-09-11T12:00:00Z"));  state.refreshProviders.mockClear();  state.presentations = new Map([    [      EnvironmentId.make("test"),      {        entry: { target: { label: "Test" } },        connection: { phase: "connected" },        serverConfig: {          providers: [            {              instanceId: ProviderInstanceId.make("codex"),              driver: "codex",              enabled: true,              installed: true,              version: null,              status: "ready",              auth: { status: "authenticated" },              checkedAt: "2026-09-11T12:00:00Z",              models: [],              slashCommands: [],              skills: [],              usageLimits: {                checkedAt: "2026-09-11T12:00:00Z",                windows: [                  {                    id: "five_hour",                    kind: "session",                    label: "Session",                    usedPercent: 40,                    windowDurationMins: 300,                    resetsAt: "2026-09-11T14:00:00Z",                  },                ],              },            },          ],        },      },    ],  ]);});afterEach(async () => {  await act(() => renderer?.unmount());  vi.restoreAllMocks();  vi.unstubAllGlobals();}); it.each([0, 1])(  "refreshes the visible limits countdown with refresh button %i without switching tabs, even when quota is unchanged",  async (buttonIndex) => {    await act(() => {      renderer = create(<UsagePage />);    });    expect(      JSON.stringify(renderer.toJSON(), (key, value) => (key === "props" ? undefined : value)),    ).toContain("in 2h 0m");    vi.mocked(Date.now).mockReturnValue(Date.parse("2026-09-11T12:30:00Z"));    await act(async () => {      renderer.root        .findAllByProps({ "aria-label": "Refresh limits" })        .filter((node) => node.type === "button")        .at(buttonIndex)!        .props.onClick();    });    expect(state.refreshProviders).toHaveBeenCalledWith({ environmentId: "test", input: {} });    expect(      JSON.stringify(renderer.toJSON(), (key, value) => (key === "props" ? undefined : value)),    ).toContain("in 1h 30m");    expect(      JSON.stringify(renderer.toJSON(), (key, value) => (key === "props" ? undefined : value)),    ).not.toContain("in 2h 0m");  },); it("uses the current time when returning to limits from tokens", async () => {  await act(() => {    renderer = create(<UsagePage />);  });  const selectMetric = (metric: string) => {    renderer.root      .findAll((node) => node.type === "div" && node.props["aria-label"] === "Usage metric")[0]!      .props.onValueChange([metric]);  };  await act(() => selectMetric("tokens"));  vi.mocked(Date.now).mockReturnValue(Date.parse("2026-09-11T13:00:00Z"));  await act(() => selectMetric("limits"));  expect(    JSON.stringify(renderer.toJSON(), (key, value) => (key === "props" ? undefined : value)),  ).toContain("in 1h 0m");  expect(state.refreshProviders).not.toHaveBeenCalled();});