UNPKG

wix-style-react

Version:
162 lines (147 loc) • 5.55 kB
import { act, renderHook } from '@testing-library/react-hooks'; import { sleep } from 'wix-ui-test-utils/react-helpers'; import { AmbassadorHTTPError } from '@wix/ambassador/runtime/http'; import { debounce } from '../../../test/utils/unit'; import usePlacesAutocomplete from './usePlacesAutocomplete'; jest.useFakeTimers(); const flushPromises = () => new Promise(resolve => setImmediate(resolve)); const defaultDebounceMs = 200; const mockPredictions = [ { description: 'Paris, France', distanceInMeters: 5000, matchedSubstrings: [], placeId: 'test', textStructure: { mainText: 'Paris', secondaryText: 'France', }, }, ]; describe('usePlacesAutocomplete', () => { const waitForTimeout = async timeoutMs => { jest.advanceTimersByTime(timeoutMs); await flushPromises(); }; const fetchPredictions = () => new Promise(resolve => resolve(mockPredictions)); const mockClient = { fetchPredictions, ready: true, }; const renderHelper = props => renderHook(() => usePlacesAutocomplete({ client: mockClient, // default lodash debounce doesn't work with jest fake timers debounceFn: debounce, ...props, }), ).result; it('should return loading state', async () => { const fetchDelay = 100; const fetchPredictionsFn = async () => { await sleep(fetchDelay); return mockPredictions; }; const client = { fetchPredictions: fetchPredictionsFn, ready: true }; const result = renderHelper({ client }); expect(result.current.loading).toEqual(false); act(() => result.current.updatePredictions('test')); await act(() => waitForTimeout(defaultDebounceMs)); expect(result.current.loading).toEqual(true); await act(() => waitForTimeout(fetchDelay)); expect(result.current.loading).toEqual(false); expect(result.current.predictions).toBe(mockPredictions); }); it('should return predictions data', async () => { const result = renderHelper(); expect(result.current.predictions).toEqual([]); act(() => result.current.updatePredictions('test')); await act(() => waitForTimeout(defaultDebounceMs)); expect(result.current.predictions).toBe(mockPredictions); }); describe('updatePredictions', () => { it('should call fetchPredictions with new value', async () => { const fetchPredictionsFn = jest.fn(fetchPredictions); const client = { fetchPredictions: fetchPredictionsFn, ready: true, }; const result = renderHelper({ client }); act(() => result.current.updatePredictions('test')); await act(() => waitForTimeout(defaultDebounceMs)); expect(fetchPredictionsFn).toHaveBeenCalledWith('test', undefined); }); it('should call fetchPrediction with requestOptions from arguments', async () => { const fetchPredictionsFn = jest.fn(fetchPredictions); const client = { fetchPredictions: fetchPredictionsFn, ready: true, }; const requestOptions = { languageCode: 'he' }; const result = renderHelper({ client }); act(() => result.current.updatePredictions('test', requestOptions)); await act(() => waitForTimeout(defaultDebounceMs)); expect(fetchPredictionsFn).toHaveBeenCalledWith('test', requestOptions); }); it('should call `onError` prop when a fetch error occurs', async () => { const error = new AmbassadorHTTPError(403); const client = { fetchPredictions: () => { throw error; }, ready: true, }; const onError = jest.fn(); const result = renderHelper({ client, onError }); act(() => result.current.updatePredictions('test')); await act(() => waitForTimeout(defaultDebounceMs)); expect(onError).toHaveBeenCalledWith(error); }); }); describe('clearPredictions', () => { it('should clear predictions', async () => { const result = renderHelper(); act(() => result.current.updatePredictions('test')); await act(() => waitForTimeout(defaultDebounceMs)); expect(result.current.predictions).toBe(mockPredictions); act(() => result.current.clearPredictions()); expect(result.current.predictions).toEqual([]); }); }); describe('props', () => { describe('debounceMs', () => { it('should set the debounce timeout for fetching request', async () => { const debounceMs = 100; const fetchPredictionsFn = jest.fn(fetchPredictions); const client = { fetchPredictions: fetchPredictionsFn, ready: true, }; const result = renderHelper({ client, debounceMs }); act(() => result.current.updatePredictions('t')); jest.advanceTimersByTime(10); act(() => result.current.updatePredictions('te')); jest.advanceTimersByTime(10); act(() => result.current.updatePredictions('tes')); jest.advanceTimersByTime(10); act(() => result.current.updatePredictions('test')); await act(() => waitForTimeout(defaultDebounceMs)); act(() => result.current.updatePredictions('blah')); await act(() => waitForTimeout(defaultDebounceMs)); expect(fetchPredictionsFn).toHaveBeenCalledTimes(2); expect(fetchPredictionsFn).toHaveBeenNthCalledWith( 1, 'test', undefined, ); expect(fetchPredictionsFn).toHaveBeenNthCalledWith( 2, 'blah', undefined, ); }); }); }); });