// @vitest-environment jsdom import type { ComponentProps, ReactNode } from "react"; import { flushSync } from "react-dom"; import { createRoot } from "react-dom/client"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { queryKeys } from "../lib/queryKeys"; import { trackRecentAssignee, trackRecentAssigneeUser } from "../lib/recent-assignees"; import { getLastProjectId, trackRecentProject } from "../lib/recent-projects"; import { rememberComposerEffort } from "../lib/recent-composer-effort"; import { NewIssueDialog } from "./NewIssueDialog"; const primaryState = vi.hoisted(() => ({ primaryAgentId: null as string | null, loading: false })); vi.mock("./primary-agent/PrimaryAgentPresentation", () => ({ usePrimaryAgentPresentation: () => primaryState })); const dialogState = vi.hoisted(() => ({ newIssueOpen: true, newIssueDefaults: {} as Record, closeNewIssue: vi.fn(), })); const dialogContentState = vi.hoisted(() => ({ onEscapeKeyDown: null as null | ((event: KeyboardEvent) => void), onPointerDownOutside: null as null | ((event: { detail: { originalEvent: { target: EventTarget | null } }; preventDefault: () => void; }) => void), })); const companyState = vi.hoisted(() => ({ companies: [ { id: "company-1", name: "Paperclip", status: "active", issuePrefix: "PAP", }, ], selectedCompanyId: "company-1", selectedCompany: { id: "company-1", name: "Paperclip", status: "active", issuePrefix: "PAP", }, })); const toastState = vi.hoisted(() => ({ pushToast: vi.fn(), })); const navigateMock = vi.hoisted(() => vi.fn()); const mockIssuesApi = vi.hoisted(() => ({ get: vi.fn(), list: vi.fn(), create: vi.fn(), upsertDocument: vi.fn(), uploadAttachment: vi.fn(), })); const mockExecutionWorkspacesApi = vi.hoisted(() => ({ list: vi.fn(), listSummaries: vi.fn(), })); const mockProjectsApi = vi.hoisted(() => ({ list: vi.fn(), })); const mockAgentsApi = vi.hoisted(() => ({ list: vi.fn(), adapterModels: vi.fn(), })); const mockAuthApi = vi.hoisted(() => ({ getSession: vi.fn(), })); const mockAssetsApi = vi.hoisted(() => ({ uploadImage: vi.fn(), })); const mockInstanceSettingsApi = vi.hoisted(() => ({ getExperimental: vi.fn(), })); const mockMissingUserSecretsBannerRender = vi.hoisted(() => vi.fn()); vi.mock("../context/DialogContext", () => ({ useDialog: () => dialogState, })); vi.mock("../context/SidebarContext", () => ({ useSidebar: () => ({ isMobile: false }) })); vi.mock("../context/CompanyContext", () => ({ useCompany: () => companyState, })); vi.mock("../context/ToastContext", () => ({ useToastActions: () => toastState, })); vi.mock("../lib/router", async (importOriginal) => ({ ...await importOriginal(), useNavigate: () => navigateMock, })); vi.mock("../api/issues", () => ({ issuesApi: mockIssuesApi, })); vi.mock("../api/execution-workspaces", () => ({ executionWorkspacesApi: mockExecutionWorkspacesApi, })); vi.mock("../api/projects", () => ({ projectsApi: mockProjectsApi, })); vi.mock("../api/agents", () => ({ agentsApi: mockAgentsApi, })); vi.mock("../api/auth", () => ({ authApi: mockAuthApi, })); vi.mock("../api/assets", () => ({ assetsApi: mockAssetsApi, })); vi.mock("../api/instanceSettings", () => ({ instanceSettingsApi: mockInstanceSettingsApi, })); vi.mock("../pages/secrets/MissingUserSecretsBanner", async () => { const React = await import("react"); return { MissingUserSecretsBanner: (props: { definitionKeys?: string[] }) => { mockMissingUserSecretsBannerRender(props); return React.createElement( "div", { "data-testid": "missing-user-secrets-banner" }, props.definitionKeys?.join(",") ?? "", ); }, }; }); vi.mock("../hooks/useProjectOrder", () => ({ useProjectOrder: ({ projects }: { projects: unknown[] }) => ({ orderedProjects: projects, }), })); vi.mock("../api/access", () => ({ accessApi: { listUserDirectory: async () => ({ users: [] }) }, })); vi.mock("../lib/assignees", () => ({ assigneeValueFromSelection: ({ assigneeAgentId, assigneeUserId, }: { assigneeAgentId?: string; assigneeUserId?: string; }) => assigneeAgentId ? `agent:${assigneeAgentId}` : assigneeUserId ? `user:${assigneeUserId}` : "", currentUserAssigneeOption: (id: string | null) => id ? [{ id: `user:${id}`, label: "Me" }] : [], parseAssigneeValue: (value: string) => ({ assigneeAgentId: value.startsWith("agent:") ? value.slice("agent:".length) : null, assigneeUserId: value.startsWith("user:") ? value.slice("user:".length) : null, }), })); vi.mock("./MarkdownEditor", async () => { const React = await import("react"); return { MarkdownEditor: React.forwardRef< { focus: () => void }, { value: string; onChange?: (value: string) => void; placeholder?: string } >(function MarkdownEditorMock({ value, onChange, placeholder }, ref) { React.useImperativeHandle(ref, () => ({ focus: () => undefined, })); return (