aboutsummaryrefslogtreecommitdiffstats
path: root/src/utils/hooks/use-pagination/use-pagination.test.ts
blob: 18f3ac55522a25efffdf67a05cc5f01488ab810d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import { beforeEach, describe, expect, it, jest } from '@jest/globals';
import { act, renderHook, waitFor } from '@testing-library/react';
import { getConnection } from '../../../../tests/utils/graphql';
import type { GraphQLConnection } from '../../../types';
import {
  type UsePaginationFetcherInput,
  usePagination,
} from './use-pagination';

type Data = {
  id: number;
  title: string;
};

describe('usePagination', () => {
  const data: Data[] = [
    { id: 1, title: 'illo sequi nihil' },
    { id: 2, title: 'atque et magni' },
    { id: 3, title: 'cupiditate ut sit' },
    { id: 4, title: 'aut rerum quisquam' },
    { id: 5, title: 'et ea officia' },
    { id: 6, title: 'ratione eos numquam' },
    { id: 7, title: 'repellat quos et' },
  ];
  const fetcher = jest.fn(
    async ({
      after,
      first,
      search,
    }: UsePaginationFetcherInput): Promise<GraphQLConnection<Data>> => {
      const filteredData = search
        ? data.filter((d) => d.title.includes(search))
        : data;

      return Promise.resolve(
        getConnection({ after, first, data: filteredData })
      );
    }
  );

  beforeEach(() => {
    jest.clearAllMocks();
  });

  it('can use a fetcher to retrieve data from a GraphQL API', async () => {
    /* We should use this statement because of async nature but with waitFor
     * the number of assertion in inaccurate... */
    // eslint-disable-next-line @typescript-eslint/no-magic-numbers
    //expect.assertions(6);

    expect(fetcher).not.toHaveBeenCalled();

    const perPage = 10;
    const { result } = renderHook(() =>
      usePagination({
        fetcher,
        perPage,
      })
    );

    await waitFor(() => {
      // `data.length` is lower than `perPage` so 1 page.
      expect(result.current.data?.length).toBe(1);
    });
    expect(result.current.data?.[0].edges.length).toBe(data.length);
    expect(result.current.hasNextPage).toBe(false);
    expect(fetcher).toHaveBeenCalledTimes(1);
    expect(fetcher).toHaveBeenCalledWith({ first: perPage });
  });

  it('can retrieve more data from the GraphQL API', async () => {
    /* We should use this statement because of async nature but with waitFor
     * the number of assertion in inaccurate... */
    // eslint-disable-next-line @typescript-eslint/no-magic-numbers
    //expect.assertions(7);

    const perPage = 5;
    const { result } = renderHook(() =>
      usePagination({
        fetcher,
        perPage,
      })
    );

    await waitFor(() => {
      expect(result.current.data?.length).toBe(1);
    });
    expect(result.current.data?.[0].edges.length).toBe(perPage);
    expect(result.current.hasNextPage).toBe(true);
    expect(fetcher).toHaveBeenCalledTimes(1);

    await act(async () => {
      await result.current.loadMore();
    });

    expect(result.current.data?.length).toBe(2);
    expect(result.current.data?.[1].edges.length).toBe(data.length - perPage);
  });
});