import { describe, it, expect, beforeEach } from 'vitest' import { renderHook, act } from '@testing-library/react' import { usePagination } from './use-pagination' import { useWidgetStore } from '../../stores/widget-store' import type { TableRow } from '../types' describe('usePagination', () => { const createTestData = (count: number): TableRow[] => Array.from({ length: count }, (_, i) => ({ id: i + 1, name: `Item ${i + 1}`, })) // Clear widget store before each test beforeEach(() => { useWidgetStore.getState().clearWidgets() }) describe('local mode', () => { it('should initialize with default values', () => { const data = createTestData(25) const { result } = renderHook(() => usePagination('test-widget', data)) expect(result.current.page).toBe(0) expect(result.current.rowsPerPage).toBe(10) expect(result.current.total).toBe(25) expect(result.current.rowsPerPageOptions).toEqual([5, 10, 25, 50]) }) it('should initialize with custom values', () => { useWidgetStore.getState().setWidget('test-widget', { pagination: { page: 0, rowsPerPage: 10, rowsPerPageOptions: [10, 25, 50, 100], }, }) const data = createTestData(100) const { result } = renderHook(() => usePagination('test-widget', data)) expect(result.current.page).toBe(0) expect(result.current.rowsPerPage).toBe(10) expect(result.current.rowsPerPageOptions).toEqual([10, 25, 50, 100]) }) it('should paginate data correctly', () => { useWidgetStore.getState().setWidget('test-widget', { pagination: { page: 0, rowsPerPage: 10, }, }) const data = createTestData(25) const { result } = renderHook(() => usePagination('test-widget', data)) expect(result.current.paginatedData).toHaveLength(10) expect(result.current.paginatedData[0]?.id).toBe(1) expect(result.current.paginatedData[9]?.id).toBe(10) }) it('should change page', () => { const data = createTestData(25) const { result } = renderHook(() => usePagination('test-widget', data)) act(() => { result.current.setPage(1) }) expect(result.current.page).toBe(1) expect(result.current.paginatedData[0]?.id).toBe(11) }) it('should bound page to max page', () => { const data = createTestData(25) const { result } = renderHook(() => usePagination('test-widget', data)) act(() => { result.current.setPage(100) }) // Max page for 25 items with 10 per page is 2 (pages 0, 1, 2) expect(result.current.page).toBe(2) }) it('should bound page to 0 for negative values', () => { const data = createTestData(25) const { result } = renderHook(() => usePagination('test-widget', data)) act(() => { result.current.setPage(-5) }) expect(result.current.page).toBe(0) }) it('should change rows per page and reset to first page', () => { const data = createTestData(50) const { result } = renderHook(() => usePagination('test-widget', data)) // First navigate to page 2 act(() => { result.current.setPage(2) }) expect(result.current.page).toBe(2) act(() => { result.current.setRowsPerPage(25) }) expect(result.current.rowsPerPage).toBe(25) expect(result.current.page).toBe(0) }) it('should navigate to first page', () => { const data = createTestData(50) const { result } = renderHook(() => usePagination('test-widget', data)) // First navigate to page 3 act(() => { result.current.setPage(3) }) act(() => { result.current.goToFirstPage() }) expect(result.current.page).toBe(0) }) it('should navigate to last page', () => { const data = createTestData(50) const { result } = renderHook(() => usePagination('test-widget', data)) act(() => { result.current.goToLastPage() }) // 50 items / 10 per page = 5 pages (0-4) expect(result.current.page).toBe(4) }) it('should navigate to next page', () => { const data = createTestData(50) const { result } = renderHook(() => usePagination('test-widget', data)) act(() => { result.current.goToNextPage() }) expect(result.current.page).toBe(1) }) it('should navigate to previous page', () => { const data = createTestData(50) const { result } = renderHook(() => usePagination('test-widget', data)) // First navigate to page 2 act(() => { result.current.setPage(2) }) act(() => { result.current.goToPreviousPage() }) expect(result.current.page).toBe(1) }) it('should handle empty data', () => { const { result } = renderHook(() => usePagination('test-widget', [])) expect(result.current.total).toBe(0) expect(result.current.paginatedData).toEqual([]) }) it('should persist state in widget store', () => { const data = createTestData(50) const { result, unmount } = renderHook(() => usePagination('test-widget', data), ) // Change page act(() => { result.current.setPage(2) }) expect(result.current.page).toBe(2) // Unmount and remount - state should persist unmount() const { result: newResult } = renderHook(() => usePagination('test-widget', data), ) expect(newResult.current.page).toBe(2) }) }) describe('remote mode', () => { it('should use remote total', () => { useWidgetStore.getState().setWidget('test-widget', { mode: 'remote', pagination: { page: 0, rowsPerPage: 10, rowsPerPageOptions: [10], total: 100, }, }) const data = createTestData(10) const { result } = renderHook(() => usePagination('test-widget', data)) expect(result.current.total).toBe(100) // In remote mode, data is already paginated from server expect(result.current.paginatedData).toHaveLength(10) }) it('should update store state when page changes in remote mode', () => { useWidgetStore.getState().setWidget('test-widget', { mode: 'remote', pagination: { page: 0, rowsPerPage: 10, rowsPerPageOptions: [10], total: 100, }, }) const data = createTestData(10) const { result } = renderHook(() => usePagination('test-widget', data)) act(() => { result.current.setPage(2) }) expect(result.current.page).toBe(2) }) it('should update store state when rows per page changes in remote mode', () => { useWidgetStore.getState().setWidget('test-widget', { mode: 'remote', pagination: { page: 0, rowsPerPage: 10, rowsPerPageOptions: [10], total: 100, }, }) const data = createTestData(10) const { result } = renderHook(() => usePagination('test-widget', data)) act(() => { result.current.setRowsPerPage(25) }) expect(result.current.rowsPerPage).toBe(25) expect(result.current.page).toBe(0) }) it('should handle undefined remote total', () => { useWidgetStore.getState().setWidget('test-widget', { mode: 'remote', pagination: { page: 0, rowsPerPage: 10, rowsPerPageOptions: [10], }, }) const data = createTestData(10) const { result } = renderHook(() => usePagination('test-widget', data)) expect(result.current.total).toBe(10) }) it('should return data as-is in remote mode', () => { useWidgetStore.getState().setWidget('test-widget', { mode: 'remote', pagination: { page: 0, rowsPerPage: 10, rowsPerPageOptions: [10], total: 100, }, }) const data = createTestData(5) const { result } = renderHook(() => usePagination('test-widget', data)) // In remote mode, paginatedData should return the data as-is // since server already handles pagination expect(result.current.paginatedData).toEqual(data) }) }) })