1 | import React from 'react';
|
2 | import { fireEvent, render, screen } from '@testing-library/react';
|
3 | import user from '@testing-library/user-event';
|
4 | import {
|
5 | Alert,
|
6 | ButtonDropdown,
|
7 | DropdownToggle,
|
8 | DropdownMenu,
|
9 | DropdownItem,
|
10 | UncontrolledAlert,
|
11 | UncontrolledButtonDropdown,
|
12 | UncontrolledDropdown,
|
13 | UncontrolledTooltip,
|
14 | } from '..';
|
15 | import { testForDefaultClass } from '../testUtils';
|
16 | import '@testing-library/jest-dom';
|
17 |
|
18 | describe('UncontrolledAlert', () => {
|
19 | beforeEach(() => {
|
20 | jest.useFakeTimers();
|
21 | });
|
22 |
|
23 | afterEach(() => {
|
24 | jest.clearAllTimers();
|
25 | });
|
26 |
|
27 | it('should be an Alert', () => {
|
28 | testForDefaultClass(Alert, 'alert');
|
29 | });
|
30 |
|
31 | it('should be open by default', () => {
|
32 | render(<UncontrolledAlert>Yo!</UncontrolledAlert>);
|
33 | expect(screen.getByText('Yo!')).toBeInTheDocument();
|
34 | });
|
35 |
|
36 | it('should toggle when close is clicked', async () => {
|
37 | render(<UncontrolledAlert>Yo!</UncontrolledAlert>);
|
38 | await user.click(screen.getByLabelText('Close'));
|
39 | jest.advanceTimersByTime(1000);
|
40 | expect(screen.queryByText('Yo!')).not.toBeInTheDocument();
|
41 | });
|
42 | });
|
43 |
|
44 | describe('UncontrolledButtonDropdown', () => {
|
45 | beforeEach(() => {
|
46 | jest.useFakeTimers();
|
47 | });
|
48 |
|
49 | afterEach(() => {
|
50 | jest.clearAllTimers();
|
51 | });
|
52 |
|
53 | it('should be an ButtonDropdown', () => {
|
54 | testForDefaultClass(ButtonDropdown, 'btn-group');
|
55 | });
|
56 |
|
57 | it('should be open by default', () => {
|
58 | render(<UncontrolledButtonDropdown>Yo!</UncontrolledButtonDropdown>);
|
59 | expect(screen.getByText('Yo!')).toBeInTheDocument();
|
60 | });
|
61 |
|
62 | it('should toggle isOpen when toggle is called', async () => {
|
63 | render(
|
64 | <UncontrolledButtonDropdown>
|
65 | <DropdownToggle caret>Dropdown</DropdownToggle>
|
66 | <DropdownMenu>
|
67 | <DropdownItem header>Header</DropdownItem>
|
68 | </DropdownMenu>
|
69 | </UncontrolledButtonDropdown>,
|
70 | );
|
71 |
|
72 | await user.click(screen.getByText('Dropdown'));
|
73 | jest.advanceTimersByTime(1000);
|
74 | expect(screen.getByRole('menu')).toHaveClass('show');
|
75 | });
|
76 | });
|
77 |
|
78 | describe('UncontrolledDropdown', () => {
|
79 | beforeEach(() => {
|
80 | jest.useFakeTimers();
|
81 | });
|
82 |
|
83 | afterEach(() => {
|
84 | jest.clearAllTimers();
|
85 | });
|
86 |
|
87 | it('should be an Dropdown', () => {
|
88 | testForDefaultClass(UncontrolledDropdown, 'dropdown');
|
89 | });
|
90 |
|
91 | it('should be closed by default', () => {
|
92 | render(
|
93 | <UncontrolledDropdown>
|
94 | <DropdownToggle caret>Dropdown</DropdownToggle>
|
95 | <DropdownMenu data-testid="sandman">
|
96 | <DropdownItem header>Header</DropdownItem>
|
97 | </DropdownMenu>
|
98 | </UncontrolledDropdown>,
|
99 | );
|
100 |
|
101 | expect(screen.getByTestId('sandman')).not.toHaveClass('show');
|
102 | });
|
103 |
|
104 | it('should toggle on button click', async () => {
|
105 | render(
|
106 | <UncontrolledDropdown>
|
107 | <DropdownToggle caret>Dropdown</DropdownToggle>
|
108 | <DropdownMenu data-testid="sandman">
|
109 | <DropdownItem header>Header</DropdownItem>
|
110 | </DropdownMenu>
|
111 | </UncontrolledDropdown>,
|
112 | );
|
113 |
|
114 | expect(screen.getByTestId('sandman')).not.toHaveClass('show');
|
115 | await user.click(screen.getByText('Dropdown'));
|
116 | jest.advanceTimersByTime(1000);
|
117 | expect(screen.getByTestId('sandman')).toHaveClass('show');
|
118 | });
|
119 |
|
120 | describe('onToggle', () => {
|
121 | beforeEach(() => {
|
122 | jest.useFakeTimers();
|
123 | });
|
124 |
|
125 | afterEach(() => {
|
126 |
|
127 |
|
128 | jest.clearAllTimers();
|
129 | });
|
130 |
|
131 | it('should be closed on document body click', async () => {
|
132 | render(
|
133 | <UncontrolledDropdown defaultOpen>
|
134 | <DropdownToggle id="toggle">Toggle</DropdownToggle>
|
135 | <DropdownMenu data-testid="sandman">
|
136 | <DropdownItem>Test</DropdownItem>
|
137 | <DropdownItem id="divider" divider />
|
138 | </DropdownMenu>
|
139 | </UncontrolledDropdown>,
|
140 | );
|
141 |
|
142 | expect(screen.getByTestId('sandman')).toHaveClass('show');
|
143 | await user.click(document.body);
|
144 | jest.advanceTimersByTime(1000);
|
145 | expect(screen.getByTestId('sandman')).not.toHaveClass('show');
|
146 | });
|
147 |
|
148 | it('should be closed on container click', async () => {
|
149 | const { container } = render(
|
150 | <UncontrolledDropdown id="test" defaultOpen>
|
151 | <DropdownToggle id="toggle">Toggle</DropdownToggle>
|
152 | <DropdownMenu data-testid="dream">
|
153 | <DropdownItem>Test</DropdownItem>
|
154 | <DropdownItem id="divider" divider />
|
155 | </DropdownMenu>
|
156 | </UncontrolledDropdown>,
|
157 | );
|
158 |
|
159 | expect(screen.getByTestId('dream')).toHaveClass('show');
|
160 | await user.click(container);
|
161 | jest.advanceTimersByTime(1000);
|
162 | expect(screen.getByTestId('dream')).not.toHaveClass('show');
|
163 | });
|
164 |
|
165 | it('should toggle when toggle button is clicked', async () => {
|
166 | render(
|
167 | <UncontrolledDropdown id="test" defaultOpen={false}>
|
168 | <DropdownToggle id="toggle">Toggle</DropdownToggle>
|
169 | <DropdownMenu data-testid="lucien">
|
170 | <DropdownItem>Test</DropdownItem>
|
171 | <DropdownItem id="divider" divider />
|
172 | </DropdownMenu>
|
173 | </UncontrolledDropdown>,
|
174 | );
|
175 |
|
176 | expect(screen.getByTestId('lucien')).not.toHaveClass('show');
|
177 | await user.click(screen.getByText('Toggle'));
|
178 |
|
179 | jest.advanceTimersByTime(1000);
|
180 | expect(screen.getByTestId('lucien')).toHaveClass('show');
|
181 | });
|
182 |
|
183 | it('onToggle should be called on toggler click when opened', async () => {
|
184 | render(
|
185 | <UncontrolledDropdown id="test" defaultOpen>
|
186 | <DropdownToggle id="toggle">Toggle</DropdownToggle>
|
187 | <DropdownMenu data-testid="lucien">
|
188 | <DropdownItem>Test</DropdownItem>
|
189 | <DropdownItem id="divider" divider />
|
190 | </DropdownMenu>
|
191 | </UncontrolledDropdown>,
|
192 | );
|
193 |
|
194 | expect(screen.getByTestId('lucien')).toHaveClass('show');
|
195 | await user.click(screen.getByText('Toggle'));
|
196 |
|
197 | jest.advanceTimersByTime(1000);
|
198 | expect(screen.getByTestId('lucien')).not.toHaveClass('show');
|
199 | });
|
200 |
|
201 | it('onToggle should be called on key closing', async () => {
|
202 | const handleToggle = jest.fn();
|
203 | render(
|
204 | <UncontrolledDropdown id="test" onToggle={handleToggle} defaultOpen>
|
205 | <DropdownToggle id="toggle">Toggle</DropdownToggle>
|
206 | <DropdownMenu>
|
207 | <DropdownItem>Test</DropdownItem>
|
208 | <DropdownItem id="divider" divider />
|
209 | </DropdownMenu>
|
210 | </UncontrolledDropdown>,
|
211 | );
|
212 |
|
213 | screen.getByText('Toggle').focus();
|
214 | expect(handleToggle.mock.calls.length).toBe(0);
|
215 |
|
216 | await user.keyboard('{esc}');
|
217 | expect(handleToggle.mock.calls.length).toBe(1);
|
218 | });
|
219 |
|
220 | it('onToggle should be called on key opening', async () => {
|
221 | const handleToggle = jest.fn();
|
222 | render(
|
223 | <UncontrolledDropdown
|
224 | id="test"
|
225 | onToggle={handleToggle}
|
226 | defaultOpen={false}
|
227 | >
|
228 | <DropdownToggle id="toggle">Toggle</DropdownToggle>
|
229 | <DropdownMenu>
|
230 | <DropdownItem>Test</DropdownItem>
|
231 | <DropdownItem id="divider" divider />
|
232 | </DropdownMenu>
|
233 | </UncontrolledDropdown>,
|
234 | );
|
235 |
|
236 | screen.getByText('Toggle').focus();
|
237 | expect(handleToggle.mock.calls.length).toBe(0);
|
238 |
|
239 | await user.keyboard('[ArrowDown]');
|
240 | expect(handleToggle.mock.calls.length).toBe(1);
|
241 | });
|
242 | });
|
243 | });
|
244 |
|
245 | describe('UncontrolledTooltip', () => {
|
246 | it('tooltip should not be rendered by default', async () => {
|
247 | render(
|
248 | <div>
|
249 | <span href="#" id="dream">
|
250 | sandman
|
251 | </span>
|
252 | <UncontrolledTooltip target="dream">
|
253 | king of dream world
|
254 | </UncontrolledTooltip>
|
255 | </div>,
|
256 | );
|
257 | expect(screen.queryByText('king of dream world')).not.toBeInTheDocument();
|
258 | });
|
259 |
|
260 | it('tooltip should not be rendered on hover', async () => {
|
261 | render(
|
262 | <div>
|
263 | <span href="#" id="dream">
|
264 | sandman
|
265 | </span>
|
266 | <UncontrolledTooltip target="dream">
|
267 | king of dream world
|
268 | </UncontrolledTooltip>
|
269 | </div>,
|
270 | );
|
271 |
|
272 | await fireEvent.mouseOver(screen.getByText('sandman'));
|
273 | jest.advanceTimersByTime(1000);
|
274 | expect(screen.getByText('king of dream world')).toBeInTheDocument();
|
275 | });
|
276 |
|
277 | it('should render correctly with a ref object as the target', async () => {
|
278 | const target = React.createRef(null);
|
279 | render(
|
280 | <div>
|
281 | <span href="#" ref={target}>
|
282 | sandman
|
283 | </span>
|
284 | <UncontrolledTooltip target={target}>
|
285 | king of dream world
|
286 | </UncontrolledTooltip>
|
287 | </div>,
|
288 | );
|
289 |
|
290 | await fireEvent.mouseOver(screen.getByText('sandman'));
|
291 | jest.advanceTimersByTime(1000);
|
292 |
|
293 | expect(screen.queryByText('king of dream world')).toBeInTheDocument();
|
294 | });
|
295 | });
|