// @vitest-environment jsdom import { act, createRef, forwardRef, useImperativeHandle } from "react"; import type { ReactNode } from "react"; import { createRoot } from "react-dom/client"; import { MemoryRouter } from "react-router-dom"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import type { Agent } from "@paperclipai/shared"; import { IssueChatThread, canStopIssueChatRun, resolveAssistantMessageFoldedState, resolveIssueChatHumanAuthor, } from "./IssueChatThread"; import type { AskUserQuestionsInteraction, RequestConfirmationInteraction, SuggestTasksInteraction, } from "../lib/issue-thread-interactions"; const { markdownEditorFocusMock } = vi.hoisted(() => ({ markdownEditorFocusMock: vi.fn(), })); const { appendMock } = vi.hoisted(() => ({ appendMock: vi.fn(async () => undefined), })); const { captureComposerViewportSnapshotMock, restoreComposerViewportSnapshotMock, shouldPreserveComposerViewportMock, } = vi.hoisted(() => ({ captureComposerViewportSnapshotMock: vi.fn(), restoreComposerViewportSnapshotMock: vi.fn(), shouldPreserveComposerViewportMock: vi.fn(), })); vi.mock("@assistant-ui/react", () => ({ AssistantRuntimeProvider: ({ children }: { children: ReactNode }) =>
{children}
, useAui: () => ({ thread: () => ({ append: appendMock }) }), })); vi.mock("./transcript/useLiveRunTranscripts", () => ({ useLiveRunTranscripts: () => ({ transcriptByRun: new Map(), hasOutputForRun: () => false, }), })); vi.mock("../lib/issue-chat-scroll", async (importOriginal) => { const actual = await importOriginal(); return { ...actual, captureComposerViewportSnapshot: captureComposerViewportSnapshotMock.mockImplementation(actual.captureComposerViewportSnapshot), restoreComposerViewportSnapshot: restoreComposerViewportSnapshotMock.mockImplementation(actual.restoreComposerViewportSnapshot), shouldPreserveComposerViewport: shouldPreserveComposerViewportMock.mockImplementation(actual.shouldPreserveComposerViewport), }; }); vi.mock("./MarkdownBody", () => ({ MarkdownBody: ({ children }: { children: ReactNode }) =>
{children}
, })); vi.mock("./MarkdownEditor", () => ({ MarkdownEditor: forwardRef(({ value = "", onChange, placeholder, className, contentClassName, }: { value?: string; onChange?: (value: string) => void; placeholder?: string; className?: string; contentClassName?: string; }, ref) => { useImperativeHandle(ref, () => ({ focus: markdownEditorFocusMock, })); return (