import { fireEvent, render, screen } from "@testing-library/react" import { beforeEach, describe, expect, it, vi } from "vitest" import { EXPORT_PRESETS, ExportPresets } from "../../components/export-presets" describe("ExportPresets", () => { const mockOnSelectPreset = vi.fn() beforeEach(() => { vi.clearAllMocks() }) describe("Basic rendering", () => { it("should render all export presets", () => { render() // Check that all presets are rendered expect(screen.getByText("Custom Export")).toBeInTheDocument() expect(screen.getByText("H.264 Master")).toBeInTheDocument() expect(screen.getByText("H.265 Master")).toBeInTheDocument() expect(screen.getByText("ProRes 422 HQ")).toBeInTheDocument() expect(screen.getByText("HyperDeck")).toBeInTheDocument() expect(screen.getByText("YouTube 1080p")).toBeInTheDocument() expect(screen.getByText("Vimeo 1080p")).toBeInTheDocument() expect(screen.getByText("TikTok 1080p")).toBeInTheDocument() }) it("should render correct number of preset buttons", () => { render() const buttons = screen.getAllByRole("button") expect(buttons).toHaveLength(EXPORT_PRESETS.length) }) it("should render without crashing", () => { expect(() => render(), ).not.toThrow() }) }) describe("Preset selection", () => { it("should highlight selected preset", () => { render() const h264Button = screen.getByText("H.264 Master").closest("button") const customButton = screen.getByText("Custom Export").closest("button") // Selected preset should have primary background expect(h264Button).toHaveClass("bg-primary") expect(customButton).not.toHaveClass("bg-primary") }) it("should call onSelectPreset when clicking a preset", () => { render() const h264Button = screen.getByText("H.264 Master") fireEvent.click(h264Button) expect(mockOnSelectPreset).toHaveBeenCalledTimes(1) const calledWith = mockOnSelectPreset.mock.calls[0][0] expect(calledWith.id).toBe("h264-master") expect(calledWith.name).toBe("H.264 Master") }) it("should handle multiple preset selections", () => { render() // Click multiple presets fireEvent.click(screen.getByText("YouTube 1080p")) fireEvent.click(screen.getByText("TikTok 1080p")) fireEvent.click(screen.getByText("ProRes 422 HQ")) expect(mockOnSelectPreset).toHaveBeenCalledTimes(3) expect(mockOnSelectPreset.mock.calls[0][0].id).toBe("youtube") expect(mockOnSelectPreset.mock.calls[1][0].id).toBe("tiktok") expect(mockOnSelectPreset.mock.calls[2][0].id).toBe("prores") }) }) describe("Preset configurations", () => { it("should have correct settings for Custom Export", () => { const customPreset = EXPORT_PRESETS.find((p) => p.id === "custom") expect(customPreset).toBeDefined() expect(customPreset?.settings.format).toBe("mp4") expect(customPreset?.settings.codec).toBe("h264") expect(customPreset?.settings.resolution).toBe("timeline") expect(customPreset?.settings.fps).toBe("timeline") }) it("should have correct settings for H.264 Master", () => { const h264Preset = EXPORT_PRESETS.find((p) => p.id === "h264-master") expect(h264Preset).toBeDefined() expect(h264Preset?.settings.format).toBe("mp4") expect(h264Preset?.settings.codec).toBe("h264") expect(h264Preset?.settings.codecProfile).toBe("high") expect(h264Preset?.settings.bitrate).toBe(80000) expect(h264Preset?.settings.bitrateMode).toBe("cbr") expect(h264Preset?.settings.useHardwareAcceleration).toBe(true) }) it("should have correct settings for H.265 Master", () => { const h265Preset = EXPORT_PRESETS.find((p) => p.id === "h265-master") expect(h265Preset).toBeDefined() expect(h265Preset?.settings.format).toBe("mp4") expect(h265Preset?.settings.codec).toBe("h265") expect(h265Preset?.settings.codecProfile).toBe("main10") expect(h265Preset?.settings.bitrate).toBe(60000) expect(h265Preset?.settings.bitrateMode).toBe("vbr") expect(h265Preset?.settings.optimizeForSpeed).toBe(true) }) it("should have correct settings for ProRes", () => { const proresPreset = EXPORT_PRESETS.find((p) => p.id === "prores") expect(proresPreset).toBeDefined() expect(proresPreset?.settings.format).toBe("quicktime") expect(proresPreset?.settings.codec).toBe("prores") expect(proresPreset?.settings.resolution).toBe("timeline") expect(proresPreset?.settings.fps).toBe("timeline") }) it("should have correct settings for YouTube preset", () => { const youtubePreset = EXPORT_PRESETS.find((p) => p.id === "youtube") expect(youtubePreset).toBeDefined() expect(youtubePreset?.settings.format).toBe("mp4") expect(youtubePreset?.settings.codec).toBe("h264") expect(youtubePreset?.settings.resolution).toBe("1080") expect(youtubePreset?.settings.bitrate).toBe(12000) expect(youtubePreset?.settings.normalizeAudio).toBe(true) expect(youtubePreset?.settings.audioTarget).toBe(-14) expect(youtubePreset?.settings.uploadDirectly).toBe(true) }) it("should have correct settings for TikTok preset", () => { const tiktokPreset = EXPORT_PRESETS.find((p) => p.id === "tiktok") expect(tiktokPreset).toBeDefined() expect(tiktokPreset?.settings.format).toBe("mp4") expect(tiktokPreset?.settings.codec).toBe("h264") expect(tiktokPreset?.settings.resolution).toBe("1080") expect(tiktokPreset?.settings.fps).toBe("30") expect(tiktokPreset?.settings.useVerticalResolution).toBe(true) expect(tiktokPreset?.settings.uploadDirectly).toBe(true) }) it("should have correct settings for HyperDeck preset", () => { const hyperdeckPreset = EXPORT_PRESETS.find((p) => p.id === "hyperdeck") expect(hyperdeckPreset).toBeDefined() expect(hyperdeckPreset?.settings.format).toBe("mov") expect(hyperdeckPreset?.settings.codec).toBe("h264") expect(hyperdeckPreset?.settings.codecProfile).toBe("main") expect(hyperdeckPreset?.settings.bitrate).toBe(50000) expect(hyperdeckPreset?.settings.bitrateMode).toBe("cbr") }) }) describe("Visual presentation", () => { it("should render preset icons", () => { render() // Check that buttons contain icon containers const buttons = screen.getAllByRole("button") buttons.forEach((button) => { const iconContainer = button.querySelector(".flex.items-center.justify-center") expect(iconContainer).toBeInTheDocument() }) }) it("should show hover styles on buttons", () => { render() const button = screen.getByText("H.264 Master").closest("button") expect(button).toHaveClass("hover:bg-accent") }) it("should have proper accessible focus styles", () => { render() const button = screen.getByText("Custom Export").closest("button") expect(button).toHaveClass("focus:outline-none") expect(button).toHaveClass("focus:ring-2") expect(button).toHaveClass("focus:ring-primary") }) it("should render with custom className", () => { const { container } = render( , ) const mainContainer = container.firstChild expect(mainContainer).toHaveClass("custom-class") }) }) describe("Accessibility", () => { it("should have proper button roles", () => { render() const buttons = screen.getAllByRole("button") expect(buttons).toHaveLength(EXPORT_PRESETS.length) }) it("should be keyboard navigable", () => { render() const firstButton = screen.getByText("Custom Export").closest("button") firstButton?.focus() expect(document.activeElement).toBe(firstButton) }) it("should have readable text content", () => { render() // All preset names should be visible EXPORT_PRESETS.forEach((preset) => { expect(screen.getByText(preset.name)).toBeInTheDocument() }) }) }) describe("Component structure", () => { it("should have scrollable container", () => { const { container } = render() const scrollContainer = container.querySelector(".overflow-x-auto") expect(scrollContainer).toBeInTheDocument() }) it("should have proper spacing and layout classes", () => { const { container } = render() const mainContainer = container.firstChild expect(mainContainer).toHaveClass("flex", "gap-2", "p-4", "border-b") }) it("should render buttons with minimum width", () => { render() const buttons = screen.getAllByRole("button") buttons.forEach((button) => { expect(button).toHaveClass("min-w-[100px]") }) }) }) describe("Edge cases", () => { it("should handle invalid selectedPresetId gracefully", () => { expect(() => render(), ).not.toThrow() }) it("should handle empty onSelectPreset function", () => { const emptyFunction = vi.fn() render() const button = screen.getByText("Custom Export") fireEvent.click(button) expect(emptyFunction).toHaveBeenCalled() }) it("should verify all presets have required properties", () => { EXPORT_PRESETS.forEach((preset) => { expect(preset).toHaveProperty("id") expect(preset).toHaveProperty("name") expect(preset).toHaveProperty("icon") expect(preset).toHaveProperty("description") expect(preset).toHaveProperty("settings") expect(preset.settings).toHaveProperty("format") expect(preset.settings).toHaveProperty("codec") expect(preset.settings).toHaveProperty("resolution") expect(preset.settings).toHaveProperty("fps") }) }) }) })