import { renderHook } from '@testing-library/react'; import useTapNavigation from '../useTapNavigation'; describe('useTapNavigation', () => { let containerRef: { current: HTMLDivElement | null }; let onNext: jest.Mock; let onPrevious: jest.Mock; beforeEach(() => { // jsdom does not implement document.elementFromPoint at all, so jest.spyOn // won't work. Define it directly, returning null by default // (means "no interactive element at the tap point", navigation proceeds normally). Object.defineProperty(document, 'elementFromPoint', { writable: true, configurable: true, value: jest.fn().mockReturnValue(null), }); // Create a mock container element with dimensions containerRef = { current: document.createElement('div') }; // Mock getBoundingClientRect to return consistent dimensions containerRef.current!.getBoundingClientRect = jest.fn().mockReturnValue({ width: 1000, height: 500, top: 0, left: 0, right: 1000, bottom: 500, x: 0, y: 0, toJSON: jest.fn(), }); // Mock event listeners containerRef.current!.addEventListener = jest.fn(); containerRef.current!.removeEventListener = jest.fn(); // Mock callback functions onNext = jest.fn(); onPrevious = jest.fn(); }); afterEach(() => { jest.restoreAllMocks(); }); test('calls onPrevious when tapping on the left side', () => { renderHook(() => useTapNavigation({ containerRef, onNext, onPrevious, }), ); // Get the click handler const clickHandler = (containerRef.current!.addEventListener as jest.Mock).mock.calls.find( (call) => call[0] === 'click', )[1]; // Simulate a click on the left side (less than 40% of width) const mockClickEvent = { clientX: 350, // 35% of container width clientY: 250, // Middle of container height target: document.createElement('div'), }; clickHandler(mockClickEvent); // Check if onPrevious was called expect(onPrevious).toHaveBeenCalledTimes(1); expect(onNext).not.toHaveBeenCalled(); }); test('calls onNext when tapping on the right side', () => { renderHook(() => useTapNavigation({ containerRef, onNext, onPrevious, }), ); // Get the click handler const clickHandler = (containerRef.current!.addEventListener as jest.Mock).mock.calls.find( (call) => call[0] === 'click', )[1]; // Simulate a click on the right side (more than 40% of width) const mockClickEvent = { clientX: 600, // 60% of container width clientY: 250, // Middle of container height target: document.createElement('div'), }; clickHandler(mockClickEvent); // Check if onNext was called expect(onNext).toHaveBeenCalledTimes(1); expect(onPrevious).not.toHaveBeenCalled(); }); test('ignores clicks on play button', () => { renderHook(() => useTapNavigation({ containerRef, onNext, onPrevious, }), ); // Get the click handler const clickHandler = (containerRef.current!.addEventListener as jest.Mock).mock.calls.find( (call) => call[0] === 'click', )[1]; // Make elementFromPoint return a