diff --git a/src/Select.js b/src/Select.js index 3c40175f13..ad29127ca9 100644 --- a/src/Select.js +++ b/src/Select.js @@ -303,11 +303,13 @@ class Select extends React.Component { this.setState({ isOpen: toOpen, isPseudoFocused: false, + focusedOption: null, }); } else { // otherwise, focus the input and open the menu this._openAfterFocus = this.props.openOnClick; this.focus(); + this.setState({ focusedOption: null }); } } diff --git a/test/Select-test.js b/test/Select-test.js index e73f92d238..c7e8f615d0 100644 --- a/test/Select-test.js +++ b/test/Select-test.js @@ -4550,4 +4550,204 @@ describe('Select', () => { }); }); }); + + describe('handleMouseDown method', () => { + let preventDefault = {}; + let event = {}; + let focusStub = {}; + let setStateStub = {}; + + beforeEach(() => { + preventDefault = sinon.spy(); + event = { + type: 'mousedown', + button: 0, + target: { + tagName: 'yo', + }, + preventDefault, + }; + + instance = createControl({ + openOnClick: true, + }); + + focusStub = sinon.stub(instance, 'focus'); + setStateStub = sinon.stub(instance, 'setState'); + }); + + afterEach(() => { + focusStub.restore(); + setStateStub.restore(); + }); + + it('for isFocused=false should set _openAfterFocus and call focus, setState, preventDefault', () => { + instance.state.isFocused = false; + expect(instance._openAfterFocus, 'to equal', false ); + expect(instance.props.openOnClick, 'to equal', true ); + expect(instance.state.isFocused, 'to equal', false ); + + instance.handleMouseDown(event); + + expect(preventDefault, 'was called once'); + expect(focusStub, 'was called once'); + expect(setStateStub, 'was called once'); + expect(instance._openAfterFocus, 'to equal', true ); + expect(setStateStub, 'was called with', { focusedOption: null }); + }); + + it('for isFocused=true and _focusAfterClear=false should call focus, setState, preventDefault', () => { + expect(instance._focusAfterClear, 'to equal', false ); + expect(instance.state.isFocused, 'to equal', true ); + + instance.handleMouseDown(event); + + expect(preventDefault, 'was called once'); + expect(focusStub, 'was called once'); + expect(setStateStub, 'was called once'); + expect(setStateStub, 'was called with', + { + isOpen: true, + isPseudoFocused: false, + focusedOption: null + }); + + }); + + it('for isFocused=true and _focusAfterClear=true should set _focusAfterClear and call focus, setState, preventDefault', () => { + instance._focusAfterClear = true; + + expect(instance._focusAfterClear, 'to equal', true ); + expect(instance.state.isFocused, 'to equal', true ); + + instance.handleMouseDown(event); + + expect(instance._focusAfterClear, 'to equal', false ); + expect(preventDefault, 'was called once'); + expect(focusStub, 'was called once'); + expect(setStateStub, 'was called once'); + expect(setStateStub, 'was called with', + { + isOpen: false, + isPseudoFocused: false, + focusedOption: null + }); + }); + + it('for searchable=false and should call focus, setState, preventDefault', () => { + instance = createControl({ searchable: false }); + + focusStub = sinon.stub(instance, 'focus'); + setStateStub = sinon.stub(instance, 'setState'); + const isOpen = instance.state.isOpen; + + instance.handleMouseDown(event); + + expect(preventDefault, 'was called once'); + expect(focusStub, 'was called once'); + expect(setStateStub, 'was called once'); + expect(setStateStub, 'was called with', { isOpen: !isOpen }); + }); + + it('for tagName="INPUT", isFocused=false should call only focus', () => { + event = { + type: 'mousedown', + button: 0, + target: { + tagName: 'INPUT', + }, + preventDefault, + }; + + instance.state.isFocused = false; + expect(instance._openAfterFocus, 'to equal', false ); + + instance.handleMouseDown(event); + + expect(instance._openAfterFocus, 'to equal', true ); + expect(preventDefault, 'was not called'); + expect(focusStub, 'was called once'); + expect(setStateStub, 'was not called'); + }); + + it('for tagName="INPUT", isFocused=true, isOpen=false should call setState', () => { + event = { + type: 'mousedown', + button: 0, + target: { + tagName: 'INPUT', + }, + preventDefault, + }; + + instance.state.isFocused = true; + instance.state.isOpen = false; + + instance.handleMouseDown(event); + + expect(preventDefault, 'was not called'); + expect(focusStub, 'was not called'); + expect(setStateStub, 'was called once'); + expect(setStateStub, 'was called with', { isOpen: true, isPseudoFocused: false }); + }); + + it('for tagName="INPUT", isFocused=true, isOpen=true should return', () => { + event = { + type: 'mousedown', + button: 0, + target: { + tagName: 'INPUT', + }, + preventDefault, + }; + + instance.state.isFocused = true; + instance.state.isOpen = true; + + instance.handleMouseDown(event); + + expect(preventDefault, 'was not called'); + expect(focusStub, 'was not called'); + expect(setStateStub, 'was not called'); + }); + + it('should return for disabled', () => { + event = { + type: 'mousedown', + button: 0, + target: { + tagName: 'INPUT', + }, + preventDefault, + }; + + instance = createControl({ disabled: true }); + + focusStub = sinon.stub(instance, 'focus'); + setStateStub = sinon.stub(instance, 'setState'); + + instance.handleMouseDown(event); + + expect(preventDefault, 'was not called'); + expect(focusStub, 'was not called'); + expect(setStateStub, 'was not called'); + }); + + it('should return for button !=0', () => { + event = { + type: 'mousedown', + button: 2, + target: { + tagName: 'INPUT', + }, + preventDefault, + }; + + instance.handleMouseDown(event); + + expect(preventDefault, 'was not called'); + expect(focusStub, 'was not called'); + expect(setStateStub, 'was not called'); + }); + }); });