// @vitest-environment jsdom import { act } from "react"; import type { ReactNode } from "react"; import { createRoot } from "react-dom/client"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { CommandPalette } from "./CommandPalette"; const companyState = vi.hoisted(() => ({ selectedCompanyId: "company-1", })); const dialogState = vi.hoisted(() => ({ openNewIssue: vi.fn(), openNewAgent: vi.fn(), })); const sidebarState = vi.hoisted(() => ({ isMobile: false, setSidebarOpen: vi.fn(), })); const mockIssuesApi = vi.hoisted(() => ({ list: vi.fn(), })); const mockAgentsApi = vi.hoisted(() => ({ list: vi.fn(), })); const mockProjectsApi = vi.hoisted(() => ({ list: vi.fn(), })); vi.mock("../context/CompanyContext", () => ({ useCompany: () => companyState, })); vi.mock("../context/DialogContext", () => ({ useDialog: () => dialogState, })); vi.mock("../context/SidebarContext", () => ({ useSidebar: () => sidebarState, })); vi.mock("@/lib/router", () => ({ useNavigate: () => vi.fn(), })); vi.mock("../api/issues", () => ({ issuesApi: mockIssuesApi, })); vi.mock("../api/agents", () => ({ agentsApi: mockAgentsApi, })); vi.mock("../api/projects", () => ({ projectsApi: mockProjectsApi, })); vi.mock("./Identity", () => ({ Identity: ({ name }: { name: string }) => {name}, })); vi.mock("@/components/ui/command", () => ({ CommandDialog: ({ open, children }: { open: boolean; children: ReactNode }) => (open ?
{children}
: null), CommandEmpty: ({ children }: { children: ReactNode }) =>
{children}
, CommandGroup: ({ children }: { children: ReactNode }) =>
{children}
, CommandInput: ({ value, onValueChange, }: { value: string; onValueChange: (value: string) => void; }) => (
onValueChange(event.currentTarget.value)} />
), CommandItem: ({ children, onSelect, }: { children: ReactNode; onSelect?: () => void; }) => , CommandList: ({ children }: { children: ReactNode }) =>
{children}
, CommandSeparator: () =>
, })); // eslint-disable-next-line @typescript-eslint/no-explicit-any (globalThis as any).IS_REACT_ACT_ENVIRONMENT = true; async function flush() { await act(async () => { await Promise.resolve(); }); } async function waitForAssertion(assertion: () => void, attempts = 20) { let lastError: unknown; for (let attempt = 0; attempt < attempts; attempt += 1) { try { assertion(); return; } catch (error) { lastError = error; await flush(); } } throw lastError; } function renderWithQueryClient(node: ReactNode, container: HTMLDivElement) { const root = createRoot(container); const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false, }, }, }); act(() => { root.render( {node} , ); }); return { root, queryClient }; } describe("CommandPalette", () => { let container: HTMLDivElement; beforeEach(() => { container = document.createElement("div"); document.body.appendChild(container); dialogState.openNewIssue.mockReset(); dialogState.openNewAgent.mockReset(); sidebarState.setSidebarOpen.mockReset(); mockIssuesApi.list.mockReset(); mockAgentsApi.list.mockReset(); mockProjectsApi.list.mockReset(); mockIssuesApi.list.mockResolvedValue([]); mockAgentsApi.list.mockResolvedValue([]); mockProjectsApi.list.mockResolvedValue([]); }); afterEach(() => { container.remove(); }); it("includes routine execution issues in search queries", async () => { const { root } = renderWithQueryClient(, container); act(() => { document.dispatchEvent(new KeyboardEvent("keydown", { key: "k", metaKey: true, bubbles: true })); }); const setQueryButton = container.querySelector('button[aria-label="Set query"]'); expect(setQueryButton).not.toBeNull(); act(() => { setQueryButton!.dispatchEvent(new MouseEvent("click", { bubbles: true })); }); await waitForAssertion(() => { expect(mockIssuesApi.list).toHaveBeenCalledWith("company-1", { q: "pull/3303", limit: 10, includeRoutineExecutions: true, }); }); act(() => { root.unmount(); }); }); });