135 lines
3.7 KiB
TypeScript
135 lines
3.7 KiB
TypeScript
import { act } from "react";
|
|
import { createRoot, type Root } from "react-dom/client";
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
import type { ReactNode } from "react";
|
|
import { MoveEmbedPickerDialog } from "./move-embed-picker-dialog";
|
|
|
|
(globalThis as typeof globalThis & { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
|
|
|
|
const sidebarData = {
|
|
activeWorkspaceId: "ws_test",
|
|
workspaces: [],
|
|
documents: [],
|
|
kernelSidebarProjection: {
|
|
projectionId: "kernel_projection:sidebar_tree:workspace_root",
|
|
projection: "sidebar_tree",
|
|
rootNodeId: null,
|
|
items: [],
|
|
edges: [],
|
|
},
|
|
kernelSidebarTree: [],
|
|
trashedDocuments: [],
|
|
};
|
|
|
|
vi.mock("@tanstack/react-query", () => ({
|
|
useQuery: ({ queryKey }: { queryKey: unknown[] }) => {
|
|
const key = Array.isArray(queryKey) ? queryKey[0] : queryKey;
|
|
if (key === "move-embed-picker-sidebar") {
|
|
return {
|
|
data: sidebarData,
|
|
isLoading: false,
|
|
error: null,
|
|
};
|
|
}
|
|
return {
|
|
data: null,
|
|
isLoading: false,
|
|
error: null,
|
|
};
|
|
},
|
|
}));
|
|
|
|
vi.mock("@/hooks/use-document-search", () => ({
|
|
useDocumentSearch: () => ({
|
|
data: null,
|
|
isLoading: false,
|
|
error: null,
|
|
}),
|
|
}));
|
|
|
|
vi.mock("@/components/ui/dialog", () => ({
|
|
Dialog: ({ open, children }: { open: boolean; children: ReactNode }) => (open ? <div>{children}</div> : null),
|
|
DialogContent: ({ children, className }: { children: ReactNode; className?: string }) => (
|
|
<div className={className}>{children}</div>
|
|
),
|
|
DialogTitle: ({ children, className }: { children: ReactNode; className?: string }) => (
|
|
<div className={className}>{children}</div>
|
|
),
|
|
}));
|
|
|
|
vi.mock("@/components/ui/input", () => ({
|
|
Input: (props: React.InputHTMLAttributes<HTMLInputElement>) => <input {...props} />,
|
|
}));
|
|
|
|
vi.mock("@/components/ui/tabs", () => ({
|
|
Tabs: ({ children }: { children: ReactNode }) => <div>{children}</div>,
|
|
TabsList: ({ children, className }: { children: ReactNode; className?: string }) => (
|
|
<div className={className}>{children}</div>
|
|
),
|
|
TabsTrigger: ({
|
|
children,
|
|
className,
|
|
value,
|
|
}: {
|
|
children: ReactNode;
|
|
className?: string;
|
|
value: string;
|
|
}) => (
|
|
<button type="button" className={className} data-value={value}>
|
|
{children}
|
|
</button>
|
|
),
|
|
TabsContent: ({ children, className }: { children: ReactNode; className?: string }) => (
|
|
<div className={className}>{children}</div>
|
|
),
|
|
}));
|
|
|
|
describe("MoveEmbedPickerDialog", () => {
|
|
let container: HTMLDivElement;
|
|
let root: Root;
|
|
|
|
beforeEach(() => {
|
|
container = document.createElement("div");
|
|
document.body.appendChild(container);
|
|
root = createRoot(container);
|
|
});
|
|
|
|
afterEach(() => {
|
|
act(() => {
|
|
root.unmount();
|
|
});
|
|
container.remove();
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it("空查询时会使用统一 picker surface 并透传根目录选择", async () => {
|
|
const onPick = vi.fn(async () => undefined);
|
|
const onOpenChange = vi.fn();
|
|
|
|
await act(async () => {
|
|
root.render(
|
|
<MoveEmbedPickerDialog
|
|
open
|
|
onOpenChange={onOpenChange}
|
|
workspaceId="ws_test"
|
|
defaultMode="move"
|
|
allowRoot
|
|
excludeIds={["doc_hidden"]}
|
|
onPick={onPick}
|
|
/>,
|
|
);
|
|
});
|
|
|
|
const shellPickButton = container.querySelector('[data-testid="tree-picker-root"]');
|
|
expect(shellPickButton).not.toBeNull();
|
|
|
|
await act(async () => {
|
|
shellPickButton?.dispatchEvent(new MouseEvent("click", { bubbles: true }));
|
|
});
|
|
|
|
expect(onPick).toHaveBeenCalledTimes(1);
|
|
expect(onPick).toHaveBeenCalledWith("move", null);
|
|
expect(onOpenChange).toHaveBeenCalledWith(false);
|
|
});
|
|
});
|