veza/apps/web/src/hooks/useOnlineStatus.test.ts

125 lines
3 KiB
TypeScript

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();
});
});