Testing: Use React Testing Library (#27072)

* Add RTL

* Add setupTests.ts

* Refactor DashboardSearch tests
This commit is contained in:
Alex Khomenko
2020-08-20 16:21:42 +03:00
committed by GitHub
parent 3504009914
commit 6b2d44416d
7 changed files with 190 additions and 66 deletions

View File

@@ -1,6 +1,5 @@
import React from 'react';
import { mount } from 'enzyme';
import { act } from 'react-dom/test-utils';
import { render, fireEvent, screen, waitFor, act } from '@testing-library/react';
import { mockSearch } from './mocks';
import { DashboardSearch, Props } from './DashboardSearch';
import { searchResults } from '../testData';
@@ -15,18 +14,13 @@ afterEach(() => {
jest.useRealTimers();
});
const setup = async (testProps?: Partial<Props>): Promise<any> => {
const setup = (testProps?: Partial<Props>) => {
const props: any = {
onCloseSearch: () => {},
...testProps,
};
let wrapper;
//@ts-ignore
await act(async () => {
wrapper = await mount(<DashboardSearch {...props} />);
jest.runAllTimers();
});
return wrapper;
render(<DashboardSearch {...props} />);
jest.runAllTimers();
};
/**
@@ -35,7 +29,9 @@ const setup = async (testProps?: Partial<Props>): Promise<any> => {
*/
describe('DashboardSearch', () => {
it('should call search api with default query when initialised', async () => {
await setup();
setup();
await waitFor(() => screen.getByPlaceholderText('Search dashboards by name'));
expect(mockSearch).toHaveBeenCalledTimes(1);
expect(mockSearch).toHaveBeenCalledWith({
@@ -51,19 +47,13 @@ describe('DashboardSearch', () => {
});
it('should call api with updated query on query change', async () => {
let wrapper = await setup();
//@ts-ignore
await act(async () => {
// @ts-ignore
await wrapper
.find({ placeholder: 'Search dashboards by name' })
.hostNodes()
//@ts-ignore
.prop('onChange')({ currentTarget: { value: 'Test' } });
setup();
const input = await screen.findByPlaceholderText('Search dashboards by name');
await act((async () => {
await fireEvent.input(input, { target: { value: 'Test' } });
jest.runAllTimers();
});
}) as any);
expect(mockSearch).toHaveBeenCalledWith({
query: 'Test',
@@ -78,58 +68,61 @@ describe('DashboardSearch', () => {
});
it("should render 'No results' message when there are no dashboards", async () => {
let wrapper = await setup();
setup();
wrapper.update();
expect(
wrapper
.findWhere((c: any) => c.type() === 'div' && c.text() === 'No dashboards matching your query were found.')
.exists()
).toBe(true);
const message = await screen.findByText('No dashboards matching your query were found.');
expect(message).toBeInTheDocument();
});
it('should render search results', async () => {
//@ts-ignore
mockSearch.mockImplementation(() => Promise.resolve(searchResults));
let wrapper = await setup();
wrapper.update();
expect(wrapper.find({ 'aria-label': 'Search section' })).toHaveLength(2);
expect(wrapper.find({ 'aria-label': 'Search items' }).children()).toHaveLength(2);
mockSearch.mockResolvedValueOnce(searchResults);
setup();
const section = await screen.findAllByLabelText('Search section');
expect(section).toHaveLength(2);
expect(screen.getAllByLabelText('Search items')).toHaveLength(2);
});
it('should call search with selected tags', async () => {
let wrapper = await setup();
setup();
//@ts-ignore
await act(async () => {
//@ts-ignore
await wrapper.find('TagFilter').prop('onChange')(['TestTag']);
jest.runAllTimers();
});
await waitFor(() => screen.getByLabelText('Tag filter'));
// Get the actual element for the underlying Select component, since Select doesn't accept aria- props
const tagComponent = screen.getByLabelText('Tag filter').querySelector('div') as Node;
fireEvent.keyDown(tagComponent, { keyCode: 40 });
expect(mockSearch).toHaveBeenCalledWith({
query: '',
skipRecent: false,
skipStarred: false,
tag: ['TestTag'],
starred: false,
folderIds: [],
layout: SearchLayout.Folders,
sort: undefined,
});
await waitFor(() => screen.getByText('tag1'));
fireEvent.click(screen.getByText('tag1'));
expect(tagComponent).toBeInTheDocument();
await waitFor(() =>
expect(mockSearch).toHaveBeenCalledWith({
query: '',
skipRecent: false,
skipStarred: false,
tag: ['tag1'],
starred: false,
folderIds: [],
layout: SearchLayout.Folders,
sort: undefined,
})
);
});
it('should call search api with provided search params', async () => {
const params = { query: 'test query', tag: ['tag1'], sort: { value: 'asc' } };
await setup({ params });
setup({ params });
expect(mockSearch).toHaveBeenCalledTimes(1);
expect(mockSearch).toHaveBeenCalledWith(
expect.objectContaining({
query: 'test query',
tag: ['tag1'],
sort: 'asc',
})
);
await waitFor(() => {
expect(mockSearch).toHaveBeenCalledTimes(1);
expect(mockSearch).toHaveBeenCalledWith(
expect.objectContaining({
query: 'test query',
tag: ['tag1'],
sort: 'asc',
})
);
});
});
});

View File

@@ -1,12 +1,18 @@
export const mockSearch = jest.fn(() => {
export const mockSearch = jest.fn<any, any>(() => {
return Promise.resolve([]);
});
jest.mock('app/core/services/search_srv', () => {
return {
SearchSrv: jest.fn().mockImplementation(() => {
return {
search: mockSearch,
getDashboardTags: jest.fn(() => Promise.resolve(['Tag1', 'Tag2'])),
getDashboardTags: jest.fn(() =>
Promise.resolve([
{ term: 'tag1', count: 2 },
{ term: 'tag2', count: 10 },
])
),
getSortOptions: jest.fn(() => Promise.resolve({ sortOptions: [{ name: 'test', displayName: 'Test' }] })),
};
}),