From 9d5533d60edcf5c22ade4c194e7dd6535d382cb7 Mon Sep 17 00:00:00 2001 From: Kimmo Puputti Date: Tue, 14 Feb 2017 20:32:00 +0200 Subject: [PATCH] Use withRouter HOC from react-router - Provides router props form the context - Changed API requires us to use the history.push function --- src/containers/Topbar/Topbar.js | 31 +++++++++++++++++-------------- src/ducks/Auth.ducks.js | 6 +++--- src/ducks/Auth.test.js | 26 +++++++++++++------------- 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/containers/Topbar/Topbar.js b/src/containers/Topbar/Topbar.js index 9ba0f6d3..00d892d6 100644 --- a/src/containers/Topbar/Topbar.js +++ b/src/containers/Topbar/Topbar.js @@ -1,25 +1,24 @@ import React, { PropTypes } from 'react'; import { connect } from 'react-redux'; -import { Link } from 'react-router-dom'; +import { Link, withRouter } from 'react-router-dom'; import { logout } from '../../ducks/Auth.ducks'; import css from './Topbar.css'; -const Topbar = (props, context) => { - const { isAuthenticated, onLogout, user } = props; - const { router } = context; +const Topbar = props => { + const { isAuthenticated, onLogout, user, push: historyPush } = props; const house = { dangerouslySetInnerHTML: { __html: '🏠' } }; const hamburger = { dangerouslySetInnerHTML: { __html: '🍔' } }; const handleChange = e => { const value = e.target.value; - router.transitionTo(value); + historyPush(value); }; const handleLogout = () => { - // Router is passed to the action to enable redirect to home when - // logout succeeds. - onLogout(router); + // History push function is passed to the action to enable + // redirect to home when logout succeeds. + onLogout(historyPush); }; return ( @@ -60,17 +59,21 @@ const Topbar = (props, context) => { Topbar.defaultProps = { user: null }; -const { bool, object, func, any } = PropTypes; +const { bool, object, func } = PropTypes; -Topbar.propTypes = { isAuthenticated: bool.isRequired, user: object, onLogout: func.isRequired }; - -Topbar.contextTypes = { router: any }; +Topbar.propTypes = { + isAuthenticated: bool.isRequired, + user: object, + onLogout: func.isRequired, + // history.push prop from withRouter + push: func.isRequired, +}; const mapStateToProps = state => ({ isAuthenticated: state.Auth.isAuthenticated, user: state.Auth.user, }); -const mapDispatchToProps = dispatch => ({ onLogout: router => dispatch(logout(router)) }); +const mapDispatchToProps = dispatch => ({ onLogout: historyPush => dispatch(logout(historyPush)) }); -export default connect(mapStateToProps, mapDispatchToProps)(Topbar); +export default connect(mapStateToProps, mapDispatchToProps)(withRouter(Topbar)); diff --git a/src/ducks/Auth.ducks.js b/src/ducks/Auth.ducks.js index f9e0a3d3..dfc6259e 100644 --- a/src/ducks/Auth.ducks.js +++ b/src/ducks/Auth.ducks.js @@ -58,7 +58,7 @@ export const login = (email, password) => ({ type: LOGIN_REQUEST, payload: { ema export const loginSuccess = user => ({ type: LOGIN_SUCCESS, payload: user }); export const loginError = error => ({ type: LOGIN_ERROR, payload: error, error: true }); -export const logout = router => ({ type: LOGOUT_REQUEST, payload: { router } }); +export const logout = historyPush => ({ type: LOGOUT_REQUEST, payload: { historyPush } }); export const logoutSuccess = () => ({ type: LOGOUT_SUCCESS }); export const logoutError = error => ({ type: LOGOUT_ERROR, payload: error, error: true }); @@ -77,11 +77,11 @@ export function* callLogin(action, sdk) { export function* callLogout(action, sdk) { const { payload } = action; - const { router } = payload; + const { historyPush } = payload; try { yield call(sdk.logout); yield put(logoutSuccess()); - yield call(router.transitionTo, '/'); + yield call(historyPush, '/'); } catch (e) { yield put(logoutError(e)); } diff --git a/src/ducks/Auth.test.js b/src/ducks/Auth.test.js index 3511cfd7..e194155d 100644 --- a/src/ducks/Auth.test.js +++ b/src/ducks/Auth.test.js @@ -93,28 +93,28 @@ describe('Auth duck', () => { describe('logout worker', () => { it('should redirect to root after logout', () => { const sdk = { logout: jest.fn() }; - const router = { transitionTo: jest.fn() }; - const action = logout(router); + const historyPush = jest.fn(); + const action = logout(historyPush); const worker = callLogout(action, sdk); expect(worker.next()).toEqual({ done: false, value: call(sdk.logout) }); expect(worker.next()).toEqual({ done: false, value: put(logoutSuccess()) }); - expect(worker.next()).toEqual({ done: false, value: call(router.transitionTo, '/') }); + expect(worker.next()).toEqual({ done: false, value: call(historyPush, '/') }); expect(worker.next().done).toEqual(true); expect(sdk.logout).not.toHaveBeenCalled(); - expect(router.transitionTo).not.toHaveBeenCalled(); + expect(historyPush).not.toHaveBeenCalled(); }); it('should not redirect if logout fails', () => { const sdk = { logout: jest.fn() }; - const router = { transitionTo: jest.fn() }; - const action = logout(router); + const historyPush = jest.fn(); + const action = logout(historyPush); const worker = callLogout(action, sdk); expect(worker.next()).toEqual({ done: false, value: call(sdk.logout) }); const error = new Error('Test logout error'); expect(worker.throw(error)).toEqual({ done: false, value: put(logoutError(error)) }); expect(worker.next().done).toEqual(true); expect(sdk.logout).not.toHaveBeenCalled(); - expect(router.transitionTo).not.toHaveBeenCalled(); + expect(historyPush).not.toHaveBeenCalled(); }); }); @@ -140,9 +140,9 @@ describe('Auth duck', () => { it('calls logout', () => { const sdk = { logout: jest.fn() }; - const router = { transitionTo: jest.fn() }; + const historyPush = jest.fn(); const watcher = watchAuth(sdk); - const logoutAction = logout(router); + const logoutAction = logout(historyPush); const takeLoginOrLogout = take([LOGIN_REQUEST, LOGOUT_REQUEST]); const forkLogout = fork(callLogout, logoutAction, sdk); @@ -156,7 +156,7 @@ describe('Auth duck', () => { expect(watcher.next().value).toEqual(takeLoginOrLogout); expect(sdk.logout).not.toHaveBeenCalled(); - expect(router.transitionTo).not.toHaveBeenCalled(); + expect(historyPush).not.toHaveBeenCalled(); }); it('should cancel login if another login comes', () => { @@ -195,10 +195,10 @@ describe('Auth duck', () => { it('should cancel login if a logout comes', () => { const sdk = { login: jest.fn(), logout: jest.fn() }; - const router = { transitionTo: jest.fn() }; + const historyPush = jest.fn(); const watcher = watchAuth(sdk); const loginAction = login('email', 'password'); - const logoutAction = logout(router); + const logoutAction = logout(historyPush); const task = createMockTask(); const takeLoginOrLogout = take([LOGIN_REQUEST, LOGOUT_REQUEST]); const forkLogin = fork(callLogin, loginAction, sdk); @@ -226,7 +226,7 @@ describe('Auth duck', () => { expect(sdk.login).not.toHaveBeenCalled(); expect(sdk.logout).not.toHaveBeenCalled(); - expect(router.transitionTo).not.toHaveBeenCalled(); + expect(historyPush).not.toHaveBeenCalled(); }); }); });