Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / packages / hooks / useInterval.test.ts
blob1777e9fbfab7ded4b7369b39d459f4b2b593bdc5
1 import { renderHook } from '@testing-library/react-hooks';
3 import useInterval from './useInterval';
5 describe('useInterval', () => {
6     let callback: jest.Mock<any, any>;
7     let setInterval: jest.SpyInstance<any, any>;
8     let clearInterval: jest.SpyInstance<any, any>;
10     beforeEach(() => {
11         callback = jest.fn();
12         setInterval = jest.spyOn(window, 'setInterval');
13         clearInterval = jest.spyOn(window, 'clearInterval');
14     });
16     beforeAll(() => {
17         jest.useFakeTimers();
18     });
20     afterEach(() => {
21         callback.mockRestore();
22         jest.clearAllTimers();
23     });
25     afterAll(() => {
26         jest.useRealTimers();
27     });
29     it('should init hook with no delay', () => {
30         const { result } = renderHook(() => useInterval(callback, null));
32         const value = result.current;
34         expect(value).toBeUndefined();
35         // if null delay provided, it's assumed as no delay
36         expect(setInterval).not.toHaveBeenCalled();
37     });
39     it('should set pass delay to setInterval', () => {
40         const delay = 5000;
41         const { result } = renderHook(() => useInterval(callback, delay));
43         const value = result.current;
45         expect(value).toBeUndefined();
46         expect(setInterval).toHaveBeenCalledTimes(1);
47         expect(setInterval).toHaveBeenCalledWith(expect.any(Function), delay);
48     });
50     it('should repeatedly calls provided callback with a fixed time delay between each call', () => {
51         renderHook(() => useInterval(callback, 200));
52         expect(callback).not.toHaveBeenCalled();
54         // fast-forward time until 1 millisecond before it should be executed
55         jest.advanceTimersByTime(199);
56         expect(callback).not.toHaveBeenCalled();
58         // fast-forward until 1st call should be executed
59         jest.advanceTimersByTime(1);
60         expect(callback).toHaveBeenCalledTimes(1);
62         // fast-forward until next timer should be executed
63         jest.advanceTimersToNextTimer();
64         expect(callback).toHaveBeenCalledTimes(2);
66         // fast-forward until 3 more timers should be executed
67         jest.advanceTimersToNextTimer(3);
68         expect(callback).toHaveBeenCalledTimes(5);
69     });
71     it('should clear interval on unmount', () => {
72         const { unmount } = renderHook(() => useInterval(callback, 200));
73         const initialTimerCount = jest.getTimerCount();
74         expect(clearInterval).not.toHaveBeenCalled();
76         unmount();
78         expect(clearInterval).toHaveBeenCalledTimes(1);
79         expect(jest.getTimerCount()).toBe(initialTimerCount - 1);
80     });
82     it('should handle new interval when delay is updated', () => {
83         let delay = 200;
84         const { rerender } = renderHook(() => useInterval(callback, delay));
85         expect(callback).not.toHaveBeenCalled();
87         // fast-forward initial delay
88         jest.advanceTimersByTime(200);
89         expect(callback).toHaveBeenCalledTimes(1);
91         // update delay by increasing previous one
92         delay = 500;
93         rerender();
95         // fast-forward initial delay again but this time it should not execute the cb
96         jest.advanceTimersByTime(200);
97         expect(callback).toHaveBeenCalledTimes(1);
99         // fast-forward remaining time for new delay
100         jest.advanceTimersByTime(300);
101         expect(callback).toHaveBeenCalledTimes(2);
102     });
104     it('should clear pending interval when delay is updated', () => {
105         let delay = 200;
106         const { rerender } = renderHook(() => useInterval(callback, delay));
107         expect(clearInterval).not.toHaveBeenCalled();
108         const initialTimerCount = jest.getTimerCount();
110         // update delay while there is a pending interval
111         delay = 500;
112         rerender();
114         expect(clearInterval).toHaveBeenCalledTimes(1);
115         expect(jest.getTimerCount()).toBe(initialTimerCount);
116     });