import { fireEvent, render, screen } from "@testing-library/react" import { beforeEach, describe, expect, it, vi } from "vitest" import { TimelineMarker } from "../../../components/markers/timeline-marker" import { ExtendedTimelineMarker } from "../../../types/markers" // Mock компонентов vi.mock("@/components/ui/tooltip", () => ({ TooltipProvider: ({ children }: any) =>
{children}
, Tooltip: ({ children }: any) =>
{children}
, TooltipContent: ({ children }: any) =>
{children}
, TooltipTrigger: ({ children }: any) =>
{children}
, })) vi.mock("@/components/ui/context-menu", () => ({ ContextMenu: ({ children }: any) =>
{children}
, ContextMenuContent: ({ children }: any) =>
{children}
, ContextMenuItem: ({ children, onClick }: any) =>
{children}
, ContextMenuTrigger: ({ children }: any) =>
{children}
, })) describe("TimelineMarker", () => { const mockMarker: ExtendedTimelineMarker = { id: "marker-1", time: 5.5, name: "Test Chapter", description: "A test chapter marker", color: "#3b82f6", type: "chapter", isLocked: false, duration: 2.0, } const defaultProps = { marker: mockMarker, timeScale: 100, isSelected: false, onDrag: vi.fn(), onClick: vi.fn(), onDelete: vi.fn(), } beforeEach(() => { vi.clearAllMocks() }) it("рендерит маркер с правильной позицией", () => { render() const markerElement = screen.getByTestId ? screen.getByTestId("timeline-marker") : screen.getByRole("generic", { hidden: true }) expect(markerElement).toHaveStyle({ left: "550px", // 5.5 секунд * 100 пикселей/сек }) }) it("показывает правильные данные в tooltip", () => { render() expect(screen.getByText("Test Chapter")).toBeInTheDocument() expect(screen.getByText("00:05.15")).toBeInTheDocument() // 5.5 сек = 5 сек + 15 кадров при 30fps expect(screen.getByText("A test chapter marker")).toBeInTheDocument() }) it("вызывает onClick при клике на маркер", () => { const onClick = vi.fn() render() const markerElement = screen.getByTestId("timeline-marker") fireEvent.click(markerElement) expect(onClick).toHaveBeenCalledWith("marker-1") }) it("начинает перетаскивание при mouseDown", () => { const onDrag = vi.fn() render() const markerElement = screen.getByTestId("timeline-marker") fireEvent.mouseDown(markerElement, { clientX: 550 }) // Симулируем движение мыши fireEvent.mouseMove(document, { clientX: 650 }) expect(onDrag).toHaveBeenCalledWith("marker-1", expect.any(Number)) }) it("не позволяет перетаскивать заблокированный маркер", () => { const lockedMarker = { ...mockMarker, isLocked: true } const onDrag = vi.fn() render() const markerElement = screen.getByTestId("timeline-marker") fireEvent.mouseDown(markerElement, { clientX: 550 }) fireEvent.mouseMove(document, { clientX: 650 }) expect(onDrag).not.toHaveBeenCalled() }) it("показывает визуальную индикацию для выбранного маркера", () => { render() const markerElement = screen.getByTestId("timeline-marker") expect(markerElement).toHaveClass("ring-2") expect(markerElement).toHaveClass("ring-primary") }) it("показывает флаг длительности для маркеров с duration", () => { render() // Проверяем, что есть дополнительный элемент для duration const markerElement = screen.getByTestId("timeline-marker") const durationFlag = markerElement.querySelector('[style*="width: 200px"]') // 2.0 * 100 expect(durationFlag).toBeInTheDocument() }) it("не показывает флаг длительности для маркеров без duration", () => { const markerWithoutDuration = { ...mockMarker, duration: undefined } render() const markerElement = screen.getByTestId("timeline-marker") const durationFlag = markerElement.querySelector('[style*="width:"]') expect(durationFlag).not.toBeInTheDocument() }) it("отображает правильную иконку для типа маркера", () => { // Проверяем иконку chapter (bookmark) const { rerender } = render() expect(screen.getByTestId("timeline-marker")).toBeInTheDocument() // Тест для другого типа маркера const noteMarker = { ...mockMarker, type: "note" as const } rerender() expect(screen.getByTestId("timeline-marker")).toBeInTheDocument() }) it("вызывает onDelete из контекстного меню", () => { const onDelete = vi.fn() render() const deleteMenuItem = screen.getByText("Delete Marker") fireEvent.click(deleteMenuItem) expect(onDelete).toHaveBeenCalledWith("marker-1") }) it('вызывает onClick из контекстного меню "Go to Marker"', () => { const onClick = vi.fn() render() const goToMenuItem = screen.getByText("Go to Marker") fireEvent.click(goToMenuItem) expect(onClick).toHaveBeenCalledWith("marker-1") }) it("форматирует время правильно", () => { // Тест различных значений времени const testCases = [ { time: 0, expected: "00:00.00" }, { time: 65.5, expected: "01:05.15" }, // 1 минута 5.5 секунд { time: 125.25, expected: "02:05.07" }, // 2 минуты 5.25 секунд ] testCases.forEach(({ time, expected }) => { const markerWithTime = { ...mockMarker, time } const { rerender } = render() expect(screen.getByText(expected)).toBeInTheDocument() rerender(
) // Очистка для следующего теста }) }) })