/**
* Тесты для Track компонента
*/
import { render, screen } from "@testing-library/react"
import { describe, expect, it, vi } from "vitest"
// Import mocks before components
import "@/test/mocks/dnd-kit"
import "../../__mocks__/hooks"
import { Track } from "../../components/track/track"
// Мокаем данные трека
const mockTrack = {
id: "track-1",
name: "Test Track",
type: "video" as const,
clips: [],
isLocked: false,
isMuted: false,
isHidden: false,
isSolo: false,
volume: 1,
pan: 0,
height: 120,
order: 0,
trackEffects: [],
trackFilters: [],
}
describe("Track Component", () => {
describe("Component Initialization", () => {
it("should be defined and exportable", () => {
expect(Track).toBeDefined()
expect(typeof Track).toBe("function")
})
it("should render without errors", () => {
expect(() => {
render()
}).not.toThrow()
})
it("should render with track test id", () => {
render()
const trackElement = screen.getByTestId("timeline-track")
expect(trackElement).toBeInTheDocument()
})
})
describe("Track Properties", () => {
it("should display track name", () => {
render()
expect(screen.getByText("Test Track")).toBeInTheDocument()
})
it("should handle different track types", () => {
const videoTrack = { ...mockTrack, type: "video" as const }
const audioTrack = { ...mockTrack, type: "audio" as const, name: "Audio Track" }
const { rerender } = render()
expect(screen.getByTestId("timeline-track")).toBeInTheDocument()
rerender()
expect(screen.getByText("Audio Track")).toBeInTheDocument()
})
it("should reflect track state in UI", () => {
const mutedTrack = { ...mockTrack, isMuted: true, name: "Muted Track" }
const lockedTrack = { ...mockTrack, isLocked: true, name: "Locked Track" }
const { rerender } = render()
expect(screen.getByText("Muted Track")).toBeInTheDocument()
rerender()
expect(screen.getByText("Locked Track")).toBeInTheDocument()
})
})
describe("Track Interactions", () => {
it("should handle track selection", () => {
const onSelect = vi.fn()
render()
const trackElement = screen.getByTestId("timeline-track")
expect(trackElement).toBeInTheDocument()
// Клик по треку должен вызвать onSelect
trackElement.click()
expect(onSelect).toHaveBeenCalledWith(mockTrack.id)
})
it("should handle track lock toggle", () => {
const onUpdate = vi.fn()
render()
// Ищем кнопку lock
const lockButton = screen.getByTestId("track-lock-button")
expect(lockButton).toBeInTheDocument()
lockButton.click()
expect(onUpdate).toHaveBeenCalledWith({ ...mockTrack, isLocked: !mockTrack.isLocked })
})
it("should handle track mute toggle for audio tracks", () => {
const audioTrack = { ...mockTrack, type: "audio" as const }
const onUpdate = vi.fn()
render()
// Ищем кнопку mute (только для аудио треков)
const muteButton = screen.getByTestId("track-mute-button")
expect(muteButton).toBeInTheDocument()
muteButton.click()
expect(onUpdate).toHaveBeenCalledWith({ ...audioTrack, isMuted: !audioTrack.isMuted })
})
it("should not show mute button for video tracks", () => {
render()
// Для видео треков кнопка mute не должна отображаться
const muteButton = screen.queryByTestId("track-mute-button")
expect(muteButton).not.toBeInTheDocument()
})
})
describe("Track Styling", () => {
it("should accept className and style props without errors", () => {
const customStyle = { backgroundColor: "blue", height: "150px" }
expect(() => {
render()
}).not.toThrow()
const trackElement = screen.getByTestId("timeline-track")
expect(trackElement).toBeInTheDocument()
})
})
describe("Track State Variations", () => {
it("should render hidden track", () => {
const hiddenTrack = { ...mockTrack, isHidden: true, name: "Hidden Track" }
expect(() => {
render()
}).not.toThrow()
})
it("should render solo track", () => {
const soloTrack = { ...mockTrack, isSolo: true, name: "Solo Track" }
render()
expect(screen.getByText("Solo Track")).toBeInTheDocument()
})
it("should handle track with clips", () => {
const trackWithClips = {
...mockTrack,
clips: [
{
id: "clip-1",
name: "Test Clip",
mediaId: "media-1",
trackId: "track-1",
startTime: 0,
duration: 10,
mediaStartTime: 0,
mediaEndTime: 10,
volume: 1,
speed: 1,
isReversed: false,
opacity: 1,
effects: [],
filters: [],
transitions: [],
isSelected: false,
isLocked: false,
createdAt: new Date(),
updatedAt: new Date(),
},
],
}
expect(() => {
render()
}).not.toThrow()
})
})
describe("Track Error Handling", () => {
it("should handle missing track prop gracefully", () => {
expect(() => {
render()
}).not.toThrow()
// Проверяем, что отображается fallback
expect(screen.getByText("Invalid track")).toBeInTheDocument()
})
it("should render track with null gracefully", () => {
render()
const trackElement = screen.getByTestId("timeline-track")
expect(trackElement).toBeInTheDocument()
expect(screen.getByText("Invalid track")).toBeInTheDocument()
})
})
describe("Track Accessibility", () => {
it("should have proper ARIA attributes", () => {
render()
const trackElement = screen.getByTestId("timeline-track")
expect(trackElement).toBeInTheDocument()
// Семантический button элемент имеет встроенную доступность
expect(trackElement.tagName).toBe("BUTTON")
})
it("should be keyboard accessible", () => {
render()
const trackElement = screen.getByTestId("timeline-track")
// Button элементы по умолчанию доступны с клавиатуры
expect(trackElement.tagName).toBe("BUTTON")
// Button элементы имеют tabIndex 0 по умолчанию
expect(trackElement).toBeInTheDocument()
})
})
})