import React from 'react'; import { render, mount } from 'enzyme'; import KeyCode from 'rc-util/lib/KeyCode'; import Cascader from '..'; import focusTest from '../../../tests/shared/focusTest'; const options = [{ value: 'zhejiang', label: 'Zhejiang', children: [{ value: 'hangzhou', label: 'Hangzhou', children: [{ value: 'xihu', label: 'West Lake', }], }], }, { value: 'jiangsu', label: 'Jiangsu', children: [{ value: 'nanjing', label: 'Nanjing', children: [{ value: 'zhonghuamen', label: 'Zhong Hua Men', }], }], }]; function filter(inputValue, path) { return path.some(option => (option.label).toLowerCase().indexOf(inputValue.toLowerCase()) > -1); } describe('Cascader', () => { focusTest(Cascader); it('popup correctly when panel is hidden', () => { const wrapper = mount( ); expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot(); }); it('popup correctly when panel is open', () => { const onPopupVisibleChange = jest.fn(); const wrapper = mount( ); wrapper.find('input').simulate('click'); expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot(); expect(onPopupVisibleChange).toHaveBeenCalledWith(true); }); it('support controlled mode', () => { const wrapper = mount( ); wrapper.setProps({ value: ['zhejiang', 'hangzhou', 'xihu'], }); expect(wrapper.render()).toMatchSnapshot(); }); it('popup correctly with defaultValue', () => { const wrapper = mount( ); wrapper.find('input').simulate('click'); expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot(); }); it('should support popupVisible', () => { const wrapper = mount( ); expect(wrapper.find('Trigger').instance().getComponent().props.visible).toBe(false); wrapper.setProps({ popupVisible: true }); expect(wrapper.find('Trigger').instance().getComponent().props.visible).toBe(true); }); it('can be selected', () => { const onChange = jest.fn(); const wrapper = mount(); wrapper.find('input').simulate('click'); let popupWrapper = mount(wrapper.find('Trigger').instance().getComponent()); popupWrapper.find('.ant-cascader-menu').at(0).find('.ant-cascader-menu-item').at(0) .simulate('click'); expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot(); popupWrapper = mount(wrapper.find('Trigger').instance().getComponent()); popupWrapper.find('.ant-cascader-menu').at(1).find('.ant-cascader-menu-item').at(0) .simulate('click'); expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot(); popupWrapper = mount(wrapper.find('Trigger').instance().getComponent()); popupWrapper.find('.ant-cascader-menu').at(2).find('.ant-cascader-menu-item').at(0) .simulate('click'); expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot(); expect(onChange).toHaveBeenCalledWith(['zhejiang', 'hangzhou', 'xihu'], expect.anything()); }); it('backspace should work with `Cascader[showSearch]`', () => { const wrapper = mount(); wrapper.find('input').simulate('change', { target: { value: '123' } }); expect(wrapper.state('inputValue')).toBe('123'); wrapper.find('input').simulate('keydown', { keyCode: KeyCode.BACKSPACE }); // Simulate onKeyDown will not trigger onChange by default, so the value is still '123' expect(wrapper.state('inputValue')).toBe('123'); }); it('should highlight keyword and filter when search in Cascader', () => { const wrapper = mount(); wrapper.find('input').simulate('click'); wrapper.find('input').simulate('change', { target: { value: 'z' } }); expect(wrapper.state('inputValue')).toBe('z'); const popupWrapper = mount(wrapper.find('Trigger').instance().getComponent()); expect(popupWrapper).toMatchSnapshot(); }); it('should render not found content', () => { const wrapper = mount(); wrapper.find('input').simulate('click'); wrapper.find('input').simulate('change', { target: { value: '__notfoundkeyword__' } }); expect(wrapper.state('inputValue')).toBe('__notfoundkeyword__'); const popupWrapper = mount(wrapper.find('Trigger').instance().getComponent()); expect(popupWrapper).toMatchSnapshot(); }); it('should support to clear selection', () => { const wrapper = mount(); expect(wrapper.find('.ant-cascader-picker-label').text()).toBe('Zhejiang / Hangzhou'); wrapper.find('.ant-cascader-picker-clear').at(0).simulate('click'); expect(wrapper.find('.ant-cascader-picker-label').text()).toBe(''); }); it('should close popup when clear selection', () => { const onPopupVisibleChange = jest.fn(); const wrapper = mount( ); wrapper.find('.ant-cascader-picker-clear').at(0).simulate('click'); expect(onPopupVisibleChange).toHaveBeenCalledWith(false); }); it('should clear search input when clear selection', () => { const wrapper = mount( ); wrapper.find('input').simulate('click'); wrapper.find('input').simulate('change', { target: { value: 'xxx' } }); expect(wrapper.state('inputValue')).toBe('xxx'); wrapper.find('.ant-cascader-picker-clear').at(0).simulate('click'); expect(wrapper.state('inputValue')).toBe(''); }); it('should not trigger visible change when click search input', () => { const onPopupVisibleChange = jest.fn(); const wrapper = mount( ); wrapper.find('input').simulate('focus'); expect(onPopupVisibleChange).toHaveBeenCalledTimes(0); wrapper.find('input').simulate('click'); expect(onPopupVisibleChange).toHaveBeenCalledTimes(1); wrapper.find('input').simulate('click'); expect(onPopupVisibleChange).toHaveBeenCalledTimes(1); wrapper.find('input').simulate('blur'); wrapper.setState({ popupVisible: false }); wrapper.find('input').simulate('click'); expect(onPopupVisibleChange).toHaveBeenCalledTimes(2); }); it('should change filtered item when options are changed', () => { const wrapper = mount(); wrapper.find('input').simulate('click'); wrapper.find('input').simulate('change', { target: { value: 'a' } }); expect(wrapper.find('.ant-cascader-menu-item').length).toBe(2); wrapper.setProps({ options: [options[0]] }); expect(wrapper.find('.ant-cascader-menu-item').length).toBe(1); }); it('can use fieldNames', () => { const customerOptions = [{ code: 'zhejiang', name: 'Zhejiang', items: [{ code: 'hangzhou', name: 'Hangzhou', items: [{ code: 'xihu', name: 'West Lake', }], }], }, { code: 'jiangsu', name: 'Jiangsu', items: [{ code: 'nanjing', name: 'Nanjing', items: [{ code: 'zhonghuamen', name: 'Zhong Hua Men', }], }], }]; const wrapper = mount( ); wrapper.instance().handleChange(['zhejiang', 'hangzhou', 'xihu'], customerOptions); expect(wrapper.find('.ant-cascader-picker-label').text().split('/').length).toBe(3); }); // https://github.com/ant-design/ant-design/issues/12970 it('can use filedNames too, for compatibility', () => { const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); const customerOptions = [{ code: 'zhejiang', name: 'Zhejiang', items: [{ code: 'hangzhou', name: 'Hangzhou', items: [{ code: 'xihu', name: 'West Lake', }], }], }, { code: 'jiangsu', name: 'Jiangsu', items: [{ code: 'nanjing', name: 'Nanjing', items: [{ code: 'zhonghuamen', name: 'Zhong Hua Men', }], }], }]; const wrapper = mount( ); wrapper.instance().handleChange(['zhejiang', 'hangzhou', 'xihu'], customerOptions); expect(wrapper.find('.ant-cascader-picker-label').text().split('/').length).toBe(3); expect(errorSpy).toHaveBeenLastCalledWith( 'Warning: `filedNames` of Cascader is a typo usage and deprecated, please use `fieldNames` instead.' ); errorSpy.mockReset(); }); describe('limit filtered item count', () => { const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); afterAll(() => { errorSpy.mockRestore(); }); it('limit with positive number', () => { const wrapper = mount(); wrapper.find('input').simulate('click'); wrapper.find('input').simulate('change', { target: { value: 'a' } }); expect(wrapper.find('.ant-cascader-menu-item').length).toBe(1); }); it('not limit', () => { const wrapper = mount(); wrapper.find('input').simulate('click'); wrapper.find('input').simulate('change', { target: { value: 'a' } }); expect(wrapper.find('.ant-cascader-menu-item').length).toBe(2); }); it('negative limit', () => { const wrapper = mount(); wrapper.find('input').simulate('click'); wrapper.find('input').simulate('change', { target: { value: 'a' } }); expect(wrapper.find('.ant-cascader-menu-item').length).toBe(2); expect(errorSpy).toBeCalledWith( 'Warning: \'limit\' of showSearch in Cascader should be positive number or false.' ); }); }); });