diff --git a/packages/kbn-securitysolution-hook-utils/src/use_async/index.test.ts b/packages/kbn-securitysolution-hook-utils/src/use_async/index.test.ts index 886a3dd27befc..7503f2c5c2be8 100644 --- a/packages/kbn-securitysolution-hook-utils/src/use_async/index.test.ts +++ b/packages/kbn-securitysolution-hook-utils/src/use_async/index.test.ts @@ -18,6 +18,13 @@ interface TestArgs { type TestReturn = Promise; describe('useAsync', () => { + /** + * Timeout for both jest tests and for the waitForNextUpdate. + * jest tests default to 5 seconds and waitForNextUpdate defaults to 1 second. + * 20_0000 = 20,000 milliseconds = 20 seconds + */ + const timeout = 20_000; + let fn: jest.Mock; let args: TestArgs; @@ -31,16 +38,20 @@ describe('useAsync', () => { expect(fn).not.toHaveBeenCalled(); }); - it('invokes the function when start is called', async () => { - const { result, waitForNextUpdate } = renderHook(() => useAsync(fn)); + it( + 'invokes the function when start is called', + async () => { + const { result, waitForNextUpdate } = renderHook(() => useAsync(fn)); - act(() => { - result.current.start(args); - }); - await waitForNextUpdate(); + act(() => { + result.current.start(args); + }); + await waitForNextUpdate({ timeout }); - expect(fn).toHaveBeenCalled(); - }); + expect(fn).toHaveBeenCalled(); + }, + timeout + ); it('invokes the function with start args', async () => { const { result, waitForNextUpdate } = renderHook(() => useAsync(fn)); @@ -49,84 +60,99 @@ describe('useAsync', () => { act(() => { result.current.start(args); }); - await waitForNextUpdate(); + await waitForNextUpdate({ timeout }); expect(fn).toHaveBeenCalledWith(expectedArgs); }); - it('populates result with the resolved value of the fn', async () => { - const { result, waitForNextUpdate } = renderHook(() => useAsync(fn)); - fn.mockResolvedValue({ resolved: 'value' }); - - act(() => { - result.current.start(args); - }); - await waitForNextUpdate(); - - expect(result.current.result).toEqual({ resolved: 'value' }); - expect(result.current.error).toBeUndefined(); - }); - - it('populates error if function rejects', async () => { - fn.mockRejectedValue(new Error('whoops')); - const { result, waitForNextUpdate } = renderHook(() => useAsync(fn)); - - act(() => { - result.current.start(args); - }); - await waitForNextUpdate(); - - expect(result.current.result).toBeUndefined(); - expect(result.current.error).toEqual(new Error('whoops')); - }); - - it('populates the loading state while the function is pending', async () => { - let resolve: () => void; - fn.mockImplementation(() => new Promise((_resolve) => (resolve = _resolve))); - - const { result, waitForNextUpdate } = renderHook(() => useAsync(fn)); - - act(() => { - result.current.start(args); - }); - - expect(result.current.loading).toBe(true); - - act(() => resolve()); - await waitForNextUpdate(); - - expect(result.current.loading).toBe(false); - }); - - it('multiple start calls reset state', async () => { - let resolve: (result: string) => void; - fn.mockImplementation(() => new Promise((_resolve) => (resolve = _resolve))); - - const { result, waitForNextUpdate } = renderHook(() => useAsync(fn)); - - act(() => { - result.current.start(args); - }); - - expect(result.current.loading).toBe(true); - - act(() => resolve('result')); - await waitForNextUpdate(); - - expect(result.current.loading).toBe(false); - expect(result.current.result).toBe('result'); - - act(() => { - result.current.start(args); - }); - - expect(result.current.loading).toBe(true); - expect(result.current.result).toBe(undefined); - - act(() => resolve('result')); - await waitForNextUpdate(); - - expect(result.current.loading).toBe(false); - expect(result.current.result).toBe('result'); - }); + it( + 'populates result with the resolved value of the fn', + async () => { + const { result, waitForNextUpdate } = renderHook(() => useAsync(fn)); + fn.mockResolvedValue({ resolved: 'value' }); + + act(() => { + result.current.start(args); + }); + await waitForNextUpdate({ timeout }); + + expect(result.current.result).toEqual({ resolved: 'value' }); + expect(result.current.error).toBeUndefined(); + }, + timeout + ); + + it( + 'populates error if function rejects', + async () => { + fn.mockRejectedValue(new Error('whoops')); + const { result, waitForNextUpdate } = renderHook(() => useAsync(fn)); + + act(() => { + result.current.start(args); + }); + await waitForNextUpdate({ timeout }); + + expect(result.current.result).toBeUndefined(); + expect(result.current.error).toEqual(new Error('whoops')); + }, + timeout + ); + + it( + 'populates the loading state while the function is pending', + async () => { + let resolve: () => void; + fn.mockImplementation(() => new Promise((_resolve) => (resolve = _resolve))); + + const { result, waitForNextUpdate } = renderHook(() => useAsync(fn)); + + act(() => { + result.current.start(args); + }); + + expect(result.current.loading).toBe(true); + + act(() => resolve()); + await waitForNextUpdate({ timeout }); + + expect(result.current.loading).toBe(false); + }, + timeout + ); + + it( + 'multiple start calls reset state', + async () => { + let resolve: (result: string) => void; + fn.mockImplementation(() => new Promise((_resolve) => (resolve = _resolve))); + + const { result, waitForNextUpdate } = renderHook(() => useAsync(fn)); + + act(() => { + result.current.start(args); + }); + + expect(result.current.loading).toBe(true); + + act(() => resolve('result')); + await waitForNextUpdate({ timeout }); + + expect(result.current.loading).toBe(false); + expect(result.current.result).toBe('result'); + + act(() => { + result.current.start(args); + }); + + expect(result.current.loading).toBe(true); + expect(result.current.result).toBe(undefined); + act(() => resolve('result')); + await waitForNextUpdate({ timeout }); + + expect(result.current.loading).toBe(false); + expect(result.current.result).toBe('result'); + }, + timeout + ); });