-
Notifications
You must be signed in to change notification settings - Fork 264
Expand file tree
/
Copy pathSearchPanelControls.test.jsx
More file actions
125 lines (103 loc) · 4.37 KB
/
SearchPanelControls.test.jsx
File metadata and controls
125 lines (103 loc) · 4.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import { cloneElement } from 'react';
import { render, screen } from '@tests/utils/test-utils';
import userEvent from '@testing-library/user-event';
import { SearchPanelControls } from '../../../src/components/SearchPanelControls';
/**
* Helper function to create a shallow wrapper around AttributionPanel
*/
function createWrapper(props) {
const component = (
<SearchPanelControls
companionWindowId="cw"
windowId="window"
fetchSearch={vi.fn()}
searchService={{ id: 'http://example.com/search' }}
{...props}
/>
);
return { component, ...render(component) };
}
describe('SearchPanelControls', () => {
it('renders a form', () => {
createWrapper();
expect(screen.getByRole('form')).toBeInTheDocument();
});
it('submits a search when an autocomplete suggestion is picked', async () => {
const user = userEvent.setup();
const fetchSearch = vi.fn();
fetch.mockResponse(JSON.stringify({ terms: ['somestring 12345'] }));
createWrapper({
autocompleteService: { id: 'http://example.com/autocomplete' },
fetchSearch,
searchService: { id: 'http://example.com/search', options: { resource: { id: 'abc' } } },
});
await user.click(screen.getByRole('combobox'));
await user.keyboard('somestring');
await user.click(await screen.findByText('somestring 12345'));
expect(fetchSearch).toHaveBeenCalledWith('window', 'cw', 'http://example.com/search?q=somestring+12345', 'somestring 12345');
fetch.resetMocks();
});
it('should fetch result only once', async () => {
const fetchSearch = vi.fn();
const user = userEvent.setup();
createWrapper({
autocompleteService: { id: 'http://example.com/autocomplete' },
fetchSearch,
searchService: { id: 'http://example.com/search', options: { resource: { id: 'abc' } } },
});
await user.click(screen.getByRole('combobox'));
await user.keyboard('somestring');
await user.keyboard('{Enter}');
expect(fetchSearch).toHaveBeenCalledTimes(1);
});
it('renders a text input through the renderInput prop', () => {
createWrapper();
expect(screen.getByRole('combobox')).toHaveAttribute('id', 'search-cw');
});
it('endAdornment is a SearchIcon (with no CircularProgress indicator)', () => {
createWrapper();
expect(screen.getByRole('button').querySelector('svg')).toBeInTheDocument(); // eslint-disable-line testing-library/no-node-access
expect(screen.queryByRole('progressbar')).not.toBeInTheDocument();
});
it('endAdornment has a CircularProgress indicator when there the current search is fetching', () => {
createWrapper({ searchIsFetching: true });
expect(screen.getByRole('progressbar')).toBeInTheDocument();
});
it('form change and submission triggers an action', async () => {
const user = userEvent.setup();
const fetchSearch = vi.fn();
const searchService = {
id: 'http://www.example.com/search',
options: { resource: { id: 'example.com/manifest' } },
};
createWrapper({ fetchSearch, query: 'asdf', searchService });
await user.clear(screen.getByRole('combobox'));
await user.keyboard('yolo');
await user.click(screen.getByRole('button'));
expect(fetchSearch).toHaveBeenCalledWith('window', 'cw', 'http://www.example.com/search?q=yolo', 'yolo');
});
it('does not submit an empty search', async () => {
const user = userEvent.setup();
const fetchSearch = vi.fn();
const searchService = {
id: 'http://www.example.com/search',
options: { resource: { id: 'example.com/manifest' } },
};
createWrapper({ fetchSearch, query: '', searchService });
await user.clear(screen.getByRole('combobox'));
await user.click(screen.getByRole('button', { name: 'Submit search' }));
expect(fetchSearch).not.toHaveBeenCalled();
});
describe('input', () => {
it('has the query prop has the input value on intial render', () => {
createWrapper({ query: 'Wolpertinger' });
expect(screen.getByRole('combobox')).toHaveValue('Wolpertinger');
});
it('clears the local search state/input when the incoming query prop has been cleared', () => {
const { component, rerender } = createWrapper({ query: 'Wolpertinger' });
expect(screen.getByRole('combobox')).toHaveValue('Wolpertinger');
rerender(cloneElement(component, { query: '' }));
expect(screen.getByRole('combobox')).toHaveValue('');
});
});
});