diff --git a/recipe-server/client/control/state/actions/reducers.js b/recipe-server/client/control/state/actions/reducers.js index 83bb0020..4570c199 100644 --- a/recipe-server/client/control/state/actions/reducers.js +++ b/recipe-server/client/control/state/actions/reducers.js @@ -3,31 +3,15 @@ import { combineReducers } from 'redux'; import { ACTION_RECEIVE, - RECIPE_RECEIVE, - REVISION_RECEIVE, } from '../action-types'; function items(state = new Map(), action) { - let newActions; switch (action.type) { case ACTION_RECEIVE: return state.set(action.action.id, fromJS(action.action)); - case RECIPE_RECEIVE: - newActions = { - [action.recipe.latest_revision.action.id]: fromJS(action.recipe.latest_revision.action), - }; - if (action.recipe.approved_revision) { - newActions[action.recipe.approved_revision.action.id] = - fromJS(action.recipe.approved_revision.action); - } - return state.merge(newActions); - - case REVISION_RECEIVE: - return state.set(action.revision.recipe.action.id, fromJS(action.revision.recipe.action)); - default: return state; } diff --git a/recipe-server/client/control/state/recipes/actions.js b/recipe-server/client/control/state/recipes/actions.js index a7838b1f..d849bc40 100644 --- a/recipe-server/client/control/state/recipes/actions.js +++ b/recipe-server/client/control/state/recipes/actions.js @@ -1,4 +1,5 @@ import { + ACTION_RECEIVE, RECIPE_RECEIVE, RECIPE_FILTERS_RECEIVE, RECIPE_HISTORY_RECEIVE, @@ -10,15 +11,36 @@ import { } from '../requests/actions'; +function recipeReceived(dispatch, recipe) { + dispatch({ + type: RECIPE_RECEIVE, + recipe, + }); + + dispatch({ + type: ACTION_RECEIVE, + action: recipe.action, + }); + + dispatch({ + type: REVISION_RECEIVE, + revision: recipe.latest_revision, + }); + + if (recipe.approved_revision) { + dispatch({ + type: REVISION_RECEIVE, + revision: recipe.approved_revision, + }); + } +} + + export function fetchRecipe(pk) { return async dispatch => { const requestId = `fetch-recipe-${pk}`; const recipe = await dispatch(makeApiRequest(requestId, `v2/recipe/${pk}/`)); - - dispatch({ - type: RECIPE_RECEIVE, - recipe, - }); + recipeReceived(dispatch, recipe); }; } @@ -29,10 +51,7 @@ export function fetchAllRecipes() { const recipes = await dispatch(makeApiRequest(requestId, 'v2/recipe/')); recipes.forEach(recipe => { - dispatch({ - type: RECIPE_RECEIVE, - recipe, - }); + recipeReceived(dispatch, recipe); }); }; } diff --git a/recipe-server/client/control/state/recipes/reducers.js b/recipe-server/client/control/state/recipes/reducers.js index 9a9fcb62..40216a12 100644 --- a/recipe-server/client/control/state/recipes/reducers.js +++ b/recipe-server/client/control/state/recipes/reducers.js @@ -36,18 +36,18 @@ function items(state = new Map(), action) { switch (action.type) { case RECIPE_RECEIVE: recipe = fromJS(action.recipe); - recipe.set('action_id', action.recipe.action.id); - recipe.remove('action'); + recipe = recipe.set('action_id', action.recipe.action.id); + recipe = recipe.remove('action'); - recipe.set('latest_revision_id', action.recipe.latest_revision.id); - recipe.remove('latest_revision'); + recipe = recipe.set('latest_revision_id', action.recipe.latest_revision.id); + recipe = recipe.remove('latest_revision'); if (action.recipe.approved_revision) { - recipe.set('approved_revision_id', action.recipe.approved_revision.id); + recipe = recipe.set('approved_revision_id', action.recipe.approved_revision.id); } else { - recipe.set('approved_revision_id', null); + recipe = recipe.set('approved_revision_id', null); } - recipe.remove('approved_revision'); + recipe = recipe.remove('approved_revision'); return state.set(action.recipe.id, recipe); diff --git a/recipe-server/client/control/state/revisions/actions.js b/recipe-server/client/control/state/revisions/actions.js index 7e8626de..331e4dc0 100644 --- a/recipe-server/client/control/state/revisions/actions.js +++ b/recipe-server/client/control/state/revisions/actions.js @@ -1,4 +1,5 @@ import { + ACTION_RECEIVE, REVISION_RECEIVE, } from '../action-types'; @@ -7,15 +8,24 @@ import { } from '../requests/actions'; +function revisionReceived(dispatch, revision) { + dispatch({ + type: REVISION_RECEIVE, + revision, + }); + + dispatch({ + type: ACTION_RECEIVE, + action: revision.recipe.action, + }); +} + + export function fetchRevision(pk) { return async dispatch => { const requestId = `fetch-revision-${pk}`; const revision = await dispatch(makeApiRequest(requestId, `v2/recipe_revision/${pk}/`)); - - dispatch({ - type: REVISION_RECEIVE, - revision, - }); + revisionReceived(dispatch, revision); }; } @@ -26,10 +36,7 @@ export function fetchAllRevisions() { const revisions = await dispatch(makeApiRequest(requestId, 'v2/recipe_revision/')); revisions.forEach(revision => { - dispatch({ - type: REVISION_RECEIVE, - revision, - }); + revisionReceived(dispatch, revision); }); }; } diff --git a/recipe-server/client/control/state/revisions/reducers.js b/recipe-server/client/control/state/revisions/reducers.js index 70a4127b..8b63be4e 100644 --- a/recipe-server/client/control/state/revisions/reducers.js +++ b/recipe-server/client/control/state/revisions/reducers.js @@ -2,35 +2,20 @@ import { fromJS, Map } from 'immutable'; import { combineReducers } from 'redux'; import { - RECIPE_RECEIVE, REVISION_RECEIVE, } from '../action-types'; -function reduceRevision(revision) { - const reduced = fromJS(revision); - reduced.setIn(['recipe', 'action_id'], revision.recipe.action.id); - reduced.removeIn(['recipe', 'action']); - return reduced; -} - - function items(state = new Map(), action) { - let newRevisions; + let revision; switch (action.type) { - case RECIPE_RECEIVE: - newRevisions = { - [action.recipe.latest_revision.id]: reduceRevision(action.recipe.latest_revision), - }; - if (action.recipe.approved_revision) { - newRevisions[action.recipe.approved_revision.id] = - reduceRevision(action.recipe.approved_revision); - } - return state.merge(newRevisions); - case REVISION_RECEIVE: - return state.set(action.revision.id, reduceRevision(action.revision)); + revision = fromJS(action.revision); + revision = revision.setIn(['recipe', 'action_id'], action.revision.recipe.action.id); + revision = revision.removeIn(['recipe', 'action']); + + return state.set(action.revision.id, revision); default: return state; diff --git a/recipe-server/client/control/tests/state/recipes/index.js b/recipe-server/client/control/tests/state/recipes/index.js index 31eb0d9d..18e7c956 100644 --- a/recipe-server/client/control/tests/state/recipes/index.js +++ b/recipe-server/client/control/tests/state/recipes/index.js @@ -18,6 +18,10 @@ export const RECIPE = { id: '9f86d081', recipe: { id: 1, + action: { + id: 1, + name: 'test-action', + }, }, }, approved_revision: null, diff --git a/recipe-server/client/control/tests/state/recipes/test_reducers.js b/recipe-server/client/control/tests/state/recipes/test_reducers.js index 18234768..500078ae 100644 --- a/recipe-server/client/control/tests/state/recipes/test_reducers.js +++ b/recipe-server/client/control/tests/state/recipes/test_reducers.js @@ -1,4 +1,5 @@ import { fromJS, List } from 'immutable'; +import * as matchers from 'jasmine-immutable-matchers'; import { RECIPE_RECEIVE, @@ -19,18 +20,34 @@ import { describe('Recipes reducer', () => { + beforeEach(() => { + jasmine.addMatchers(matchers); + }); + it('should return initial state by default', () => { expect(recipesReducer(undefined, {})).toEqual(INITIAL_STATE); }); it('should handle RECIPE_RECEIVE', () => { - expect(recipesReducer(undefined, { + const reducedRecipe = { + ...RECIPE, + action_id: RECIPE.action.id, + latest_revision_id: RECIPE.latest_revision.id, + approved_revision_id: null, + }; + + delete reducedRecipe.action; + delete reducedRecipe.latest_revision; + delete reducedRecipe.approved_revision; + + const updatedState = recipesReducer(undefined, { type: RECIPE_RECEIVE, recipe: RECIPE, - })).toEqual({ - ...INITIAL_STATE, - items: INITIAL_STATE.items.set(RECIPE.id, fromJS(RECIPE)), }); + + expect(updatedState.items).toEqualImmutable( + INITIAL_STATE.items.set(RECIPE.id, fromJS(reducedRecipe)) + ); }); it('should handle RECIPE_FILTERS_RECEIVE', () => { diff --git a/recipe-server/client/control/tests/state/revisions/test_reducers.js b/recipe-server/client/control/tests/state/revisions/test_reducers.js index b751756e..d629d2b9 100644 --- a/recipe-server/client/control/tests/state/revisions/test_reducers.js +++ b/recipe-server/client/control/tests/state/revisions/test_reducers.js @@ -1,4 +1,5 @@ import { fromJS } from 'immutable'; +import * as matchers from 'jasmine-immutable-matchers'; import { REVISION_RECEIVE, @@ -12,17 +13,32 @@ import { describe('Revisions reducer', () => { + beforeEach(() => { + jasmine.addMatchers(matchers); + }); + it('should return initial state by default', () => { expect(revisionsReducer(undefined, {})).toEqual(INITIAL_STATE); }); it('should handle REVISION_RECEIVE', () => { - expect(revisionsReducer(undefined, { + const reducedRevision = { + ...REVISION, + recipe: { + ...REVISION.recipe, + action_id: REVISION.recipe.action.id, + }, + }; + + delete reducedRevision.recipe.action; + + const updatedState = revisionsReducer(undefined, { type: REVISION_RECEIVE, revision: REVISION, - })).toEqual({ - ...INITIAL_STATE, - items: INITIAL_STATE.items.set(REVISION.id, fromJS(REVISION)), }); + + expect(updatedState.items).toEqualImmutable( + INITIAL_STATE.items.set(REVISION.id, fromJS(reducedRevision)) + ); }); });