From db2d698c05b42b315c78641fecf7f4a5ec32b03a Mon Sep 17 00:00:00 2001 From: Vladimir Metnev Date: Mon, 19 Feb 2018 01:35:20 +0200 Subject: [PATCH] feat(reducer-layout): update layout reducer and test --- src/common/reducers/layout/index.js | 51 +++++----------- src/common/reducers/layout/index.test.js | 74 +++++++++--------------- 2 files changed, 42 insertions(+), 83 deletions(-) diff --git a/src/common/reducers/layout/index.js b/src/common/reducers/layout/index.js index 683641b9..c717f814 100644 --- a/src/common/reducers/layout/index.js +++ b/src/common/reducers/layout/index.js @@ -1,64 +1,43 @@ // @flow import { - UI_OPEN_SIDEBAR, - UI_CLOSE_SIDEBAR, + UI_TOGGLE_SIDEBAR, UI_WINDOW_RESIZE } from 'actions/layout' import {LOCATION_CHANGE} from 'actions/common' -// -import type {LOCATION_CHANGE_TYPE} from 'actions/common' -import type { - UI_OPEN_SIDEBAR_TYPE, - UI_CLOSE_SIDEBAR_TYPE, - UI_WINDOW_RESIZE_TYPE -} from 'actions/layout' +import {computeLayoutMobileStatuses} from 'selectors' export type State = { sidebarOpened: boolean, - isMobile: boolean, - isMobileXS: boolean, - isMobileSM: boolean + innerWidth?: number } -type Action = - | UI_OPEN_SIDEBAR_TYPE - | UI_CLOSE_SIDEBAR_TYPE - | UI_WINDOW_RESIZE_TYPE - | LOCATION_CHANGE_TYPE - +// NOTE: sidebar is opened by default and rendered as visible on server export const initialState: State = { - sidebarOpened: false, - isMobile: false, - isMobileXS: false, - isMobileSM: false + sidebarOpened: true, + innerWidth: 993 } -export function layout (state: State = initialState, action: Action): State { - const computeMobileStatuses = (innerWidth: number) => { - const isMobile: boolean = innerWidth < 1025 // 1024px - is the main breakpoint in ui - const isMobileXS: boolean = innerWidth < 481 - const isMobileSM: boolean = innerWidth > 480 && innerWidth < 767 - return {isMobileSM, isMobileXS, isMobile} - } +export function layout (state: State = initialState, action): State { switch (action.type) { case UI_WINDOW_RESIZE: { const {innerWidth} = action.payload - const mobileStates = computeMobileStatuses(innerWidth) + const {isMobile} = computeLayoutMobileStatuses({innerWidth}) + return { - ...state, - ...mobileStates + innerWidth, + sidebarOpened: !isMobile } } - case UI_OPEN_SIDEBAR: + case UI_TOGGLE_SIDEBAR: return { ...state, - sidebarOpened: true + sidebarOpened: !state.sidebarOpened } case LOCATION_CHANGE: - case UI_CLOSE_SIDEBAR: + const {isMobile} = computeLayoutMobileStatuses(state) return { ...state, - sidebarOpened: false + sidebarOpened: !isMobile } default: return state diff --git a/src/common/reducers/layout/index.test.js b/src/common/reducers/layout/index.test.js index 773a9478..91d66c87 100644 --- a/src/common/reducers/layout/index.test.js +++ b/src/common/reducers/layout/index.test.js @@ -1,80 +1,60 @@ import {layout as reducer, initialState} from 'reducers/layout' -import { - UI_CLOSE_SIDEBAR, - UI_OPEN_SIDEBAR, - UI_WINDOW_RESIZE -} from 'actions/layout' +import {UI_TOGGLE_SIDEBAR, UI_WINDOW_RESIZE} from 'actions/layout' import {LOCATION_CHANGE} from 'actions/common' -const closeSidebar = { - type: UI_CLOSE_SIDEBAR -} - -const openSidebar = { - type: UI_OPEN_SIDEBAR +const toggleSidebar = { + type: UI_TOGGLE_SIDEBAR } const locationChange = { type: LOCATION_CHANGE } -const windowResize = { - type: UI_WINDOW_RESIZE, - payload: { - innerWidth: 1280 - } -} - -const appInit = { - type: UI_WINDOW_RESIZE, - payload: { - innerWidth: 360 - } -} +const windowResize = (innerWidth) => ({type: UI_WINDOW_RESIZE, payload: {innerWidth}}) describe('LAYOUT REDUCER', () => { it('should return the initial state', () => { expect(reducer(undefined, {x: 'string'})).toEqual(initialState) }) - it('should handle UI_OPEN_SIDEBAR', () => { - expect(reducer(initialState, openSidebar)).toEqual({ - ...initialState, + it('should handle UI_TOGGLE_SIDEBAR', () => { + expect( + reducer({innerWidth: 480, sidebarOpened: false}, toggleSidebar) + ).toEqual({ + innerWidth: 480, sidebarOpened: true }) }) - describe('Mobile properties', () => { + describe('Mobile properties WINDOW_RESIZE', () => { it('should handle WINDOW_RESIZE with 360px screen', () => { - expect(reducer(initialState, appInit)).toEqual({ - ...initialState, - isMobile: true, - isMobileXS: true, - isMobileSM: false + expect(reducer(initialState, windowResize(360))).toEqual({ + sidebarOpened: false, + innerWidth: 360 }) }) it('should handle WINDOW_RESIZE with 1280px screen', () => { - expect(reducer(initialState, windowResize)).toEqual({ - ...initialState, - isMobile: false, - isMobileXS: false, - isMobileSM: false + expect(reducer(initialState, windowResize(1280))).toEqual({ + sidebarOpened: true, + innerWidth: 1280 }) }) }) - it('should handle UI_CLOSE_SIDEBAR', () => { - expect(reducer(initialState, closeSidebar)).toEqual({ - ...initialState, - sidebarOpened: false + describe('LOCATION_CHANGE', () => { + it('should close sidebar on mobile after LOCATION_CHANGE', () => { + expect(reducer({sidebarOpened: true, innerWidth: 360}, locationChange)).toEqual({ + innerWidth: 360, + sidebarOpened: false + }) }) - }) - it('should handle LOCATION_CHANGE', () => { - expect(reducer(initialState, locationChange)).toEqual({ - ...initialState, - sidebarOpened: false + it('should NOT close sidebar on desktop after LOCATION_CHANGE', () => { + expect(reducer({sidebarOpened: true, innerWidth: 993}, locationChange)).toEqual({ + innerWidth: 993, + sidebarOpened: true + }) }) }) })