import { act, renderHook, waitFor } from "@testing-library/react" import { mockIsIntersecting } from "react-intersection-observer/test-utils" import { test, vi, describe, expect } from "vitest" import { useScrollingPagination } from "./useScrollingPagination" describe("useScrollingPagination", () => { test("loads more when element is in view", async () => { const loadNext = vi.fn() const { result } = renderHook(() => useScrollingPagination({ hasNext: true, loadNext, isLoadingNext: false }), ) const element = document.createElement("div") await act(() => { result.current.ref(element) }) expect(result.current.isLoading).toBe(false) mockIsIntersecting(element, true) expect(result.current.isLoading).toBe(true) expect(loadNext).toHaveBeenCalled() await act(() => { mockIsIntersecting(element, false) }) await waitFor(() => expect(result.current.isLoading).toBe(false)) }) test("does not load more if it's in view but doesn't have next page", async () => { const loadNext = vi.fn() const { result, rerender } = renderHook( ({ hasNext, loadNext, isLoadingNext }) => useScrollingPagination({ hasNext, loadNext, isLoadingNext }), { initialProps: { hasNext: true, loadNext, isLoadingNext: false } }, ) const element = document.createElement("div") await act(() => { result.current.ref(element) }) expect(result.current.isLoading).toBe(false) mockIsIntersecting(element, true) rerender({ hasNext: false, loadNext, isLoadingNext: false }) await waitFor(() => expect(result.current.isLoading).toBe(false)) }) test("calls onError when loadNext fails", async () => { const error = new Error("Failed to load next items") const loadNext = vi.fn().mockRejectedValue(error) const onError = vi.fn() const { result } = renderHook(() => useScrollingPagination({ hasNext: true, loadNext, isLoadingNext: false, onError, }), ) const element = document.createElement("div") await act(() => { result.current.ref(element) }) expect(result.current.isLoading).toBe(false) mockIsIntersecting(element, true) expect(result.current.isLoading).toBe(true) expect(loadNext).toHaveBeenCalled() await waitFor(() => { expect(onError).toHaveBeenCalled() }) }) })