Skip to content

Commit cc3b839

Browse files
committed
test: add test cases for keyboard operations
1 parent 751e850 commit cc3b839

File tree

4 files changed

+181
-103
lines changed

4 files changed

+181
-103
lines changed

examples/mutiple-with-maxCount.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,20 +46,31 @@ export default () => {
4646
multiple
4747
maxCount={3}
4848
treeData={treeData}
49-
onChange={onChange}
50-
value={value}
49+
// onChange={onChange}
50+
// value={value}
5151
/>
5252

5353
<h2>checkable with maxCount</h2>
5454
<TreeSelect
5555
style={{ width: 300 }}
5656
multiple
5757
treeCheckable
58+
treeCheckStrictly
5859
maxCount={3}
5960
treeData={treeData}
6061
onChange={onChange}
6162
value={value}
6263
/>
64+
<TreeSelect
65+
style={{ width: 300 }}
66+
treeData={[
67+
{ key: '0', value: '0', title: '0 label' },
68+
{ key: '1', value: '1', title: '1 label' },
69+
{ key: '2', value: '2', title: '2 label' },
70+
]}
71+
multiple
72+
maxCount={2}
73+
/>
6374
</>
6475
);
6576
};

tests/Select.maxCount.spec.tsx

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import { render, fireEvent, within } from '@testing-library/react';
2+
import KeyCode from 'rc-util/lib/KeyCode';
3+
import { keyDown, keyUp } from './util';
4+
import React from 'react';
5+
import TreeSelect from '../src';
6+
7+
describe('TreeSelect.maxCount', () => {
8+
const treeData = [
9+
{ key: '0', value: '0', title: '0 label' },
10+
{ key: '1', value: '1', title: '1 label' },
11+
{ key: '2', value: '2', title: '2 label' },
12+
{ key: '3', value: '3', title: '3 label' },
13+
];
14+
15+
const renderTreeSelect = (props?: any) => {
16+
return render(<TreeSelect multiple maxCount={2} treeData={treeData} open {...props} />);
17+
};
18+
19+
const selectOptions = (container, optionTexts) => {
20+
const dropdownList = container.querySelector('.rc-tree-select-dropdown');
21+
optionTexts.forEach(text => {
22+
fireEvent.click(within(dropdownList).getByText(text));
23+
});
24+
};
25+
26+
it('should disable unselected options when selection reaches maxCount', () => {
27+
const { container } = renderTreeSelect();
28+
29+
selectOptions(container, ['0 label', '1 label']);
30+
31+
// Check if third and fourth options are disabled
32+
const dropdownList = container.querySelector('.rc-tree-select-dropdown') as HTMLElement;
33+
const option3 = within(dropdownList).getByText('2 label');
34+
const option4 = within(dropdownList).getByText('3 label');
35+
36+
expect(option3.closest('div')).toHaveClass('rc-tree-select-tree-treenode-disabled');
37+
expect(option4.closest('div')).toHaveClass('rc-tree-select-tree-treenode-disabled');
38+
});
39+
40+
it('should allow deselecting options after reaching maxCount', () => {
41+
const { container } = renderTreeSelect();
42+
const dropdownList = container.querySelector('.rc-tree-select-dropdown') as HTMLElement;
43+
44+
selectOptions(container, ['0 label', '1 label']);
45+
46+
// Try selecting third option, should be disabled
47+
const option3 = within(dropdownList).getByText('2 label');
48+
fireEvent.click(option3);
49+
expect(option3.closest('div')).toHaveClass('rc-tree-select-tree-treenode-disabled');
50+
51+
// Deselect first option
52+
fireEvent.click(within(dropdownList).getByText('0 label'));
53+
expect(within(dropdownList).queryByText('0 label')).toBeInTheDocument();
54+
55+
// Now should be able to select third option
56+
fireEvent.click(option3);
57+
expect(option3.closest('div')).not.toHaveClass('rc-tree-select-tree-treenode-disabled');
58+
});
59+
60+
it('should not trigger onChange when trying to select beyond maxCount', () => {
61+
const handleChange = jest.fn();
62+
const { container } = renderTreeSelect({ onChange: handleChange });
63+
64+
selectOptions(container, ['0 label', '1 label']);
65+
expect(handleChange).toHaveBeenCalledTimes(2);
66+
67+
// Try selecting third option
68+
const dropdownList = container.querySelector('.rc-tree-select-dropdown') as HTMLElement;
69+
fireEvent.click(within(dropdownList).getByText('2 label'));
70+
expect(handleChange).toHaveBeenCalledTimes(2); // Should not increase
71+
});
72+
73+
it('should not affect deselection operations when maxCount is reached', () => {
74+
const handleChange = jest.fn();
75+
const { container } = renderTreeSelect({ onChange: handleChange });
76+
77+
selectOptions(container, ['0 label', '1 label']);
78+
expect(handleChange).toHaveBeenCalledTimes(2);
79+
80+
// Deselect first option
81+
const dropdownList = container.querySelector('.rc-tree-select-dropdown') as HTMLElement;
82+
fireEvent.click(within(dropdownList).getByText('0 label'));
83+
expect(handleChange).toHaveBeenCalledTimes(3);
84+
85+
// Should be able to select third option
86+
fireEvent.click(within(dropdownList).getByText('2 label'));
87+
expect(handleChange).toHaveBeenCalledTimes(4);
88+
});
89+
90+
it('should not allow any selection when maxCount is 0', () => {
91+
const handleChange = jest.fn();
92+
const { container } = renderTreeSelect({ maxCount: 0, onChange: handleChange });
93+
94+
selectOptions(container, ['0 label', '1 label']);
95+
expect(handleChange).not.toHaveBeenCalled();
96+
});
97+
98+
it('should not limit selection when maxCount is greater than number of options', () => {
99+
const handleChange = jest.fn();
100+
const { container } = renderTreeSelect({ maxCount: 5, onChange: handleChange });
101+
102+
selectOptions(container, ['0 label', '1 label', '2 label', '3 label']);
103+
expect(handleChange).toHaveBeenCalledTimes(4);
104+
});
105+
});
106+
107+
describe('TreeSelect.maxCount keyboard operations', () => {
108+
const treeData = [
109+
{ key: '0', value: '0', title: '0 label' },
110+
{ key: '1', value: '1', title: '1 label' },
111+
{ key: '2', value: '2', title: '2 label' },
112+
];
113+
114+
it('keyboard operations should not exceed maxCount limit', () => {
115+
const onSelect = jest.fn();
116+
const { container } = render(
117+
<TreeSelect treeData={treeData} multiple open maxCount={2} onSelect={onSelect} />,
118+
);
119+
120+
const input = container.querySelector('input');
121+
122+
keyDown(input, KeyCode.ENTER);
123+
keyUp(input, KeyCode.ENTER);
124+
125+
expect(onSelect).toHaveBeenCalledWith('0', expect.anything());
126+
127+
keyDown(input, KeyCode.DOWN);
128+
keyDown(input, KeyCode.ENTER);
129+
keyUp(input, KeyCode.ENTER);
130+
131+
expect(onSelect).toHaveBeenCalledWith('1', expect.anything());
132+
133+
keyDown(input, KeyCode.DOWN);
134+
keyDown(input, KeyCode.ENTER);
135+
keyUp(input, KeyCode.ENTER);
136+
137+
expect(onSelect).toHaveBeenCalledTimes(2);
138+
});
139+
140+
it('when maxCount is reached, the option should be disabled', () => {
141+
const { container } = render(
142+
<TreeSelect
143+
treeData={treeData}
144+
multiple
145+
open
146+
treeDefaultExpandAll
147+
maxCount={2}
148+
value={['0', '1']}
149+
/>,
150+
);
151+
152+
// verify that the third option is disabled
153+
expect(container.querySelector('.rc-tree-select-tree-treenode-disabled')?.textContent).toBe(
154+
'2 label',
155+
);
156+
});
157+
});

tests/Select.multiple.spec.js

Lines changed: 0 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -354,104 +354,4 @@ describe('TreeSelect.multiple', () => {
354354
expect(placeholder).toBeTruthy();
355355
expect(placeholder.textContent).toBe('Fake placeholder');
356356
});
357-
358-
describe('TreeSelect.maxCount', () => {
359-
const treeData = [
360-
{ key: '0', value: '0', title: '0 label' },
361-
{ key: '1', value: '1', title: '1 label' },
362-
{ key: '2', value: '2', title: '2 label' },
363-
{ key: '3', value: '3', title: '3 label' },
364-
];
365-
366-
const renderTreeSelect = props => {
367-
return render(<TreeSelect multiple maxCount={2} treeData={treeData} open {...props} />);
368-
};
369-
370-
const selectOptions = (container, optionTexts) => {
371-
const dropdownList = container.querySelector('.rc-tree-select-dropdown');
372-
optionTexts.forEach(text => {
373-
fireEvent.click(within(dropdownList).getByText(text));
374-
});
375-
};
376-
377-
it('should disable unselected options when selection reaches maxCount', () => {
378-
const { container } = renderTreeSelect();
379-
380-
selectOptions(container, ['0 label', '1 label']);
381-
382-
// Check if third and fourth options are disabled
383-
const dropdownList = container.querySelector('.rc-tree-select-dropdown');
384-
const option3 = within(dropdownList).getByText('2 label');
385-
const option4 = within(dropdownList).getByText('3 label');
386-
387-
expect(option3.closest('div')).toHaveClass('rc-tree-select-tree-treenode-disabled');
388-
expect(option4.closest('div')).toHaveClass('rc-tree-select-tree-treenode-disabled');
389-
});
390-
391-
it('should allow deselecting options after reaching maxCount', () => {
392-
const { container } = renderTreeSelect();
393-
const dropdownList = container.querySelector('.rc-tree-select-dropdown');
394-
395-
selectOptions(container, ['0 label', '1 label']);
396-
397-
// Try selecting third option, should be disabled
398-
const option3 = within(dropdownList).getByText('2 label');
399-
fireEvent.click(option3);
400-
expect(option3.closest('div')).toHaveClass('rc-tree-select-tree-treenode-disabled');
401-
402-
// Deselect first option
403-
fireEvent.click(within(dropdownList).getByText('0 label'));
404-
expect(within(dropdownList).queryByText('0 label')).toBeInTheDocument();
405-
406-
// Now should be able to select third option
407-
fireEvent.click(option3);
408-
expect(option3.closest('div')).not.toHaveClass('rc-tree-select-tree-treenode-disabled');
409-
});
410-
411-
it('should not trigger onChange when trying to select beyond maxCount', () => {
412-
const handleChange = jest.fn();
413-
const { container } = renderTreeSelect({ onChange: handleChange });
414-
415-
selectOptions(container, ['0 label', '1 label']);
416-
expect(handleChange).toHaveBeenCalledTimes(2);
417-
418-
// Try selecting third option
419-
const dropdownList = container.querySelector('.rc-tree-select-dropdown');
420-
fireEvent.click(within(dropdownList).getByText('2 label'));
421-
expect(handleChange).toHaveBeenCalledTimes(2); // Should not increase
422-
});
423-
424-
it('should not affect deselection operations when maxCount is reached', () => {
425-
const handleChange = jest.fn();
426-
const { container } = renderTreeSelect({ onChange: handleChange });
427-
428-
selectOptions(container, ['0 label', '1 label']);
429-
expect(handleChange).toHaveBeenCalledTimes(2);
430-
431-
// Deselect first option
432-
const dropdownList = container.querySelector('.rc-tree-select-dropdown');
433-
fireEvent.click(within(dropdownList).getByText('0 label'));
434-
expect(handleChange).toHaveBeenCalledTimes(3);
435-
436-
// Should be able to select third option
437-
fireEvent.click(within(dropdownList).getByText('2 label'));
438-
expect(handleChange).toHaveBeenCalledTimes(4);
439-
});
440-
441-
it('should not allow any selection when maxCount is 0', () => {
442-
const handleChange = jest.fn();
443-
const { container } = renderTreeSelect({ maxCount: 0, onChange: handleChange });
444-
445-
selectOptions(container, ['0 label', '1 label']);
446-
expect(handleChange).not.toHaveBeenCalled();
447-
});
448-
449-
it('should not limit selection when maxCount is greater than number of options', () => {
450-
const handleChange = jest.fn();
451-
const { container } = renderTreeSelect({ maxCount: 5, onChange: handleChange });
452-
453-
selectOptions(container, ['0 label', '1 label', '2 label', '3 label']);
454-
expect(handleChange).toHaveBeenCalledTimes(4);
455-
});
456-
});
457357
});

tests/util.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
1-
import { fireEvent } from '@testing-library/react';
1+
import { fireEvent, createEvent } from '@testing-library/react';
22

33
export function selectNode(index = 0) {
44
const treeNode = document.querySelectorAll('.rc-tree-select-tree-node-content-wrapper')[index];
55
fireEvent.click(treeNode);
66
}
7+
8+
export function keyDown(element: HTMLElement, keyCode: number) {
9+
const event = createEvent.keyDown(element, { keyCode });
10+
fireEvent(element, event);
11+
}
12+
13+
export function keyUp(element: HTMLElement, keyCode: number) {
14+
const event = createEvent.keyUp(element, { keyCode });
15+
fireEvent(element, event);
16+
}

0 commit comments

Comments
 (0)