import { act, render, renderHook, screen } from "@testing-library/react" import { beforeEach, describe, expect, it, vi } from "vitest" import { VideoEffect } from "@/features/effects/types" import { VideoFilter } from "@/features/filters/types/filters" import { MediaFile } from "@/features/media/types/media" import { MediaTemplate } from "@/features/templates/lib/templates" import { Transition } from "@/features/transitions/types/transitions" import { ResourcesProvider, useResources } from "../../services/resources-provider" // Мокаем backend-sync const mockSendCommand = vi.fn() const mockExecuteCommand = vi.fn().mockResolvedValue({ success: true }) vi.mock("@/features/app-state/services/backend-sync", () => ({ getBackendSync: () => ({ onStateChange: vi.fn(() => () => {}), sendCommand: mockSendCommand, executeCommand: mockExecuteCommand, }), })) // Мокаем console.log, console.error и console.warn const logSpy = vi.spyOn(console, "log").mockImplementation(() => {}) const errorSpy = vi.spyOn(console, "error").mockImplementation(() => {}) const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}) beforeEach(() => { vi.clearAllMocks() mockExecuteCommand.mockClear() }) // Компонент-обертка для тестирования хука useResources function ResourcesWrapper({ children }: { children: React.ReactNode }) { return {children} } // Тестовый компонент, который использует хук useResources function TestComponent() { const { resources, effectResources, filterResources, transitionResources, templateResources, musicResources, mediaResources, } = useResources() return (
{resources.length}
{mediaResources.length}
{effectResources.length}
{filterResources.length}
{transitionResources.length}
{templateResources.length}
{musicResources.length}
) } describe("ResourcesProvider", () => { beforeEach(() => { vi.clearAllMocks() mockExecuteCommand.mockClear() }) it("should provide initial context values", () => { render( , ) expect(screen.getByTestId("resources-count")).toHaveTextContent("0") expect(screen.getByTestId("media-resources-count")).toHaveTextContent("0") expect(screen.getByTestId("effect-resources-count")).toHaveTextContent("0") expect(screen.getByTestId("filter-resources-count")).toHaveTextContent("0") expect(screen.getByTestId("transition-resources-count")).toHaveTextContent("0") expect(screen.getByTestId("template-resources-count")).toHaveTextContent("0") expect(screen.getByTestId("music-resources-count")).toHaveTextContent("0") }) it("should have useResources hook", () => { const { result } = renderHook(() => useResources(), { wrapper: ResourcesWrapper, }) expect(result.current).toBeDefined() expect(result.current.resources).toBeDefined() expect(result.current.mediaResources).toBeDefined() expect(result.current.effectResources).toBeDefined() expect(result.current.filterResources).toBeDefined() expect(result.current.transitionResources).toBeDefined() expect(result.current.templateResources).toBeDefined() expect(result.current.musicResources).toBeDefined() }) it("should provide correct methods for adding resources", () => { const { result } = renderHook(() => useResources(), { wrapper: ResourcesWrapper, }) expect(typeof result.current.addMedia).toBe("function") expect(typeof result.current.addEffect).toBe("function") expect(typeof result.current.addFilter).toBe("function") expect(typeof result.current.addTransition).toBe("function") expect(typeof result.current.addTemplate).toBe("function") expect(typeof result.current.addMusic).toBe("function") }) it("should provide correct utility methods", () => { const { result } = renderHook(() => useResources(), { wrapper: ResourcesWrapper, }) expect(typeof result.current.getResourceById).toBe("function") expect(typeof result.current.getResourcesByType).toBe("function") }) it("should have addEffect method", () => { const { result } = renderHook(() => useResources(), { wrapper: ResourcesWrapper, }) expect(result.current.addEffect).toBeDefined() expect(typeof result.current.addEffect).toBe("function") }) it("should have addMusic method", () => { const { result } = renderHook(() => useResources(), { wrapper: ResourcesWrapper, }) expect(result.current.addMusic).toBeDefined() expect(typeof result.current.addMusic).toBe("function") }) it("should call send with correct parameters when adding an effect", async () => { const { result } = renderHook(() => useResources(), { wrapper: ResourcesWrapper, }) const mockEffect: VideoEffect = { id: "effect-1", name: "Test Effect", category: "color", description: "Test effect description", parameters: {}, defaultIntensity: 1, preview: "test-preview.jpg", isPremium: false, } await act(async () => { await result.current.addEffect(mockEffect) }) expect(console.warn).toHaveBeenCalledWith("Effect resources not yet integrated with backend") }) it("should call send with correct parameters when adding a filter", async () => { const { result } = renderHook(() => useResources(), { wrapper: ResourcesWrapper, }) const mockFilter: VideoFilter = { id: "filter-1", name: "Test Filter", category: "color", description: "Test filter description", value: "grayscale(100%)", preview: "test-preview.jpg", } await act(async () => { await result.current.addFilter(mockFilter) }) expect(console.warn).toHaveBeenCalledWith("Filter resources not yet integrated with backend") }) it("should call send with correct parameters when adding a transition", async () => { const { result } = renderHook(() => useResources(), { wrapper: ResourcesWrapper, }) const mockTransition: Transition = { id: "transition-1", name: "Test Transition", type: "fade", durationMin: 500, durationMax: 2000, defaultDuration: 1000, easing: "linear", category: "basic", isPremium: false, } await act(async () => { await result.current.addTransition(mockTransition) }) expect(console.warn).toHaveBeenCalledWith("Transition resources not yet integrated with backend") }) it("should call send with correct parameters when adding a template", async () => { const { result } = renderHook(() => useResources(), { wrapper: ResourcesWrapper, }) const mockTemplate: MediaTemplate = { id: "template-1", name: "Test Template", category: "basic", thumbnail: "test-thumbnail.jpg", minVideos: 2, maxVideos: 4, layout: { id: "layout-1", name: "Test Layout", type: "grid", positions: [], }, preview: "test-preview.jpg", } await act(async () => { await result.current.addTemplate(mockTemplate) }) expect(console.warn).toHaveBeenCalledWith("Template resources not yet integrated with backend") }) it("should call send with correct parameters when adding a music file", async () => { const { result } = renderHook(() => useResources(), { wrapper: ResourcesWrapper, }) const mockMusicFile: MediaFile = { id: "music-1", name: "Test Music.mp3", path: "/path/to/music.mp3", size: 1024, duration: 180, isVideo: false, } await act(async () => { await result.current.addMusic(mockMusicFile) }) expect(mockExecuteCommand).toHaveBeenCalledWith({ type: "AddMedia", params: { path: mockMusicFile.path, media_type: "Audio" }, }) }) it("should provide resource arrays", () => { const { result } = renderHook(() => useResources(), { wrapper: ResourcesWrapper, }) // Проверяем, что массивы ресурсов существуют expect(Array.isArray(result.current.effectResources)).toBe(true) expect(Array.isArray(result.current.filterResources)).toBe(true) expect(Array.isArray(result.current.transitionResources)).toBe(true) expect(Array.isArray(result.current.templateResources)).toBe(true) expect(Array.isArray(result.current.musicResources)).toBe(true) }) })