All files / src reducer.js

100% Statements 26/26
75% Branches 6/8
100% Functions 14/14
100% Lines 18/18
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80                  35x 10x 5x 10x 5x 5x   24x 1x 24x       25x               1x 10x               5x                 5x             1x           4x 4x 4x                                
import {
  ACTION_FETCH_START,
  ACTION_FETCH_COMPLETE,
  ACTION_FETCH_FAILURE,
  ACTION_UPDATE_LOCAL,
  ACTION_RESET_LOCAL,
} from './constants';
import handleActions from './utils/handleActions';
 
const getName = action => action.payload.name;
const getRequestedAt = action => action.payload.requestedAt;
const getRespondedAt = action => action.payload.respondedAt;
const getJSONResponse = action => action.payload.json;
const getError = action => action.payload.error;
const getPreviousError = (state, action) => state[getName(action)] ? state[getName(action)].error : null;
 
const includeString = (element, array) => array.indexOf(element) !== -1;
const resetOrKeepValue = (field, action, currentData) => (
  includeString(field, action.payload.data) ? undefined : currentData[field]
);
 
 
const updateWith = (state, name, obj) => ({
  ...state,
  [name]: {
    ...state[name],
    ...obj,
  },
});
 
const reducer = handleActions({
  [ACTION_FETCH_START]: (state, action) => updateWith(
    state,
    getName(action), {
      lastRequest: getRequestedAt(action),
      isFetching: !action.error,
      isInvalidated: true,
      error: action.error ? getError(action) : getPreviousError(state, action),
    }),
  [ACTION_FETCH_COMPLETE]: (state, action) => updateWith(
    state,
    getName(action), {
      isFetching: false,
      isInvalidated: false,
      lastResponse: getRespondedAt(action),
      data: getJSONResponse(action),
      error: null,
    }),
  [ACTION_FETCH_FAILURE]: (state, action) => updateWith(
    state,
    getName(action), {
      isFetching: false,
      isInvalidated: true,
      error: getJSONResponse(action),
    }),
  [ACTION_UPDATE_LOCAL]: (state, action) => updateWith(
    state,
    getName(action), {
      data: action.payload.data,
    }),
  [ACTION_RESET_LOCAL]: (state, action) => {
    const name = getName(action);
    const currentData = state[name] || {};
    return updateWith(
      state,
      name,
      {
        lastRequest: resetOrKeepValue('lastRequest', action, currentData),
        isFetching: resetOrKeepValue('isFetching', action, currentData),
        isInvalidated: resetOrKeepValue('isInvalidated', action, currentData),
        lastResponse: resetOrKeepValue('lastResponse', action, currentData),
        data: resetOrKeepValue('data', action, currentData),
        error: resetOrKeepValue('error', action, currentData),
      }
    );
  },
});
 
export default reducer;