From 101b60c80b14840797132354d0e9b1ad20628b3d Mon Sep 17 00:00:00 2001 From: Mac Deluca Date: Fri, 8 Dec 2023 14:11:09 -0800 Subject: [PATCH] added tests for useDebounce and useFuzzySearch --- app/src/hooks/useDebounce.test.tsx | 21 ++++ .../hooks/{useDebounce.ts => useDebounce.tsx} | 0 app/src/hooks/useFuzzySearch.test.tsx | 102 ++++++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 app/src/hooks/useDebounce.test.tsx rename app/src/hooks/{useDebounce.ts => useDebounce.tsx} (100%) create mode 100644 app/src/hooks/useFuzzySearch.test.tsx diff --git a/app/src/hooks/useDebounce.test.tsx b/app/src/hooks/useDebounce.test.tsx new file mode 100644 index 000000000..67975049b --- /dev/null +++ b/app/src/hooks/useDebounce.test.tsx @@ -0,0 +1,21 @@ +import { act, renderHook } from '@testing-library/react-hooks'; +import { waitFor } from 'test-helpers/test-utils'; +import useDebounce from './useDebounce'; + +const mockCallback = jest.fn(); + +describe('useDebounce', () => { + it('should debounce repeated calls', async () => { + const { result } = renderHook(() => useDebounce(mockCallback, 500)); + const debounce = result.current; + act(() => debounce()); + await waitFor(() => { + expect(mockCallback.mock.calls[0]).toBeDefined(); + }); + // this request should fail as it is being requested too quickly + act(() => debounce()); + await waitFor(() => { + expect(mockCallback.mock.calls[1]).not.toBeDefined(); + }); + }); +}); diff --git a/app/src/hooks/useDebounce.ts b/app/src/hooks/useDebounce.tsx similarity index 100% rename from app/src/hooks/useDebounce.ts rename to app/src/hooks/useDebounce.tsx diff --git a/app/src/hooks/useFuzzySearch.test.tsx b/app/src/hooks/useFuzzySearch.test.tsx new file mode 100644 index 000000000..4afdf6287 --- /dev/null +++ b/app/src/hooks/useFuzzySearch.test.tsx @@ -0,0 +1,102 @@ +import { act, renderHook } from '@testing-library/react-hooks'; +import { FuseResult } from 'fuse.js'; +import useFuzzySearch from './useFuzzySearch'; + +const item = { a: 'zzz', b: 'hello world' }; +const mockDataArray = [item]; + +const mockFuzzyData: FuseResult[] = [ + { + item, + matches: [], + refIndex: 0 + } +]; + +const mockOptions = { minMatchCharLength: 5 }; + +describe('useFuzzySearch', () => { + describe('mounting conditions', () => { + const { result } = renderHook(() => useFuzzySearch(mockDataArray, {})); + + it('should mount with empty search string', () => { + expect(result.current.searchValue).toBe(''); + }); + + it('should mount with fuzzyData array in FuseResult structure', () => { + expect(result.current.fuzzyData).toStrictEqual(mockFuzzyData); + }); + }); + describe('handleFuzzyData', () => { + it('should set fuzzyData with new array', () => { + const { result } = renderHook(() => useFuzzySearch(mockDataArray, {})); + act(() => result.current.handleFuzzyData([{ item: { a: 'test', b: 'test' }, matches: [], refIndex: 0 }])); + expect(result.current.fuzzyData[0].item.a).toBe('test'); + }); + }); + + describe('handleSearch', () => { + it('should set searchValue', () => { + const { result } = renderHook(() => useFuzzySearch(mockDataArray, {})); + act(() => result.current.handleSearch({ target: { value: 'test' } } as any)); + expect(result.current.searchValue).toBe('test'); + }); + + it('should setFuzzyData to default when no search value provided', () => { + const { result } = renderHook(() => useFuzzySearch(mockDataArray, {})); + act(() => result.current.handleSearch({ target: { value: '' } } as any)); + expect(result.current.searchValue).toBe(''); + expect(result.current.fuzzyData).toStrictEqual(mockFuzzyData); + }); + + it('should setFuzzyData to default when no search value provided', () => { + const { result } = renderHook(() => useFuzzySearch(mockDataArray, {})); + act(() => result.current.handleSearch({ target: { value: '' } } as any)); + expect(result.current.searchValue).toBe(''); + expect(result.current.fuzzyData).toStrictEqual(mockFuzzyData); + }); + + it('should setFuzzyData to default when character count is less than minMatchCharLength', () => { + const { result } = renderHook(() => useFuzzySearch(mockDataArray, mockOptions)); + act(() => result.current.handleSearch({ target: { value: 'aaaa' } } as any)); + expect(result.current.searchValue).toBe('aaaa'); + expect(result.current.fuzzyData).toStrictEqual(mockFuzzyData); + }); + }); + describe('highlight', () => { + const { result } = renderHook(() => useFuzzySearch(mockDataArray, { highlightColour: '#ffff' })); + it('should return formatted html if highlight indices provided', () => { + act(() => { + const jsx = result.current.highlight('abc', [[0, 1]]); + const shouldEqual = ( + <> + abc + + ); + expect(jsx.toString()).toEqual(shouldEqual.toString()); + }); + }); + + it('should return string value if no indices', () => { + act(() => { + const jsx = result.current.highlight('abc', []); + expect(jsx.toString()).toEqual('abc'); + }); + }); + + it('should highlight whole string', () => { + act(() => { + const jsx = result.current.highlight('abc', [ + [0, 1], + [2, 2] + ]); + const shouldEqual = ( + <> + abc + + ); + expect(jsx.toString()).toEqual(shouldEqual.toString()); + }); + }); + }); +});