21720:
[arvados.git] / services / workbench2 / src / common / use-async-interval.test.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import React from 'react';
6 import { useAsyncInterval } from './use-async-interval';
7 import { configure, mount } from 'enzyme';
8 import Adapter from 'enzyme-adapter-react-16';
9 import FakeTimers from "@sinonjs/fake-timers";
10
11 configure({ adapter: new Adapter() });
12 const clock = FakeTimers.install();
13
14 jest.mock('react', () => {
15     const originalReact = jest.requireActual('react');
16     const mUseRef = jest.fn();
17     return {
18         ...originalReact,
19         useRef: mUseRef,
20     };
21 });
22
23 const TestComponent = (props): JSX.Element => {
24     useAsyncInterval(props.callback, 2000);
25     return <span />;
26 };
27
28 describe('useAsyncInterval', () => {
29     it('should fire repeatedly after the interval', async () => {
30         const mockedReact = React as jest.Mocked<typeof React>;
31         const ref = { current: {} };
32         mockedReact.useRef.mockReturnValue(ref);
33
34         const syncCallback = jest.fn();
35         const testComponent = mount(<TestComponent
36             callback={syncCallback}
37         />);
38
39         // cb queued with interval but not called
40         expect(syncCallback).not.toHaveBeenCalled();
41
42         // wait for first tick
43         await clock.tickAsync(2000);
44         expect(syncCallback).toHaveBeenCalledTimes(1);
45
46         // wait for second tick
47         await clock.tickAsync(2000);
48         expect(syncCallback).toHaveBeenCalledTimes(2);
49
50         // wait for third tick
51         await clock.tickAsync(2000);
52         expect(syncCallback).toHaveBeenCalledTimes(3);
53     });
54
55     it('should wait for async callbacks to complete in between polling', async () => {
56         const mockedReact = React as jest.Mocked<typeof React>;
57         const ref = { current: {} };
58         mockedReact.useRef.mockReturnValue(ref);
59
60         const delayedCallback = jest.fn(() => (
61             new Promise<void>((resolve) => {
62                 setTimeout(() => {
63                     resolve();
64                 }, 2000);
65             })
66         ));
67         const testComponent = mount(<TestComponent
68             callback={delayedCallback}
69         />);
70
71         // cb queued with setInterval but not called
72         expect(delayedCallback).not.toHaveBeenCalled();
73
74         // Wait 2 seconds for first tick
75         await clock.tickAsync(2000);
76         // First cb called after 2 seconds
77         expect(delayedCallback).toHaveBeenCalledTimes(1);
78         // Wait for cb to resolve for 2 seconds
79         await clock.tickAsync(2000);
80         expect(delayedCallback).toHaveBeenCalledTimes(1);
81
82         // Wait 2 seconds for second tick
83         await clock.tickAsync(2000);
84         expect(delayedCallback).toHaveBeenCalledTimes(2);
85         // Wait for cb to resolve for 2 seconds
86         await clock.tickAsync(2000);
87         expect(delayedCallback).toHaveBeenCalledTimes(2);
88
89         // Wait 2 seconds for third tick
90         await clock.tickAsync(2000);
91         expect(delayedCallback).toHaveBeenCalledTimes(3);
92         // Wait for cb to resolve for 2 seconds
93         await clock.tickAsync(2000);
94         expect(delayedCallback).toHaveBeenCalledTimes(3);
95     });
96 });