import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { renderHook } from '@testing-library/react'; import { useOnlineStatus } from './useOnlineStatus'; describe('useOnlineStatus', () => { beforeEach(() => { // Mock navigator.onLine Object.defineProperty(navigator, 'onLine', { writable: true, configurable: true, value: true, }); }); afterEach(() => { vi.restoreAllMocks(); }); it('should return true when navigator.onLine is true', () => { Object.defineProperty(navigator, 'onLine', { writable: true, configurable: true, value: true, }); const { result } = renderHook(() => useOnlineStatus()); expect(result.current).toBe(true); }); it('should return false when navigator.onLine is false', () => { Object.defineProperty(navigator, 'onLine', { writable: true, configurable: true, value: false, }); const { result } = renderHook(() => useOnlineStatus()); expect(result.current).toBe(false); }); it('should update when online event fires', async () => { Object.defineProperty(navigator, 'onLine', { writable: true, configurable: true, value: false, }); const { result, waitForNextUpdate } = renderHook(() => useOnlineStatus()); expect(result.current).toBe(false); // Simulate online event Object.defineProperty(navigator, 'onLine', { writable: true, configurable: true, value: true, }); window.dispatchEvent(new Event('online')); // Wait for state update await waitForNextUpdate(); expect(result.current).toBe(true); }); it('should update when offline event fires', async () => { Object.defineProperty(navigator, 'onLine', { writable: true, configurable: true, value: true, }); const { result, waitForNextUpdate } = renderHook(() => useOnlineStatus()); expect(result.current).toBe(true); // Simulate offline event Object.defineProperty(navigator, 'onLine', { writable: true, configurable: true, value: false, }); window.dispatchEvent(new Event('offline')); // Wait for state update await waitForNextUpdate(); expect(result.current).toBe(false); }); it('should return true when navigator is undefined', () => { const originalNavigator = global.navigator; // @ts-ignore delete global.navigator; const { result } = renderHook(() => useOnlineStatus()); expect(result.current).toBe(true); global.navigator = originalNavigator; }); it('should clean up event listeners on unmount', () => { const removeEventListenerSpy = vi.spyOn(window, 'removeEventListener'); const { unmount } = renderHook(() => useOnlineStatus()); unmount(); expect(removeEventListenerSpy).toHaveBeenCalledWith( 'online', expect.any(Function), ); expect(removeEventListenerSpy).toHaveBeenCalledWith( 'offline', expect.any(Function), ); removeEventListenerSpy.mockRestore(); }); });