UNPKG

react-widgets

Version:

An à la carte set of polished, extensible, and accessible inputs built for React

374 lines (264 loc) 13.3 kB
require('../vendor/phantomjs-shim') import { findDOMNode } from 'react-dom'; var React = require('react/addons'); var Select = require('../src/Multiselect.jsx') , TagList = require('../src/MultiselectTagList.jsx'); var TestUtils = React.addons.TestUtils , render = TestUtils.renderIntoDocument , findTag = TestUtils.findRenderedDOMComponentWithTag , findClass = TestUtils.findRenderedDOMComponentWithClass , findType = TestUtils.findRenderedComponentWithType , trigger = TestUtils.Simulate; $.fn.myText = function(){ return this.contents().filter(function(){ return this.nodeType === 3; })[0].nodeValue } describe('Multiselect', function(){ var dataList = [ { label: 'jimmy', id: 0 }, { label: 'sally', id: 1 }, { label: 'pat', id: 2 } ]; it('should set initial values', function(){ var select = render(<Select value={['hello']} onChange={()=>{}} />) , tags = findDOMNode(findType(select, TagList)); expect($(tags).find('li:first-child > span').myText()).to.be('hello'); }) it('should respect textField and valueFields', function(){ var select = render(<Select defaultValue={[0]} data={dataList} textField='label' valueField='id' />) , tags = findDOMNode(findType(select, TagList)); expect( $(tags).find('li:first-child > span').myText() ).to.be('jimmy'); }) it('should start closed', function(done){ var select = render(<Select defaultValue={[0]} data={dataList} textField='label' valueField='id' />); var popup = findType(select, require('../src/Popup.jsx')); expect(select._values.open).to.not.be(true) expect(findDOMNode(select).className).to.not.match(/\brw-open\b/) expect(findClass(select, 'rw-input').getAttribute('aria-expanded')).to.be('false') setTimeout(function(){ expect($(findDOMNode(popup)).css('display')).to.be('none') done() }, 0) }) it('should open when focused', function(done){ var select = render(<Select defaultValue={['jimmy']} data={dataList} duration={0}/>); var popup = findType(select, require('../src/Popup.jsx')) trigger.focus(findDOMNode(select)) setTimeout(function() { expect(select._values.open).to.be(true) expect(findDOMNode(select).className).to.match(/\brw-open\b/) expect(findClass(select, 'rw-input').getAttribute('aria-expanded')).to.be('true') expect(popup.props.open).to.be(true) done() }) }) it('should set id on list', function(){ var instance = render(<Select />) , list = findTag(instance, 'ul'); expect(list.hasAttribute('id')).to.be(true); }) it('should remove tag when clicked', function(){ var del = sinon.spy() , tags = findDOMNode(render( <TagList value={[dataList[0], dataList[1]]} data={dataList} textField='label' valueField='id' onDelete={del}/>)); expect($(tags).children().length).to.be(2) trigger.click(tags.children[1].children[1]) // click button expect(del.calledOnce).to.be(true) expect(del.calledWith(dataList[1])).to.be(true) }) it('should change value when tag is clicked', function(){ var change = sinon.spy() , select = render(<Select onChange={change} value={[dataList[0], dataList[1]]} data={dataList} textField='label' valueField='id' />) , tags = findDOMNode(findType(select, TagList)) expect($(tags).children().length).to.be(2) trigger.click(tags.children[1].children[1]) // click button expect(change.calledOnce).to.be(true) expect(change.args[0][0]).to.eql([ dataList[0] ]) }) it('should trigger focus/blur events', function(done){ var blur = sinon.spy() , focus = sinon.spy() , select = render(<Select onBlur={blur} onFocus={focus}/>); expect(focus.calledOnce).to.be(false) expect(blur.calledOnce).to.be(false) trigger.focus(findDOMNode(select)) setTimeout(() => { expect(focus.calledOnce).to.be(true) trigger.blur(findDOMNode(select)) setTimeout(() => { expect(blur.calledOnce).to.be(true) done() }) }) }) it('should trigger key events', function(){ var kp = sinon.spy(), kd = sinon.spy(), ku = sinon.spy() , select = render(<Select onKeyPress={kp} onKeyUp={ku} onKeyDown={kd}/>) , input = findDOMNode(findType(select, require('../src/MultiselectInput.jsx'))); trigger.keyPress(input) trigger.keyDown(input) trigger.keyUp(input) expect(kp.calledOnce).to.be(true) expect(kd.calledOnce).to.be(true) expect(ku.calledOnce).to.be(true) }) it('should do nothing when disabled', function(done){ var select = render(<Select defaultValue={['jimmy']} data={dataList} duration={0} disabled={true}/>) , input = findDOMNode(findType(select, require('../src/MultiselectInput.jsx'))) , tags = findDOMNode(findType(select, TagList)); expect( input.hasAttribute('disabled')).to.be(true); expect( input.getAttribute('aria-disabled')).to.be('true'); //expect( input.getAttribute('disabled')).to.be(''); trigger.click(findClass(select, 'rw-tag-btn')) setTimeout(function() { expect(select._values.open).to.not.be(true) expect(tags.children.length).to.be(1) expect(findDOMNode(select).className).to.not.match(/\brw-state-focus\b/) done() }, 0) }) it('should disable only certain tags', function(done){ var select = render(<Select defaultValue={[0, 1]} data={dataList} disabled={[1]} textField='label' valueField='id'/>) , tags = findDOMNode(findType(select, TagList)); expect(tags.children.length).to.be(2) expect(tags.children[1].className).to.match(/\brw-state-disabled\b/); trigger.click(tags.children[1].children[1]) // click button setTimeout(function() { expect(tags.children.length).to.be(2) done() }, 0) }) it('should do nothing when readonly', function(done){ var select = render(<Select defaultValue={['jimmy']} data={dataList} duration={0} readOnly={true}/>) , input = findDOMNode(findType(select, require('../src/MultiselectInput.jsx'))) , tags = findDOMNode(findType(select, TagList)); expect( input.hasAttribute('readonly')).to.be(true); expect( input.getAttribute('aria-readonly')).to.be('true'); trigger.click(findClass(select, 'rw-tag-btn')) setTimeout(function() { expect(select._values.open).to.not.be(true) expect(tags.children.length).to.be(1) done() }, 0) }) it('should readonly only certain tags', function(done){ var select = render(<Select defaultValue={[0, 1]} data={dataList} readOnly={[1]} textField='label' valueField='id'/>) , tags = findDOMNode(findType(select, TagList)); expect(tags.children.length).to.be(2) expect(tags.children[1].className).to.match(/\brw-state-readonly\b/); trigger.click(tags.children[1].children[1]) // click button setTimeout(function() { expect(tags.children.length).to.be(2) done() }) }) it('should call Select handler', function(done){ var change = sinon.spy(), onSelect = sinon.spy() , instance = render(<Select value={[dataList[1]]} data={dataList} onChange={change} onSelect={onSelect}/>) findDOMNode(instance).focus() let list = findClass(instance, 'rw-list'); setTimeout(function(){ trigger.click(list.children[0]) expect(onSelect.calledOnce).to.be(true) expect(change.calledAfter(onSelect)).to.be(true) onSelect.reset() change.reset() trigger.keyDown(findDOMNode(instance), { key: 'ArrowDown'}) //move to different value so change fires trigger.keyDown(findDOMNode(instance), { key: 'Enter'}) expect(onSelect.calledOnce).to.be(true) expect(change.calledAfter(onSelect)).to.be(true) done() }) }) it('should clear SearchTerm when uncontrolled', function(){ var select = render(<Select data={dataList} defaultSearchTerm='ji' open textField='label' valueField='id' onToggle={()=>{}}/>); var input = findType(select, Select.ControlledComponent) expect(input.props.searchTerm).to.be('ji') trigger.keyDown(findDOMNode(select), { key: 'Enter'}) expect(input.props.searchTerm).to.be('') }) it('should not clear SearchTerm when controlled', function(){ var select = render(<Select searchTerm="jim" data={dataList} onSearch={()=>{}}/>); var input = findTag(select, 'input') trigger.keyDown(findDOMNode(select), { key: 'Enter'}) expect(input.value).to.be('jim') }) it('should show create tag correctly', function(){ var select = render(<Select searchTerm="custom tag" onCreate={()=>{}} data={dataList} onSearch={()=>{}}/>); expect(function err() { findClass(select, 'rw-multiselect-create-tag') }).to.not.throwException() select = render(<Select onCreate={()=>{}} data={dataList} onSearch={()=>{}}/>) expect(function err() { findClass(select, 'rw-multiselect-create-tag') }).to.throwException() select = render(<Select searchTerm="custom tag" data={dataList} onSearch={()=>{}}/>) expect(function err() { findClass(select, 'rw-multiselect-create-tag') }).to.throwException() select = render(<Select searchTerm="asfasfas tag" data={dataList} onSearch={()=>{}}/>) expect(function err() { findClass(select, 'rw-multiselect-create-tag') }).to.throwException() }) it('should call onCreate', function(){ var create = sinon.spy() , select = render(<Select open={true} searchTerm="custom tag" data={dataList} onCreate={create} onSearch={()=>{}} onToggle={()=>{}}/>) , createLi = findClass(select, 'rw-multiselect-create-tag').children[0]; trigger.click(createLi) expect(create.calledOnce).to.ok() expect(create.calledWith('custom tag')).to.ok() // only option is create create.reset() trigger.keyDown(findDOMNode(select), { key: 'Enter'}) expect(create.calledOnce).to.ok() expect(create.calledWith('custom tag')).to.ok() // other values have focus select = render(<Select open={true} searchTerm="custom tag" data={['custom tag time']} onCreate={create} onSearch={()=>{}} onToggle={()=>{}}/>) create.reset() trigger.keyDown(findDOMNode(select), { key: 'Enter'}) expect(create.called).to.be(false) trigger.keyDown(findDOMNode(select), { key: 'Enter', ctrlKey: true }) expect(create.calledOnce).to.ok() expect(create.calledWith('custom tag')).to.ok() }) it('should change values on key down', function(){ var change = sinon.spy() , select = render(<Select value={[0, 1, 2]} data={dataList} textField='label' valueField='id' onChange={change}/>) , tags = findDOMNode(findType(select, TagList)) , list = findClass(select, 'rw-list'); trigger.keyDown(findDOMNode(select), { key: 'ArrowLeft'}) expect(tags.children[2].className).to.match(/\brw-state-focus\b/) expect(tags.children[1].className).to.not.match(/\brw-state-focus\b/) trigger.keyDown(findDOMNode(select), { key: 'ArrowLeft'}) expect(tags.children[1].className).to.match(/\brw-state-focus\b/) expect(tags.children[2].className).to.not.match(/\brw-state-focus\b/) trigger.keyDown(findDOMNode(select), { key: 'ArrowRight'}) expect(tags.children[2].className).to.match(/\brw-state-focus\b/) expect(tags.children[1].className).to.not.match(/\brw-state-focus\b/) trigger.keyDown(findDOMNode(select), { key: 'Home'}) expect(tags.children[0].className).to.match(/\brw-state-focus\b/) expect(tags.children[1].className).to.not.match(/\brw-state-focus\b/) trigger.keyDown(findDOMNode(select), { key: 'Delete'}) expect(change.calledOnce).to.be(true) expect(change.args[0][0]).to.eql(dataList.slice(1, 3)) change.reset() trigger.keyDown(findDOMNode(select), { key: 'End'}) expect(tags.children[2].className).to.match(/\brw-state-focus\b/) expect(tags.children[1].className).to.not.match(/\brw-state-focus\b/) trigger.keyDown(findDOMNode(select), { key: 'Backspace'}) expect(change.calledOnce).to.be(true) expect(change.args[0][0]).to.eql(dataList.slice(0, 2)) change.reset() trigger.keyDown(findDOMNode(select), { key: 'ArrowDown'}) expect(select._values.open).to.be(true) select = render(<Select open value={[]} onToggle={()=>{}} data={dataList} textField='label' valueField='id' onChange={change}/>) list = findClass(select, 'rw-list') trigger.keyDown(findDOMNode(select), { key: 'ArrowDown'}) expect(list.children[1].className).to.match(/\brw-state-focus\b/) trigger.keyDown(findDOMNode(select), { key: 'End'}) expect(list.children[2].className).to.match(/\brw-state-focus\b/) trigger.keyDown(findDOMNode(select), { key: 'Home'}) expect(list.children[0].className).to.match(/\brw-state-focus\b/) }) })