Skip to content
Snippets Groups Projects
Commit 3048ac76 authored by Mathias Maaß's avatar Mathias Maaß
Browse files

Refactor <WindowTopBar/>

parent ab917f46
No related branches found
No related tags found
No related merge requests found
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import WindowTopBar from '../../../src/components/WindowTopBar';
import WindowIcon from '../../../src/containers/WindowIcon';
const manifestFixture = { import Typography from '@material-ui/core/Typography';
manifestation: { import Button from '@material-ui/core/Button';
getLabel: () => [{ value: 'Fixture Label' }], import IconButton from '@material-ui/core/IconButton';
}, import MenuIcon from '@material-ui/icons/Menu';
}; import Toolbar from '@material-ui/core/Toolbar';
describe('WindowTopBar', () => { import WindowTopMenuButton from '../../../src/containers/WindowTopMenuButton';
let topBar; import WindowTopBarButtons from '../../../src/containers/WindowTopBarButtons';
let mockRemoveWindow; import WindowIcon from '../../../src/containers/WindowIcon';
let mockToggleWindowSideBar; import WindowTopBar from '../../../src/components/WindowTopBar';
beforeEach(() => { /** create wrapper */
mockRemoveWindow = jest.fn(); function createWrapper(props) {
mockToggleWindowSideBar = jest.fn(); return shallow(
topBar = shallow(
<WindowTopBar <WindowTopBar
manifest={manifestFixture} manifestTitle="awesome manifest"
windowId="foo" windowId="xyz"
removeWindow={mockRemoveWindow}
toggleWindowSideBar={mockToggleWindowSideBar}
classes={{}} classes={{}}
t={key => key} t={str => str}
removeWindow={() => {}}
toggleWindowSideBar={() => {}}
{...props}
/>, />,
).dive(); ).dive(); // unwrap HOC created by withStyles()
}
describe('WindowTopBar', () => {
it('renders all needed elements', () => {
const wrapper = createWrapper();
expect(wrapper.find(Toolbar).length).toBe(1);
expect(wrapper.find(IconButton).length).toBe(1);
expect(wrapper.find(MenuIcon).length).toBe(1);
expect(wrapper.find(WindowIcon).length).toBe(1);
expect(wrapper.find(Typography).length).toBe(1);
expect(wrapper.find(WindowTopBarButtons).length).toBe(1);
expect(wrapper.find(WindowTopMenuButton).length).toBe(1);
expect(wrapper.find(Button).length).toBe(1);
});
it('passes correct props to <IconButton/>', () => {
const toggleWindowSideBar = jest.fn();
const wrapper = createWrapper({ toggleWindowSideBar });
expect(wrapper.find(IconButton).first().props().onClick).toBe(toggleWindowSideBar);
});
it('passes correct props to <WindowIcon/>', () => {
const wrapper = createWrapper();
expect(wrapper.find(WindowIcon).first().props().windowId).toBe('xyz');
}); });
it('renders wrapping element', () => { it('passes correct props to <Typography/>', () => {
expect(topBar.find('.mirador-window-top-bar').length).toBe(1); const wrapper = createWrapper();
expect(wrapper.find(Typography).first().render().text()).toBe('awesome manifest');
}); });
it('provides removeWindow() function to the close button component', () => { it('passes correct props to <WindowTopBarButtons/>', () => {
expect(topBar.find('.mirador-window-close').prop('onClick')) const wrapper = createWrapper();
.toBe(mockRemoveWindow); expect(wrapper.find(WindowTopBarButtons).first().props().windowId).toBe('xyz');
}); });
it('renders a window icon', () => { it('passe correct props to <WindowTopMenuButton', () => {
expect(topBar.find(WindowIcon).length).toBe(1); const wrapper = createWrapper();
expect(wrapper.find(WindowTopMenuButton).first().props().windowId).toBe('xyz');
}); });
it('calls the toggleWindowSideBar prop when the menu IconButton is clicked', () => { it('passes correct props to <Button/>', () => {
topBar.find('WithStyles(IconButton)').simulate('click'); const removeWindow = jest.fn();
expect(mockToggleWindowSideBar).toHaveBeenCalledTimes(1); const wrapper = createWrapper({ removeWindow });
expect(mockToggleWindowSideBar).toHaveBeenCalledWith('foo'); expect(wrapper.find(Button).first().props().onClick).toBe(removeWindow);
}); });
}); });
import manifesto from 'manifesto.js'; import manifesto from 'manifesto.js';
import manifestFixture from '../../fixtures/version-2/001.json'; import manifestFixture001 from '../../fixtures/version-2/001.json';
import { import {
getWindowManifest, getWindowManifest,
getManifestLogo, getManifestLogo,
getManifestCanvases, getManifestCanvases,
getThumbnailNavigationPosition, getThumbnailNavigationPosition,
getManifestTitle,
} from '../../../src/state/selectors'; } from '../../../src/state/selectors';
...@@ -44,9 +45,9 @@ describe('getWindowManifest()', () => { ...@@ -44,9 +45,9 @@ describe('getWindowManifest()', () => {
describe('getManifestLogo()', () => { describe('getManifestLogo()', () => {
it('should return manifest logo id', () => { it('should return manifest logo id', () => {
const manifest = { manifestation: manifesto.create(manifestFixture) }; const manifest = { manifestation: manifesto.create(manifestFixture001) };
const received = getManifestLogo(manifest); const received = getManifestLogo(manifest);
expect(received).toEqual(manifestFixture.logo['@id']); expect(received).toEqual(manifestFixture001.logo['@id']);
}); });
it('should return null if manifest has no logo', () => { it('should return null if manifest has no logo', () => {
...@@ -64,7 +65,7 @@ describe('getManifestCanvases', () => { ...@@ -64,7 +65,7 @@ describe('getManifestCanvases', () => {
}); });
it('returns canvases from the manifest', () => { it('returns canvases from the manifest', () => {
const manifest = { manifestation: manifesto.create(manifestFixture) }; const manifest = { manifestation: manifesto.create(manifestFixture001) };
const received = getManifestCanvases(manifest); const received = getManifestCanvases(manifest);
expect(received.length).toBe(1); expect(received.length).toBe(1);
expect(received[0].id).toBe('https://iiif.bodleian.ox.ac.uk/iiif/canvas/9cca8fdd-4a61-4429-8ac1-f648764b4d6d.json'); expect(received[0].id).toBe('https://iiif.bodleian.ox.ac.uk/iiif/canvas/9cca8fdd-4a61-4429-8ac1-f648764b4d6d.json');
...@@ -94,3 +95,22 @@ describe('getThumbnailNavigationPosition', () => { ...@@ -94,3 +95,22 @@ describe('getThumbnailNavigationPosition', () => {
expect(received).toBeUndefined(); expect(received).toBeUndefined();
}); });
}); });
describe('getManifestTitle', () => {
it('should return manifest title', () => {
const manifest = { manifestation: manifesto.create(manifestFixture001) };
const received = getManifestTitle(manifest);
expect(received).toBe('Bodleian Library Human Freaks 2 (33)');
});
it('should return undefined if manifest undefined', () => {
const received = getManifestTitle(undefined);
expect(received).toBeUndefined();
});
it('should return undefined if no manifestation', () => {
const manifest = {};
const received = getManifestTitle(manifest);
expect(received).toBeUndefined();
});
});
...@@ -17,39 +17,26 @@ import ns from '../config/css-ns'; ...@@ -17,39 +17,26 @@ import ns from '../config/css-ns';
* WindowTopBar * WindowTopBar
*/ */
class WindowTopBar extends Component { class WindowTopBar extends Component {
/**
* titleContent
*
* @return {String}
*/
titleContent() {
const { manifest } = this.props;
if (manifest && manifest.manifestation) {
return manifest.manifestation.getLabel().map(label => label.value)[0];
}
return '';
}
/** /**
* render * render
* @return * @return
*/ */
render() { render() {
const { const {
removeWindow, windowId, classes, toggleWindowSideBar, t, removeWindow, windowId, classes, toggleWindowSideBar, t, manifestTitle,
} = this.props; } = this.props;
return ( return (
<Toolbar disableGutters className={classNames(classes.reallyDense, ns('window-top-bar'))} variant="dense"> <Toolbar disableGutters className={classNames(classes.reallyDense, ns('window-top-bar'))} variant="dense">
<IconButton <IconButton
aria-label={t('toggleWindowSideBar')} aria-label={t('toggleWindowSideBar')}
color="inherit" color="inherit"
onClick={() => toggleWindowSideBar(windowId)} onClick={toggleWindowSideBar}
> >
<MenuIcon /> <MenuIcon />
</IconButton> </IconButton>
<WindowIcon windowId={windowId} /> <WindowIcon windowId={windowId} />
<Typography variant="h3" noWrap color="inherit" className={classes.typographyBody}> <Typography variant="h3" noWrap color="inherit" className={classes.typographyBody}>
{this.titleContent()} {manifestTitle}
</Typography> </Typography>
<WindowTopBarButtons windowId={windowId} /> <WindowTopBarButtons windowId={windowId} />
<WindowTopMenuButton className={ns('window-menu-btn')} windowId={windowId} /> <WindowTopMenuButton className={ns('window-menu-btn')} windowId={windowId} />
...@@ -60,17 +47,16 @@ class WindowTopBar extends Component { ...@@ -60,17 +47,16 @@ class WindowTopBar extends Component {
} }
WindowTopBar.propTypes = { WindowTopBar.propTypes = {
manifest: PropTypes.object, // eslint-disable-line react/forbid-prop-types manifestTitle: PropTypes.string,
removeWindow: PropTypes.func.isRequired, removeWindow: PropTypes.func.isRequired,
windowId: PropTypes.string.isRequired, windowId: PropTypes.string.isRequired,
classes: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types classes: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
toggleWindowSideBar: PropTypes.func, toggleWindowSideBar: PropTypes.func.isRequired,
t: PropTypes.func, t: PropTypes.func,
}; };
WindowTopBar.defaultProps = { WindowTopBar.defaultProps = {
manifest: null, manifestTitle: '',
toggleWindowSideBar: () => {},
t: key => key, t: key => key,
}; };
......
...@@ -3,20 +3,26 @@ import { connect } from 'react-redux'; ...@@ -3,20 +3,26 @@ import { connect } from 'react-redux';
import { withNamespaces } from 'react-i18next'; import { withNamespaces } from 'react-i18next';
import * as actions from '../state/actions'; import * as actions from '../state/actions';
import miradorWithPlugins from '../lib/miradorWithPlugins'; import miradorWithPlugins from '../lib/miradorWithPlugins';
import { getWindowManifest, getManifestTitle } from '../state/selectors';
import WindowTopBar from '../components/WindowTopBar'; import WindowTopBar from '../components/WindowTopBar';
/** mapStateToProps */
const mapStateToProps = (state, { windowId }) => ({
manifestTitle: getManifestTitle(getWindowManifest(state, windowId)),
});
/** /**
* mapDispatchToProps - used to hook up connect to action creators * mapDispatchToProps - used to hook up connect to action creators
* @memberof ManifestListItem * @memberof ManifestListItem
* @private * @private
*/ */
const mapDispatchToProps = (dispatch, props) => ({ const mapDispatchToProps = (dispatch, { windowId }) => ({
removeWindow: () => dispatch(actions.removeWindow(props.windowId)), removeWindow: () => dispatch(actions.removeWindow(windowId)),
toggleWindowSideBar: () => dispatch(actions.toggleWindowSideBar(props.windowId)), toggleWindowSideBar: () => dispatch(actions.toggleWindowSideBar(windowId)),
}); });
const enhance = compose( const enhance = compose(
connect(null, mapDispatchToProps), connect(mapStateToProps, mapDispatchToProps),
miradorWithPlugins, miradorWithPlugins,
withNamespaces(), withNamespaces(),
// further HOC go here // further HOC go here
......
...@@ -43,3 +43,14 @@ export function getThumbnailNavigationPosition(state, windowId) { ...@@ -43,3 +43,14 @@ export function getThumbnailNavigationPosition(state, windowId) {
return state.windows[windowId] return state.windows[windowId]
&& state.windows[windowId].thumbnailNavigationPosition; && state.windows[windowId].thumbnailNavigationPosition;
} }
/**
* Return manifest title
* @param {object} manifest
* @return {String}
*/
export function getManifestTitle(manifest) {
return manifest
&& manifest.manifestation
&& manifest.manifestation.getLabel().map(label => label.value)[0];
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment