Skip to content
Snippets Groups Projects
Unverified Commit f8e06ee8 authored by Jessie Keck's avatar Jessie Keck Committed by GitHub
Browse files

Merge pull request #1849 from ProjectMirador/refactor-windowtopbar-component

Refactor <WindowTopBar/>
parents 5c477f5e 3048ac76
Branches
Tags
No related merge requests found
import React from 'react';
import { shallow } from 'enzyme';
import WindowTopBar from '../../../src/components/WindowTopBar';
import WindowIcon from '../../../src/containers/WindowIcon';
const manifestFixture = {
manifestation: {
getLabel: () => [{ value: 'Fixture Label' }],
},
};
import Typography from '@material-ui/core/Typography';
import Button from '@material-ui/core/Button';
import IconButton from '@material-ui/core/IconButton';
import MenuIcon from '@material-ui/icons/Menu';
import Toolbar from '@material-ui/core/Toolbar';
describe('WindowTopBar', () => {
let topBar;
let mockRemoveWindow;
let mockToggleWindowSideBar;
beforeEach(() => {
mockRemoveWindow = jest.fn();
mockToggleWindowSideBar = jest.fn();
topBar = shallow(
import WindowTopMenuButton from '../../../src/containers/WindowTopMenuButton';
import WindowTopBarButtons from '../../../src/containers/WindowTopBarButtons';
import WindowIcon from '../../../src/containers/WindowIcon';
import WindowTopBar from '../../../src/components/WindowTopBar';
/** create wrapper */
function createWrapper(props) {
return shallow(
<WindowTopBar
manifest={manifestFixture}
windowId="foo"
removeWindow={mockRemoveWindow}
toggleWindowSideBar={mockToggleWindowSideBar}
manifestTitle="awesome manifest"
windowId="xyz"
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', () => {
expect(topBar.find('.mirador-window-top-bar').length).toBe(1);
it('passes correct props to <Typography/>', () => {
const wrapper = createWrapper();
expect(wrapper.find(Typography).first().render().text()).toBe('awesome manifest');
});
it('provides removeWindow() function to the close button component', () => {
expect(topBar.find('.mirador-window-close').prop('onClick'))
.toBe(mockRemoveWindow);
it('passes correct props to <WindowTopBarButtons/>', () => {
const wrapper = createWrapper();
expect(wrapper.find(WindowTopBarButtons).first().props().windowId).toBe('xyz');
});
it('renders a window icon', () => {
expect(topBar.find(WindowIcon).length).toBe(1);
it('passe correct props to <WindowTopMenuButton', () => {
const wrapper = createWrapper();
expect(wrapper.find(WindowTopMenuButton).first().props().windowId).toBe('xyz');
});
it('calls the toggleWindowSideBar prop when the menu IconButton is clicked', () => {
topBar.find('WithStyles(IconButton)').simulate('click');
expect(mockToggleWindowSideBar).toHaveBeenCalledTimes(1);
expect(mockToggleWindowSideBar).toHaveBeenCalledWith('foo');
it('passes correct props to <Button/>', () => {
const removeWindow = jest.fn();
const wrapper = createWrapper({ removeWindow });
expect(wrapper.find(Button).first().props().onClick).toBe(removeWindow);
});
});
import manifesto from 'manifesto.js';
import manifestFixture from '../../fixtures/version-2/001.json';
import manifestFixture001 from '../../fixtures/version-2/001.json';
import {
getWindowManifest,
getManifestLogo,
getManifestCanvases,
getThumbnailNavigationPosition,
getManifestTitle,
} from '../../../src/state/selectors';
......@@ -44,9 +45,9 @@ describe('getWindowManifest()', () => {
describe('getManifestLogo()', () => {
it('should return manifest logo id', () => {
const manifest = { manifestation: manifesto.create(manifestFixture) };
const manifest = { manifestation: manifesto.create(manifestFixture001) };
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', () => {
......@@ -64,7 +65,7 @@ describe('getManifestCanvases', () => {
});
it('returns canvases from the manifest', () => {
const manifest = { manifestation: manifesto.create(manifestFixture) };
const manifest = { manifestation: manifesto.create(manifestFixture001) };
const received = getManifestCanvases(manifest);
expect(received.length).toBe(1);
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', () => {
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';
* WindowTopBar
*/
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
* @return
*/
render() {
const {
removeWindow, windowId, classes, toggleWindowSideBar, t,
removeWindow, windowId, classes, toggleWindowSideBar, t, manifestTitle,
} = this.props;
return (
<Toolbar disableGutters className={classNames(classes.reallyDense, ns('window-top-bar'))} variant="dense">
<IconButton
aria-label={t('toggleWindowSideBar')}
color="inherit"
onClick={() => toggleWindowSideBar(windowId)}
onClick={toggleWindowSideBar}
>
<MenuIcon />
</IconButton>
<WindowIcon windowId={windowId} />
<Typography variant="h3" noWrap color="inherit" className={classes.typographyBody}>
{this.titleContent()}
{manifestTitle}
</Typography>
<WindowTopBarButtons windowId={windowId} />
<WindowTopMenuButton className={ns('window-menu-btn')} windowId={windowId} />
......@@ -60,17 +47,16 @@ class WindowTopBar extends Component {
}
WindowTopBar.propTypes = {
manifest: PropTypes.object, // eslint-disable-line react/forbid-prop-types
manifestTitle: PropTypes.string,
removeWindow: PropTypes.func.isRequired,
windowId: PropTypes.string.isRequired,
classes: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
toggleWindowSideBar: PropTypes.func,
toggleWindowSideBar: PropTypes.func.isRequired,
t: PropTypes.func,
};
WindowTopBar.defaultProps = {
manifest: null,
toggleWindowSideBar: () => {},
manifestTitle: '',
t: key => key,
};
......
......@@ -3,20 +3,26 @@ import { connect } from 'react-redux';
import { withNamespaces } from 'react-i18next';
import * as actions from '../state/actions';
import miradorWithPlugins from '../lib/miradorWithPlugins';
import { getWindowManifest, getManifestTitle } from '../state/selectors';
import WindowTopBar from '../components/WindowTopBar';
/** mapStateToProps */
const mapStateToProps = (state, { windowId }) => ({
manifestTitle: getManifestTitle(getWindowManifest(state, windowId)),
});
/**
* mapDispatchToProps - used to hook up connect to action creators
* @memberof ManifestListItem
* @private
*/
const mapDispatchToProps = (dispatch, props) => ({
removeWindow: () => dispatch(actions.removeWindow(props.windowId)),
toggleWindowSideBar: () => dispatch(actions.toggleWindowSideBar(props.windowId)),
const mapDispatchToProps = (dispatch, { windowId }) => ({
removeWindow: () => dispatch(actions.removeWindow(windowId)),
toggleWindowSideBar: () => dispatch(actions.toggleWindowSideBar(windowId)),
});
const enhance = compose(
connect(null, mapDispatchToProps),
connect(mapStateToProps, mapDispatchToProps),
miradorWithPlugins,
withNamespaces(),
// further HOC go here
......
......@@ -43,3 +43,14 @@ export function getThumbnailNavigationPosition(state, windowId) {
return state.windows[windowId]
&& 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