diff --git a/__tests__/fixtures/version-3/0002-mvm-audio.json b/__tests__/fixtures/version-3/0002-mvm-audio.json new file mode 100644 index 0000000000000000000000000000000000000000..75aaf7bf56966f4bdc3ad7975537e659244934c9 --- /dev/null +++ b/__tests__/fixtures/version-3/0002-mvm-audio.json @@ -0,0 +1,37 @@ +{ + "@context": "http://iiif.io/api/presentation/3/context.json", + "id": "https://iiif.io/api/cookbook/recipe/0002-mvm-audio/manifest.json", + "type": "Manifest", + "label": { + "en": [ + "Simplest Audio Example 1" + ] + }, + "items": [ + { + "id": "https://iiif.io/api/cookbook/recipe/0002-mvm-audio/canvas", + "type": "Canvas", + "duration": 1985.024, + "items": [ + { + "id": "https://iiif.io/api/cookbook/recipe/0002-mvm-audio/canvas/page", + "type": "AnnotationPage", + "items": [ + { + "id": "https://iiif.io/api/cookbook/recipe/0002-mvm-audio/canvas/page/annotation", + "type": "Annotation", + "motivation": "painting", + "body": { + "id": "https://fixtures.iiif.io/audio/indiana/mahler-symphony-3/CD1/medium/128Kbps.mp4", + "type": "Sound", + "format": "audio/mp4", + "duration": 1985.024 + }, + "target": "https://iiif.io/api/cookbook/recipe/0002-mvm-audio/canvas/page" + } + ] + } + ] + } + ] +} diff --git a/__tests__/fixtures/version-3/0015-start.json b/__tests__/fixtures/version-3/0015-start.json new file mode 100644 index 0000000000000000000000000000000000000000..65308e44a609a6af5070865b7cf22175202f5d1a --- /dev/null +++ b/__tests__/fixtures/version-3/0015-start.json @@ -0,0 +1,52 @@ +{ + "@context": "http://iiif.io/api/presentation/3/context.json", + "id": "https://iiif.io/api/cookbook/recipe/0015-start/manifest.json", + "type": "Manifest", + "label": { + "en": [ + "Video of a 30-minute digital clock" + ] + }, + "start": { + "id": "https://iiif.io/api/cookbook/recipe/0015-start/canvas-start/segment1", + "type": "SpecificResource", + "source": "https://iiif.io/api/cookbook/recipe/0015-start/canvas/segment1", + "selector": { + "type": "PointSelector", + "t": 120.5 + } + }, + "items": [ + { + "id": "https://iiif.io/api/cookbook/recipe/0015-start/canvas/segment1", + "type": "Canvas", + "duration": 1801.055, + "items": [ + { + "id": "https://iiif.io/api/cookbook/recipe/0015-start/annotation/segment1/page", + "type": "AnnotationPage", + "items": [ + { + "id": "https://iiif.io/api/cookbook/recipe/0015-start/annotation/segment1-video", + "type": "Annotation", + "motivation": "painting", + "body": [ + { + "id": "https://fixtures.iiif.io/video/indiana/30-minute-clock/medium/30-minute-clock.mp4", + "type": "Video", + "duration": 1801.055, + "format": "video/mp4" + }, + { + "id": "https://example.com/file.vtt", + "format": "text/vtt" + } + ], + "target": "https://iiif.io/api/cookbook/recipe/0015-start/canvas/segment1" + } + ] + } + ] + } + ] +} diff --git a/__tests__/src/components/AudioViewer.test.js b/__tests__/src/components/AudioViewer.test.js new file mode 100644 index 0000000000000000000000000000000000000000..1e807aaeeb4c5c2f4a2e7e5b748cd7b4c83ec9e7 --- /dev/null +++ b/__tests__/src/components/AudioViewer.test.js @@ -0,0 +1,42 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import { AudioViewer } from '../../../src/components/AudioViewer'; + +/** create wrapper */ +function createWrapper(props, suspenseFallback) { + return shallow( + <AudioViewer + classes={{}} + {...props} + />, + ); +} + +describe('AudioViewer', () => { + let wrapper; + describe('render', () => { + it('audioResources', () => { + wrapper = createWrapper({ + audioResources: [ + { getFormat: () => 'video/mp4', id: 1 }, + { getFormat: () => 'video/mp4', id: 2 }, + ], + }, true); + expect(wrapper.contains(<source src="1" type="video/mp4" />)); + expect(wrapper.contains(<source src="2" type="video/mp4" />)); + }); + it('captions', () => { + wrapper = createWrapper({ + audioResources: [ + { getFormat: () => 'video/mp4', id: 1 }, + ], + captions: [ + { getLabel: () => 'English', getProperty: () => 'en', id: 1 }, + { getLabel: () => 'French', getProperty: () => 'fr', id: 2 }, + ], + }, true); + expect(wrapper.contains(<track src="1" label="English" srcLang="en" />)); + expect(wrapper.contains(<track src="2" label="French" srcLang="fr" />)); + }); + }); +}); diff --git a/__tests__/src/components/VideoViewer.test.js b/__tests__/src/components/VideoViewer.test.js new file mode 100644 index 0000000000000000000000000000000000000000..31945a749ea8a6206c0eed0bf9637e0241f2a24f --- /dev/null +++ b/__tests__/src/components/VideoViewer.test.js @@ -0,0 +1,42 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import { VideoViewer } from '../../../src/components/VideoViewer'; + +/** create wrapper */ +function createWrapper(props, suspenseFallback) { + return shallow( + <VideoViewer + classes={{}} + {...props} + />, + ); +} + +describe('VideoViewer', () => { + let wrapper; + describe('render', () => { + it('videoResources', () => { + wrapper = createWrapper({ + videoResources: [ + { getFormat: () => 'video/mp4', id: 1 }, + { getFormat: () => 'video/mp4', id: 2 }, + ], + }, true); + expect(wrapper.contains(<source src="1" type="video/mp4" />)); + expect(wrapper.contains(<source src="2" type="video/mp4" />)); + }); + it('captions', () => { + wrapper = createWrapper({ + captions: [ + { getLabel: () => 'English', getProperty: () => 'en', id: 1 }, + { getLabel: () => 'French', getProperty: () => 'fr', id: 2 }, + ], + videoResources: [ + { getFormat: () => 'video/mp4', id: 1 }, + ], + }, true); + expect(wrapper.contains(<track src="1" label="English" srcLang="en" />)); + expect(wrapper.contains(<track src="2" label="French" srcLang="fr" />)); + }); + }); +}); diff --git a/__tests__/src/lib/MiradorCanvas.test.js b/__tests__/src/lib/MiradorCanvas.test.js index e28717725568c34c048fca46c84427f9213b7bd5..e40237b59748f58b00f5575ef9fc99dce49c7f03 100644 --- a/__tests__/src/lib/MiradorCanvas.test.js +++ b/__tests__/src/lib/MiradorCanvas.test.js @@ -6,6 +6,8 @@ import otherContentFixture from '../../fixtures/version-2/299843.json'; import otherContentStringsFixture from '../../fixtures/version-2/BibliographicResource_3000126341277.json'; import fragmentFixture from '../../fixtures/version-2/hamilton.json'; import fragmentFixtureV3 from '../../fixtures/version-3/hamilton.json'; +import audioFixture from '../../fixtures/version-3/0002-mvm-audio.json'; +import videoFixture from '../../fixtures/version-3/0015-start.json'; describe('MiradorCanvas', () => { let instance; @@ -100,4 +102,28 @@ describe('MiradorCanvas', () => { ).toEqual([552, 1584, 3360, 2368]); }); }); + describe('videoResources', () => { + it('returns video', () => { + instance = new MiradorCanvas( + Utils.parseManifest(videoFixture).getSequences()[0].getCanvases()[0], + ); + expect(instance.videoResources.length).toEqual(1); + }); + }); + describe('audioResources', () => { + it('returns audio', () => { + instance = new MiradorCanvas( + Utils.parseManifest(audioFixture).getSequences()[0].getCanvases()[0], + ); + expect(instance.audioResources.length).toEqual(1); + }); + }); + describe('vttContent', () => { + it('returns vttContent', () => { + instance = new MiradorCanvas( + Utils.parseManifest(videoFixture).getSequences()[0].getCanvases()[0], + ); + expect(instance.vttContent.length).toEqual(1); + }); + }); }); diff --git a/__tests__/src/selectors/canvases.test.js b/__tests__/src/selectors/canvases.test.js index c6dcf8145bbf416670ddda930b6dcffe04cd8a93..e8fc9adb8ce1f84de636ddfc70c2b75d7896de70 100644 --- a/__tests__/src/selectors/canvases.test.js +++ b/__tests__/src/selectors/canvases.test.js @@ -2,6 +2,8 @@ import manifestFixture001 from '../../fixtures/version-2/001.json'; import manifestFixture019 from '../../fixtures/version-2/019.json'; import minimumRequired from '../../fixtures/version-2/minimumRequired.json'; import minimumRequired3 from '../../fixtures/version-3/minimumRequired.json'; +import audioFixture from '../../fixtures/version-3/0002-mvm-audio.json'; +import videoFixture from '../../fixtures/version-3/0015-start.json'; import settings from '../../../src/config/settings'; import { @@ -12,6 +14,9 @@ import { getCanvasLabel, selectInfoResponse, getVisibleCanvasNonTiledResources, + getVisibleCanvasVideoResources, + getVisibleCanvasAudioResources, + getVisibleCanvasCaptions, getVisibleCanvasIds, } from '../../../src/state/selectors/canvases'; @@ -375,4 +380,76 @@ describe('getVisibleCanvasNonTiledResources', () => { state, { windowId: 'a' }, )[0].id).toBe('http://iiif.io/api/presentation/2.1/example/fixtures/resources/page1-full.png'); }); + + describe('getVisibleCanvasVideoResources', () => { + it('returns canvases resources', () => { + const state = { + manifests: { + 'https://iiif.io/api/cookbook/recipe/0015-start/manifest.json': { + id: 'https://iiif.io/api/cookbook/recipe/0015-start/manifest.json', + json: videoFixture, + }, + }, + windows: { + a: { + manifestId: 'https://iiif.io/api/cookbook/recipe/0015-start/manifest.json', + visibleCanvases: [ + 'https://iiif.io/api/cookbook/recipe/0015-start/canvas/segment1', + ], + }, + }, + }; + expect(getVisibleCanvasVideoResources( + state, { windowId: 'a' }, + )[0].id).toBe('https://fixtures.iiif.io/video/indiana/30-minute-clock/medium/30-minute-clock.mp4'); + }); + }); + + describe('getVisibleCanvasCaptions', () => { + it('returns canvases resources', () => { + const state = { + manifests: { + 'https://iiif.io/api/cookbook/recipe/0015-start/manifest.json': { + id: 'https://iiif.io/api/cookbook/recipe/0015-start/manifest.json', + json: videoFixture, + }, + }, + windows: { + a: { + manifestId: 'https://iiif.io/api/cookbook/recipe/0015-start/manifest.json', + visibleCanvases: [ + 'https://iiif.io/api/cookbook/recipe/0015-start/canvas/segment1', + ], + }, + }, + }; + expect(getVisibleCanvasCaptions( + state, { windowId: 'a' }, + )[0].id).toBe('https://example.com/file.vtt'); + }); + }); + + describe('getVisibleCanvasAudioResources', () => { + it('returns canvases resources', () => { + const state = { + manifests: { + 'https://iiif.io/api/cookbook/recipe/0002-mvm-audio/manifest.json': { + id: 'https://iiif.io/api/cookbook/recipe/0002-mvm-audio/manifest.json', + json: audioFixture, + }, + }, + windows: { + a: { + manifestId: 'https://iiif.io/api/cookbook/recipe/0002-mvm-audio/manifest.json', + visibleCanvases: [ + 'https://iiif.io/api/cookbook/recipe/0002-mvm-audio/canvas', + ], + }, + }, + }; + expect(getVisibleCanvasAudioResources( + state, { windowId: 'a' }, + )[0].id).toBe('https://fixtures.iiif.io/audio/indiana/mahler-symphony-3/CD1/medium/128Kbps.mp4'); + }); + }); }); diff --git a/src/components/PrimaryWindow.js b/src/components/PrimaryWindow.js index f7ad1d18b34ec846ba183d9078cf06d974747eb6..3313139085422dbb06c24f01b88834cbf9448446 100644 --- a/src/components/PrimaryWindow.js +++ b/src/components/PrimaryWindow.js @@ -28,7 +28,8 @@ export class PrimaryWindow extends Component { */ renderViewer() { const { - audioResources, isCollection, isCollectionDialogVisible, isFetching, videoResources, view, windowId, + audioResources, isCollection, isCollectionDialogVisible, + isFetching, videoResources, view, windowId, } = this.props; if (isCollection) { return (