import { renderHook, waitFor } from '@testing-library/react'; import useSettings from '../useSettings'; // Mock fetch global.fetch = jest.fn(); describe('useSettings', () => { beforeEach(() => { jest.clearAllMocks(); }); test('should fetch settings on mount', async () => { const mockSettings = { theme: 'dark', notifications: true }; (fetch as jest.MockedFunction).mockResolvedValue({ ok: true, json: jest.fn().mockResolvedValue(mockSettings), } as any); const { result } = renderHook(() => useSettings()); expect(result.current.loading).toBe(true); expect(result.current.settings).toBe(null); await waitFor(() => { expect(result.current.loading).toBe(false); }); expect(result.current.settings).toEqual(mockSettings); expect(result.current.error).toBe(null); expect(fetch).toHaveBeenCalledWith('/api/settings'); }); test('should handle fetch errors', async () => { const mockError = new Error('Network error'); (fetch as jest.MockedFunction).mockRejectedValue(mockError); const { result } = renderHook(() => useSettings()); await waitFor(() => { expect(result.current.loading).toBe(false); }); expect(result.current.settings).toBe(null); expect(result.current.error).toBe(mockError); }); test('should update settings', async () => { const initialSettings = { theme: 'light', notifications: false }; const updatedSettings = { theme: 'dark', notifications: true }; (fetch as jest.MockedFunction) .mockResolvedValueOnce({ ok: true, json: jest.fn().mockResolvedValue(initialSettings), } as any) .mockResolvedValueOnce({ ok: true, json: jest.fn().mockResolvedValue(updatedSettings), } as any); const { result } = renderHook(() => useSettings()); await waitFor(() => { expect(result.current.loading).toBe(false); }); await result.current.updateSettings(updatedSettings); expect(result.current.settings).toEqual(updatedSettings); expect(fetch).toHaveBeenCalledWith('/api/settings', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(updatedSettings), }); }); });