diff --git a/plugins/search/src/components/SearchFilter/hooks.test.tsx b/plugins/search/src/components/SearchFilter/hooks.test.tsx index e71ce537e6..d8fbe698ce 100644 --- a/plugins/search/src/components/SearchFilter/hooks.test.tsx +++ b/plugins/search/src/components/SearchFilter/hooks.test.tsx @@ -16,11 +16,13 @@ import React from 'react'; import { ApiProvider } from '@backstage/core-app-api'; import { TestApiRegistry } from '@backstage/test-utils'; -import { act, renderHook } from '@testing-library/react-hooks'; +import { renderHook } from '@testing-library/react-hooks'; import { SearchContextProvider, useSearch } from '../SearchContext'; import { useDefaultFilterValue, useAsyncFilterValues } from './hooks'; import { searchApiRef } from '../../apis'; +jest.useFakeTimers(); + describe('SearchFilter.hooks', () => { describe('useDefaultFilterValue', () => { const query = jest.fn().mockResolvedValue({}); @@ -225,11 +227,12 @@ describe('SearchFilter.hooks', () => { const expectedValues = ['value1', 'value2']; const asyncFn = () => Promise.resolve(expectedValues); const { result, waitForNextUpdate } = renderHook(() => - useAsyncFilterValues(asyncFn, '', undefined, 1), + useAsyncFilterValues(asyncFn, '', undefined, 1000), ); expect(result.current.loading).toEqual(true); + jest.runAllTimers(); await waitForNextUpdate(); expect(result.current.loading).toEqual(false); @@ -239,16 +242,16 @@ describe('SearchFilter.hooks', () => { it('should debounce method invocation', async () => { const expectedValues = ['value1', 'value2']; const asyncFn = jest.fn().mockResolvedValue(expectedValues); - renderHook(() => useAsyncFilterValues(asyncFn, '', undefined, 10)); + renderHook(() => useAsyncFilterValues(asyncFn, '', undefined, 1000)); expect(asyncFn).not.toHaveBeenCalled(); - // Allow 6 milliseconds to pass. - await act(() => new Promise(resolve => setTimeout(resolve, 6))); + // Advance timers by 600ms + jest.advanceTimersByTime(600); expect(asyncFn).not.toHaveBeenCalled(); - // Allow an additional 6 milliseconds to pass. - await act(() => new Promise(resolve => setTimeout(resolve, 6))); + // Another 600ms to exceed the 1000ms debounce + jest.advanceTimersByTime(600); expect(asyncFn).toHaveBeenCalled(); }); @@ -258,16 +261,18 @@ describe('SearchFilter.hooks', () => { .mockImplementation((x: string) => Promise.resolve([x])); const { rerender, waitForNextUpdate } = renderHook( (props: { inputValue: string } = { inputValue: '' }) => - useAsyncFilterValues(asyncFn, props.inputValue, undefined, 1), + useAsyncFilterValues(asyncFn, props.inputValue, undefined, 1000), ); expect(asyncFn).not.toHaveBeenCalled(); + jest.runAllTimers(); await waitForNextUpdate(); expect(asyncFn).toHaveBeenCalledTimes(1); expect(asyncFn).toHaveBeenCalledWith(''); // Re-render with different input value. rerender({ inputValue: 'somethingElse' }); + jest.runAllTimers(); await waitForNextUpdate(); expect(asyncFn).toHaveBeenCalledTimes(2); expect(asyncFn).toHaveBeenLastCalledWith('somethingElse'); @@ -278,10 +283,12 @@ describe('SearchFilter.hooks', () => { const asyncFn = jest.fn().mockResolvedValue(expectedValues); const { rerender, waitForNextUpdate } = renderHook( (props: { inputValue: string } = { inputValue: '' }) => - useAsyncFilterValues(asyncFn, props.inputValue, undefined, 1), + useAsyncFilterValues(asyncFn, props.inputValue, undefined, 1000), ); expect(asyncFn).not.toHaveBeenCalled(); + + jest.runAllTimers(); await waitForNextUpdate(); expect(asyncFn).toHaveBeenCalledTimes(1);