// action-keys.jsexport const SET_NAME = 'SET_NAME';export const SET_IS_LOADING = 'SET_IS_LOADING';export const SET_CUSTOMER_EMAIL = 'SET_CUSTOMER_EMAIL';export const SET_CUSTOMER_AGE = 'SET_CUSTOMER_AGE';export const SET_CUSTOMER_INFO = 'SET_CUSTOMER_INFO';export const SET_DATA = 'SET_DATA';export const SET_FRIEND_NAMES = 'SET_FRIEND_NAMES';export const ADD_FRIEND_NAME = 'ADD_FRIEND_NAME';export const REMOVE_FRIEND_NAME = 'REMOVE_FRIEND_NAME';export const SET_FRIEND_NAME = 'SET_FRIEND_NAME';export const SET_CONNECTIONS = 'SET_CONNECTIONS';export const ADD_CONNECTION = 'ADD_CONNECTION';export const REMOVE_CONNECTION = 'REMOVE_CONNECTION';export const SET_CONNECTION_TYPE = 'SET_CONNECTION_TYPE';export const SET_CONNECTION_CON_MAN = 'SET_CONNECTION_CON_MAN';export const SET_CONNECTION_CON_DATA = 'SET_CONNECTION_CON_DATA';
// actions.jsimport * as actionKeys from './action-keys';/*** @param {string} name*/export const setName = name => ({type: actionKeys.SET_NAME,payload: name});/*** @param {boolean} isLoading*/export const setIsLoading = isLoading => ({type: actionKeys.SET_IS_LOADING,payload: isLoading});/*** @param {string} email*/export const setCustomerEmail = email => ({type: actionKeys.SET_CUSTOMER_EMAIL,payload: email});/*** @param {number} age*/export const setCustomerAge = age => ({type: actionKeys.SET_CUSTOMER_AGE,payload: age});/*** @param {any} info*/export const setCustomerInfo = info => ({type: actionKeys.SET_CUSTOMER_INFO,payload: info});/*** @param {any} data*/export const setData = data => ({type: actionKeys.SET_DATA,payload: data});/*** @param {string[]} friendNames*/export const setFriendNames = friendNames => ({type: actionKeys.SET_FRIEND_NAMES,payload: friendNames});/*** @param {string} friendName*/export const addFriendName = friendName => ({type: actionKeys.ADD_FRIEND_NAME,payload: friendName});/*** @param {number} index*/export const removeFriendName = index => ({type: actionKeys.REMOVE_FRIEND_NAME,payload: index});/*** @param {number} index* @param {string} friendName*/export const setFriendName = (index, friendName) => ({type: actionKeys.SET_FRIEND_NAME,payload: { index, friendName }});/*** @param {Array} connections*/export const setConnections = connections => ({type: actionKeys.SET_CONNECTIONS,payload: connections});/*** @param {any} connection*/export const addConnection = connection => ({type: actionKeys.ADD_CONNECTION,payload: connection});/*** @param {number} index*/export const removeConnection = index => ({type: actionKeys.REMOVE_CONNECTION,payload: index});/*** @param {number} index* @param {string} type*/export const setConnectionType = (index, type) => ({type: actionKeys.SET_CONNECTION_TYPE,payload: { index, type }});/*** @param {number} index* @param {string} man*/export const setConnectionConMan = (index, man) => ({type: actionKeys.SET_CONNECTION_CON_MAN,payload: { index, man }});/*** @param {number} index* @param {any} data*/export const setConnectionConData = (index, data) => ({type: actionKeys.SET_CONNECTION_CON_DATA,payload: { index, data }});
// root-reducer.jsimport * as actionKeys from './action-keys';const DEFAULT_STATE = {"name": "","isLoading": true,"customer": {"email": "","age": 21,"info": null},"data": null,"friendNames": [""],"connections": [{"type": "colleague","con": {"man": "Malcolm","data": null}}]};export const rootReducer = (state = DEFAULT_STATE, action) => {switch (action.type){case actionKeys.SET_NAME:return {...state,name: action.payload}case actionKeys.SET_IS_LOADING:return {...state,isLoading: action.payload}case actionKeys.SET_CUSTOMER_EMAIL:return {...state,customer: {...state.customer,email: action.payload}}case actionKeys.SET_CUSTOMER_AGE:return {...state,customer: {...state.customer,age: action.payload}}case actionKeys.SET_CUSTOMER_INFO:return {...state,customer: {...state.customer,info: action.payload}}case actionKeys.SET_DATA:return {...state,data: action.payload}case actionKeys.SET_FRIEND_NAMES:return {...state,friendNames: action.payload}case actionKeys.ADD_FRIEND_NAME:return {...state,friendNames: state.friendNames.concat(action.payload)}case actionKeys.REMOVE_FRIEND_NAME:return {...state,friendNames: state.friendNames.filter((_, index) => index !== action.payload)}case actionKeys.SET_FRIEND_NAME:return {...state,friendNames: state.friendNames.map((item, index) => index === action.payload.index ? action.payload.friendName : item)}case actionKeys.SET_CONNECTIONS:return {...state,connections: action.payload}case actionKeys.ADD_CONNECTION:return {...state,connections: state.connections.concat(action.payload)}case actionKeys.REMOVE_CONNECTION:return {...state,connections: state.connections.filter((_, index) => index !== action.payload)}case actionKeys.SET_CONNECTION_TYPE:return {...state,connections: state.connections.map((item, index) => index !== action.payload.index? item: {...item,type: action.payload.type})}case actionKeys.SET_CONNECTION_CON_MAN:return {...state,connections: state.connections.map((item, index) => index !== action.payload.index? item: {...item,con: {...item.con,man: action.payload.man}})}case actionKeys.SET_CONNECTION_CON_DATA:return {...state,connections: state.connections.map((item, index) => index !== action.payload.index? item: {...item,con: {...item.con,data: action.payload.data}})}default:return state;}}export default rootReducer;
// selectors.js// get the state of this storeconst selectState = state => state;/*** @returns {string}*/export const selectName = state => selectState(state).name;/*** @returns {boolean}*/export const selectIsLoading = state => selectState(state).isLoading;/*** @returns {string}*/export const selectCustomerEmail = state => selectState(state).customer.email;/*** @returns {number}*/export const selectCustomerAge = state => selectState(state).customer.age;export const selectCustomerInfo = state => selectState(state).customer.info;export const selectData = state => selectState(state).data;/*** @returns {string[]}*/export const selectFriendNames = state => selectState(state).friendNames;/*** @returns {string}*/export const selectFriendName = (state, index) => selectState(state).friendNames[index];export const selectConnections = state => selectState(state).connections;/*** @returns {string}*/export const selectConnectionType = (state, index) => selectState(state).connections[index].type;/*** @returns {string}*/export const selectConnectionConMan = (state, index) => selectState(state).connections[index].con.man;export const selectConnectionConData = (state, index) => selectState(state).connections[index].con.data;
// store.test.jsimport * as actionCreators from './actions';import rootReducer from './root-reducer';import * as selectors from './selectors';describe('rootReducer', () => {const initialState = rootReducer(undefined, { type: '@@INIT' });test('setName', () => {const action = actionCreators.setName('Noelia Hammes');const finalState = rootReducer(initialState, action);expect(selectors.selectName(finalState)).toEqual('Noelia Hammes')// assert new object is createdexpect(finalState).not.toBe(initialState);});test('setIsLoading', () => {const action = actionCreators.setIsLoading(true);const finalState = rootReducer(initialState, action);expect(selectors.selectIsLoading(finalState)).toEqual(true)// assert new object is createdexpect(finalState).not.toBe(initialState);});test('setCustomerEmail', () => {const action = actionCreators.setCustomerEmail('Luciano_Stamm@yahoo.com');const finalState = rootReducer(initialState, action);expect(selectors.selectCustomerEmail(finalState)).toEqual('Luciano_Stamm@yahoo.com')// assert new object is createdexpect(finalState).not.toBe(initialState);});test('setCustomerAge', () => {const action = actionCreators.setCustomerAge(41789);const finalState = rootReducer(initialState, action);expect(selectors.selectCustomerAge(finalState)).toEqual(41789)// assert new object is createdexpect(finalState).not.toBe(initialState);});test('setCustomerInfo', () => {const action = actionCreators.setCustomerInfo({}); // populate data?const finalState = rootReducer(initialState, action);expect(selectors.selectCustomerInfo(finalState)).toEqual({})// assert new object is createdexpect(finalState).not.toBe(initialState);});test('setData', () => {const action = actionCreators.setData({}); // populate data?const finalState = rootReducer(initialState, action);expect(selectors.selectData(finalState)).toEqual({})// assert new object is createdexpect(finalState).not.toBe(initialState);});test('setFriendNames', () => {const action = actionCreators.setFriendNames(['Wilhelmine Metz DVM']);const finalState = rootReducer(initialState, action);expect(selectors.selectFriendNames(finalState)).toEqual(['Wilhelmine Metz DVM'])// assert new object is createdexpect(finalState).not.toBe(initialState);});test('addFriendName', () => {const action = actionCreators.addFriendName('Tressie Cremin');const finalState = rootReducer(initialState, action);expect(selectors.selectFriendNames(finalState)).toContainEqual('Tressie Cremin')// assert new object is createdexpect(finalState).not.toBe(initialState);});test('removeFriendName', () => {const oriState = rootReducer(initialState, actionCreators.setFriendNames(['Wilhelmine Metz DVM', 'Tressie Cremin']))const action = actionCreators.removeFriendName(0);const finalState = rootReducer(oriState, action);expect(selectors.selectFriendNames(finalState)).not.toContainEqual('Wilhelmine Metz DVM')expect(selectors.selectFriendNames(finalState)).toContainEqual('Tressie Cremin')// assert new object is createdexpect(finalState).not.toBe(initialState);});test('setFriendName', () => {const oriState = { ...initialState };const action = actionCreators.setFriendName(0, 'Cheyenne Kerluke');const finalState = rootReducer(oriState, action);expect(selectors.selectFriendName(finalState, 0)).toEqual('Cheyenne Kerluke')// assert new object is createdexpect(finalState).not.toBe(initialState);});test('setConnections', () => {const action = actionCreators.setConnections([{type: '',con: {man: '',data: {},},}]); // populate data?const finalState = rootReducer(initialState, action);expect(selectors.selectConnections(finalState)).toEqual([{type: '',con: {man: '',data: {},},}])// assert new object is createdexpect(finalState).not.toBe(initialState);});test('addConnection', () => {const action = actionCreators.addConnection({type: '',con: {man: '',data: {},},}); // populate data?const finalState = rootReducer(initialState, action);expect(selectors.selectConnections(finalState)).toContainEqual({type: '',con: {man: '',data: {},},})// assert new object is createdexpect(finalState).not.toBe(initialState);});test('removeConnection', () => {const oriState = rootReducer(initialState, actionCreators.setConnections([{type: '',con: {man: '',data: {},},}, {type: '',con: {man: '',data: {},},}]))// populate data?const action = actionCreators.removeConnection(0);const finalState = rootReducer(oriState, action);expect(selectors.selectConnections(finalState)).not.toContainEqual({type: '',con: {man: '',data: {},},})expect(selectors.selectConnections(finalState)).toContainEqual({type: '',con: {man: '',data: {},},})// assert new object is createdexpect(finalState).not.toBe(initialState);});test('setConnectionType', () => {const oriState = { ...initialState };const action = actionCreators.setConnectionType(0, '');const finalState = rootReducer(oriState, action);expect(selectors.selectConnectionType(finalState, 0)).toEqual('')// assert new object is createdexpect(finalState).not.toBe(initialState);});test('setConnectionConMan', () => {const oriState = { ...initialState };const action = actionCreators.setConnectionConMan(0, '');const finalState = rootReducer(oriState, action);expect(selectors.selectConnectionConMan(finalState, 0)).toEqual('')// assert new object is createdexpect(finalState).not.toBe(initialState);});test('setConnectionConData', () => {const oriState = { ...initialState };const action = actionCreators.setConnectionConData(0, {});const finalState = rootReducer(oriState, action);expect(selectors.selectConnectionConData(finalState, 0)).toEqual({})// assert new object is createdexpect(finalState).not.toBe(initialState);});});