Skip to content

Commit

Permalink
Merge pull request #9381 from Yoast/stories/9305-2-implement-openSect…
Browse files Browse the repository at this point in the history
…ions

Implement openSidebarSections in redux store
  • Loading branch information
Alexander Botteram authored Apr 3, 2018
2 parents 32913c6 + 232e690 commit ec9aaf0
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 0 deletions.
2 changes: 2 additions & 0 deletions js/src/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import AnalysisSection from "./components/contentAnalysis/AnalysisSection";
import Data from "./analysis/data.js";
import { isGutenbergDataAvailable } from "./helpers/isGutenbergAvailable";
import SnippetPreviewSection from "./components/SnippetPreviewSection";
import openSidebarSectionsReducer from "./redux/reducers/openSidebarSections";
import cornerstoneContentReducer from "./redux/reducers/cornerstoneContent";

// This should be the entry point for all the edit screens. Because of backwards compatibility we can't change this at once.
Expand Down Expand Up @@ -53,6 +54,7 @@ function configureStore() {
const rootReducer = combineReducers( {
marksButtonStatus: markerStatusReducer,
keywords: keywordsReducer,
openSidebarSections: openSidebarSectionsReducer,
analysis: analysisReducer,
activeKeyword: activeKeywordReducer,
isCornerstone: cornerstoneContentReducer,
Expand Down
44 changes: 44 additions & 0 deletions js/src/redux/actions/openSidebarSections.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const PREFIX = "WPSEO_";

export const OPEN_SIDEBAR_SECTION = `${ PREFIX }OPEN_SIDEBAR_SECTION`;
export const CLOSE_SIDEBAR_SECTION = `${ PREFIX }CLOSE_SIDEBAR_SECTION`;
export const CLOSE_ALL_SIDEBAR_SECTIONS = `${ PREFIX }CLOSE_ALL_SIDEBAR_SECTIONS`;

/**
* An action creator for the action that opens a section.
*
* @param {string} sectionId The to be opened section.
*
* @returns {Object} A (WPSEO_)OPEN_SECTION action.
*/
export const openSidebarSection = function( sectionId ) {
return {
type: OPEN_SIDEBAR_SECTION,
sectionId,
};
};

/**
* An action creator for the action that closes a section.
*
* @param {string} sectionId The to be closed section.
*
* @returns {Object} A (WPSEO_)CLOSE_SECTION action.
*/
export const closeSidebarSection = function( sectionId ) {
return {
type: CLOSE_SIDEBAR_SECTION,
sectionId,
};
};

/**
* An action creator for the action that closes all sections.
*
* @returns {Object} A (WPSEO_)CLOSE_ALL_SECTIONS action.
*/
export const closeAllSidebarSections = function() {
return {
type: CLOSE_ALL_SIDEBAR_SECTIONS,
};
};
57 changes: 57 additions & 0 deletions js/src/redux/reducers/openSidebarSections.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { CLOSE_ALL_SIDEBAR_SECTIONS, OPEN_SIDEBAR_SECTION, CLOSE_SIDEBAR_SECTION } from "../actions/openSidebarSections";

const INITIAL_STATE = [];

/**
* Helper function: returns an array with the passed item added.
*
* @param {Array} openSidebarSections The array to which the item should be added.
* @param {string} sectionId The item to be added.
*
* @returns {Array} The array including the item that should be added.
*/
const sidebarSectionOpener = ( openSidebarSections, sectionId ) => {
if ( typeof sectionId !== "string" || openSidebarSections.includes( sectionId ) ) {
return openSidebarSections;
}

return [
...openSidebarSections,
sectionId,
];
};

/**
* Helper function: returns an array with the passed item removed.
*
* @param {Array} openSidebarSections The array from which the item should be removed.
* @param {string} sectionId The item to be removed.
*
* @returns {Array} The array without the item that should be removed.
*/
const sidebarSectionCloser = ( openSidebarSections, sectionId ) => {
return openSidebarSections.filter( item => item !== sectionId );
};

/**
* A reducer for adding and removing sections from openSidebarSections.
*
* @param {Object} state The current state, which in this case is openSidebarSections.
* @param {Object} action The current action received.
*
* @returns {Object} The new state.
*/
function openSidebarSectionsReducer( state = INITIAL_STATE, action ) {
switch( action.type ) {
case OPEN_SIDEBAR_SECTION:
return sidebarSectionOpener( state, action.sectionId );
case CLOSE_SIDEBAR_SECTION:
return sidebarSectionCloser( state, action.sectionId );
case CLOSE_ALL_SIDEBAR_SECTIONS:
return [];
default:
return state;
}
}

export default openSidebarSectionsReducer;
34 changes: 34 additions & 0 deletions js/tests/redux/actions/openSidebarSections.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/* global describe, it, expect */

import * as actions from "../../../src/redux/actions/openSidebarSections";

describe( "openSidebarSections actions", () => {
it( "should pass along the id when opening a section", () => {
const expected = {
type: actions.OPEN_SIDEBAR_SECTION,
sectionId: "sectionOpened",
};
const actual = actions.openSidebarSection( "sectionOpened" );

expect( actual ).toEqual( expected );
} );

it( "should pass along the keyword when closing a section", () => {
const expected = {
type: actions.CLOSE_SIDEBAR_SECTION,
sectionId: "sectionClosed",
};
const actual = actions.closeSidebarSection( "sectionClosed" );

expect( actual ).toEqual( expected );
} );

it( "should pass nothing but the type in the action object when closing all sections", () => {
const expected = {
type: actions.CLOSE_ALL_SIDEBAR_SECTIONS,
};
const actual = actions.closeAllSidebarSections();

expect( actual ).toEqual( expected );
} );
} );
66 changes: 66 additions & 0 deletions js/tests/redux/reducers/openSidebarSections.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/* global describe, it, expect */

import { openSidebarSection, closeSidebarSection, closeAllSidebarSections } from "../../../src/redux/actions/openSidebarSections";
import openSidebarSectionsReducer from "../../../src/redux/reducers/openSidebarSections";

describe( "openSidebarSections reducers", () => {
describe( "openSidebarSection", () => {
it( "should add the to be opened section to the openSidebarSections array", () => {
const state = [];
const action = openSidebarSection( "openThisSection" );
const expected = [ "openThisSection" ];
const actual = openSidebarSectionsReducer( state, action );

expect( actual ).toEqual( expected );
} );

it( "should not add a section that is already open to the openSidebarSections array", () => {
const state = [ "alreadyOpen", "alsoOpen" ];
const action = openSidebarSection( "alreadyOpen" );
const expected = [ "alreadyOpen", "alsoOpen" ];
const actual = openSidebarSectionsReducer( state, action );

expect( actual ).toEqual( expected );
} );

it( "should not add the section to the array if the passed argument is not a string", () => {
const state = [ "alreadyOpen", "alsoOpen" ];
const action = openSidebarSection( 1234 );
const expected = [ "alreadyOpen", "alsoOpen" ];
const actual = openSidebarSectionsReducer( state, action );

expect( actual ).toEqual( expected );
} );
} );

describe( "closeSidebarSection", () => {
it( "should remove the to be closed section from the openSidebarSections array", () => {
const state = [ "alreadyOpen", "alsoOpen" ];
const action = closeSidebarSection( "alsoOpen" );
const expected = [ "alreadyOpen" ];
const actual = openSidebarSectionsReducer( state, action );

expect( actual ).toEqual( expected );
} );

it( "should not change the array when closing a section that was already closed", () => {
const state = [ "alreadyOpen", "alsoOpen" ];
const action = closeSidebarSection( "fictionalSection" );
const expected = [ "alreadyOpen", "alsoOpen" ];
const actual = openSidebarSectionsReducer( state, action );

expect( actual ).toEqual( expected );
} );
} );

describe( "closeAllSidebarSections", () => {
it( "should empty the openSidebarSections array", () => {
const state = [ "alreadyOpen", "alsoOpen" ];
const action = closeAllSidebarSections();
const expected = [];
const actual = openSidebarSectionsReducer( state, action );

expect( actual ).toEqual( expected );
} );
} );
} );

0 comments on commit ec9aaf0

Please sign in to comment.