import React from 'react' import {renderHook} from '@testing-library/react' import {describe, expect, it, vi, beforeEach} from 'vitest' import {useImagePicker} from './useImagePicker' import type { OpenCameraParams, OpenGalleryParams, } from '../../providers/ImagePickerProvider' // Mock the ImagePickerProvider context const mockOpenCamera = vi.fn() const mockOpenGallery = vi.fn() vi.mock('../../providers/ImagePickerProvider', () => ({ useImagePickerContext: () => ({ openCamera: mockOpenCamera, openGallery: mockOpenGallery, }), ImagePickerProvider: ({children}: {children: React.ReactNode}) => children, })) describe('useImagePicker', () => { beforeEach(() => { vi.clearAllMocks() }) describe('openCamera', () => { it('calls context openCamera with provided params', async () => { const mockFile = new File(['test'], 'test.jpg', {type: 'image/jpeg'}) mockOpenCamera.mockResolvedValue(mockFile) const {result} = renderHook(() => useImagePicker()) const params: OpenCameraParams = { cameraFacing: 'front', quality: 'high', customQuality: {size: 2000, compression: 0.9}, } const file = await result.current.openCamera(params) expect(mockOpenCamera).toHaveBeenCalledWith(params) expect(file).toBe(mockFile) }) it('calls context openCamera with default params when none provided', async () => { const mockFile = new File(['test'], 'test.jpg', {type: 'image/jpeg'}) mockOpenCamera.mockResolvedValue(mockFile) const {result} = renderHook(() => useImagePicker()) const file = await result.current.openCamera() expect(mockOpenCamera).toHaveBeenCalledWith({ cameraFacing: undefined, quality: undefined, customQuality: undefined, }) expect(file).toBe(mockFile) }) it('supports partial params', async () => { const mockFile = new File(['test'], 'test.jpg', {type: 'image/jpeg'}) mockOpenCamera.mockResolvedValue(mockFile) const {result} = renderHook(() => useImagePicker()) const file = await result.current.openCamera({quality: 'low'}) expect(mockOpenCamera).toHaveBeenCalledWith({ cameraFacing: undefined, quality: 'low', customQuality: undefined, }) expect(file).toBe(mockFile) }) }) describe('openGallery', () => { it('calls context openGallery with provided params', async () => { const mockFile = new File(['test'], 'test.jpg', {type: 'image/jpeg'}) mockOpenGallery.mockResolvedValue(mockFile) const {result} = renderHook(() => useImagePicker()) const params: OpenGalleryParams = { quality: 'medium', customQuality: {size: 1500, compression: 0.8}, } const file = await result.current.openGallery(params) expect(mockOpenGallery).toHaveBeenCalledWith(params) expect(file).toBe(mockFile) }) it('calls context openGallery with default params when none provided', async () => { const mockFile = new File(['test'], 'test.jpg', {type: 'image/jpeg'}) mockOpenGallery.mockResolvedValue(mockFile) const {result} = renderHook(() => useImagePicker()) const file = await result.current.openGallery() expect(mockOpenGallery).toHaveBeenCalledWith({ quality: undefined, customQuality: undefined, }) expect(file).toBe(mockFile) }) it('supports partial params', async () => { const mockFile = new File(['test'], 'test.jpg', {type: 'image/jpeg'}) mockOpenGallery.mockResolvedValue(mockFile) const {result} = renderHook(() => useImagePicker()) const file = await result.current.openGallery({quality: 'original'}) expect(mockOpenGallery).toHaveBeenCalledWith({ quality: 'original', customQuality: undefined, }) expect(file).toBe(mockFile) }) }) describe('Error handling', () => { it('propagates errors from openCamera', async () => { const error = new Error('Camera permission denied') mockOpenCamera.mockRejectedValue(error) const {result} = renderHook(() => useImagePicker()) await expect(result.current.openCamera()).rejects.toThrow( 'Camera permission denied' ) }) it('propagates errors from openGallery', async () => { const error = new Error('Gallery access denied') mockOpenGallery.mockRejectedValue(error) const {result} = renderHook(() => useImagePicker()) await expect(result.current.openGallery()).rejects.toThrow( 'Gallery access denied' ) }) }) describe('Quality settings', () => { it('passes through all quality options for camera', async () => { const mockFile = new File(['test'], 'test.jpg', {type: 'image/jpeg'}) mockOpenCamera.mockResolvedValue(mockFile) const {result} = renderHook(() => useImagePicker()) // Test each quality setting const qualities = ['low', 'medium', 'high', 'original'] as const for (const quality of qualities) { await result.current.openCamera({quality}) expect(mockOpenCamera).toHaveBeenLastCalledWith({ cameraFacing: undefined, quality, customQuality: undefined, }) } }) it('passes through all quality options for gallery', async () => { const mockFile = new File(['test'], 'test.jpg', {type: 'image/jpeg'}) mockOpenGallery.mockResolvedValue(mockFile) const {result} = renderHook(() => useImagePicker()) // Test each quality setting const qualities = ['low', 'medium', 'high', 'original'] as const for (const quality of qualities) { await result.current.openGallery({quality}) expect(mockOpenGallery).toHaveBeenLastCalledWith({ quality, customQuality: undefined, }) } }) }) })