/** * Tests for DataProviderContext - data-provider-context.tsx * * TDD RED phase: Write failing tests first. */ import { describe, it, expect, vi } from 'vitest' import { render, screen } from '@testing-library/react' import { DataProviderProvider, useDataProvider } from '../../context/data-provider-context' import type { DataProvider } from '../../types' // Helper component to consume data provider context function DataProviderConsumer({ onProvider }: { onProvider: (dp: DataProvider) => void }) { const dataProvider = useDataProvider() onProvider(dataProvider) return
true
} function createMockDataProvider(overrides: Partial = {}): DataProvider { return { getList: vi.fn().mockResolvedValue({ data: [], total: 0 }), getOne: vi.fn().mockResolvedValue({ data: { id: '1' } }), getMany: vi.fn().mockResolvedValue({ data: [] }), create: vi.fn().mockResolvedValue({ data: { id: '1' } }), update: vi.fn().mockResolvedValue({ data: { id: '1' } }), delete: vi.fn().mockResolvedValue({ data: { id: '1' } }), ...overrides, } } describe('DataProviderContext', () => { describe('DataProviderProvider', () => { it('should provide the data provider to children', () => { const mockProvider = createMockDataProvider() let receivedProvider: DataProvider | undefined render( { receivedProvider = dp }} /> ) expect(screen.getByTestId('has-provider').textContent).toBe('true') expect(receivedProvider).toBe(mockProvider) }) it('should allow calling data provider methods', async () => { const mockGetList = vi.fn().mockResolvedValue({ data: [{ id: '1', name: 'Test' }], total: 1 }) const mockProvider = createMockDataProvider({ getList: mockGetList }) let receivedProvider: DataProvider | undefined render( { receivedProvider = dp }} /> ) const result = await receivedProvider!.getList('users', { pagination: { page: 1, perPage: 10 } }) expect(mockGetList).toHaveBeenCalledWith('users', { pagination: { page: 1, perPage: 10 } }) expect(result.data).toEqual([{ id: '1', name: 'Test' }]) expect(result.total).toBe(1) }) it('should support all DataProvider methods', async () => { const mockProvider = createMockDataProvider() let receivedProvider: DataProvider | undefined render( { receivedProvider = dp }} /> ) // Call all methods await receivedProvider!.getList('users') await receivedProvider!.getOne('users', { id: '1' }) await receivedProvider!.getMany('users', { ids: ['1', '2'] }) await receivedProvider!.create('users', { data: { name: 'New' } }) await receivedProvider!.update('users', { id: '1', data: { name: 'Updated' } }) await receivedProvider!.delete('users', { id: '1' }) expect(mockProvider.getList).toHaveBeenCalled() expect(mockProvider.getOne).toHaveBeenCalled() expect(mockProvider.getMany).toHaveBeenCalled() expect(mockProvider.create).toHaveBeenCalled() expect(mockProvider.update).toHaveBeenCalled() expect(mockProvider.delete).toHaveBeenCalled() }) }) describe('useDataProvider', () => { it('should throw error when used outside DataProviderProvider', () => { const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {}) expect(() => { render( {}} />) }).toThrow('useDataProvider must be used within a DataProviderProvider') consoleError.mockRestore() }) }) })