import { fireEvent, render, screen, waitFor } from "@testing-library/react" import { beforeEach, describe, expect, it, vi } from "vitest" import { ModalProvider } from "@/features/modals" import { CameraCaptureModal } from "../../components/camera-capture-modal" // Мокируем useToast vi.mock("@/hooks/use-toast", () => ({ useToast: () => ({ toast: vi.fn(), }), })) // Мокируем useMediaImport vi.mock("@/features/media/hooks/use-media-import", () => ({ useMediaImport: () => ({ importFile: vi.fn(), importFolder: vi.fn(), isImporting: false, progress: 0, }), })) // Mock navigator.mediaDevices beforeEach(() => { Object.defineProperty(navigator, "mediaDevices", { value: { getUserMedia: vi.fn(), enumerateDevices: vi.fn(), getDisplayMedia: vi.fn(), }, writable: true, }) }) // Мокаем хуки vi.mock("../../hooks", () => ({ useCameraPermissions: vi.fn(() => ({ permissionStatus: "granted", errorMessage: null, requestPermissions: vi.fn(), })), useCameraStream: vi.fn(() => ({ isDeviceReady: true, setIsDeviceReady: vi.fn(), initCamera: vi.fn(), streamRef: { current: null }, })), useDeviceCapabilities: vi.fn(() => ({ availableResolutions: ["1920x1080", "1280x720"], supportedResolutions: ["1920x1080", "1280x720"], supportedFrameRates: [30, 60], isLoadingCapabilities: false, getDeviceCapabilities: vi.fn(), })), useDevices: vi.fn(() => ({ devices: [{ deviceId: "camera1", label: "Camera 1" }], audioDevices: [{ deviceId: "mic1", label: "Mic 1" }], selectedDevice: "camera1", selectedAudioDevice: "mic1", setSelectedDevice: vi.fn(), setSelectedAudioDevice: vi.fn(), getDevices: vi.fn(), })), useRecording: vi.fn(() => ({ isRecording: false, recordingTime: 0, showCountdown: false, countdown: 3, setCountdown: vi.fn(), startCountdown: vi.fn(), stopRecording: vi.fn(), formatRecordingTime: vi.fn((time: number) => `00:${time.toString().padStart(2, "0")}`), })), useScreenCapture: vi.fn(() => ({ screenStream: null, isScreenSharing: false, error: null, startScreenCapture: vi.fn(), stopScreenCapture: vi.fn(), getSourceInfo: vi.fn(() => null), })), })) vi.mock("@/features/modals", () => ({ useModal: vi.fn(() => ({ isOpen: true, closeModal: vi.fn(), })), ModalProvider: ({ children }: { children: React.ReactNode }) =>
{children}
, })) vi.mock("react-i18next", () => ({ useTranslation: () => ({ t: (key: string, options?: any) => { if (typeof options === "string") { return options // default value } const translations: Record = { "cameraCapture.cameraMode": "Camera", "cameraCapture.screenMode": "Screen", "cameraCapture.screenSettings": "Screen Recording Settings", "cameraCapture.screenInfo": "Select a window, tab, or entire screen to record", "cameraCapture.microphone": "Microphone", "cameraCapture.noAudio": "No Audio", "cameraCapture.countdown": "Countdown", "cameraCapture.noCountdown": "No countdown", "cameraCapture.seconds": "seconds", "dialogs.cameraCapture.device": "Camera", "dialogs.cameraCapture.quality": "Quality", "dialogs.cameraCapture.supportedResolutions": "{{count}} supported resolutions", "common.ok": "OK", } let result = translations[key] || key // Handle interpolation if (options && typeof options === "object") { Object.entries(options).forEach(([k, v]) => { result = result.replace(`{{${k}}}`, String(v)) }) } return result }, }), })) describe("CameraCaptureModal - Screen Recording", () => { beforeEach(() => { vi.clearAllMocks() }) it("should render mode switch buttons", () => { render( , ) expect(screen.getByText("Camera")).toBeInTheDocument() expect(screen.getByText("Screen")).toBeInTheDocument() }) it("should switch to screen mode when Screen button is clicked", async () => { const mockStartScreenCapture = vi.fn() const mockStopScreenCapture = vi.fn() const { useScreenCapture } = await import("../../hooks") vi.mocked(useScreenCapture).mockReturnValue({ screenStream: null, isScreenSharing: false, error: null, startScreenCapture: mockStartScreenCapture, stopScreenCapture: mockStopScreenCapture, getSourceInfo: vi.fn(() => null), }) render( , ) const screenButton = screen.getByText("Screen") fireEvent.click(screenButton) await waitFor(() => { expect(mockStartScreenCapture).toHaveBeenCalledWith({ video: true, audio: true, }) }) }) it("should show screen settings when in screen mode", async () => { render( , ) const screenButton = screen.getByText("Screen") fireEvent.click(screenButton) await waitFor(() => { expect(screen.getByText("Screen Recording Settings")).toBeInTheDocument() expect(screen.getByText("Select a window, tab, or entire screen to record")).toBeInTheDocument() }) }) it("should hide camera settings when in screen mode", async () => { render( , ) // Сначала проверяем что настройки камеры видны (ищем элемент по роли) expect(screen.getAllByRole("combobox").length).toBeGreaterThan(2) // Камера, микрофон, разрешение и т.д. const screenButton = screen.getByText("Screen") fireEvent.click(screenButton) await waitFor(() => { // В режиме экрана должно быть меньше combobox элементов (только микрофон и обратный отсчет) expect(screen.getAllByRole("combobox").length).toBeLessThan(3) }) }) it("should stop screen capture when switching back to camera", async () => { const mockStopScreenCapture = vi.fn() const { useScreenCapture } = await import("../../hooks") vi.mocked(useScreenCapture).mockReturnValue({ screenStream: new MediaStream(), isScreenSharing: true, error: null, startScreenCapture: vi.fn(), stopScreenCapture: mockStopScreenCapture, getSourceInfo: vi.fn(() => ({ width: 1920, height: 1080, frameRate: 30, displaySurface: "monitor", cursor: "always", })), }) render( , ) // Переключаемся на экран const screenButton = screen.getByText("Screen") fireEvent.click(screenButton) // Переключаемся обратно на камеру const cameraButton = screen.getByText("Camera") fireEvent.click(cameraButton) await waitFor(() => { expect(mockStopScreenCapture).toHaveBeenCalled() }) }) it("should show error message if screen capture fails", async () => { const { useScreenCapture } = await import("../../hooks") vi.mocked(useScreenCapture).mockReturnValue({ screenStream: null, isScreenSharing: false, error: "Permission denied", startScreenCapture: vi.fn().mockRejectedValue(new Error("Permission denied")), stopScreenCapture: vi.fn(), getSourceInfo: vi.fn(() => null), }) render( , ) const screenButton = screen.getByText("Screen") fireEvent.click(screenButton) await waitFor(() => { expect(screen.getByText("Permission denied")).toBeInTheDocument() }) }) it("should disable mode switch buttons when recording", async () => { const { useRecording } = await import("../../hooks") vi.mocked(useRecording).mockReturnValue({ isRecording: true, recordingTime: 10, showCountdown: false, countdown: 3, setCountdown: vi.fn(), startCountdown: vi.fn(), stopRecording: vi.fn(), formatRecordingTime: vi.fn((time: number) => `00:${time.toString().padStart(2, "0")}`), }) render( , ) const cameraButton = screen.getByText("Camera") const screenButton = screen.getByText("Screen") expect(cameraButton).toBeDisabled() expect(screenButton).toBeDisabled() }) })