UNPKG

react-route-hook

Version:

A simple React Component for adding onEnter and onChange Hooks to the Route Component of react-router v4

202 lines (193 loc) 8.34 kB
import React from 'react'; import { Route, MemoryRouter } from 'react-router'; import { shallow, configure, mount } from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; import chai, { expect } from 'chai'; import sinon from 'sinon'; import sinonChai from 'sinon-chai'; import PropTypes from 'prop-types'; import RouteHook from '../src/index'; import ArtistsContainer from './ArtistsContainer'; import Search from './Search'; chai.use(sinonChai); configure({ adapter: new Adapter() }); const Test = () => ( <div>Hola</div> ); class Transition extends React.Component { componentDidMount() { this.props.history.push('/test/1'); } render() { return <RouteHook path="/test" exact={this.props.exact} component={Test} onChange={this.props.spy} onLeave={this.props.spy} />; } } Transition.propTypes = { history: PropTypes.shape({ push: PropTypes.func }).isRequired, spy: PropTypes.func.isRequired, exact: PropTypes.bool, }; Transition.defaultProps = { exact: false, }; describe('RouteHook', () => { it('returns a Route', () => { const wrapper = shallow(<RouteHook />); expect(wrapper.find(Route)).to.have.lengthOf(1); }); it('render the component when route match', () => { const router = ( <MemoryRouter initialEntries={['/test']}> <RouteHook path="/test" component={Test} /> </MemoryRouter> ); const wrapper = mount(router); expect(wrapper.find(Test)).to.have.lengthOf(1); }); it('render the render when route match', () => { const router = ( <MemoryRouter initialIndex={0} initialEntries={['/test']}> <RouteHook path="/test" render={Test} /> </MemoryRouter> ); const wrapper = mount(router); expect(wrapper.contains(Test())).to.equal(true); }); it('should run the function onEnter when component is mounted', () => { const spy = sinon.spy(); const router = ( <MemoryRouter initialIndex={0} initialEntries={['/test']}> <RouteHook path="/test" component={Test} onEnter={spy} /> </MemoryRouter> ); mount(router); expect(spy).to.have.been.calledOnce; // eslint-disable-line no-unused-expressions }); it('shouldn\'t run the function onEnter if the component is not mounted', () => { const spy = sinon.spy(); const router = ( <MemoryRouter initialIndex={0} initialEntries={['/wrong']}> <RouteHook path="/test" component={Test} onEnter={spy} /> </MemoryRouter> ); mount(router); expect(spy).to.not.have.been.called; // eslint-disable-line no-unused-expressions }); it('the onEnter function should receive the router props as arguments', () => { const spy = sinon.spy(); const router = ( <MemoryRouter initialIndex={0} initialEntries={['/test']}> <RouteHook path="/test" component={Test} onEnter={spy} /> </MemoryRouter> ); mount(router); expect(spy.args[0][0].match).to.exist; // eslint-disable-line no-unused-expressions expect(spy.args[0][0].location).to.exist; // eslint-disable-line no-unused-expressions expect(spy.args[0][0].history).to.exist; // eslint-disable-line no-unused-expressions }); it('the rendered component should receive the router props', () => { const router = ( <MemoryRouter initialIndex={0} initialEntries={['/test']}> <RouteHook path="/test" component={Test} /> </MemoryRouter> ); const wrapper = mount(router); expect(wrapper.find(Test).prop('match')).to.exist; // eslint-disable-line no-unused-expressions expect(wrapper.find(Test).prop('location')).to.exist; // eslint-disable-line no-unused-expressions expect(wrapper.find(Test).prop('history')).to.exist; // eslint-disable-line no-unused-expressions }); it('the rendered by render component should receive the router props', () => { const router = ( <MemoryRouter initialIndex={0} initialEntries={['/test']}> <RouteHook path="/test" render={Test} /> </MemoryRouter> ); const wrapper = mount(router); expect(wrapper.find(Test).prop('match')).to.exist; // eslint-disable-line no-unused-expressions expect(wrapper.find(Test).prop('location')).to.exist; // eslint-disable-line no-unused-expressions expect(wrapper.find(Test).prop('history')).to.exist; // eslint-disable-line no-unused-expressions }); it('should run the onChange function when the url changes', () => { const spy = sinon.spy(); const router = ( <MemoryRouter initialIndex={0} initialEntries={['/test']}> <Route path="/" render={props => <Transition {...props} spy={spy} />} /> </MemoryRouter> ); mount(router); expect(spy).to.have.been.calledOnce; // eslint-disable-line no-unused-expressions }); it('should run the onChange function with old routerProps and newOnes', () => { const spy = sinon.spy(); const router = ( <MemoryRouter initialIndex={0} initialEntries={['/test']}> <Route path="/" render={props => <Transition {...props} spy={spy} />} /> </MemoryRouter> ); mount(router); expect(spy.args[0][0].match).to.exist; // eslint-disable-line no-unused-expressions expect(spy.args[0][0].location).to.exist; // eslint-disable-line no-unused-expressions expect(spy.args[0][0].history).to.exist; // eslint-disable-line no-unused-expressions expect(spy.args[0][1].match).to.exist; // eslint-disable-line no-unused-expressions expect(spy.args[0][1].location).to.exist; // eslint-disable-line no-unused-expressions expect(spy.args[0][1].history).to.exist; // eslint-disable-line no-unused-expressions expect(spy.args[0][1].location.pathname).to.equal('/test'); expect(spy.args[0][0].location.pathname).to.equal('/test/1'); }); it('should run the onLeave function when the url changes and the component unmounts', () => { const spy = sinon.spy(); const router = ( <MemoryRouter initialIndex={0} initialEntries={['/test']}> <Route path="/" render={props => <Transition exact {...props} spy={spy} />} /> </MemoryRouter> ); mount(router); expect(spy).to.have.been.calledOnce; // eslint-disable-line no-unused-expressions }); it('should run the onLeave function with the routerProps', () => { const spy = sinon.spy(); const router = ( <MemoryRouter initialIndex={0} initialEntries={['/test']}> <Route path="/" render={props => <Transition exact {...props} spy={spy} />} /> </MemoryRouter> ); mount(router); expect(spy.args[0][0].match).to.exist; // eslint-disable-line no-unused-expressions expect(spy.args[0][0].location).to.exist; // eslint-disable-line no-unused-expressions expect(spy.args[0][0].history).to.exist; // eslint-disable-line no-unused-expressions expect(spy.args[0][0].location.pathname).to.equal('/test'); expect(spy.args[0]).to.have.lengthOf(1); }); it('should run the onEnter function when it changes for similar routes with switch', () => { const artistsSpy = sinon.spy(); const artistSpy = sinon.spy(); const router = ( <MemoryRouter initialIndex={0} initialEntries={['/artists']}> <Route path="/" render={props => <ArtistsContainer {...props} artistsSpy={artistsSpy} artistSpy={artistSpy} />} /> </MemoryRouter> ); mount(router); expect(artistsSpy).to.have.been.calledOnce; // eslint-disable-line no-unused-expressions expect(artistSpy).to.have.been.calledOnce; // eslint-disable-line no-unused-expressions }); it('shouldn`t run onEnter when search query changes', () => { const onEnter = sinon.spy(); const router = ( <MemoryRouter initialIndex={0} initialEntries={['/search']}> <Route path="/" render={props => <Search {...props} onEnter={onEnter} />} /> </MemoryRouter> ); mount(router); expect(onEnter).to.have.been.calledOnce; // eslint-disable-line no-unused-expressions }); it('should run onChange when search query changes', () => { const onChange = sinon.spy(); const router = ( <MemoryRouter initialIndex={0} initialEntries={['/search']}> <Route path="/" render={props => <Search {...props} onChange={onChange} />} /> </MemoryRouter> ); mount(router); expect(onChange).to.have.been.calledOnce; // eslint-disable-line no-unused-expressions }); });