import { renderHook } from '@testing-library/react'; import { RefObject } from 'react'; import { useCarouselDimensions } from '../useCarouselDimensions'; // Mock the Helpers module jest.mock('../../services/helpers', () => ({ Helpers: { calculateArrowSize: jest.fn((width: number) => { if (width < 200) return 'nano'; if (width < 300) return 'micro'; if (width < 650) return 'small'; if (width < 800) return 'compact'; if (width < 1000) return 'medium'; return 'large'; }), }, })); describe('useCarouselDimensions', () => { const createMockRef = (clientWidth: number): RefObject => ({ current: { clientWidth, } as HTMLDivElement, }); it('should calculate dimensions correctly for desktop with arrows', () => { const { result } = renderHook(() => useCarouselDimensions({ widgetWidth: 800, slideRef: createMockRef(800), hideArrows: false, hasItems: true, nbElems: 4, itemCount: 10, isMobile: false, }), ); expect(result.current).toEqual({ containerWidth: 800, arrowSize: 'medium', arrowSpace: 64, // (26 + 3*2) * 2 = 32 * 2 = 64 contentWidth: 736, // 800 - 64 itemWidth: Math.floor(736 / 4), // 184 }); }); it('should honor forced arrow size when provided', () => { const { result } = renderHook(() => useCarouselDimensions({ widgetWidth: 400, slideRef: createMockRef(400), hideArrows: false, hasItems: true, nbElems: 3, itemCount: 6, isMobile: false, forcedArrowSize: 'medium', }), ); expect(result.current.arrowSize).toBe('medium'); expect(result.current.arrowSpace).toBe(64); }); it('should calculate dimensions correctly for mobile', () => { const { result } = renderHook(() => useCarouselDimensions({ widgetWidth: 400, slideRef: createMockRef(400), hideArrows: false, hasItems: true, nbElems: 1, itemCount: 5, isMobile: true, }), ); expect(result.current).toEqual({ containerWidth: 400, arrowSize: 'medium', // Default when arrows not shown (mobile) arrowSpace: 0, // No arrows on mobile contentWidth: 400, itemWidth: 320, // 80% of 400 }); }); it('should calculate dimensions correctly without arrows', () => { const { result } = renderHook(() => useCarouselDimensions({ widgetWidth: 600, slideRef: createMockRef(600), hideArrows: true, hasItems: true, nbElems: 3, itemCount: 6, isMobile: false, }), ); expect(result.current).toEqual({ containerWidth: 600, arrowSize: 'medium', arrowSpace: 0, // Arrows hidden contentWidth: 600, itemWidth: Math.floor(600 / 3), // 200 }); }); it('should handle partial item width for even number of items', () => { const { result } = renderHook(() => useCarouselDimensions({ widgetWidth: 800, slideRef: createMockRef(800), hideArrows: false, hasItems: true, nbElems: 4, // Even number itemCount: 10, isMobile: false, partialItemWidth: 0.4, }), ); const expectedArrowSpace = (26 + 3 * 2) * 2; // medium arrows: (26 + 3*2) * 2 = 64 const expectedContentWidth = 800 - expectedArrowSpace; const expectedItemWidth = Math.floor(expectedContentWidth / (4 + 0.4)); // 4 items + 0.4 partial expect(result.current.itemWidth).toBe(expectedItemWidth); }); it('should not add partial width for odd number of items', () => { const { result } = renderHook(() => useCarouselDimensions({ widgetWidth: 800, slideRef: createMockRef(800), hideArrows: false, hasItems: true, nbElems: 3, // Odd number itemCount: 10, isMobile: false, partialItemWidth: 0.4, }), ); const expectedArrowSpace = (26 + 3 * 2) * 2; // medium arrows: (26 + 3*2) * 2 = 64 const expectedContentWidth = 800 - expectedArrowSpace; const expectedItemWidth = Math.floor(expectedContentWidth / 3); // No partial width added expect(result.current.itemWidth).toBe(expectedItemWidth); }); it('should fallback to slideRef width when widgetWidth is 0', () => { const { result } = renderHook(() => useCarouselDimensions({ widgetWidth: 0, slideRef: createMockRef(500), hideArrows: false, hasItems: true, nbElems: 2, itemCount: 4, isMobile: false, }), ); expect(result.current.containerWidth).toBe(500); }); it('should fallback to default width when both widgetWidth and slideRef are unavailable', () => { const { result } = renderHook(() => useCarouselDimensions({ widgetWidth: 0, slideRef: { current: null }, hideArrows: false, hasItems: true, nbElems: 2, itemCount: 4, isMobile: false, }), ); expect(result.current.containerWidth).toBe(600); }); });