From 1a9e90363f8670e6cb6f4f06304bf145c3347507 Mon Sep 17 00:00:00 2001 From: Chris Beer <cabeer@stanford.edu> Date: Sun, 21 Jun 2020 07:06:15 -0700 Subject: [PATCH] Handle importing configuration in a saga --- __tests__/src/lib/MiradorViewer.test.js | 13 +--------- __tests__/src/sagas/app.test.js | 32 +++++++++++++++++++++++-- src/lib/MiradorViewer.js | 17 ------------- src/state/sagas/app.js | 29 +++++++++++++++++++++- 4 files changed, 59 insertions(+), 32 deletions(-) diff --git a/__tests__/src/lib/MiradorViewer.test.js b/__tests__/src/lib/MiradorViewer.test.js index aa207f7bd..87aa50943 100644 --- a/__tests__/src/lib/MiradorViewer.test.js +++ b/__tests__/src/lib/MiradorViewer.test.js @@ -5,17 +5,6 @@ jest.unmock('react-i18next'); jest.mock('react-dom'); jest.mock('isomorphic-unfetch', () => jest.fn(() => Promise.resolve({ json: () => ({}) }))); -jest.mock('../../../src/state/selectors', () => ({ - getCanvasGrouping: () => [], - getCompanionWindowIdsForPosition: () => ['cwid'], - getManifestoInstance: () => {}, - getManifests: () => ( - { 'https://iiif.harvardartmuseums.org/manifests/object/299843': { isFetching: true } } - ), - getManifestSearchService: () => ({ id: 'http://example.com/search' }), - getSearchForWindow: () => {}, -})); - describe('MiradorViewer', () => { let instance; beforeAll(() => { @@ -61,7 +50,7 @@ describe('MiradorViewer', () => { expect(windows[windowIds[0]].layoutOrder).toBe(0); expect(windows[windowIds[1]].layoutOrder).toBe(1); expect(windows[windowIds[0]].thumbnailNavigationPosition).toBe('far-bottom'); - expect(windows[windowIds[1]].thumbnailNavigationPosition).toBe('off'); + expect(windows[windowIds[1]].thumbnailNavigationPosition).toBe(undefined); expect(windows[windowIds[0]].view).toBe(undefined); expect(windows[windowIds[1]].view).toBe('book'); diff --git a/__tests__/src/sagas/app.test.js b/__tests__/src/sagas/app.test.js index 6ce748e34..807e401ce 100644 --- a/__tests__/src/sagas/app.test.js +++ b/__tests__/src/sagas/app.test.js @@ -1,9 +1,10 @@ import { call } from 'redux-saga/effects'; -import { testSaga } from 'redux-saga-test-plan'; +import { expectSaga, testSaga } from 'redux-saga-test-plan'; -import { importState } from '../../../src/state/sagas/app'; +import { importConfig, importState } from '../../../src/state/sagas/app'; import { fetchManifest } from '../../../src/state/sagas/iiif'; import { fetchWindowManifest } from '../../../src/state/sagas/windows'; +import { addWindow } from '../../../src/state/actions'; describe('app-level sagas', () => { describe('importState', () => { @@ -52,4 +53,31 @@ describe('app-level sagas', () => { .all([]); }); }); + + describe('importConfig', () => { + it('adds windows from the provided config', () => { + const action = { + config: { + thumbnailNavigation: {}, + windows: [ + { id: 'x', manifestId: 'a' }, + { id: 'y', manifestId: 'b' }, + ], + }, + }; + + return expectSaga(importConfig, action) + .provide([ + [call(addWindow, { + id: 'x', layoutOrder: 0, manifestId: 'a', thumbnailNavigationPosition: undefined, + }), { type: 'thunk1' }], + [call(addWindow, { + id: 'y', layoutOrder: 1, manifestId: 'b', thumbnailNavigationPosition: undefined, + }), { type: 'thunk2' }], + ]) + .put({ type: 'thunk1' }) + .put({ type: 'thunk2' }) + .run(); + }); + }); }); diff --git a/src/lib/MiradorViewer.js b/src/lib/MiradorViewer.js index cf54c62b4..81346abba 100644 --- a/src/lib/MiradorViewer.js +++ b/src/lib/MiradorViewer.js @@ -1,7 +1,6 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; -import { v4 as uuid } from 'uuid'; import HotApp from '../components/App'; import createStore from '../state/createStore'; import * as actions from '../state/actions'; @@ -46,22 +45,6 @@ class MiradorViewer { /** merge type for arrays */ const action = actions.importConfig(this.config); this.store.dispatch(action); - const { config: storedConfig } = this.store.getState(); - - storedConfig.windows.forEach((miradorWindow, layoutOrder) => { - const windowId = `window-${uuid()}`; - const manifestId = miradorWindow.manifestId || miradorWindow.loadedManifest; - - this.store.dispatch(actions.addWindow({ - // these are default values ... - id: windowId, - layoutOrder, - manifestId, - thumbnailNavigationPosition: storedConfig.thumbnailNavigation.defaultPosition, - // ... overridden by values from the window configuration ... - ...miradorWindow, - })); - }); } } diff --git a/src/state/sagas/app.js b/src/state/sagas/app.js index 08de29310..de4490542 100644 --- a/src/state/sagas/app.js +++ b/src/state/sagas/app.js @@ -1,8 +1,10 @@ import { - all, call, takeEvery, + all, call, put, takeEvery, } from 'redux-saga/effects'; +import { v4 as uuid } from 'uuid'; import { fetchManifest } from './iiif'; import { fetchWindowManifest } from './windows'; +import { addWindow } from '../actions'; import ActionTypes from '../actions/action-types'; /** */ @@ -16,9 +18,34 @@ export function* importState(action) { ]); } +/** Add windows from the imported config */ +export function* importConfig({ config: { thumbnailNavigation, windows } }) { + if (!windows || windows.length === 0) return; + + const thunks = yield all( + windows.map((miradorWindow, layoutOrder) => { + const windowId = `window-${uuid()}`; + const manifestId = miradorWindow.manifestId || miradorWindow.loadedManifest; + + return call(addWindow, { + // these are default values ... + id: windowId, + layoutOrder, + manifestId, + thumbnailNavigationPosition: thumbnailNavigation && thumbnailNavigation.defaultPosition, + // ... overridden by values from the window configuration ... + ...miradorWindow, + }); + }), + ); + + yield all(thunks.map(thunk => put(thunk))); +} + /** */ export default function* appSaga() { yield all([ takeEvery(ActionTypes.IMPORT_MIRADOR_STATE, importState), + takeEvery(ActionTypes.IMPORT_CONFIG, importConfig), ]); } -- GitLab