Skip to content

Commit

Permalink
fix: thunks in production intercepted
Browse files Browse the repository at this point in the history
  • Loading branch information
rgommezz committed Jul 31, 2017
1 parent ad9d283 commit ec11280
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 42 deletions.
43 changes: 13 additions & 30 deletions src/__tests__/createNetworkMiddleware.spec.js
Expand Up @@ -167,11 +167,14 @@ describe('createNetworkMiddleware with thunks', () => {
}, 1000);
});

function fetchThunk(dispatch) {
function fetchData(dispatch) {
dispatch({ type: 'FETCH_DATA_REQUEST' });
return fetchMockData(dispatch);
}
function anotherThunk(dispatch) {

fetchData.interceptInOffline = true;

function fetchSomethingWithoutInterception(dispatch) {
return dispatch({ type: 'TOGGLE_DROPDOWN' });
}

Expand All @@ -187,9 +190,10 @@ describe('createNetworkMiddleware with thunks', () => {
};
const store = mockStore(initialState);

store.dispatch(anotherThunk);
store.dispatch(fetchSomethingWithoutInterception);

const actions = store.getActions();
// The action went through and was dispatched
expect(actions).toEqual([{ type: 'TOGGLE_DROPDOWN' }]);
});

Expand All @@ -205,29 +209,29 @@ describe('createNetworkMiddleware with thunks', () => {
};
const store = mockStore(initialState);

store.dispatch(fetchThunk);
store.dispatch(fetchData);

const actions = store.getActions();
expect(actions).toEqual([actionCreators.fetchOfflineMode(fetchThunk)]);
expect(actions).toEqual([actionCreators.fetchOfflineMode(fetchData)]);
});

it('thunk enqueued, regex MATCHES criteria, back ONLINE -> thunk gets redispatched', () => {
const networkMiddleware = createNetworkMiddleware();
const middlewares = [networkMiddleware, thunk];
const mockStore = configureStore(middlewares);
fetchThunk.retry = true;
fetchData.retry = true;
const initialState = {
network: {
isConnected: true,
actionQueue: [fetchThunk],
actionQueue: [fetchData],
},
};
const store = mockStore(initialState);

store.dispatch(fetchThunk).then(() => {
store.dispatch(fetchData).then(() => {
const actions = store.getActions();
expect(actions).toEqual([
actionCreators.removeActionFromQueue(fetchThunk),
actionCreators.removeActionFromQueue(fetchData),
{ type: 'FETCH_DATA_REQUEST' },
{ type: 'FETCH_DATA_SUCCESS' },
]);
Expand Down Expand Up @@ -410,25 +414,4 @@ describe('createNetworkMiddleware with wrong type params', () => {
'You should pass an array as actionTypes param',
);
});

it('invalid regexFunctionName', () => {
const initialState = {
network: {
isConnected: false,
actionQueue: [],
},
};
const networkMiddleware = createNetworkMiddleware({
regexFunctionName: 'REFRESH',
});
const middlewares = [networkMiddleware];
const mockStore = configureStore(middlewares);

const store = mockStore(initialState);
const action = getFetchAction('REFRESH_DATA');

expect(() => store.dispatch(action)).toThrow(
'You should pass a regex as regexFunctionName param',
);
});
});
14 changes: 2 additions & 12 deletions src/createNetworkMiddleware.js
Expand Up @@ -20,15 +20,10 @@ type State = {
type Arguments = {|
regexActionType: RegExp,
actionTypes: Array<string>,
regexFunctionName: RegExp,
|};

function createNetworkMiddleware(
{
regexActionType = /FETCH.*REQUEST/,
actionTypes = [],
regexFunctionName = /fetch/,
}: Arguments = {},
{ regexActionType = /FETCH.*REQUEST/, actionTypes = [] }: Arguments = {},
) {
return ({ getState }: MiddlewareAPI<State>) => (
next: (action: any) => void,
Expand All @@ -39,19 +34,14 @@ function createNetworkMiddleware(
if ({}.toString.call(actionTypes) !== '[object Array]')
throw new Error('You should pass an array as actionTypes param');

if ({}.toString.call(regexFunctionName) !== '[object RegExp]')
throw new Error('You should pass a regex as regexFunctionName param');

const { isConnected, actionQueue } = getState().network;

const isObjectAndMatchCondition =
typeof action === 'object' &&
(regexActionType.test(action.type) || actionTypes.includes(action.type));

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name
// in ECMAScript 2015, variables and methods can infer the name of an anonymous function from its syntactic position
const isFunctionAndMatchCondition =
typeof action === 'function' && regexFunctionName.test(action.name);
typeof action === 'function' && action.interceptInOffline === true;

if (isObjectAndMatchCondition || isFunctionAndMatchCondition) {
if (isConnected === false) {
Expand Down

0 comments on commit ec11280

Please sign in to comment.