import React from 'react'; import { render, fireEvent, screen, waitForElementToBeRemoved, queryByRole, queryAllByRole, } from '@testing-library/react'; import '@testing-library/jest-dom/extend-expect'; import { doc } from 'prettier'; import DataListInput from '../../src/DataListInput'; const defaultProps = { placeholder: '', match: undefined, inputClassName: '', dropdownClassName: '', itemClassName: '', activeItemClassName: '', requiredInputLength: 0, clearInputOnSelect: false, suppressReselect: true, dropDownLength: Infinity, initialValue: '', debounceTime: 0, debounceLoader: undefined, onDropdownOpen: () => {}, onDropdownClose: () => {}, onInput: () => {}, }; const data = [ { key: '0', label: 'Apple', }, { key: '1', label: 'Mango', }, { key: '2', label: 'Potatoe', }, { key: '3', label: 'Pear', }, { key: '4', label: 'Peach', }, { key: '5', label: 'Cherry', }, { key: '6', label: 'Grapes', }, { key: '7', label: 'Watermelon', }, { key: '8', label: 'Lime', }, { key: '9', label: 'Peumo', }, ]; const placeholder = 'Type something in here...'; const customMatch = (currentInput, item) => item.label.toLowerCase().includes(currentInput); const handleSelect = jest.fn(); const onDropdownOpen = jest.fn(); const onDropdownClose = jest.fn(); const onInput = jest.fn(); describe('DataListInput', async () => { afterEach(() => { jest.clearAllMocks(); }); test('renders without errors and sets default props correctly', () => { render(); const datalistInput = screen.getByRole('textbox'); expect(datalistInput).toHaveTextContent(defaultProps.initialValue); expect(datalistInput).toHaveAttribute( 'placeholder', defaultProps.placeholder ); expect(datalistInput).toHaveAttribute('type', 'text'); }); test('renders input field with placeholder', () => { render( ); const datalistInput = screen.getByRole('textbox'); expect(datalistInput).toHaveAttribute('placeholder', placeholder); }); test('renders right items into dropdown with default match function', async () => { render( ); const datalistInput = screen.getByRole('textbox'); fireEvent.click(datalistInput); const items = await screen.getAllByRole('button'); expect(items.length).toBe(data.length); fireEvent.change(datalistInput, { target: { value: 'Pe' } }); const matchingItems = await screen.getAllByRole('button'); expect(matchingItems.length).toBe(3); }); test('renders only dropDownLength items', async () => { render( ); const datalistInput = screen.getByRole('textbox'); fireEvent.click(datalistInput); const items = await screen.getAllByRole('button'); expect(items.length).toBe(2); fireEvent.change(datalistInput, { target: { value: 'Pe' } }); const matchingItems = await screen.getAllByRole('button'); expect(matchingItems.length).toBe(2); }); test('renders only if requiredInputLength reached', async () => { render( ); const datalistInput = screen.getByRole('textbox'); fireEvent.click(datalistInput); const items = await screen.queryAllByRole('button'); expect(items.length).toBe(0); fireEvent.change(datalistInput, { target: { value: 'Pe' } }); const matchingButInvisible = await screen.queryAllByRole('button'); expect(matchingButInvisible.length).toBe(0); fireEvent.change(datalistInput, { target: { value: 'Pea' } }); const matchingItems = await screen.getAllByRole('button'); expect(matchingItems.length).toBe(2); }); test('renders matching items with initialValue', async () => { render( ); const datalistInput = screen.getByRole('textbox'); fireEvent.click(datalistInput); const items = await screen.getAllByRole('button'); expect(items.length).toBe(data.length); }); test('renders matching items with custom matching func', async () => { render( ); const datalistInput = screen.getByRole('textbox'); fireEvent.click(datalistInput); const items = await screen.getAllByRole('button'); expect(items.length).toBe(data.length); fireEvent.change(datalistInput, { target: { value: 'ap' } }); const matchingItems = await screen.getAllByRole('button'); expect(matchingItems.length).toBe(2); }); test('calls lifecycle functions correctly', async () => { render( ); expect(handleSelect).toBeCalledTimes(0); expect(onDropdownOpen).toBeCalledTimes(0); expect(onDropdownClose).toBeCalledTimes(0); expect(onInput).toBeCalledTimes(0); const datalistInput = screen.getByRole('textbox'); fireEvent.click(datalistInput); await screen.getAllByRole('button'); expect(handleSelect).toBeCalledTimes(0); expect(onDropdownOpen).toBeCalledTimes(1); expect(onDropdownClose).toBeCalledTimes(0); expect(onInput).toBeCalledTimes(0); fireEvent.change(datalistInput, { target: { value: 'Apple' } }); const appleItem = await screen.getByRole('button'); expect(handleSelect).toBeCalledTimes(0); expect(onDropdownOpen).toBeCalledTimes(1); expect(onDropdownClose).toBeCalledTimes(0); expect(onInput).toBeCalledTimes(1); fireEvent.click(appleItem); expect(handleSelect).toBeCalledTimes(1); expect(onDropdownOpen).toBeCalledTimes(1); expect(onDropdownClose).toBeCalledTimes(1); expect(onInput).toBeCalledTimes(1); }); test('click outside menu closes menu', async () => { render( ); expect(onDropdownClose).toBeCalledTimes(0); const datalistInput = screen.getByRole('textbox'); fireEvent.click(datalistInput); await screen.getAllByRole('button'); expect(onDropdownClose).toBeCalledTimes(0); fireEvent.change(datalistInput, { target: { value: 'Pe' } }); const matchingItems = await screen.getAllByRole('button'); expect(matchingItems.length).toBe(3); expect(onDropdownClose).toBeCalledTimes(0); fireEvent.click(document.body); expect(onDropdownClose).toBeCalledTimes(1); expect(screen.queryAllByRole('button')).toEqual([]); }); test('renders the same html based on the same inputs', async () => { render( ); expect(document.body).toMatchSnapshot(); const datalistInput = screen.getByRole('textbox'); fireEvent.click(datalistInput); await screen.getAllByRole('button'); expect(document.body).toMatchSnapshot(); fireEvent.change(datalistInput, { target: { value: 'Pe' } }); await screen.getAllByRole('button'); expect(document.body).toMatchSnapshot(); fireEvent.click(document.body); expect(document.body).toMatchSnapshot(); fireEvent.click(datalistInput); const items = await screen.getAllByRole('button'); fireEvent.click(items[0]); expect(document.body).toMatchSnapshot(); fireEvent.click(datalistInput); await screen.getAllByRole('button'); expect(document.body).toMatchSnapshot(); }); });