import React from 'react'; import { BrowserRouter as Router } from 'react-router-dom'; import '@testing-library/jest-dom/extend-expect'; import { render, fireEvent, waitForElement } from '../../utils/test-react-testing-library'; import api from '../../utils/api'; import Search from './Search'; /* eslint-disable verdaccio/jsx-spread */ const ComponentToBeRendered: React.FC = () => ( ); describe(' component', () => { beforeEach(() => { jest.resetModules(); jest.resetAllMocks(); jest.spyOn(api, 'request').mockImplementation(() => Promise.resolve([ { name: '@verdaccio/types', version: '8.4.2', }, { name: 'verdaccio', version: '4.3.5', }, ]) ); }); test('should load the component in default state', () => { const { container } = render(); expect(container.firstChild).toMatchSnapshot(); }); test('handleSearch: when user type package name in search component, show suggestions', async () => { const { getByPlaceholderText, getAllByText } = render(); const autoCompleteInput = getByPlaceholderText('Search Packages'); fireEvent.focus(autoCompleteInput); fireEvent.change(autoCompleteInput, { target: { value: 'verdaccio' } }); expect(autoCompleteInput).toHaveAttribute('value', 'verdaccio'); const suggestionsElements = await waitForElement(() => getAllByText('verdaccio', { exact: true })); expect(suggestionsElements).toHaveLength(2); expect(api.request).toHaveBeenCalledTimes(1); }); test('onBlur: should cancel all search requests', async () => { const { getByPlaceholderText, getByRole, getAllByText } = render(); const autoCompleteInput = getByPlaceholderText('Search Packages'); fireEvent.focus(autoCompleteInput); fireEvent.change(autoCompleteInput, { target: { value: 'verdaccio' } }); expect(autoCompleteInput).toHaveAttribute('value', 'verdaccio'); const suggestionsElements = await waitForElement(() => getAllByText('verdaccio', { exact: true })); expect(suggestionsElements).toHaveLength(2); expect(api.request).toHaveBeenCalledTimes(1); fireEvent.blur(autoCompleteInput); const listBoxElement = await waitForElement(() => getByRole('listbox')); expect(listBoxElement).toBeEmpty(); }); test('handleSearch: cancel all search requests when there is no value in search component with type method', async () => { const { getByPlaceholderText, getByRole } = render(); const autoCompleteInput = getByPlaceholderText('Search Packages'); fireEvent.focus(autoCompleteInput); fireEvent.change(autoCompleteInput, { target: { value: ' ', method: 'type' } }); expect(autoCompleteInput).toHaveAttribute('value', ''); const listBoxElement = await waitForElement(() => getByRole('listbox')); expect(listBoxElement).toBeEmpty(); expect(api.request).toHaveBeenCalledTimes(0); }); test('handleSearch: when method is not type method', async () => { const { getByPlaceholderText, getByRole } = render(); const autoCompleteInput = getByPlaceholderText('Search Packages'); fireEvent.focus(autoCompleteInput); fireEvent.change(autoCompleteInput, { target: { value: ' ', method: 'click' } }); expect(autoCompleteInput).toHaveAttribute('value', ''); const listBoxElement = await waitForElement(() => getByRole('listbox')); expect(listBoxElement).toBeEmpty(); expect(api.request).toHaveBeenCalledTimes(0); }); test('handleSearch: loading is been displayed', async () => { const { getByPlaceholderText, getByRole, getByText } = render(); const autoCompleteInput = getByPlaceholderText('Search Packages'); fireEvent.focus(autoCompleteInput); fireEvent.change(autoCompleteInput, { target: { value: 'verdaccio' } }); expect(autoCompleteInput).toHaveAttribute('value', 'verdaccio'); const loadingElement = await waitForElement(() => getByText('Loading...')); expect(loadingElement).toBeTruthy(); }); test('handlePackagesClearRequested: should clear suggestions', async () => { const { getByPlaceholderText, getAllByText, getByRole } = render(); const autoCompleteInput = getByPlaceholderText('Search Packages'); fireEvent.focus(autoCompleteInput); fireEvent.change(autoCompleteInput, { target: { value: 'verdaccio' } }); expect(autoCompleteInput).toHaveAttribute('value', 'verdaccio'); const suggestionsElements = await waitForElement(() => getAllByText('verdaccio', { exact: true })); expect(suggestionsElements).toHaveLength(2); fireEvent.change(autoCompleteInput, { target: { value: ' ' } }); const listBoxElement = await waitForElement(() => getByRole('listbox')); expect(listBoxElement).toBeEmpty(); expect(api.request).toHaveBeenCalledTimes(2); }); test('handleClickSearch: should change the window location on click or return key', async () => { const { getByPlaceholderText, getAllByText, getByRole } = render(); const autoCompleteInput = getByPlaceholderText('Search Packages'); fireEvent.focus(autoCompleteInput); fireEvent.change(autoCompleteInput, { target: { value: 'verdaccio' } }); expect(autoCompleteInput).toHaveAttribute('value', 'verdaccio'); const suggestionsElements = await waitForElement(() => getAllByText('verdaccio', { exact: true })); expect(suggestionsElements).toHaveLength(2); // click on the second suggestion fireEvent.click(suggestionsElements[1]); const listBoxElement = await waitForElement(() => getByRole('listbox')); // when the page redirects, the list box should be empty again expect(listBoxElement).toBeEmpty(); }); });