diff --git a/packages/react-bootstrap-table2-filter/test/components/multiselect.test.js b/packages/react-bootstrap-table2-filter/test/components/multiselect.test.js new file mode 100644 index 0000000..fc1eb73 --- /dev/null +++ b/packages/react-bootstrap-table2-filter/test/components/multiselect.test.js @@ -0,0 +1,354 @@ +import 'jsdom-global/register'; +import React from 'react'; +import sinon from 'sinon'; +import { mount } from 'enzyme'; +import MultiSelectFilter from '../../src/components/multiselect'; +import { FILTER_TYPE } from '../../src/const'; + + +describe('Multi Select Filter', () => { + let wrapper; + let instance; + + // onFilter(x)(y) = filter result + const onFilter = sinon.stub(); + const onFilterFirstReturn = sinon.stub(); + + const column = { + dataField: 'quality', + text: 'Product Quality' + }; + + const options = { + 0: 'Bad', + 1: 'Good', + 2: 'Unknown' + }; + + afterEach(() => { + onFilter.reset(); + onFilterFirstReturn.reset(); + + onFilter.returns(onFilterFirstReturn); + }); + + describe('initialization', () => { + beforeEach(() => { + wrapper = mount( + + ); + instance = wrapper.instance(); + }); + + it('should have correct state', () => { + expect(instance.state.isSelected).toBeFalsy(); + }); + + it('should rendering component successfully', () => { + expect(wrapper).toHaveLength(1); + expect(wrapper.find('select')).toHaveLength(1); + expect(wrapper.find('.select-filter')).toHaveLength(1); + expect(wrapper.find('.placeholder-selected')).toHaveLength(1); + }); + + it('should rendering select options correctly', () => { + const select = wrapper.find('select'); + expect(select.find('option')).toHaveLength(Object.keys(options).length + 1); + expect(select.childAt(0).text()).toEqual(`Select ${column.text}...`); + + Object.keys(options).forEach((key, i) => { + expect(select.childAt(i + 1).prop('value')).toEqual(key); + expect(select.childAt(i + 1).text()).toEqual(options[key]); + }); + }); + }); + + describe('when defaultValue is defined', () => { + let defaultValue; + + describe('and it is valid', () => { + beforeEach(() => { + defaultValue = ['0']; + wrapper = mount( + + ); + instance = wrapper.instance(); + }); + + it('should have correct state', () => { + expect(instance.state.isSelected).toBeTruthy(); + }); + + it('should rendering component successfully', () => { + expect(wrapper).toHaveLength(1); + expect(wrapper.find('.placeholder-selected')).toHaveLength(0); + }); + + it('should calling onFilter on componentDidMount', () => { + expect(onFilter.calledOnce).toBeTruthy(); + expect(onFilter.calledWith(column, FILTER_TYPE.MULTISELECT)).toBeTruthy(); + expect(onFilterFirstReturn.calledOnce).toBeTruthy(); + expect(onFilterFirstReturn.calledWith(defaultValue)).toBeTruthy(); + }); + }); + }); + + describe('when props.getFilter is defined', () => { + let programmaticallyFilter; + + const filterValue = ['foo']; + + const getFilter = (filter) => { + programmaticallyFilter = filter; + }; + + beforeEach(() => { + wrapper = mount( + + ); + instance = wrapper.instance(); + + programmaticallyFilter(filterValue); + }); + + it('should do onFilter correctly when exported function was executed', () => { + expect(onFilter.calledOnce).toBeTruthy(); + expect(onFilter.calledWith(column, FILTER_TYPE.MULTISELECT)).toBeTruthy(); + expect(onFilterFirstReturn.calledOnce).toBeTruthy(); + expect(onFilterFirstReturn.calledWith(filterValue)).toBeTruthy(); + }); + + it('should setState correctly when exported function was executed', () => { + expect(instance.state.isSelected).toBeTruthy(); + }); + }); + + describe('when placeholder is defined', () => { + const placeholder = 'test'; + beforeEach(() => { + wrapper = mount( + + ); + instance = wrapper.instance(); + }); + + it('should rendering component successfully', () => { + expect(wrapper).toHaveLength(1); + const select = wrapper.find('select'); + expect(select.childAt(0).text()).toEqual(placeholder); + }); + }); + + describe('when style is defined', () => { + const style = { backgroundColor: 'red' }; + beforeEach(() => { + wrapper = mount( + + ); + }); + + it('should rendering component successfully', () => { + expect(wrapper).toHaveLength(1); + expect(wrapper.find('select').prop('style')).toEqual(style); + }); + }); + + describe('when withoutEmptyOption is defined', () => { + beforeEach(() => { + wrapper = mount( + + ); + }); + + it('should rendering select without default empty option', () => { + const select = wrapper.find('select'); + expect(select.find('option')).toHaveLength(Object.keys(options).length); + }); + }); + + describe('componentDidUpdate', () => { + let prevProps; + + describe('when props.defaultValue is diff from prevProps.defaultValue', () => { + const defaultValue = ['0']; + + beforeEach(() => { + wrapper = mount( + + ); + prevProps = { + column, + options, + defaultValue: ['1'] + }; + instance = wrapper.instance(); + instance.componentDidUpdate(prevProps); + }); + + it('should update', () => { + expect(onFilter.callCount).toBe(2); + expect(onFilter.calledWith(column, FILTER_TYPE.MULTISELECT)).toBeTruthy(); + expect(onFilterFirstReturn.callCount).toBe(2); + expect(onFilterFirstReturn.calledWith(instance.props.defaultValue)).toBeTruthy(); + }); + }); + + describe('when props.options is diff from prevProps.options', () => { + const defaultValue = ['0']; + beforeEach(() => { + wrapper = mount( + + ); + prevProps = { + column, + options + }; + instance = wrapper.instance(); + instance.componentDidUpdate(prevProps); + }); + + it('should update', () => { + expect(onFilter.callCount).toBe(2); + expect(onFilter.calledWith(column, FILTER_TYPE.MULTISELECT)).toBeTruthy(); + expect(onFilterFirstReturn.callCount).toBe(2); + expect(onFilterFirstReturn.calledWith(instance.props.defaultValue)).toBeTruthy(); + }); + }); + }); + + describe('cleanFiltered', () => { + describe('when props.defaultValue is defined', () => { + const defaultValue = ['0']; + beforeEach(() => { + wrapper = mount( + + ); + instance = wrapper.instance(); + instance.cleanFiltered(); + }); + + it('should setting state correctly', () => { + expect(instance.state.isSelected).toBeTruthy(); + }); + + it('should calling onFilter correctly', () => { + expect(onFilter.callCount).toBe(2); + expect(onFilter.calledWith(column, FILTER_TYPE.MULTISELECT)).toBeTruthy(); + expect(onFilterFirstReturn.callCount).toBe(2); + expect(onFilterFirstReturn.calledWith(defaultValue)).toBeTruthy(); + }); + }); + + describe('when props.defaultValue is not defined', () => { + beforeEach(() => { + wrapper = mount( + + ); + instance = wrapper.instance(); + instance.cleanFiltered(); + }); + + it('should setting state correctly', () => { + expect(instance.state.isSelected).toBeFalsy(); + }); + + it('should calling onFilter correctly', () => { + expect(onFilter.callCount).toBe(1); + expect(onFilterFirstReturn.callCount).toBe(1); + }); + }); + }); + + describe('applyFilter', () => { + const values = ['2']; + beforeEach(() => { + wrapper = mount( + + ); + instance = wrapper.instance(); + instance.applyFilter(values); + }); + + it('should setting state correctly', () => { + expect(instance.state.isSelected).toBeTruthy(); + }); + + it('should calling onFilter correctly', () => { + expect(onFilter.calledOnce).toBeTruthy(); + expect(onFilter.calledWith(column, FILTER_TYPE.MULTISELECT)).toBeTruthy(); + expect(onFilterFirstReturn.calledOnce).toBeTruthy(); + expect(onFilterFirstReturn.calledWith(values)).toBeTruthy(); + }); + }); + + describe('filter', () => { + const event = { target: { selectedOptions: [{ value: 'tester'}] } }; + + beforeEach(() => { + wrapper = mount( + + ); + instance = wrapper.instance(); + instance.filter(event); + }); + + it('should setting state correctly', () => { + expect(instance.state.isSelected).toBeTruthy(); + }); + + it('should calling onFilter correctly', () => { + expect(onFilter.calledOnce).toBeTruthy(); + expect(onFilter.calledWith(column, FILTER_TYPE.MULTISELECT)).toBeTruthy(); + expect(onFilterFirstReturn.calledOnce).toBeTruthy(); + expect(onFilterFirstReturn.calledWith( + event.target.selectedOptions.map(item => item.value))).toBeTruthy(); + }); + }); +});