diff --git a/frontend/redux/nodes/entities/base/base_config.js b/frontend/redux/nodes/entities/base/base_config.js index 20a51cb94a..eae7313e70 100644 --- a/frontend/redux/nodes/entities/base/base_config.js +++ b/frontend/redux/nodes/entities/base/base_config.js @@ -162,6 +162,7 @@ class BaseConfig { } _genericThunkAction (type, options = {}) { + const { TYPES } = BaseConfig; const apiCall = this._apiCallForType(type); return (...args) => { @@ -172,7 +173,13 @@ class BaseConfig { return apiCall(...args) .then((response) => { - const thunk = this._genericSuccess(type); + let thunk = this._genericSuccess(type); + if (type === TYPES.DESTROY) { + // Destroy is a special case in which the API does not return an + // object, so we need to generate a thunk that stores the entity + // ID for removal from the entity store. + thunk = this._destroySuccess(...args); + } dispatch(this.successAction(response, thunk)); @@ -227,6 +234,19 @@ class BaseConfig { }; } + _destroySuccess (entity) { + const { actionTypes } = this; + + return () => { + // No data should be returned from a DELETE API call, and instead the + // payload should be the ID of the entity deleted. + return { + type: actionTypes.DESTROY_SUCCESS, + payload: { data: entity.id }, + }; + }; + } + _genericFailure (type) { const { actionTypes } = this; diff --git a/frontend/redux/nodes/entities/base/config.tests.js b/frontend/redux/nodes/entities/base/config.tests.js index d0aca6f3ef..07df2ff7b5 100644 --- a/frontend/redux/nodes/entities/base/config.tests.js +++ b/frontend/redux/nodes/entities/base/config.tests.js @@ -164,13 +164,13 @@ describe('ReduxConfig - class', () => { }); }); - describe('#destroySuccess', () => { - it('sets the data in the payload', () => { - const data = { id: 1, name: 'Mike' }; + describe('#_destroySuccess', () => { + it('sets the data in the request', () => { + const data = { id: 1 }; - expect(actions.destroySuccess(data)).toEqual({ + expect(config._destroySuccess(data)()).toEqual({ type: 'users_DESTROY_SUCCESS', - payload: { data }, + payload: { data: data.id }, }); }); }); diff --git a/frontend/redux/nodes/entities/base/config_thunks.tests.js b/frontend/redux/nodes/entities/base/config_thunks.tests.js index 4a269d6c37..ea63c00462 100644 --- a/frontend/redux/nodes/entities/base/config_thunks.tests.js +++ b/frontend/redux/nodes/entities/base/config_thunks.tests.js @@ -134,10 +134,10 @@ describe('ReduxConfig - thunks', () => { schema: schemas.USERS, }); const mockStore = reduxMockStore(store); + beforeEach(() => { mockStore.clearActions(); }); + const params = { id: 1 }; it('calls the destroyFunc', () => { - const params = { id: 1 }; - return mockStore.dispatch(config.actions.destroy(params)) .then(() => { expect(destroyFunc).toHaveBeenCalledWith(params); @@ -145,14 +145,13 @@ describe('ReduxConfig - thunks', () => { }); it('dispatches the correct actions', () => { - return mockStore.dispatch(config.actions.destroy()) + return mockStore.dispatch(config.actions.destroy(params)) .then(() => { const dispatchedActions = mockStore.getActions(); - const dispatchedActionTypes = dispatchedActions.map((action) => { return action.type; }); - - expect(dispatchedActionTypes).toInclude('users_DESTROY_REQUEST'); - expect(dispatchedActionTypes).toInclude('users_DESTROY_SUCCESS'); - expect(dispatchedActionTypes).toNotInclude('users_DESTROY_FAILURE'); + expect(dispatchedActions).toEqual([ + { type: 'users_DESTROY_REQUEST' }, + { type: 'users_DESTROY_SUCCESS', payload: { data: params.id } }, + ]); }); }); }); @@ -438,4 +437,3 @@ describe('ReduxConfig - thunks', () => { }); }); }); -