UNPKG

react-geosuggest-mui

Version:

A React autosuggest for the Google Maps Places API.

462 lines (391 loc) 20.7 kB
import React from 'react'; // eslint-disable-line no-unused-vars import {expect} from 'chai'; import TestUtils from 'react-addons-test-utils'; import sinon from 'sinon'; import googleStub from './google_stub'; import Geosuggest from '../src/Geosuggest'; window.google = global.google = googleStub(); describe('Component: Geosuggest', () => { let component = null, onSuggestSelect = null, onActivateSuggest = null, onSuggestNoResults = null, onFocus = null, onKeyPress = null, onChange = null, onBlur = null, render = props => { onSuggestSelect = sinon.spy(); onActivateSuggest = sinon.spy(); onSuggestNoResults = sinon.spy(); onChange = sinon.spy(); onFocus = sinon.spy(); onKeyPress = sinon.spy(); onBlur = sinon.spy(); component = TestUtils.renderIntoDocument( <Geosuggest radius='20' queryDelay={0} onSuggestSelect={onSuggestSelect} onActivateSuggest={onActivateSuggest} onSuggestNoResults={onSuggestNoResults} onChange={onChange} onFocus={onFocus} onKeyPress={onKeyPress} onBlur={onBlur} style={{ 'input': { 'borderColor': '#000' }, 'suggests': { 'borderColor': '#000' }, 'suggestItem': { 'borderColor': '#000', 'borderWidth': 1 } }} {...props} /> ); }; describe('default', () => { // eslint-disable-line max-statements beforeEach(() => render()); it('should have an input field', () => { const input = TestUtils.scryRenderedDOMComponentsWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len expect(input).to.have.lengthOf(1); }); it('should not show any suggestions when the input is empty', () => { const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len TestUtils.Simulate.focus(geoSuggestInput); const suggestItems = TestUtils.scryRenderedDOMComponentsWithClass(component, 'geosuggest__item'), // eslint-disable-line max-len, one-var suggests = TestUtils.scryRenderedDOMComponentsWithClass(component, 'geosuggest__suggests'); // eslint-disable-line max-len expect(suggestItems.length).to.equal(0); expect(suggests[0].classList.contains('geosuggest__suggests--hidden')).to.be.true; // eslint-disable-line no-unused-expressions, max-len }); it('should call `onSuggestSelect` when we type a city name and choose some of the suggestions', () => { // eslint-disable-line max-len const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len geoSuggestInput.value = 'New'; TestUtils.Simulate.change(geoSuggestInput); TestUtils.Simulate.keyDown(geoSuggestInput, { key: 'keyDown', keyCode: 40, which: 40 }); TestUtils.Simulate.keyDown(geoSuggestInput, { key: 'keyDown', keyCode: 40, which: 40 }); TestUtils.Simulate.keyDown(geoSuggestInput, { key: 'keyUp', keyCode: 38, which: 38 }); TestUtils.Simulate.keyDown(geoSuggestInput, { key: 'Enter', keyCode: 13, which: 13 }); expect(onSuggestSelect.calledOnce).to.be.true; // eslint-disable-line no-unused-expressions, max-len }); it('should call `onSuggestSelect` when we type a city name and click on one of the suggestions', () => { // eslint-disable-line max-len const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len geoSuggestInput.value = 'New'; TestUtils.Simulate.change(geoSuggestInput); TestUtils.Simulate.focus(geoSuggestInput); const suggestItems = TestUtils.scryRenderedDOMComponentsWithClass(component, 'geosuggest__item'); // eslint-disable-line max-len, one-var TestUtils.Simulate.click(suggestItems[0]); expect(onSuggestSelect.calledOnce).to.be.true; // eslint-disable-line no-unused-expressions, max-len }); it('should call `onActivateSuggest` when we key down to a suggestion', () => { // eslint-disable-line max-len const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len geoSuggestInput.value = 'New'; TestUtils.Simulate.change(geoSuggestInput); TestUtils.Simulate.focus(geoSuggestInput); TestUtils.Simulate.keyDown(geoSuggestInput, { key: 'keyDown', keyCode: 40, which: 40 }); expect(onActivateSuggest.calledOnce).to.be.true; // eslint-disable-line no-unused-expressions, max-len }); it('should call `onFocus` when we focus the input', () => { const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len TestUtils.Simulate.focus(geoSuggestInput); expect(onFocus.calledOnce).to.be.true; // eslint-disable-line no-unused-expressions, max-len }); it('should call `onBlur` when we remove the focus from the input', () => { const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len TestUtils.Simulate.focus(geoSuggestInput); geoSuggestInput.value = 'New'; TestUtils.Simulate.change(geoSuggestInput); TestUtils.Simulate.blur(geoSuggestInput); expect(onBlur.withArgs('New').calledOnce).to.be.true; // eslint-disable-line no-unused-expressions, max-len }); it('should call `onChange` when we change the input value', () => { const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len geoSuggestInput.value = 'New'; TestUtils.Simulate.change(geoSuggestInput); expect(onChange.withArgs('New').calledOnce).to.be.true; // eslint-disable-line no-unused-expressions, max-len }); it('should call `onChange` when the update method is called', () => { component.update('New'); expect(onChange.withArgs('New').calledOnce).to.be.true; // eslint-disable-line no-unused-expressions, max-len }); it('should call `onKeyPress` when we key press in the input', () => { const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len TestUtils.Simulate.keyPress(geoSuggestInput); expect(onKeyPress.calledOnce).to.be.true; // eslint-disable-line no-unused-expressions, max-len }); it('should clear the input text when calling `clear`', () => { const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len geoSuggestInput.value = 'New'; TestUtils.Simulate.change(geoSuggestInput); component.clear(); expect(geoSuggestInput.value).to.equal(''); }); it('should not change the active suggest while it remains in the list', () => { // eslint-disable-line max-len const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len geoSuggestInput.value = 'Ne'; TestUtils.Simulate.change(geoSuggestInput); TestUtils.Simulate.focus(geoSuggestInput); TestUtils.Simulate.keyDown(geoSuggestInput, { key: 'keyDown', keyCode: 40, which: 40 }); geoSuggestInput.value = 'New'; TestUtils.Simulate.change(geoSuggestInput); TestUtils.Simulate.keyDown(geoSuggestInput, { key: 'Enter', keyCode: 13, which: 13 }); expect(onSuggestSelect.args[0][0].placeId).to.equal(onActivateSuggest.args[0][0].placeId); // eslint-disable-line max-len }); it('should reset the active suggest when it disappears from the list', () => { // eslint-disable-line max-len const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len geoSuggestInput.value = 'Ne'; TestUtils.Simulate.change(geoSuggestInput); TestUtils.Simulate.keyDown(geoSuggestInput, { key: 'keyDown', keyCode: 40, which: 40 }); geoSuggestInput.value = ''; TestUtils.Simulate.change(geoSuggestInput); TestUtils.Simulate.keyDown(geoSuggestInput, { key: 'Enter', keyCode: 13, which: 13 }); expect(onActivateSuggest.args.length).to.be.equal(0); // eslint-disable-line max-len }); it('should deactivate the active suggest when pressing arrow down on the last suggest', () => { // eslint-disable-line max-len const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len geoSuggestInput.value = 'Ne'; TestUtils.Simulate.change(geoSuggestInput); const geoSuggestItems = TestUtils.scryRenderedDOMComponentsWithClass(component, 'geosuggest__item'); // eslint-disable-line max-len, one-var for (let i = 0; i < geoSuggestItems.length + 1; i++) { TestUtils.Simulate.keyDown(geoSuggestInput, { key: 'keyDown', keyCode: 40, which: 40 }); } const activeItems = TestUtils.scryRenderedDOMComponentsWithClass(component, 'geosuggest__item--active'); // eslint-disable-line max-len, one-var expect(activeItems.length).to.be.equal(0); }); it('should activate the last suggest in the list when pressing arrow up', () => { // eslint-disable-line max-len const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len geoSuggestInput.value = 'New'; TestUtils.Simulate.change(geoSuggestInput); TestUtils.Simulate.focus(geoSuggestInput); TestUtils.Simulate.keyDown(geoSuggestInput, { key: 'keyUp', keyCode: 38, which: 38 }); const allItems = TestUtils.scryRenderedDOMComponentsWithClass(component, 'geosuggest__item'), // eslint-disable-line max-len, one-var activeItem = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__item--active'); // eslint-disable-line max-len expect(activeItem).to.be.equal(allItems[allItems.length - 1]); }); it('should have the focus after calling `focus`', () => { component.focus(); expect(document.activeElement.classList.contains('geosuggest__input')).to.be.true; // eslint-disable-line no-unused-expressions, max-len }); it('should add external inline `style` to input component', () => { // eslint-disable-line max-len const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len expect(geoSuggestInput.style['border-color']).to.be.equal('#000'); }); it('should add external inline `style` to suggestList component', () => { // eslint-disable-line max-len const geoSuggestList = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__suggests'); // eslint-disable-line max-len expect(geoSuggestList.style['border-color']).to.be.equal('#000'); }); it('should add external inline `style` to suggestItem component', () => { // eslint-disable-line max-len const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len geoSuggestInput.value = 'New'; TestUtils.Simulate.change(geoSuggestInput); TestUtils.Simulate.focus(geoSuggestInput); const geoSuggestItems = TestUtils.scryRenderedDOMComponentsWithClass(component, 'geosuggest__item'); // eslint-disable-line max-len, one-var expect(geoSuggestItems[0].style['border-color']).to.be.equal('#000'); }); it('should hide the suggestion box when there are no suggestions', () => { const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'), // eslint-disable-line max-len geoSuggestList = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__suggests'); // eslint-disable-line max-len geoSuggestInput.value = 'There is no result for this. Really.'; TestUtils.Simulate.change(geoSuggestInput); expect(geoSuggestList.classList.contains('geosuggest__suggests--hidden')).to.be.true; // eslint-disable-line max-len, no-unused-expressions }); it('should call `onSuggestNoResults` when there are no suggestions', () => { const input = component.refs.input, geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len input.value = 'There is no result for this. Really.'; TestUtils.Simulate.change(geoSuggestInput); TestUtils.Simulate.focus(geoSuggestInput); expect(onSuggestNoResults.calledOnce).to.be.true; // eslint-disable-line max-len, no-unused-expressions }); it('should call onSuggestSelect on enter', () => { const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len geoSuggestInput.value = 'New'; TestUtils.Simulate.change(geoSuggestInput); TestUtils.Simulate.keyDown(geoSuggestInput, { key: 'Enter', keyCode: 13, which: 13 }); expect(onSuggestSelect.calledOnce).to.be.true; // eslint-disable-line no-unused-expressions, max-len }); it('should call onSuggestSelect on tab', () => { const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len geoSuggestInput.value = 'New'; TestUtils.Simulate.change(geoSuggestInput); TestUtils.Simulate.keyDown(geoSuggestInput, { key: 'Tab', keyCode: 9, which: 9 }); expect(onSuggestSelect.calledOnce).to.be.true; // eslint-disable-line no-unused-expressions, max-len }); }); describe('with tab ignored', () => { beforeEach(() => render({ignoreTab: true})); it('should not call onSuggestSelect on tab', () => { const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len geoSuggestInput.value = 'New'; TestUtils.Simulate.keyDown(geoSuggestInput, { key: 'Tab', keyCode: 9, which: 9 }); expect(onSuggestSelect.calledOnce).to.be.false; // eslint-disable-line no-unused-expressions, max-len }); }); describe('with fixtures', () => { const fixtures = [ {label: 'New York', location: {lat: 40.7033127, lng: -73.979681}}, {label: 'Rio', location: {lat: -22.066452, lng: -42.9232368}}, {label: 'Tokyo', location: {lat: 35.673343, lng: 139.710388}} ]; beforeEach(() => render({fixtures})); it('should show the fixtures on focus when the input is empty', () => { const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len TestUtils.Simulate.focus(geoSuggestInput); const suggestItems = TestUtils.scryRenderedDOMComponentsWithClass(component, 'geosuggest__item'); // eslint-disable-line max-len, one-var expect(suggestItems.length).to.equal(fixtures.length); }); it('should filter the fixtures depending on the user input', () => { const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len geoSuggestInput.value = 'Rio'; TestUtils.Simulate.change(geoSuggestInput); TestUtils.Simulate.focus(geoSuggestInput); const suggests = TestUtils.scryRenderedDOMComponentsWithClass(component, 'geosuggest__item'); // eslint-disable-line max-len, one-var expect(suggests.length).to.be.equal(1); }); it('should fire `onSuggestSelect` when selecting a fixture', () => { const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len geoSuggestInput.value = 'Rio'; TestUtils.Simulate.change(geoSuggestInput); TestUtils.Simulate.keyDown(geoSuggestInput, { key: 'keyDown', keyCode: 40, which: 40 }); TestUtils.Simulate.keyDown(geoSuggestInput, { key: 'Enter', keyCode: 13, which: 13 }); expect(onSuggestSelect.calledOnce).to.be.true; // eslint-disable-line no-unused-expressions, max-len }); it('should show the fixtures when pressing arrow up', () => { const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'), // eslint-disable-line max-len suggest = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__suggests'); // eslint-disable-line max-len expect(suggest.classList.contains('geosuggest__suggests--hidden')).to.be.true; // eslint-disable-line no-unused-expressions, max-len TestUtils.Simulate.keyDown(geoSuggestInput, { key: 'keyUp', keyCode: 38, which: 38 }); expect(suggest.classList.contains('geosuggest__suggests--hidden')).to.be.false; // eslint-disable-line no-unused-expressions, max-len }); }); describe('with autoActivateFirstSuggest enabled', () => { const props = { autoActivateFirstSuggest: true }; beforeEach(() => render(props)); it('should not activate a suggest before focus', () => { const activeItems = TestUtils.scryRenderedDOMComponentsWithClass(component, 'geosuggest__item--active'); // eslint-disable-line max-len expect(activeItems.length).to.be.equal(0); expect(onActivateSuggest.called).to.be.false; // eslint-disable-line no-unused-expressions, max-len }); it('should call `onActivateSuggest` when auto-activating the first suggest', () => { // eslint-disable-line max-len const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len geoSuggestInput.value = 'New'; TestUtils.Simulate.change(geoSuggestInput); TestUtils.Simulate.focus(geoSuggestInput); expect(onActivateSuggest.calledOnce).to.be.true; // eslint-disable-line no-unused-expressions, max-len }); it('should not change the active suggest when it is set already', () => { const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len geoSuggestInput.value = 'New'; TestUtils.Simulate.change(geoSuggestInput); geoSuggestInput.value = 'New York'; TestUtils.Simulate.change(geoSuggestInput); TestUtils.Simulate.focus(geoSuggestInput); expect(onActivateSuggest.calledOnce).to.be.true; // eslint-disable-line no-unused-expressions, max-len }); it('should activate a suggest once there is some input', done => { const geoSuggestInput = TestUtils.findRenderedDOMComponentWithClass(component, 'geosuggest__input'); // eslint-disable-line max-len geoSuggestInput.value = 'New'; TestUtils.Simulate.change(geoSuggestInput); TestUtils.Simulate.focus(geoSuggestInput); setImmediate(() => { const activeItems = TestUtils.scryRenderedDOMComponentsWithClass(component, 'geosuggest__item--active'); // eslint-disable-line max-len expect(activeItems.length).to.be.equal(1); done(); }); }); }); describe('with label and id props', () => { const props = { id: 'geosuggest-id', label: 'some label' }; beforeEach(() => render(props)); it('should render a <label> if the `label` and `id` props were supplied', () => { // eslint-disable-line max-len const label = TestUtils.findRenderedDOMComponentWithTag(component, 'label'); // eslint-disable-line max-len expect(label).to.not.equal(null); }); }); describe('without label and id props', () => { beforeEach(() => render()); it('should not render a <label> if no `label` and `id` props were supplied', () => { // eslint-disable-line max-len expect(() => TestUtils.findRenderedDOMComponentWithTag(component, 'label') ).to.throw(Error); }); }); });