From 2d9408eaea697fcf9f1760fbc2bfd6d016682db8 Mon Sep 17 00:00:00 2001 From: Chris Chua Date: Sat, 16 May 2020 14:59:01 -0700 Subject: [PATCH] add reduxDevtoolsConfig token for configuration set up of redux devtools extension Some applications need to configure the behavior of Redux Devtools Extension. Allow customization of opting out of the setup altogether. --- .../__tests__/index.browser.js | 66 ++++++++++++++++++- fusion-plugin-react-redux/src/browser.js | 19 +++++- fusion-plugin-react-redux/src/tokens.js | 3 + 3 files changed, 84 insertions(+), 4 deletions(-) diff --git a/fusion-plugin-react-redux/__tests__/index.browser.js b/fusion-plugin-react-redux/__tests__/index.browser.js index 7205b483c6..9b7f000859 100644 --- a/fusion-plugin-react-redux/__tests__/index.browser.js +++ b/fusion-plugin-react-redux/__tests__/index.browser.js @@ -21,12 +21,13 @@ import { ReducerToken, PreloadedStateToken, EnhancerToken, + ReduxDevtoolsConfigToken, } from '../src/tokens.js'; Enzyme.configure({adapter: new Adapter()}); /* Test fixtures */ -const appCreator = (reducer, preloadedState, enhancer) => { +const appCreator = (reducer, preloadedState, enhancer, reduxDevToolsConfig) => { const app = new App('test', el => el); if (reducer) { app.register(ReducerToken, reducer); @@ -37,6 +38,9 @@ const appCreator = (reducer, preloadedState, enhancer) => { if (enhancer) { app.register(EnhancerToken, enhancer); } + if (reduxDevToolsConfig !== undefined && reduxDevToolsConfig !== null) { + app.register(ReduxDevtoolsConfigToken, reduxDevToolsConfig); + } return () => app; }; @@ -173,6 +177,66 @@ test('browser with devtools enhancer', () => { delete window.__REDUX_DEVTOOLS_EXTENSION__; }); +test('browser with devtools enhancer with custom devToolsConfig', () => { + const Redux = GetReduxPlugin(); + const reducer = (state, action) => { + return { + ...state, + test: action.payload || 1, + }; + }; + let enhancerCalls = 0; + let devToolsInitArg = null; + window.__REDUX_DEVTOOLS_EXTENSION__ = initArg => createStore => { + devToolsInitArg = initArg; + enhancerCalls++; + expect(typeof createStore).toBe('function'); + return (...args) => { + expect(args[0]).toBe(reducer); + return createStore(...args); + }; + }; + // https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/API/Arguments.md#actionsanitizer--statesanitizer + const customReduxDevtoolsConfig = { + actionSanitizer: action => action, + }; + const {store} = getService( + appCreator(reducer, null, null, customReduxDevtoolsConfig), + Redux + ).from(); + expect(store.getState()).toStrictEqual({test: 1}); + store.dispatch({type: 'CHANGE', payload: 2}); + expect(store.getState().test).toBe(2); + expect(devToolsInitArg).toEqual( + expect.objectContaining(customReduxDevtoolsConfig) + ); + expect(enhancerCalls).toBe(1); + delete window.__REDUX_DEVTOOLS_EXTENSION__; +}); + +test('browser with devtools enhancer, and devToolsConfig set to false', () => { + const Redux = GetReduxPlugin(); + const reducer = (state, action) => { + return { + ...state, + test: action.payload || 1, + }; + }; + let enhancerCalls = 0; + window.__REDUX_DEVTOOLS_EXTENSION__ = () => createStore => { + enhancerCalls++; + }; + const {store} = getService( + appCreator(reducer, null, null, false), + Redux + ).from(); + expect(store.getState()).toStrictEqual({test: 1}); + store.dispatch({type: 'CHANGE', payload: 2}); + expect(store.getState().test).toBe(2); + expect(enhancerCalls).toBe(0); + delete window.__REDUX_DEVTOOLS_EXTENSION__; +}); + test('browser with devtools enhancer and normal enhancer', () => { const Redux = GetReduxPlugin(); const reducer = (state, action) => { diff --git a/fusion-plugin-react-redux/src/browser.js b/fusion-plugin-react-redux/src/browser.js index 78c1ab7d50..3c3b0051ab 100644 --- a/fusion-plugin-react-redux/src/browser.js +++ b/fusion-plugin-react-redux/src/browser.js @@ -18,7 +18,12 @@ import type {Context, FusionPlugin} from 'fusion-core'; import ctxEnhancer from './ctx-enhancer'; import {deserialize} from './codec.js'; -import {ReducerToken, PreloadedStateToken, EnhancerToken} from './tokens.js'; +import { + ReducerToken, + PreloadedStateToken, + EnhancerToken, + ReduxDevtoolsConfigToken, +} from './tokens.js'; import type { StoreWithContextType, ReactReduxDepsType, @@ -32,8 +37,9 @@ const getPlugin = () => { reducer: ReducerToken, preloadedState: PreloadedStateToken.optional, enhancer: EnhancerToken.optional, + reduxDevToolsConfig: ReduxDevtoolsConfigToken.optional, }, - provides({reducer, preloadedState, enhancer}) { + provides({reducer, preloadedState, enhancer, reduxDevToolsConfig}) { class Redux { store: StoreWithContextType<*, *, *>; @@ -53,10 +59,17 @@ const getPlugin = () => { } } const devTool = + reduxDevToolsConfig !== false && __DEV__ && window.__REDUX_DEVTOOLS_EXTENSION__ && // $FlowFixMe - __REDUX_DEVTOOLS_EXTENSION__({trace: true, traceLimit: 25}); + __REDUX_DEVTOOLS_EXTENSION__({ + trace: true, + traceLimit: 25, + ...((typeof reduxDevToolsConfig === 'object' && + reduxDevToolsConfig) || + {}), + }); const enhancers = [enhancer, ctxEnhancer(ctx), devTool].filter( Boolean ); diff --git a/fusion-plugin-react-redux/src/tokens.js b/fusion-plugin-react-redux/src/tokens.js index b664788903..bb91f494d0 100644 --- a/fusion-plugin-react-redux/src/tokens.js +++ b/fusion-plugin-react-redux/src/tokens.js @@ -23,6 +23,9 @@ export const PreloadedStateToken: Token = createToken( export const EnhancerToken: Token> = createToken( 'EnhancerToken' ); +export const ReduxDevtoolsConfigToken: Token<{} | false> = createToken( + 'ReduxDevtoolsConfigToken' +); export const GetInitialStateToken: Token> = createToken( 'GetInitialStateToken' );