Files
flyer-crawler.projectium.com/src/hooks/useApiOnMount.test.ts
Torben Sorensen d1c09d18a4
Some checks failed
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Failing after 3m29s
testing routes
2025-11-28 21:03:11 -08:00

78 lines
2.9 KiB
TypeScript

// src/hooks/useApiOnMount.test.ts
import { renderHook, waitFor } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { useApiOnMount } from './useApiOnMount';
// Create a mock API function that the hook will call.
// This allows us to control its behavior (success/failure) in our tests.
const mockApiFunction = vi.fn();
describe('useApiOnMount', () => {
beforeEach(() => {
// Clear mock history before each test to ensure isolation.
vi.clearAllMocks();
});
it('should return loading: true on initial render', () => {
// Arrange:
// Mock the API function to return a promise that never resolves.
// This keeps the hook in a perpetual "loading" state for the initial check.
mockApiFunction.mockReturnValue(new Promise(() => {}));
// Act:
// Render the hook, which will immediately call the API function on mount.
const { result } = renderHook(() => useApiOnMount(mockApiFunction));
// Assert:
// Check that the hook's initial state is correct.
expect(result.current.loading).toBe(true);
expect(result.current.data).toBeNull();
expect(result.current.error).toBeNull();
expect(mockApiFunction).toHaveBeenCalledTimes(1);
});
it('should return data on successful API call', async () => {
// Arrange:
// Mock the API function to resolve with a successful Response object.
// The underlying `useApi` hook will handle the `.json()` parsing.
const mockData = { message: 'Success!' };
mockApiFunction.mockResolvedValue(new Response(JSON.stringify(mockData)));
// Act:
// Render the hook.
const { result } = renderHook(() => useApiOnMount(mockApiFunction));
// Assert:
// Use `waitFor` to wait for the hook's state to update after the promise resolves.
await waitFor(() => {
// The hook should no longer be loading.
expect(result.current.loading).toBe(false);
// The data should be populated with our mock data.
expect(result.current.data).toEqual(mockData);
// There should be no error.
expect(result.current.error).toBeNull();
});
});
it('should return an error on failed API call', async () => {
// Arrange:
// Mock the API function to reject with an error.
const mockError = new Error('API Failure');
mockApiFunction.mockRejectedValue(mockError);
// Act:
// Render the hook.
const { result } = renderHook(() => useApiOnMount(mockApiFunction));
// Assert:
// Use `waitFor` to wait for the hook's state to update after the promise rejects.
await waitFor(() => {
// The hook should no longer be loading.
expect(result.current.loading).toBe(false);
// Data should remain null.
expect(result.current.data).toBeNull();
// The error state should be populated with the error we threw.
expect(result.current.error).toEqual(mockError);
});
});
});