4 changed files with 315 additions and 2 deletions
@ -0,0 +1,147 @@ |
|||
import { describe, it, expect, vi, beforeEach } from "vitest"; |
|||
import { fireEvent, render, screen } from "@testing-library/react"; |
|||
import { ReactFlowProvider } from "@xyflow/react"; |
|||
import { VideoInputNode } from "@/components/nodes/VideoInputNode"; |
|||
|
|||
const TRY_LABEL = "\u5c1d\u8bd5:"; |
|||
const KEYFRAMES_LABEL = "\u9996\u5c3e\u5e27\u751f\u6210\u89c6\u9891"; |
|||
const FIRST_FRAME_LABEL = "\u9996\u5e27\u751f\u6210\u89c6\u9891"; |
|||
const FIRST_FRAME_NODE_LABEL = "\u9996\u5e27"; |
|||
const LAST_FRAME_NODE_LABEL = "\u5c3e\u5e27"; |
|||
|
|||
const mockUpdateNodeData = vi.fn(); |
|||
let addNodeSequence = 0; |
|||
const mockAddNode = vi.fn((type: string) => `${type}-${++addNodeSequence}`); |
|||
const mockOnConnect = vi.fn(); |
|||
|
|||
vi.mock("@/store/workflowStore", () => ({ |
|||
useWorkflowStore: vi.fn((selector) => selector({ |
|||
updateNodeData: mockUpdateNodeData, |
|||
addNode: mockAddNode, |
|||
onConnect: mockOnConnect, |
|||
currentNodeIds: [], |
|||
groups: {}, |
|||
nodes: [ |
|||
{ |
|||
id: "video-1", |
|||
type: "videoInput", |
|||
position: { x: 120, y: 160 }, |
|||
measured: { width: 300, height: 280 }, |
|||
style: { width: 300, height: 280 }, |
|||
data: {}, |
|||
}, |
|||
], |
|||
getNodesWithComments: vi.fn(() => []), |
|||
markCommentViewed: vi.fn(), |
|||
setNavigationTarget: vi.fn(), |
|||
})), |
|||
})); |
|||
|
|||
vi.mock("@/utils/videoFile", () => ({ |
|||
readVideoFile: vi.fn((file: File) => Promise.resolve({ |
|||
video: `data:video/mp4;base64,${file.name}`, |
|||
filename: file.name, |
|||
format: file.type, |
|||
duration: 3, |
|||
dimensions: { width: 1280, height: 720 }, |
|||
})), |
|||
})); |
|||
|
|||
function TestWrapper({ children }: { children: React.ReactNode }) { |
|||
return <ReactFlowProvider>{children}</ReactFlowProvider>; |
|||
} |
|||
|
|||
describe("VideoInputNode", () => { |
|||
const defaultProps = { |
|||
id: "video-1", |
|||
type: "videoInput" as const, |
|||
data: { |
|||
video: null, |
|||
videoRef: undefined, |
|||
filename: null, |
|||
duration: null, |
|||
dimensions: null, |
|||
format: null, |
|||
}, |
|||
selected: false, |
|||
isConnectable: true, |
|||
positionAbsoluteX: 0, |
|||
positionAbsoluteY: 0, |
|||
zIndex: 0, |
|||
dragging: false, |
|||
deletable: true, |
|||
selectable: true, |
|||
parentId: undefined, |
|||
dragHandle: undefined, |
|||
}; |
|||
|
|||
beforeEach(() => { |
|||
addNodeSequence = 0; |
|||
vi.clearAllMocks(); |
|||
}); |
|||
|
|||
it("renders video generation shortcuts when empty", () => { |
|||
render( |
|||
<TestWrapper> |
|||
<VideoInputNode {...defaultProps} /> |
|||
</TestWrapper> |
|||
); |
|||
|
|||
expect(screen.getByText(TRY_LABEL)).toBeInTheDocument(); |
|||
expect(screen.getByRole("button", { name: KEYFRAMES_LABEL })).toBeInTheDocument(); |
|||
expect(screen.getByRole("button", { name: FIRST_FRAME_LABEL })).toBeInTheDocument(); |
|||
}); |
|||
|
|||
it("labels the current node as first frame and links it to a generate video node", () => { |
|||
render( |
|||
<TestWrapper> |
|||
<VideoInputNode {...defaultProps} /> |
|||
</TestWrapper> |
|||
); |
|||
|
|||
fireEvent.click(screen.getByRole("button", { name: FIRST_FRAME_LABEL })); |
|||
|
|||
expect(mockUpdateNodeData).toHaveBeenCalledWith("video-1", { |
|||
label: FIRST_FRAME_NODE_LABEL, |
|||
}); |
|||
expect(mockAddNode).toHaveBeenCalledWith("generateVideo", { x: 600, y: 160 }); |
|||
expect(mockOnConnect).toHaveBeenCalledWith({ |
|||
source: "video-1", |
|||
sourceHandle: "video", |
|||
target: "generateVideo-1", |
|||
targetHandle: "video", |
|||
}); |
|||
}); |
|||
|
|||
it("creates an empty last-frame video node and links both videos to a generate video node", () => { |
|||
render( |
|||
<TestWrapper> |
|||
<VideoInputNode {...defaultProps} /> |
|||
</TestWrapper> |
|||
); |
|||
|
|||
fireEvent.click(screen.getByRole("button", { name: KEYFRAMES_LABEL })); |
|||
|
|||
expect(mockUpdateNodeData).toHaveBeenCalledWith("video-1", { |
|||
label: FIRST_FRAME_NODE_LABEL, |
|||
}); |
|||
expect(mockAddNode).toHaveBeenCalledWith( |
|||
"videoInput", |
|||
{ x: 120, y: 492 }, |
|||
{ label: LAST_FRAME_NODE_LABEL } |
|||
); |
|||
expect(mockAddNode).toHaveBeenCalledWith("generateVideo", { x: 600, y: 316 }); |
|||
expect(mockOnConnect).toHaveBeenCalledWith({ |
|||
source: "video-1", |
|||
sourceHandle: "video", |
|||
target: "generateVideo-2", |
|||
targetHandle: "video", |
|||
}); |
|||
expect(mockOnConnect).toHaveBeenCalledWith({ |
|||
source: "videoInput-1", |
|||
sourceHandle: "video", |
|||
target: "generateVideo-2", |
|||
targetHandle: "video", |
|||
}); |
|||
}); |
|||
}); |
|||
Loading…
Reference in new issue