// @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 { NewIssueDialog } from "./NewIssueDialog"; const dialogState = vi.hoisted(() => ({ newIssueOpen: true, newIssueDefaults: {} as Record, closeNewIssue: vi.fn(), })); const dialogContentState = vi.hoisted(() => ({ 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", brandColor: "#123456", issuePrefix: "PAP", }, ], selectedCompanyId: "company-1", selectedCompany: { id: "company-1", name: "Paperclip", status: "active", brandColor: "#123456", issuePrefix: "PAP", }, })); const toastState = vi.hoisted(() => ({ pushToast: vi.fn(), })); const mockIssuesApi = vi.hoisted(() => ({ 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(), })); vi.mock("../context/DialogContext", () => ({ useDialog: () => dialogState, })); vi.mock("../context/CompanyContext", () => ({ useCompany: () => companyState, })); vi.mock("../context/ToastContext", () => ({ useToastActions: () => toastState, })); 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("../hooks/useProjectOrder", () => ({ useProjectOrder: ({ projects }: { projects: unknown[] }) => ({ orderedProjects: projects, }), })); vi.mock("../lib/recent-assignees", () => ({ getRecentAssigneeIds: () => [], sortAgentsByRecency: (agents: unknown[]) => agents, trackRecentAssignee: vi.fn(), })); vi.mock("../lib/assignees", () => ({ assigneeValueFromSelection: ({ assigneeAgentId, assigneeUserId, }: { assigneeAgentId?: string; assigneeUserId?: string; }) => assigneeAgentId ? `agent:${assigneeAgentId}` : assigneeUserId ? `user:${assigneeUserId}` : "", currentUserAssigneeOption: () => [], 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 (