import { createRef, type ReactNode, useEffect, useImperativeHandle, useRef } from "react"; import { act, cleanup, fireEvent, render, screen, waitFor } from "@testing-library/react"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { TaskCreateDialog } from "./task-create-dialog"; import type { DialogFormState, TaskFormInputsHandle } from "./task-create-dialog-types"; const enhancePromptMock = vi.fn(); const toastMock = vi.fn(); const setHasDescriptionMock = vi.fn(); const ORIGINAL_PROMPT = "Original prompt"; const IMPROVED_PROMPT = "Improved prompt"; const USER_EDIT = "User edit"; const PROMPT_RESULT_RECOVERY_TEST_ID = "prompt-result-recovery"; const ENHANCE_PROMPT_BUTTON_TEST_ID = "enhance-prompt-button"; let allowProgrammaticSet = true; let mockFs: DialogFormState; vi.mock("@kandev/ui/dialog", () => ({ Dialog: ({ children }: { children: ReactNode }) =>
{children}
, DialogContent: ({ children }: { children: ReactNode }) =>
{children}
, DialogHeader: ({ children }: { children: ReactNode }) =>
{children}
, DialogFooter: ({ children }: { children: ReactNode }) =>
{children}
, })); vi.mock("@kandev/ui/button", () => ({ Button: ({ children, ...rest }: { children: ReactNode } & Record) => ( ), })); vi.mock("@/components/routing/app-link", () => ({ default: ({ children, href }: { children: ReactNode; href: string }) => ( {children} ), })); vi.mock("@/components/workflow-selector-row", () => ({ WorkflowSelectorRow: () => null, })); vi.mock("@/components/agent-logo", () => ({ AgentLogo: () => null, })); vi.mock("@/hooks/use-is-utility-configured", () => ({ useIsUtilityConfigured: () => true, })); vi.mock("@/hooks/use-utility-agent-generator", () => ({ useUtilityAgentGenerator: () => ({ enhancePrompt: enhancePromptMock, isEnhancingPrompt: false, }), })); vi.mock("@/components/toast-provider", () => ({ useToast: () => ({ toast: toastMock }), })); vi.mock("@/hooks/use-keyboard-shortcut", () => ({ useKeyboardShortcutHandler: () => () => undefined, })); vi.mock("@/components/task-create-dialog-footer", () => ({ TaskCreateDialogFooter: () => null, })); vi.mock("@/components/discard-local-changes-dialog", () => ({ DiscardLocalChangesDialog: () => null, })); vi.mock("@/components/task-create-dialog-header", () => ({ DialogHeaderContent: () => null, })); vi.mock("@/components/task-create-dialog-create-mode-selectors", () => ({ CreateModeSelectors: () => null, })); vi.mock("@/components/task-create-dialog-repo-chips", () => ({ RepoChipsRow: () => null, })); vi.mock("@/hooks/use-task-create-dialog-popover-container", () => ({ TaskCreateDialogPopoverContainerProvider: ({ children }: { children: ReactNode }) => ( <>{children} ), })); vi.mock("@/components/task-create-dialog-handlers", () => ({ resetTaskCreateLastUsedSync: () => undefined, })); vi.mock("@/components/state-provider", () => ({ useAppStore: (selector: (state: { userSettings: { taskCreateLastUsed: null } }) => unknown) => selector({ userSettings: { taskCreateLastUsed: null } }), })); vi.mock("@/components/task-create-dialog-submit", () => ({ useTaskSubmitHandlers: () => ({ handleSubmit: () => undefined, handleCancel: () => undefined, handleUpdateWithoutAgent: () => undefined, handleCreateWithoutAgent: () => undefined, handleCreateWithPlanMode: () => undefined, pendingDiscard: null, }), })); vi.mock("@/components/task-create-dialog-selectors", () => ({ InlineTaskName: () => null, AgentSelector: () => null, ExecutorProfileSelector: () => null, TaskFormInputs: ({ initialDescription, descriptionValueRef, onDescriptionChange, onEnhancePrompt, }: { initialDescription: string; descriptionValueRef: React.RefObject; onDescriptionChange: (hasDescription: boolean) => void; onEnhancePrompt?: () => void; }) => { const textareaRef = useRef(null); const latestValueRef = useRef(initialDescription); useEffect(() => { latestValueRef.current = initialDescription; if (textareaRef.current) { textareaRef.current.value = initialDescription; } }, [initialDescription]); useImperativeHandle( descriptionValueRef, () => ({ getValue: () => latestValueRef.current, setValue: (next: string) => { if (allowProgrammaticSet) { latestValueRef.current = next; if (textareaRef.current) { textareaRef.current.value = next; } } }, getAttachments: () => [], }), [], ); return (