2019-06-20 19:37:28 +07:00
|
|
|
import React from 'react';
|
2019-12-04 23:09:02 +07:00
|
|
|
import { BrowserRouter as Router } from 'react-router-dom';
|
|
|
|
import '@testing-library/jest-dom/extend-expect';
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
import { render, fireEvent, waitForElement } from '../../utils/test-react-testing-library';
|
|
|
|
import api from '../../utils/api';
|
2019-11-23 19:41:14 +07:00
|
|
|
|
2019-06-20 19:37:28 +07:00
|
|
|
import Search from './Search';
|
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
/* eslint-disable verdaccio/jsx-spread */
|
|
|
|
const ComponentToBeRendered: React.FC = () => (
|
|
|
|
<Router>
|
|
|
|
<Search />
|
|
|
|
</Router>
|
|
|
|
);
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
describe('<Search /> component', () => {
|
2019-06-20 19:37:28 +07:00
|
|
|
beforeEach(() => {
|
2019-12-04 23:09:02 +07:00
|
|
|
jest.resetModules();
|
|
|
|
jest.resetAllMocks();
|
|
|
|
jest.spyOn(api, 'request').mockImplementation(() =>
|
|
|
|
Promise.resolve([
|
|
|
|
{
|
|
|
|
name: '@verdaccio/types',
|
|
|
|
version: '8.4.2',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: 'verdaccio',
|
|
|
|
version: '4.3.5',
|
|
|
|
},
|
|
|
|
])
|
2019-06-20 19:37:28 +07:00
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should load the component in default state', () => {
|
2019-12-04 23:09:02 +07:00
|
|
|
const { container } = render(<ComponentToBeRendered />);
|
|
|
|
expect(container.firstChild).toMatchSnapshot();
|
2019-06-20 19:37:28 +07:00
|
|
|
});
|
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
test('handleSearch: when user type package name in search component, show suggestions', async () => {
|
|
|
|
const { getByPlaceholderText, getAllByText } = render(<ComponentToBeRendered />);
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
const autoCompleteInput = getByPlaceholderText('Search Packages');
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
fireEvent.focus(autoCompleteInput);
|
|
|
|
fireEvent.change(autoCompleteInput, { target: { value: 'verdaccio' } });
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
expect(autoCompleteInput).toHaveAttribute('value', 'verdaccio');
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
const suggestionsElements = await waitForElement(() => getAllByText('verdaccio', { exact: true }));
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
expect(suggestionsElements).toHaveLength(2);
|
|
|
|
expect(api.request).toHaveBeenCalledTimes(1);
|
2019-06-20 19:37:28 +07:00
|
|
|
});
|
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
test('onBlur: should cancel all search requests', async () => {
|
|
|
|
const { getByPlaceholderText, getByRole, getAllByText } = render(<ComponentToBeRendered />);
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
const autoCompleteInput = getByPlaceholderText('Search Packages');
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
fireEvent.focus(autoCompleteInput);
|
|
|
|
fireEvent.change(autoCompleteInput, { target: { value: 'verdaccio' } });
|
|
|
|
expect(autoCompleteInput).toHaveAttribute('value', 'verdaccio');
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
const suggestionsElements = await waitForElement(() => getAllByText('verdaccio', { exact: true }));
|
|
|
|
expect(suggestionsElements).toHaveLength(2);
|
|
|
|
expect(api.request).toHaveBeenCalledTimes(1);
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
fireEvent.blur(autoCompleteInput);
|
|
|
|
const listBoxElement = await waitForElement(() => getByRole('listbox'));
|
|
|
|
expect(listBoxElement).toBeEmpty();
|
2019-06-20 19:37:28 +07:00
|
|
|
});
|
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
test('handleSearch: cancel all search requests when there is no value in search component with type method', async () => {
|
|
|
|
const { getByPlaceholderText, getByRole } = render(<ComponentToBeRendered />);
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
const autoCompleteInput = getByPlaceholderText('Search Packages');
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
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);
|
2019-06-20 19:37:28 +07:00
|
|
|
});
|
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
test('handleSearch: when method is not type method', async () => {
|
|
|
|
const { getByPlaceholderText, getByRole } = render(<ComponentToBeRendered />);
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
const autoCompleteInput = getByPlaceholderText('Search Packages');
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
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);
|
2019-06-20 19:37:28 +07:00
|
|
|
});
|
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
test('handleSearch: loading is been displayed', async () => {
|
|
|
|
const { getByPlaceholderText, getByRole, getByText } = render(<ComponentToBeRendered />);
|
|
|
|
const autoCompleteInput = getByPlaceholderText('Search Packages');
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
fireEvent.focus(autoCompleteInput);
|
|
|
|
fireEvent.change(autoCompleteInput, { target: { value: 'verdaccio' } });
|
|
|
|
expect(autoCompleteInput).toHaveAttribute('value', 'verdaccio');
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
const loadingElement = await waitForElement(() => getByText('Loading...'));
|
|
|
|
expect(loadingElement).toBeTruthy();
|
|
|
|
});
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
test('handlePackagesClearRequested: should clear suggestions', async () => {
|
|
|
|
const { getByPlaceholderText, getAllByText, getByRole } = render(<ComponentToBeRendered />);
|
|
|
|
const autoCompleteInput = getByPlaceholderText('Search Packages');
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
fireEvent.focus(autoCompleteInput);
|
|
|
|
fireEvent.change(autoCompleteInput, { target: { value: 'verdaccio' } });
|
|
|
|
expect(autoCompleteInput).toHaveAttribute('value', 'verdaccio');
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
const suggestionsElements = await waitForElement(() => getAllByText('verdaccio', { exact: true }));
|
|
|
|
expect(suggestionsElements).toHaveLength(2);
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
fireEvent.change(autoCompleteInput, { target: { value: ' ' } });
|
|
|
|
const listBoxElement = await waitForElement(() => getByRole('listbox'));
|
|
|
|
expect(listBoxElement).toBeEmpty();
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
expect(api.request).toHaveBeenCalledTimes(2);
|
|
|
|
});
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
test('handleClickSearch: should change the window location on click or return key', async () => {
|
|
|
|
const { getByPlaceholderText, getAllByText, getByRole } = render(<ComponentToBeRendered />);
|
|
|
|
const autoCompleteInput = getByPlaceholderText('Search Packages');
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
fireEvent.focus(autoCompleteInput);
|
|
|
|
fireEvent.change(autoCompleteInput, { target: { value: 'verdaccio' } });
|
|
|
|
expect(autoCompleteInput).toHaveAttribute('value', 'verdaccio');
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
const suggestionsElements = await waitForElement(() => getAllByText('verdaccio', { exact: true }));
|
|
|
|
expect(suggestionsElements).toHaveLength(2);
|
2019-06-20 19:37:28 +07:00
|
|
|
|
2019-12-04 23:09:02 +07:00
|
|
|
// 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();
|
2019-06-20 19:37:28 +07:00
|
|
|
});
|
|
|
|
});
|