Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

M4 update dependencies/components, fix tests, replace nwb with babel/web… #65

Merged
merged 4 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
{
"env": {
"jest/globals": true
},
"extends": ["airbnb"],
"env": {},
"extends": ["airbnb", "plugin:jest/recommended"],
"globals": {
"page": true,
"document": true
},
"parser": "babel-eslint",
"plugins": ["jest"],
"parser": "@babel/eslint-parser",
"plugins": ["babel", "jest", "react", "react-hooks"],
"rules": {
"import/prefer-default-export": "off",
"import/no-extraneous-dependencies": "off",
"no-console": "off",
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
"react/jsx-fragments": "off",
"react/jsx-props-no-spreading": "off",
"react/prefer-stateless-function": "off",
"react/function-component-definition": "off"
}
}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@
/umd
npm-debug.log*
package-lock.json
.cache
dist
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[![npm package][npm-badge]][npm]
[![Coveralls][coveralls-badge]][coveralls]

`mirador-dl-plugin` is a Mirador 3 plugin that adds manifest-provided download links (e.g. `rendering`) to the window options menu. A [live demo](https://mirador-download-plugin.netlify.app/) with several institutions' manifests is available for testing.
`mirador-dl-plugin` is a Mirador 4 plugin that adds manifest-provided download links (e.g. `rendering`) to the window options menu. A [live demo](https://mirador-download-plugin.netlify.app/) with several institutions' manifests is available for testing.

![download option in menu](https://user-images.githubusercontent.com/5402927/87057974-5e665a80-c1bc-11ea-8f10-7b783bdc972f.png)

Expand All @@ -22,7 +22,7 @@

## Installation

`mirador-dl-plugin` requires an instance of Mirador 3. See the [Mirador wiki](https://github.com/ProjectMirador/mirador/wiki) for examples of embedding Mirador within an application and additional information about plugins. See the [live demo's index.js](https://github.com/ProjectMirador/mirador-dl-plugin/blob/master/demo/src/index.js) for an example of importing and configuring `mirador-dl-plugin`.
`mirador-dl-plugin` requires an instance of Mirador 4. See the [Mirador wiki](https://github.com/ProjectMirador/mirador/wiki) for examples of embedding Mirador within an application and additional information about plugins. See the [live demo's index.js](https://github.com/ProjectMirador/mirador-dl-plugin/blob/master/demo/src/index.js) for an example of importing and configuring `mirador-dl-plugin`.

## Configuration

Expand Down
185 changes: 76 additions & 109 deletions __tests__/CanvasDownloadLinks.test.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import React from 'react';
import { shallow } from 'enzyme';
import Link from '@material-ui/core/Link';
import Typography from '@material-ui/core/Typography';
import { OSDReferences } from 'mirador/dist/es/src/plugins/OSDReferences';
import CanvasDownloadLinks from '../src/CanvasDownloadLinks';
import RenderingDownloadLink from '../src/RenderingDownloadLink';

import { render, screen } from './test-utils';

function createWrapper(props) {
return shallow(
return render(
<CanvasDownloadLinks
canvasId="abc123"
canvasLabel="My Canvas Label"
Expand All @@ -22,10 +19,9 @@ function createWrapper(props) {
}

describe('CanvasDownloadLinks', () => {
let wrapper;
const canvas = {
id: 'abc123',
getCanonicalImageUri: width => (
getCanonicalImageUri: (width) => (
width
? `http://example.com/iiif/abc123/full/${width},/0/default.jpg`
: 'http://example.com/iiif/abc123/full/4000,/0/default.jpg'
Expand All @@ -40,108 +36,85 @@ describe('CanvasDownloadLinks', () => {
},
],
};
const viewport = {
getBounds: () => ({
x: 0, y: 0, width: 4000, height: 1000,
}),
};
const zoomedInViewport = {
getBounds: () => ({
x: 0, y: 0, width: 2000, height: 500,
}),
};

const zoomedOutViewport = {
getBounds: () => ({
x: 0, y: 0, width: 6000, height: 1000,
}),
};

const zoomedIntoNonImageSpaceViewport = {
getBounds: () => ({
x: -100, y: 100, width: 2000, height: 500,
}),
};
let currentBoundsSpy;
beforeEach(() => {
currentBoundsSpy = jest.spyOn(CanvasDownloadLinks.prototype, 'currentBounds');
});

beforeAll(() => {
OSDReferences.set('wid123', {
current: { viewport },
});
OSDReferences.set('zoomedInWindow', {
current: { viewport: zoomedInViewport },
});
OSDReferences.set('zoomedOutWindow', {
current: { viewport: zoomedOutViewport },
});
OSDReferences.set('zoomedIntoNonImageSpaceWindow', {
current: { viewport: zoomedIntoNonImageSpaceViewport },
});
afterEach(() => {
currentBoundsSpy.mockRestore();
});

it('renders canvas label in an h3 typography', () => {
wrapper = createWrapper({ canvas });
expect(
wrapper.find(Typography)
.find({ variant: 'h3' })
.props().children,
).toEqual('My Canvas Label');
createWrapper({ canvas });

screen.getByRole('heading');
const headingElement = screen.getByText('My Canvas Label');
expect(headingElement).toBeInTheDocument();
expect(headingElement.tagName).toBe('H3');
});

it('renders canvas level renderings', () => {
wrapper = createWrapper({ canvas });
expect(
wrapper.find(RenderingDownloadLink).length,
).toEqual(1);
createWrapper({ canvas });

const dlElement = screen.getByRole('link', { name: /Whole image \(4000 x 1000px\)/i });
expect(dlElement).toBeInTheDocument();
});

describe('Zoomed region link', () => {
const infoResponse = {
json: { width: 4000, height: 1000 },
};

it('it does not render a link when the viewer is zoomed out/at the entire image', () => {
wrapper = createWrapper({ canvas, infoResponse, windowId: 'zoomedOutWindow' });
expect(wrapper.find(Link).length).toBe(2);
it('does not render a link when the viewer is zoomed out/at the entire image', () => {
currentBoundsSpy.mockImplementation(() => ({
x: 0, y: 0, width: 6000, height: 1000,
}));

wrapper = createWrapper({ canvas, infoResponse, windowId: 'wid123' });
expect(wrapper.find(Link).length).toBe(2);
createWrapper({ canvas, infoResponse, windowId: 'zoomedOutWindow' });
const zoomedLink = screen.queryByText('Zoomed region (6000 x 1000px)');
expect(zoomedLink).not.toBeInTheDocument();
});

it('does not render a link when the viewer is zoomed into non-image space (e.g. a reponse the image server cannot handle)', () => {
wrapper = createWrapper({ canvas, infoResponse, windowId: 'zoomedIntoNonImageSpaceWindow' });

expect(wrapper.find(Link).length).toBe(2);
currentBoundsSpy.mockImplementation(() => ({
x: -100, y: 100, width: 2000, height: 500,
}));
createWrapper({ canvas, infoResponse, windowId: 'zoomedIntoNonImageSpaceWindow' });
const zoomedLink = screen.queryByText('Zoomed region (2000 x 500px)');
expect(zoomedLink).not.toBeInTheDocument();
});

it('is present when the viewer is zoomed into the image', () => {
wrapper = createWrapper({ canvas, infoResponse, windowId: 'zoomedInWindow' });

expect(wrapper.find(Link).length).toBe(3);
expect(
wrapper
.find(Link)
.find({ href: 'http://example.com/iiif/abc123/0,0,2000,500/full/0/default.jpg?download=true' })
.props().children,
).toEqual('Zoomed region (2000 x 500px)');
currentBoundsSpy.mockImplementation(() => ({
x: 0, y: 0, width: 2000, height: 500,
}));
createWrapper({ canvas, infoResponse, windowId: 'zoomedInWindow' });
const zoomedLink = screen.queryByText('Zoomed region (2000 x 500px)');
expect(zoomedLink).toBeInTheDocument();
});

it('is not present when the window is in book or gallery view (only single view)', () => {
wrapper = createWrapper({
currentBoundsSpy.mockImplementation(() => ({
x: 0, y: 0, width: 2000, height: 500,
}));
createWrapper({
canvas, infoResponse, viewType: 'book', windowId: 'zoomedInWindow',
});
const zoomedLink = screen.queryByText('Zoomed region (2000 x 500px)');
expect(zoomedLink).not.toBeInTheDocument();

expect(wrapper.find(Link).length).toBe(2);

wrapper = createWrapper({
createWrapper({
canvas, infoResponse, viewType: 'gallery', windowId: 'zoomedInWindow',
});

expect(wrapper.find(Link).length).toBe(2);
const zoomedLinkGallery = screen.queryByText('Zoomed region (2000 x 500px)');
expect(zoomedLinkGallery).not.toBeInTheDocument();
});

describe('when the zoom link is set to be restricted', () => {
it('has just the whole image link from the sizes and does not present a zoomed region link', () => {
wrapper = createWrapper({
createWrapper({
canvas,
infoResponse: {
json: {
Expand All @@ -156,9 +129,8 @@ describe('CanvasDownloadLinks', () => {
restrictDownloadOnSizeDefinition: true,
windowId: 'zoomedInWindow',
});

expect(wrapper.find(Link).length).toBe(1);
expect(wrapper.find(Link).props().children).toEqual('Whole image (400 x 100px)');
const links = screen.getByRole('link', { name: /Whole image \(400 x 100px\)/i });
expect(links).toBeInTheDocument();
});
});
});
Expand All @@ -170,51 +142,46 @@ describe('CanvasDownloadLinks', () => {
{ width: 1000, height: 250 },
];
it('uses those sizes for links in the download dialog', () => {
wrapper = createWrapper({ canvas, infoResponse: { json: { sizes } } });

// console.log(wrapper.debug());
expect(wrapper.find(Link).at(0).props().children).toEqual('Whole image (4000 x 1000px)');
expect(wrapper.find(Link).at(1).props().children).toEqual('Whole image (2000 x 500px)');
expect(wrapper.find(Link).at(2).props().children).toEqual('Whole image (1000 x 250px)');
createWrapper({ canvas, infoResponse: { json: { sizes } } });
const link1 = screen.getByRole('link', { name: /Whole image \(4000 x 1000px\)/i });
const link2 = screen.getByRole('link', { name: /Whole image \(2000 x 500px\)/i });
const link3 = screen.getByRole('link', { name: /Whole image \(1000 x 250px\)/i });

expect(link1).toBeInTheDocument();
expect(link2).toBeInTheDocument();
expect(link3).toBeInTheDocument();
});
});

describe('when there are no defined sizes', () => {
it('renders a link to the whole image', () => {
wrapper = createWrapper({ canvas });
expect(
wrapper
.find(Link)
.find({ href: 'http://example.com/iiif/abc123/full/full/0/default.jpg?download=true' })
.props()
.children,
).toEqual('Whole image (4000 x 1000px)');
createWrapper({ canvas });
const link = screen.getByRole('link', { name: /Whole image \(4000 x 1000px\)/i });
expect(link).toBeInTheDocument();
expect(link).toHaveAttribute('href', 'http://example.com/iiif/abc123/full/full/0/default.jpg?download=true');
});

describe('when the image is > 1000px wide', () => {
it('renders a link to a small image (1000px wide), and calculates the correct height', () => {
wrapper = createWrapper({ canvas });
expect(wrapper.find(Link).length).toEqual(2);
expect(
wrapper
.find(Link)
.find({ href: 'http://example.com/iiif/abc123/full/1000,/0/default.jpg?download=true' })
.length,
).toEqual(1);
expect(
wrapper
.find(Link)
.find({ href: 'http://example.com/iiif/abc123/full/1000,/0/default.jpg?download=true' })
.props().children,
).toEqual('Whole image (1000 x 250px)');
createWrapper({ canvas });
const links = screen.getAllByRole('link');

expect(links).toBeInTheDocument();

const link1 = screen.getByRole('link', { name: /Whole image \(4000 x 1000px\)/i });
expect(link1).toHaveAttribute('href', 'http://example.com/iiif/abc123/full/1000,/0/default.jpg?download=true');

const link2 = screen.getByRole('link', { name: /Whole image \(1000 x 250px\)/i });
expect(link2).toHaveAttribute('href', 'http://example.com/iiif/abc123/full/1000,/0/default.jpg?download=true');
});
});

describe('when the image is < 1000px wide', () => {
it('does not render a link to a small image', () => {
canvas.getWidth = () => 999;
wrapper = createWrapper({ canvas });
expect(wrapper.find(Link).length).toEqual(1); // Does not include the 2nd link
createWrapper({ canvas });
const links = screen.getAllByRole('link');
expect(links).toHaveLength(2);
});
});
});
Expand Down
26 changes: 14 additions & 12 deletions __tests__/ManifestDownloadLinks.test.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import React from 'react';
import { shallow } from 'enzyme';
import Typography from '@material-ui/core/Typography';
import ManifestDownloadLinks from '../src/ManifestDownloadLinks';
import RenderingDownloadLink from '../src/RenderingDownloadLink';
import { render, screen } from './test-utils';

function createWrapper(props) {
return shallow(
return render(
<ManifestDownloadLinks
classes={{}}
renderings={[]}
Expand All @@ -29,18 +27,22 @@ describe('ManifestDownloadLinks', () => {
];

it('renders the heading', () => {
const wrapper = createWrapper({ renderings });
createWrapper({ renderings });
screen.debug();

expect(
wrapper.find(Typography)
.find({ variant: 'h3' })
.props().children,
).toEqual('Other download options');
screen.getByRole('heading');
const headingElement = screen.getByText('Other download options');
expect(headingElement).toBeInTheDocument();
expect(headingElement.tagName).toBe('H3');
});

it('renders a RenderingDownloadLink for each rendering', () => {
const wrapper = createWrapper({ renderings });
createWrapper({ renderings });

expect(wrapper.find(RenderingDownloadLink).length).toBe(2);
const pdfLinkElement = screen.getByRole('link', { name: /Link to the PDF/i });
expect(pdfLinkElement).toBeInTheDocument();

const ocrLinkElement = screen.getByRole('link', { name: /Link to the OCR/i });
expect(ocrLinkElement).toBeInTheDocument();
});
});
Loading
Loading