Skip to content
Snippets Groups Projects
Commit 0b392ca2 authored by Chris Beer's avatar Chris Beer
Browse files

Refactor popOutCompanionWindow into addCompanionWindow

parent b7612887
No related tags found
No related merge requests found
......@@ -9,7 +9,20 @@ describe('companionWindow actions', () => {
position: 'right',
foo: 'bar',
};
const action = actions.addCompanionWindow(payload);
const mockState = {
windows: {
abc123: { companionWindowIds: [] },
},
companionWindows: {},
};
const mockDispatch = jest.fn(() => ({}));
const mockGetState = jest.fn(() => mockState);
const thunk = actions.addCompanionWindow('abc123', payload);
thunk(mockDispatch, mockGetState);
const action = mockDispatch.mock.calls[0][0];
expect(action.type).toBe(ActionTypes.ADD_COMPANION_WINDOW);
expect(action.payload).toMatchObject(payload);
expect(action.payload.id).toMatch(/cw-.*/);
......@@ -18,138 +31,68 @@ describe('companionWindow actions', () => {
it('should set the correct default values', () => {
const payload = {};
const defaults = { foo: 'bar' };
const action = actions.addCompanionWindow(payload, defaults);
expect(action.payload.foo).toBe('bar');
});
it('should generate a new companionWindow ID', () => {
const payload = {};
expect(actions.addCompanionWindow(payload).id).toEqual(
expect.stringMatching(/^cw-\w+-\w+/),
);
});
});
describe('updateCompanionWindow', () => {
it('should return correct action object', () => {
const mockState = {
windows: {
abc123: {
companionWindowIds: ['cw-1', 'cw-2'],
},
},
companionWindows: {
'cw-1': { position: 'right' },
'cw-2': { position: 'not-right' },
abc123: { companionWindowIds: [] },
},
companionWindows: {},
};
const payload = {
content: 'info',
position: 'right',
};
const thunk = actions.updateCompanionWindow('abc123', 'cw-123', payload);
const mockDispatch = jest.fn(() => {});
const mockDispatch = jest.fn(() => ({}));
const mockGetState = jest.fn(() => mockState);
const thunk = actions.addCompanionWindow('abc123', payload, defaults);
thunk(mockDispatch, mockGetState);
expect(mockDispatch).toHaveBeenNthCalledWith(1, {
type: ActionTypes.REMOVE_COMPANION_WINDOW,
id: 'cw-1',
});
expect(mockDispatch).toHaveBeenNthCalledWith(2, {
type: ActionTypes.UPDATE_WINDOW,
id: 'abc123',
payload: { companionWindowIds: ['cw-2'] },
});
const updateCompanionWindowAction = mockDispatch.mock.calls[2][0];
const action = mockDispatch.mock.calls[0][0];
expect(updateCompanionWindowAction.type).toBe(ActionTypes.UPDATE_COMPANION_WINDOW);
expect(updateCompanionWindowAction.id).toBe('cw-123');
expect(updateCompanionWindowAction.payload).toEqual(payload);
});
expect(action.payload.foo).toBe('bar');
});
describe('removeCompanionWindow', () => {
it('should return correct action object', () => {
const action = actions.removeCompanionWindow('cw-123');
expect(action.type).toBe(ActionTypes.REMOVE_COMPANION_WINDOW);
expect(action.id).toBe('cw-123');
});
});
it('should generate a new companionWindow ID', () => {
const payload = {};
describe('popOutCompanionWindow', () => {
it('returns a thunk which dispatches the appropriate actions', () => {
const mockState = {
windows: {
abc123: {
companionWindowIds: ['cw-1', 'cw-2'],
},
},
companionWindows: {
'cw-1': { position: 'right' },
'cw-2': { position: 'not-right' },
abc123: { companionWindowIds: [] },
},
companionWindows: {},
};
const mockDispatch = jest.fn(() => ({ id: 'cw-3' }));
const mockDispatch = jest.fn(() => ({}));
const mockGetState = jest.fn(() => mockState);
const windowId = 'abc123';
const panelType = 'info';
const position = 'right';
const thunk = actions.popOutCompanionWindow(windowId, panelType, position);
expect(typeof thunk).toEqual('function');
const thunk = actions.addCompanionWindow('abc123', payload);
thunk(mockDispatch, mockGetState);
const action = mockDispatch.mock.calls[0][0];
expect(mockDispatch).toHaveBeenNthCalledWith(1, {
type: ActionTypes.REMOVE_COMPANION_WINDOW,
id: 'cw-1',
});
const addCompanionWindowAction = mockDispatch.mock.calls[1][0];
expect(addCompanionWindowAction.type).toBe(ActionTypes.ADD_COMPANION_WINDOW);
expect(addCompanionWindowAction.payload).toMatchObject({ content: 'info', position: 'right' });
expect(addCompanionWindowAction.id.startsWith('cw-')).toBe(true);
expect(mockDispatch).toHaveBeenNthCalledWith(3, {
type: ActionTypes.UPDATE_WINDOW,
id: 'abc123',
payload: { companionWindowIds: ['cw-2', 'cw-3'] },
expect(action.id).toEqual(
expect.stringMatching(/^cw-\w+-\w+/),
);
});
});
it('sets the window sidebar panel type if the companion window appears in the left position', () => {
const mockState = {
windows: {
abc123: { companionWindowIds: [] },
},
companionWindows: {},
describe('updateCompanionWindow', () => {
it('should return correct action object', () => {
const payload = {
content: 'info',
position: 'right',
foo: 'bar',
};
const mockDispatch = jest.fn(() => ({ id: 'cw-3' }));
const mockGetState = jest.fn(() => mockState);
const windowId = 'abc123';
const panelType = 'info';
const position = 'left';
const thunk = actions.popOutCompanionWindow(windowId, panelType, position);
thunk(mockDispatch, mockGetState);
const action = actions.updateCompanionWindow('abc123', 'cw-123', payload);
expect(mockDispatch).toHaveBeenNthCalledWith(1, {
type: ActionTypes.SET_WINDOW_SIDE_BAR_PANEL,
windowId: 'abc123',
panelType: 'info',
expect(action.type).toBe(ActionTypes.UPDATE_COMPANION_WINDOW);
expect(action.id).toBe('cw-123');
expect(action.payload).toEqual(payload);
});
expect(mockDispatch).toHaveBeenNthCalledWith(2, {
type: ActionTypes.UPDATE_WINDOW,
id: 'abc123',
payload: { companionAreaOpen: true },
});
describe('removeCompanionWindow', () => {
it('should return correct action object', () => {
const action = actions.removeCompanionWindow('cw-123');
expect(action.type).toBe(ActionTypes.REMOVE_COMPANION_WINDOW);
expect(action.id).toBe('cw-123');
});
});
});
......@@ -245,4 +245,52 @@ describe('windows reducer', () => {
},
});
});
it('should handle ADD_COMPANION_WINDOW', () => {
// on the right, just tacks the new id on
expect(windowsReducer({
abc123: {
id: 'abc123',
companionWindowIds: ['123'],
},
}, {
type: ActionTypes.ADD_COMPANION_WINDOW,
id: 'xyz',
windowId: 'abc123',
payload: {
position: 'right',
},
})).toEqual({
abc123: {
id: 'abc123',
companionWindowIds: ['123', 'xyz'],
},
});
// on the left, replaces all ids of windows in that position and sets some additional properties
expect(windowsReducer({
abc123: {
id: 'abc123',
companionWindowIds: ['left123'],
},
}, {
type: ActionTypes.ADD_COMPANION_WINDOW,
id: 'xyz',
windowId: 'abc123',
companionWindows: {
left123: { position: 'left' },
},
payload: {
content: 'content',
position: 'left',
},
})).toEqual({
abc123: {
id: 'abc123',
companionAreaOpen: true,
sideBarPanel: 'content',
companionWindowIds: ['xyz'],
},
});
});
});
......@@ -19,8 +19,8 @@ import { WindowSideBarButtons } from '../components/WindowSideBarButtons';
* @private
*/
const mapDispatchToProps = (dispatch, { windowId }) => ({
addCompanionWindow: panelType => dispatch(
actions.popOutCompanionWindow(windowId, panelType, 'left'),
addCompanionWindow: content => dispatch(
actions.addCompanionWindow(windowId, { content, position: 'left' }),
),
});
......
import uuid from 'uuid/v4';
import ActionTypes from './action-types';
import { updateWindow, setCompanionAreaOpen, setWindowSideBarPanel } from './window';
import { updateWindow } from './window';
const defaultProps = {
content: null,
......@@ -8,29 +8,28 @@ const defaultProps = {
};
/** */
export function addCompanionWindow(payload, defaults = defaultProps) {
export function addCompanionWindow(windowId, payload, defaults = defaultProps) {
return (dispatch, getState) => {
const { companionWindows } = getState();
const id = `cw-${uuid()}`;
return {
dispatch({
type: ActionTypes.ADD_COMPANION_WINDOW,
id,
windowId,
companionWindows,
payload: { ...defaults, ...payload, id },
});
};
}
/** */
export function updateCompanionWindow(windowId, id, payload) {
return (dispatch, getState) => {
if (payload.position === 'left') {
const { windows, companionWindows } = getState();
const { companionWindowIds } = windows[windowId];
companionWindowIds
.filter(cwid => companionWindows[cwid].position === payload.position)
.map(cwid => closeCompanionWindow(windowId, cwid)(dispatch, getState));
}
dispatch({ type: ActionTypes.UPDATE_COMPANION_WINDOW, id, payload });
return {
type: ActionTypes.UPDATE_COMPANION_WINDOW,
windowId,
id,
payload,
};
}
......@@ -50,46 +49,3 @@ export function closeCompanionWindow(windowId, companionWindowId) {
dispatch(updateWindow(windowId, { companionWindowIds }));
};
}
/**
* popOutCompanionWindow - action creator
*
* @param {String} windowId
* @param {String} panelType The type of panel content to be rendered
* in the companion window (e.g. info, canvas_navigation)
* @param {String} position The position of the companion window to
* set content for (e.g. right, bottom)
* @memberof ActionCreators
*/
export function popOutCompanionWindow(windowId, panelType, position) {
return (dispatch, getState) => {
const { windows, companionWindows } = getState();
const { companionWindowIds } = windows[windowId];
if (position === 'left') {
companionWindowIds
.filter(id => companionWindows[id].position === position)
.map(id => dispatch(removeCompanionWindow(id)));
dispatch(setWindowSideBarPanel(windowId, panelType));
dispatch(setCompanionAreaOpen(windowId, true));
}
const action = dispatch(addCompanionWindow({ content: panelType, position }));
const companionWindowId = action.id;
let existingCompanionWindowIds;
if (position === 'left') {
existingCompanionWindowIds = companionWindowIds
.filter(id => (companionWindows[id].position !== position));
} else {
existingCompanionWindowIds = companionWindowIds;
}
dispatch(updateWindow(windowId, {
companionWindowIds: existingCompanionWindowIds.concat([companionWindowId]),
}));
};
}
......@@ -96,6 +96,31 @@ export const windowsReducer = (state = {}, action) => {
return setCanvasIndex(state, action.windowId, currentIndex => currentIndex - 1);
case ActionTypes.SET_CANVAS:
return setCanvasIndex(state, action.windowId, currentIndex => action.canvasIndex);
case ActionTypes.ADD_COMPANION_WINDOW:
if (action.payload.position === 'left') {
const { companionWindowIds } = state[action.windowId];
const { companionWindows } = action;
const newCompanionWindowIds = companionWindowIds
.filter(id => companionWindows[id].position !== action.payload.position);
return {
...state,
[action.windowId]: {
...state[action.windowId],
companionAreaOpen: true,
sideBarPanel: action.payload.content,
companionWindowIds: newCompanionWindowIds.concat([action.id]),
},
};
}
return {
...state,
[action.windowId]: {
...state[action.windowId],
companionWindowIds: state[action.windowId].companionWindowIds.concat([action.id]),
},
};
default:
return state;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment