import { fireEvent, render, screen, waitFor } from "@testing-library/react" import { beforeEach, describe, expect, it, vi } from "vitest" import { SpeedCurveEditor } from "../../../components/speed-ramping/speed-curve-editor" // Mock компонентов vi.mock("@/components/ui/button", () => ({ Button: ({ children, onClick, ...props }: any) => ( ), })) vi.mock("@/components/ui/dropdown-menu", () => ({ DropdownMenu: ({ children }: any) =>
{children}
, DropdownMenuContent: ({ children }: any) =>
{children}
, DropdownMenuItem: ({ children, onClick }: any) =>
{children}
, DropdownMenuSeparator: () =>
, DropdownMenuTrigger: ({ children }: any) =>
{children}
, })) vi.mock("@/components/ui/tooltip", () => ({ TooltipProvider: ({ children }: any) =>
{children}
, Tooltip: ({ children }: any) =>
{children}
, TooltipContent: ({ children }: any) =>
{children}
, TooltipTrigger: ({ children }: any) =>
{children}
, })) // Mock хука speed ramping const mockUseSpeedRamping = { getConfig: vi.fn(), addKeyframe: vi.fn(), updateKeyframe: vi.fn(), removeKeyframe: vi.fn(), applyPreset: vi.fn(), resetToConstantSpeed: vi.fn(), getSpeedCurveData: vi.fn(), } vi.mock("../../../hooks/use-speed-ramping", () => ({ useSpeedRamping: () => mockUseSpeedRamping, })) describe("SpeedCurveEditor", () => { const defaultProps = { clipId: "test-clip-1", clipDuration: 10, pixelsPerSecond: 100, height: 120, onClose: vi.fn(), } beforeEach(() => { vi.clearAllMocks() // Mock конфигурации по умолчанию mockUseSpeedRamping.getConfig.mockReturnValue({ enabled: true, keyframes: [ { id: "kf1", time: 2, value: 0.5, interpolation: "linear" }, { id: "kf2", time: 5, value: 2.0, interpolation: "ease" }, { id: "kf3", time: 8, value: 1.0, interpolation: "ease-out" }, ], maintainPitch: true, minSpeed: 0.1, maxSpeed: 4.0, showGraph: true, graphHeight: 120, graphOpacity: 0.8, }) mockUseSpeedRamping.getSpeedCurveData.mockReturnValue([ { time: 0, speed: 1.0 }, { time: 2, speed: 0.5 }, { time: 5, speed: 2.0 }, { time: 8, speed: 1.0 }, { time: 10, speed: 1.0 }, ]) }) it("рендерит компонент с базовыми элементами", () => { render() expect(screen.getByText("Speed Ramping")).toBeInTheDocument() expect(screen.getByText("Presets")).toBeInTheDocument() expect(screen.getByText("Reset to normal speed")).toBeInTheDocument() }) it("отображает canvas с правильными размерами", () => { render() const canvas = screen.getByTestId("speed-curve-canvas") expect(canvas).toHaveAttribute("width", "1000") // 10 сек * 100 пикс/сек expect(canvas).toHaveAttribute("height", "120") }) it("добавляет keyframe при клике на canvas", async () => { render() const canvas = screen.getByTestId("speed-curve-canvas") // Симулируем клик по canvas fireEvent.click(canvas, { clientX: 300, // 3 секунды при 100 пикс/сек clientY: 60, // Середина по высоте (speed = 2.0) }) await waitFor(() => { expect(mockUseSpeedRamping.addKeyframe).toHaveBeenCalledWith( "test-clip-1", expect.any(Number), // время expect.any(Number), // значение скорости "ease", ) }) }) it("применяет пресет при выборе из меню", async () => { render() // Находим кнопку пресетов и кликаем const presetsButton = screen.getByText("Presets") fireEvent.click(presetsButton) // Симулируем выбор пресета slow-motion const slowMotionPreset = screen.getByText("Slow Motion") fireEvent.click(slowMotionPreset) await waitFor(() => { expect(mockUseSpeedRamping.applyPreset).toHaveBeenCalledWith("test-clip-1", "slow-motion") }) }) it("сбрасывает скорость к нормальной при клике на reset", async () => { render() // Ищем кнопку с иконкой RotateCcw const resetButton = screen.getByTestId("rotateccw-icon").closest("button") expect(resetButton).toBeInTheDocument() fireEvent.click(resetButton!) await waitFor(() => { expect(mockUseSpeedRamping.resetToConstantSpeed).toHaveBeenCalledWith("test-clip-1", 1.0) }) }) it("вызывает onClose при клике на кнопку закрытия", () => { const onClose = vi.fn() render() const closeButton = screen.getByText("✕") fireEvent.click(closeButton) expect(onClose).toHaveBeenCalled() }) it("отображает подсказку при отсутствии keyframes", () => { mockUseSpeedRamping.getConfig.mockReturnValue({ enabled: true, keyframes: [], // Нет keyframes maintainPitch: true, minSpeed: 0.1, maxSpeed: 4.0, showGraph: true, graphHeight: 120, graphOpacity: 0.8, }) render() expect(screen.getByText("Click to add speed keyframes")).toBeInTheDocument() }) it("обрабатывает клики по canvas для взаимодействия с keyframes", async () => { render() // Симулируем клик по canvas const canvas = screen.getByTestId("speed-curve-canvas") fireEvent.click(canvas, { clientX: 200, // Позиция на canvas clientY: 90, }) // Проверяем что canvas корректно обрабатывает клики // В реальном использовании это может добавить keyframe или выбрать существующий expect(canvas).toBeInTheDocument() }) it("показывает Y-axis labels с правильными значениями скорости", () => { render() expect(screen.getByText("4x")).toBeInTheDocument() expect(screen.getByText("3x")).toBeInTheDocument() expect(screen.getByText("2x")).toBeInTheDocument() expect(screen.getByText("1x")).toBeInTheDocument() expect(screen.getByText("0x")).toBeInTheDocument() }) })