import { describe, expect, it, vi } from "vitest" import { fireEvent, renderWithMedia as render, screen } from "@/test/test-utils" import { SubtitlePreview } from "../../components/subtitle-preview" import { SubtitleStyleTemplate } from "../../types/subtitles" // Мокаем дополнительные зависимости vi.mock("@/features/browser", () => ({ ApplyButton: () => , })) vi.mock("@/features/browser/components/layout/apply-button", () => ({ ApplyButton: () => , })) vi.mock("@/features/browser/components/layout/add-media-button", () => ({ AddMediaButton: () => , })) vi.mock("@/features/browser/components/layout/favorite-button", () => ({ FavoriteButton: () => , })) vi.mock("@/features/resources", () => ({ useResources: () => ({ addSubtitle: vi.fn(), isSubtitleAdded: vi.fn(() => false), removeResource: vi.fn(), subtitleResources: [], }), ResourcesProvider: ({ children }: { children: React.ReactNode }) => children, })) const mockSubtitle: SubtitleStyleTemplate = { id: "basic-white", name: "Basic White", category: "basic", complexity: "basic", tags: ["simple", "clean"], description: { en: "Simple white subtitles", ru: "Простые белые субтитры", }, labels: { en: "Basic White", ru: "Базовый белый", }, style: { color: "#FFFFFF", fontSize: 24, fontFamily: "Arial", fontWeight: "normal", textAlign: "center", backgroundColor: "rgba(0, 0, 0, 0.8)", padding: "10px", }, } describe("SubtitlePreview", () => { const defaultProps = { style: mockSubtitle, onClick: vi.fn(), size: 100, previewWidth: 150, previewHeight: 80, } it("должен рендериться без ошибок", () => { render() expect(screen.getByText("Базовый белый")).toBeInTheDocument() }) it("должен отображать превью текста со стилями", () => { render() // Ищем элемент с примером текста const preview = screen.getByText("Timeline Studio") expect(preview).toBeInTheDocument() // Проверяем что стили применены const styles = getComputedStyle(preview) expect(styles.color).toBe("rgb(255, 255, 255)") expect(styles.fontFamily).toContain("Arial") }) it("должен отображать название субтитра", () => { render() expect(screen.getByText("Базовый белый")).toBeInTheDocument() }) it("должен отображать индикатор категории", () => { render() expect(screen.getByText("BAS")).toBeInTheDocument() }) it("должен отображать индикатор анимации", () => { const animatedSubtitle: SubtitleStyleTemplate = { ...mockSubtitle, style: { ...mockSubtitle.style, animation: "fadeIn 1s ease-in-out", }, } render() expect(screen.getByText("ANI")).toBeInTheDocument() }) it("должен вызывать onClick при клике", () => { const onClick = vi.fn() render() // Кликаем на контейнер превью const previewElement = screen.getByText("Timeline Studio").closest(".cursor-pointer") if (previewElement) { fireEvent.click(previewElement) expect(onClick).toHaveBeenCalled() } }) it("должен применять градиент для текста если указан", () => { const gradientSubtitle: SubtitleStyleTemplate = { ...mockSubtitle, style: { ...mockSubtitle.style, background: "linear-gradient(45deg, #FF0000, #00FF00)", WebkitBackgroundClip: "text", WebkitTextFillColor: "transparent", }, } render() const preview = screen.getByText("Timeline Studio") const styles = getComputedStyle(preview) expect(styles.backgroundImage || styles.background).toContain("linear-gradient") }) it("должен применять тень текста если указана", () => { const shadowSubtitle: SubtitleStyleTemplate = { ...mockSubtitle, style: { ...mockSubtitle.style, textShadow: "2px 2px 4px rgba(0,0,0,0.8)", }, } render() const preview = screen.getByText("Timeline Studio") const styles = getComputedStyle(preview) expect(styles.textShadow).toBe("2px 2px 4px rgba(0,0,0,0.8)") }) it("должен применять анимацию если указана", () => { const animatedSubtitle: SubtitleStyleTemplate = { ...mockSubtitle, style: { ...mockSubtitle.style, animation: "fadeIn 1s ease-in-out", }, } render() const preview = screen.getByText("Timeline Studio") const styles = getComputedStyle(preview) expect(styles.animation || styles.animationName).toContain("fadeIn") }) it("должен корректно отображать размеры превью", () => { render() const container = screen.getByText("Timeline Studio").closest(".cursor-pointer") expect(container).toHaveStyle({ width: "180px", height: "100px" }) }) it("должен отображать кнопку добавления", () => { render() expect(screen.getByText(/добавить/i)).toBeInTheDocument() }) it("должен отображать кнопку избранного", () => { render() expect(screen.getByText(/избранное/i)).toBeInTheDocument() }) })