Merge pull request #9164 from backstage/search/filter-timers
Use fake timers to test search filter hooks debounce
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user