From 9f1d9a5c68d567977c9a2912ef0529d20e05e868 Mon Sep 17 00:00:00 2001 From: Justin Coyne Date: Wed, 1 Apr 2026 08:05:48 -0500 Subject: [PATCH 1/4] Add prettier --- .prettierignore | 16 ++++++++++++++++ .prettierrc | 7 +++++++ package.json | 5 ++++- 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 .prettierignore create mode 100644 .prettierrc diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..b0794c7a7 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,16 @@ +# Build artifacts +dist/ + +.github/ + +# Test fixtures +__tests__/fixtures/ + +# Dependencies +node_modules/ + +# Test coverage +coverage/ + +# Package manager files +package-lock.json diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..8b0e83d64 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "singleQuote": true, + "trailingComma": "all", + "semi": true, + "printWidth": 100, + "tabWidth": 2 +} diff --git a/package.json b/package.json index a2d71a1c0..1eccad285 100644 --- a/package.json +++ b/package.json @@ -20,12 +20,14 @@ "scripts": { "build": "vite build --config vite.config.js && vite build --config vite-umd.config.js", "clean": "rm -rf ./dist", + "format": "prettier --write .", + "format:check": "prettier --check .", "lint": "node_modules/.bin/eslint ./ && npm run lint:translations && npm run lint:containers", "lint:containers": "node ./scripts/container-lint.js", "lint:translations": "node ./scripts/i18n-lint.js", "size": "bundlewatch --config bundlewatch.config.json", "start": "vite", - "test": "npm run build && npm run lint && npm run size && vitest run" + "test": "npm run build && npm run lint && npm run format:check && npm run size && vitest run" }, "license": "Apache-2.0", "contributors": [ @@ -106,6 +108,7 @@ "glob": "^13.0.6", "globals": "^15.15.0", "happy-dom": "^20.0", + "prettier": "^3.8.1", "react": "^19.0.0", "react-dnd-test-backend": "^16.0.1", "react-dom": "^19.0.0", From ce89c115f89cda7db1de070575cac158118f28b1 Mon Sep 17 00:00:00 2001 From: Justin Coyne Date: Wed, 1 Apr 2026 09:03:34 -0500 Subject: [PATCH 2/4] Run Prettier to reformat the code --- .prettierignore | 5 + .../integration/components/AddComponentA.jsx | 4 +- .../integration/components/AddComponentB.jsx | 4 +- .../integration/components/AddComponentC.jsx | 6 +- .../CompanionWindowButtonComponent.jsx | 4 +- .../components/CompanionWindowComponent.jsx | 4 +- .../components/StateDependentComponent.jsx | 2 +- .../components/WrapIconComponent.jsx | 9 +- .../mirador-configs/collections.js | 7 +- .../integration/mirador-configs/constants.js | 6 +- .../mirador-configs/content-search.js | 17 +- .../mirador-configs/fallback-image.js | 3 +- __tests__/integration/mirador-configs/i18n.js | 68 +++- .../integration/mirador-configs/iiif-v3.js | 9 +- .../integration/mirador-configs/index.js | 78 +++- .../mirador-configs/initial-viewer-config.js | 22 +- .../integration/mirador-configs/layers.js | 32 +- .../integration/mirador-configs/minimalist.js | 14 +- .../mirador-configs/multiple-sequences.js | 3 +- .../integration/mirador-configs/plugin-add.js | 4 +- .../plugin-companion-window.js | 5 +- .../mirador-configs/plugin-priority.js | 11 +- .../mirador-configs/plugin-state.js | 12 +- __tests__/integration/mirador-configs/rtl.js | 3 +- .../mirador-configs/single-bodleian.js | 9 +- .../mirador-configs/single-van-gogh.js | 10 +- .../mirador-configs/svg-annotations.js | 3 +- .../mirador-configs/table-of-contents.js | 33 +- .../integration/mirador-configs/video.js | 6 +- .../integration/plugins/invalidPluginA.jsx | 2 +- .../integration/plugins/invalidPluginB.jsx | 4 +- .../integration/plugins/invalidPluginC.jsx | 2 +- .../integration/plugins/invalidPluginD.jsx | 2 +- .../integration/plugins/invalidPluginE.jsx | 2 +- .../integration/plugins/invalidPluginF.jsx | 2 +- .../plugins/stateDependentPlugin.jsx | 6 +- .../integration/plugins/validPluginA.jsx | 2 +- .../integration/plugins/validPluginB.jsx | 2 +- __tests__/integration/tests/basic.test.js | 16 +- .../tests/companion-windows.test.js | 12 +- .../integration/tests/import-export.test.js | 4 +- .../tests/invalid-manifest.test.js | 6 +- .../integration/tests/minimalist.test.js | 6 +- .../integration/tests/plugin-add.test.js | 7 +- .../tests/plugin-companion-window.test.js | 5 +- .../integration/tests/plugin-state.test.js | 3 +- .../tests/sequence-switching.test.js | 24 +- .../tests/thumbnail-navigation.test.js | 7 +- .../integration/tests/viewer-config.test.js | 19 +- .../integration/tests/window-actions.test.js | 14 +- __tests__/src/actions/auth.test.js | 28 +- __tests__/src/actions/catalog.test.js | 12 +- __tests__/src/actions/companionWindow.test.js | 16 +- __tests__/src/actions/elasticLayout.test.js | 10 +- __tests__/src/actions/infoResponse.test.js | 4 +- __tests__/src/actions/search.test.js | 16 +- __tests__/src/actions/window.test.js | 15 +- __tests__/src/actions/workspace.test.js | 20 +- .../src/components/AccessTokenSender.test.js | 21 +- __tests__/src/components/App.test.js | 6 +- __tests__/src/components/AppProviders.test.js | 4 +- .../src/components/AttributionPanel.test.js | 36 +- __tests__/src/components/AudioViewer.test.js | 45 ++- .../components/BackgroundPluginArea.test.js | 4 +- __tests__/src/components/CanvasInfo.test.js | 4 +- __tests__/src/components/CanvasLayers.test.js | 74 ++-- .../src/components/CollapsibleSection.test.js | 17 +- .../src/components/CollectionDialog.test.js | 35 +- .../src/components/CollectionInfo.test.js | 6 +- .../src/components/CompanionArea.test.js | 19 +- .../src/components/CompanionWindow.test.js | 25 +- .../components/CompanionWindowFactory.test.js | 15 +- __tests__/src/components/ErrorContent.test.js | 3 +- __tests__/src/components/ErrorDialog.test.js | 6 +- .../src/components/FullScreenButton.test.js | 6 +- __tests__/src/components/GalleryView.test.js | 6 +- .../components/GalleryViewThumbnail.test.js | 32 +- .../src/components/IIIFAuthentication.test.js | 40 +- .../src/components/IIIFDropTarget.test.js | 42 ++- .../src/components/IIIFThumbnail.test.js | 14 +- .../src/components/LabelValueMetadata.test.js | 6 +- .../src/components/LanguageSettings.test.js | 18 +- __tests__/src/components/LayersPanel.test.js | 11 +- __tests__/src/components/LocalePicker.test.js | 13 +- __tests__/src/components/ManifestForm.test.js | 12 +- __tests__/src/components/ManifestInfo.test.js | 4 +- .../src/components/ManifestListItem.test.js | 7 +- .../components/ManifestListItemError.test.js | 2 +- .../components/ManifestRelatedLinks.test.js | 35 +- .../src/components/MiradorMenuButton.test.js | 2 +- .../components/MosaicRenderPreview.test.js | 7 +- __tests__/src/components/NestedMenu.test.js | 8 +- .../src/components/NewBrowserWindow.test.js | 8 +- .../OpenSeadragonTileSource.test.js | 30 +- .../components/OpenSeadragonViewer.test.js | 32 +- __tests__/src/components/PluginHook.test.js | 14 +- .../src/components/PrimaryWindow.test.js | 49 +-- .../src/components/SanitizedHtml.test.js | 5 +- .../ScrollIndicatedDialogContent.test.js | 7 +- __tests__/src/components/ScrollTo.test.js | 62 +++- __tests__/src/components/SearchHit.test.js | 14 +- __tests__/src/components/SearchPanel.test.js | 13 +- .../components/SearchPanelControls.test.js | 17 +- .../components/SearchPanelNavigation.test.js | 7 +- .../src/components/SearchResults.test.js | 4 +- .../src/components/SidebarIndexItem.test.js | 8 +- .../src/components/SidebarIndexList.test.js | 8 +- .../SidebarIndexTableOfContents.test.js | 41 +- .../components/SidebarIndexThumbnail.test.js | 3 +- __tests__/src/components/TextViewer.test.js | 48 ++- .../ThumbnailCanvasGrouping.test.js | 7 +- .../components/ThumbnailNavigation.test.js | 40 +- __tests__/src/components/VideoViewer.test.js | 63 ++-- __tests__/src/components/ViewerInfo.test.js | 8 +- .../src/components/ViewerNavigation.test.js | 44 ++- __tests__/src/components/Window.test.js | 18 +- .../WindowAuthenticationBar.test.js | 3 +- .../WindowCanvasNavigationControls.test.js | 15 +- .../src/components/WindowListButton.test.js | 22 +- .../src/components/WindowSideBar.test.js | 38 +- .../WindowSideBarAnnotationsPanel.test.js | 8 +- .../WindowSideBarCanvasPanel.test.js | 6 +- .../components/WindowSideBarInfoPanel.test.js | 11 +- .../WindowThumbnailSettings.test.js | 35 +- __tests__/src/components/WindowTopBar.test.js | 34 +- .../components/WindowTopBarPluginArea.test.js | 4 +- .../components/WindowTopBarPluginMenu.test.js | 11 +- .../src/components/WindowTopBarTitle.test.js | 7 +- .../src/components/WindowTopMenu.test.js | 18 +- .../components/WindowTopMenuButton.test.js | 8 +- .../src/components/WindowViewSettings.test.js | 40 +- __tests__/src/components/WindowViewer.test.js | 6 +- __tests__/src/components/Workspace.test.js | 18 +- __tests__/src/components/WorkspaceAdd.test.js | 35 +- .../src/components/WorkspaceArea.test.js | 18 +- .../components/WorkspaceControlPanel.test.js | 16 +- .../components/WorkspaceElasticWindow.test.js | 29 +- .../src/components/WorkspaceImport.test.js | 7 +- .../src/components/WorkspaceMenu.test.js | 17 +- .../components/WorkspaceMenuButton.test.js | 4 +- .../src/components/WorkspaceMosaic.test.js | 57 ++- .../components/WorkspaceOptionsButton.test.js | 7 +- .../components/WorkspaceOptionsMenu.test.js | 19 +- .../WorkspaceSelectionDialog.test.js | 4 +- __tests__/src/components/ZoomControls.test.js | 12 +- __tests__/src/extend/pluginMapping.test.js | 24 +- .../src/extend/pluginPreprocessing.test.js | 12 +- __tests__/src/extend/pluginValidation.test.js | 20 +- __tests__/src/extend/withPlugins.test.js | 19 +- __tests__/src/lib/AnnotationFactory.test.js | 16 +- __tests__/src/lib/AnnotationItem.test.js | 90 ++--- __tests__/src/lib/AnnotationList.test.js | 12 +- __tests__/src/lib/AnnotationPage.test.js | 12 +- __tests__/src/lib/AnnotationResource.test.js | 124 ++++--- __tests__/src/lib/CanvasWorld.test.js | 135 ++++--- __tests__/src/lib/MiradorCanvas.test.js | 72 +++- __tests__/src/lib/MiradorManifest.test.js | 79 ++-- __tests__/src/lib/MiradorViewer.test.js | 78 ++-- .../lib/OpenSeadragonCanvasOverlay.test.js | 3 +- __tests__/src/lib/ThumbnailFactory.test.js | 228 ++++++++---- __tests__/src/lib/TruncatedHit.test.js | 24 +- __tests__/src/reducers/accessTokens.test.js | 97 +++-- __tests__/src/reducers/annotations.test.js | 115 +++--- __tests__/src/reducers/auth.test.js | 84 +++-- __tests__/src/reducers/catalog.test.js | 122 +++--- .../src/reducers/companionWindows.test.js | 34 +- __tests__/src/reducers/config.test.js | 85 +++-- __tests__/src/reducers/elasticLayout.test.js | 84 +++-- __tests__/src/reducers/errors.test.js | 26 +- __tests__/src/reducers/infoResponse.test.js | 118 +++--- __tests__/src/reducers/layers.test.js | 31 +- __tests__/src/reducers/manifests.test.js | 116 +++--- __tests__/src/reducers/search.test.js | 275 +++++++------- __tests__/src/reducers/utils.test.js | 2 +- __tests__/src/reducers/viewers.test.js | 167 +++++---- __tests__/src/reducers/windows.test.js | 349 +++++++++++------- __tests__/src/reducers/workspace.test.js | 201 ++++++---- __tests__/src/sagas/annotations.test.js | 12 +- __tests__/src/sagas/app.test.js | 30 +- __tests__/src/sagas/auth.test.js | 238 ++++++------ __tests__/src/sagas/iiif.test.js | 112 +++--- __tests__/src/sagas/windows.test.js | 165 +++++---- __tests__/src/selectors/annotations.test.js | 38 +- __tests__/src/selectors/auth.test.js | 44 ++- __tests__/src/selectors/canvases.test.js | 113 +++--- .../src/selectors/companionWindows.test.js | 4 +- __tests__/src/selectors/config.test.js | 9 +- __tests__/src/selectors/index.test.js | 20 +- __tests__/src/selectors/layers.test.js | 45 ++- __tests__/src/selectors/manifests.test.js | 117 +++--- __tests__/src/selectors/ranges.test.js | 241 +++++++----- __tests__/src/selectors/searches.test.js | 93 +++-- __tests__/src/selectors/sequences.test.js | 27 +- __tests__/src/selectors/thumbnails.test.js | 10 +- __tests__/src/selectors/viewer.test.js | 8 +- __tests__/src/selectors/workspace.test.js | 6 +- __tests__/utils/safe-queries.js | 5 +- __tests__/utils/test-utils.js | 16 +- eslint.config.js | 19 +- scripts/i18n-lint.js | 19 +- setupTest.js | 4 +- src/components/AccessTokenSender.jsx | 9 +- src/components/AnnotationSettings.jsx | 11 +- src/components/AnnotationsOverlay.jsx | 345 ++++++++++------- src/components/App.jsx | 8 +- src/components/AppProviders.jsx | 31 +- src/components/AttributionPanel.jsx | 65 ++-- src/components/AudioViewer.jsx | 6 +- src/components/Branding.jsx | 16 +- src/components/CanvasAnnotations.jsx | 64 +++- src/components/CanvasInfo.jsx | 17 +- src/components/CanvasLayers.jsx | 217 +++++++---- src/components/ChangeThemeDialog.jsx | 22 +- src/components/CollapsibleSection.jsx | 41 +- src/components/CollectionDialog.jsx | 152 ++++---- src/components/CollectionInfo.jsx | 22 +- src/components/CompanionArea.jsx | 62 ++-- src/components/CompanionWindow.jsx | 160 ++++---- src/components/CompanionWindowFactory.jsx | 21 +- src/components/CompanionWindowSection.jsx | 5 +- src/components/CustomPanel.jsx | 10 +- src/components/ErrorContent.jsx | 15 +- src/components/ErrorDialog.jsx | 4 +- src/components/FullScreenButton.jsx | 20 +- src/components/GalleryView.jsx | 12 +- src/components/GalleryViewThumbnail.jsx | 59 +-- src/components/IIIFAuthentication.jsx | 32 +- src/components/IIIFDropTarget.jsx | 66 ++-- src/components/IIIFIFrameCommunication.jsx | 11 +- src/components/IIIFResourceLabel.jsx | 6 +- src/components/IIIFThumbnail.jsx | 33 +- src/components/ImageFailureMessage.jsx | 4 +- src/components/LabelValueMetadata.jsx | 42 ++- src/components/LanguageSettings.jsx | 34 +- src/components/LayersPanel.jsx | 10 +- src/components/LocalePicker.jsx | 18 +- src/components/ManifestForm.jsx | 26 +- src/components/ManifestInfo.jsx | 20 +- src/components/ManifestListItem.jsx | 72 ++-- src/components/ManifestListItemError.jsx | 19 +- src/components/ManifestRelatedLinks.jsx | 171 +++++---- src/components/MinimalWindow.jsx | 9 +- src/components/MiradorMenuButton.jsx | 39 +- src/components/MosaicRenderPreview.jsx | 5 +- src/components/NestedMenu.jsx | 18 +- src/components/NewBrowserWindow.jsx | 6 +- src/components/OpenSeadragonComponent.jsx | 196 ++++++---- src/components/OpenSeadragonTileSource.jsx | 37 +- src/components/OpenSeadragonViewer.jsx | 90 +++-- src/components/PluginHook.jsx | 23 +- src/components/PrimaryWindow.jsx | 64 ++-- src/components/SanitizedHtml.jsx | 6 +- .../ScrollIndicatedDialogContent.jsx | 38 +- src/components/ScrollTo.jsx | 17 +- src/components/SearchHit.jsx | 50 +-- src/components/SearchPanel.jsx | 55 +-- src/components/SearchPanelControls.jsx | 70 ++-- src/components/SearchPanelNavigation.jsx | 16 +- src/components/SearchResults.jsx | 18 +- src/components/SelectCollection.jsx | 4 +- src/components/SidebarIndexItem.jsx | 8 +- src/components/SidebarIndexList.jsx | 41 +- src/components/SidebarIndexThumbnail.jsx | 15 +- src/components/TextViewer.jsx | 2 +- src/components/ThumbnailCanvasGrouping.jsx | 20 +- src/components/ThumbnailNavigation.jsx | 13 +- src/components/VideoViewer.jsx | 11 +- src/components/ViewerInfo.jsx | 8 +- src/components/ViewerNavigation.jsx | 19 +- src/components/Window.jsx | 32 +- src/components/WindowAuthenticationBar.jsx | 33 +- .../WindowCanvasNavigationControls.jsx | 111 +++--- src/components/WindowList.jsx | 38 +- src/components/WindowListButton.jsx | 22 +- src/components/WindowSideBar.jsx | 10 +- .../WindowSideBarAnnotationsPanel.jsx | 10 +- src/components/WindowSideBarButtons.jsx | 122 +++--- src/components/WindowSideBarCanvasPanel.jsx | 116 +++--- .../WindowSideBarCollectionPanel.jsx | 40 +- src/components/WindowSideBarInfoPanel.jsx | 43 +-- src/components/WindowThumbnailSettings.jsx | 80 ++-- src/components/WindowTopBar.jsx | 68 ++-- src/components/WindowTopBarPluginArea.jsx | 4 +- src/components/WindowTopBarPluginMenu.jsx | 7 +- src/components/WindowTopBarTitle.jsx | 17 +- src/components/WindowTopMenu.jsx | 20 +- src/components/WindowViewSettings.jsx | 62 ++-- src/components/WindowViewer.jsx | 4 +- src/components/Workspace.jsx | 44 +-- src/components/WorkspaceAdd.jsx | 51 +-- src/components/WorkspaceAddButton.jsx | 20 +- src/components/WorkspaceArea.jsx | 14 +- src/components/WorkspaceControlPanel.jsx | 92 ++--- src/components/WorkspaceDialog.jsx | 20 +- src/components/WorkspaceElastic.jsx | 18 +- src/components/WorkspaceElasticWindow.jsx | 18 +- src/components/WorkspaceExport.jsx | 31 +- src/components/WorkspaceImport.jsx | 21 +- src/components/WorkspaceMenu.jsx | 28 +- src/components/WorkspaceMenuButton.jsx | 7 +- src/components/WorkspaceMosaic.jsx | 31 +- src/components/WorkspaceOptionsButton.jsx | 8 +- src/components/WorkspaceOptionsMenu.jsx | 21 +- src/components/WorkspaceSelectionDialog.jsx | 53 +-- src/components/ZoomControls.jsx | 5 +- src/components/icons/BookViewIcon.jsx | 2 +- src/components/icons/GalleryViewIcon.jsx | 5 +- src/components/icons/MiradorIcon.jsx | 2 +- src/components/icons/RestoreZoomIcon.jsx | 2 +- .../icons/ThumbnailNavigationBottomIcon.jsx | 2 +- .../icons/ThumbnailNavigationRightIcon.jsx | 2 +- src/components/icons/WindowMaxIcon.jsx | 2 +- src/components/icons/WindowMinIcon.jsx | 2 +- src/components/icons/WindowOptionsIcon.jsx | 2 +- .../icons/WorkspaceTypeElasticIcon.jsx | 118 +++++- .../icons/WorkspaceTypeMosaicIcon.jsx | 128 ++++++- src/config/css-ns.js | 14 +- src/config/settings.js | 240 ++++++------ src/containers/AnnotationSettings.js | 10 +- src/containers/AnnotationsOverlay.js | 13 +- src/containers/AppProviders.js | 17 +- src/containers/AttributionPanel.js | 11 +- src/containers/AudioViewer.js | 23 +- src/containers/CanvasInfo.js | 5 +- src/containers/CanvasLayers.js | 10 +- src/containers/ChangeThemeDialog.js | 4 +- src/containers/CollectionDialog.js | 8 +- src/containers/CollectionInfo.js | 7 +- src/containers/CompanionArea.js | 14 +- src/containers/CompanionWindow.js | 19 +- src/containers/CompanionWindowFactory.js | 5 +- src/containers/CustomPanel.js | 8 +- src/containers/ErrorContent.js | 5 +- src/containers/ErrorDialog.js | 7 +- src/containers/FullScreenButton.js | 2 +- src/containers/GalleryView.js | 10 +- src/containers/GalleryViewThumbnail.js | 24 +- src/containers/IIIFAuthentication.js | 26 +- src/containers/IIIFThumbnail.js | 9 +- src/containers/LabelValueMetadata.js | 5 +- src/containers/LanguageSettings.js | 2 +- src/containers/LayersPanel.js | 9 +- src/containers/ManifestForm.js | 5 +- src/containers/ManifestInfo.js | 13 +- src/containers/ManifestListItem.js | 25 +- src/containers/ManifestListItemError.js | 5 +- src/containers/ManifestRelatedLinks.js | 5 +- src/containers/MinimalWindow.js | 5 +- src/containers/MiradorMenuButton.js | 4 +- src/containers/MosaicRenderPreview.js | 13 +- src/containers/OpenSeadragonViewer.js | 21 +- src/containers/PrimaryWindow.js | 12 +- src/containers/SearchHit.js | 56 +-- src/containers/SearchPanel.js | 10 +- src/containers/SearchPanelNavigation.js | 7 +- src/containers/SearchResults.js | 11 +- src/containers/SelectCollection.js | 6 +- src/containers/SidebarIndexItem.js | 5 +- src/containers/SidebarIndexList.js | 6 +- src/containers/SidebarIndexTableOfContents.js | 4 +- src/containers/SidebarIndexThumbnail.js | 5 +- src/containers/TextViewer.js | 10 +- src/containers/ThumbnailNavigation.js | 13 +- src/containers/VideoViewer.js | 23 +- src/containers/ViewerInfo.js | 9 +- src/containers/Window.js | 15 +- src/containers/WindowAuthenticationBar.js | 4 +- .../WindowCanvasNavigationControls.js | 5 +- src/containers/WindowList.js | 17 +- src/containers/WindowListButton.js | 5 +- src/containers/WindowSideBar.js | 17 +- .../WindowSideBarAnnotationsPanel.js | 10 +- src/containers/WindowSideBarButtons.js | 42 ++- src/containers/WindowSideBarCanvasPanel.js | 15 +- .../WindowSideBarCollectionPanel.js | 16 +- src/containers/WindowSideBarInfoPanel.js | 7 +- src/containers/WindowThumbnailSettings.js | 10 +- src/containers/WindowTopBar.js | 5 +- src/containers/WindowTopBarPluginArea.js | 5 +- src/containers/WindowTopBarPluginMenu.js | 4 +- src/containers/WindowTopBarTitle.js | 5 +- src/containers/WindowTopMenu.js | 9 +- src/containers/WindowTopMenuButton.js | 4 +- src/containers/WindowViewSettings.js | 10 +- src/containers/Workspace.js | 23 +- src/containers/WorkspaceAdd.js | 7 +- src/containers/WorkspaceAddButton.js | 5 +- src/containers/WorkspaceArea.js | 22 +- .../WorkspaceControlPanelButtons.js | 4 +- src/containers/WorkspaceElastic.js | 27 +- src/containers/WorkspaceElasticWindow.js | 22 +- src/containers/WorkspaceExport.js | 11 +- src/containers/WorkspaceImport.js | 5 +- src/containers/WorkspaceMenu.js | 12 +- src/containers/WorkspaceMosaic.js | 12 +- src/containers/WorkspaceOptionsButton.js | 4 +- src/containers/WorkspaceSelectionDialog.js | 2 +- src/containers/ZoomControls.js | 13 +- src/contexts/FailedImageProvider.jsx | 14 +- src/extend/PluginProvider.jsx | 6 +- src/extend/pluginMapping.js | 19 +- src/extend/pluginPreprocessing.js | 18 +- src/extend/pluginValidation.js | 40 +- src/extend/usePlugins.js | 2 +- src/extend/withPlugins.jsx | 4 +- src/hooks/index.js | 4 +- src/hooks/useThumbnailService.js | 5 +- src/lib/AnnotationItem.js | 17 +- src/lib/AnnotationList.js | 13 +- src/lib/AnnotationPage.js | 13 +- src/lib/AnnotationResource.js | 19 +- src/lib/CanvasAnnotationDisplay.js | 10 +- src/lib/CanvasGroupings.js | 2 +- src/lib/CanvasWorld.js | 117 +++--- src/lib/MiradorCanvas.js | 149 ++++---- src/lib/MiradorManifest.js | 3 +- src/lib/MiradorViewer.jsx | 7 +- src/lib/MosaicLayout.js | 15 +- src/lib/OpenSeadragonCanvasOverlay.js | 14 +- src/lib/ThumbnailFactory.js | 70 ++-- src/lib/TruncatedHit.js | 13 +- src/lib/iiif.js | 9 +- src/state/actions/annotation.js | 7 +- src/state/actions/canvas.js | 18 +- src/state/actions/catalog.js | 5 +- src/state/actions/companionWindow.js | 23 +- src/state/actions/infoResponse.js | 2 +- src/state/actions/layers.js | 5 +- src/state/actions/window.js | 53 ++- src/state/actions/workspace.js | 2 +- src/state/createPluggableStore.js | 6 +- src/state/createStore.js | 4 +- src/state/reducers/annotations.js | 3 +- src/state/reducers/auth.js | 3 +- src/state/reducers/catalog.js | 23 +- src/state/reducers/companionWindows.js | 14 +- src/state/reducers/config.js | 16 +- src/state/reducers/elasticLayout.js | 5 +- src/state/reducers/errors.js | 9 +- src/state/reducers/infoResponses.js | 6 +- src/state/reducers/manifests.js | 6 +- src/state/reducers/search.js | 25 +- src/state/reducers/utils.js | 54 +-- src/state/reducers/windows.js | 19 +- src/state/reducers/workspace.js | 48 ++- src/state/sagas/annotations.js | 20 +- src/state/sagas/app.js | 11 +- src/state/sagas/auth.js | 71 ++-- src/state/sagas/iiif.js | 138 +++---- src/state/sagas/index.js | 15 +- src/state/sagas/windows.js | 119 +++--- src/state/selectors/annotations.js | 95 ++--- src/state/selectors/auth.js | 64 ++-- src/state/selectors/canvases.js | 149 +++----- src/state/selectors/companionWindows.js | 77 ++-- src/state/selectors/config.js | 55 ++- src/state/selectors/getters.js | 17 +- src/state/selectors/layers.js | 43 +-- src/state/selectors/manifests.js | 221 +++++------ src/state/selectors/ranges.js | 64 ++-- src/state/selectors/searches.js | 208 ++++------- src/state/selectors/sequences.js | 72 ++-- src/state/selectors/thumbnails.js | 18 +- src/state/selectors/viewer.js | 11 +- src/state/selectors/windows.js | 56 +-- src/state/selectors/workspace.js | 11 +- src/state/selectors/wrappers.js | 4 +- src/styles/react-mosaic-component.js | 124 ++++--- vite-umd.config.js | 9 +- vite.config.js | 108 +++--- 470 files changed, 8208 insertions(+), 6663 deletions(-) diff --git a/.prettierignore b/.prettierignore index b0794c7a7..a20906018 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,6 +1,11 @@ # Build artifacts dist/ +# Demo artifacts +demo/ + +*.md + .github/ # Test fixtures diff --git a/__tests__/integration/components/AddComponentA.jsx b/__tests__/integration/components/AddComponentA.jsx index d5a83ee63..56b18072b 100644 --- a/__tests__/integration/components/AddComponentA.jsx +++ b/__tests__/integration/components/AddComponentA.jsx @@ -1,7 +1,5 @@ import React from 'react'; -const AddComponentA = () => ( -
Plugin A
-); +const AddComponentA = () =>
Plugin A
; export default AddComponentA; diff --git a/__tests__/integration/components/AddComponentB.jsx b/__tests__/integration/components/AddComponentB.jsx index dd3bc8682..253c3529e 100644 --- a/__tests__/integration/components/AddComponentB.jsx +++ b/__tests__/integration/components/AddComponentB.jsx @@ -1,7 +1,5 @@ import React from 'react'; -const AddComponentB = () => ( -
Plugin B
-); +const AddComponentB = () =>
Plugin B
; export default AddComponentB; diff --git a/__tests__/integration/components/AddComponentC.jsx b/__tests__/integration/components/AddComponentC.jsx index a2565214e..efa8fc010 100644 --- a/__tests__/integration/components/AddComponentC.jsx +++ b/__tests__/integration/components/AddComponentC.jsx @@ -1,9 +1,5 @@ import React from 'react'; -const AddComponentC = (props) => ( -
- Plugin C -
-); +const AddComponentC = (props) =>
Plugin C
; export default AddComponentC; diff --git a/__tests__/integration/components/CompanionWindowButtonComponent.jsx b/__tests__/integration/components/CompanionWindowButtonComponent.jsx index 0b0abd7bb..231ed3eaa 100644 --- a/__tests__/integration/components/CompanionWindowButtonComponent.jsx +++ b/__tests__/integration/components/CompanionWindowButtonComponent.jsx @@ -1,7 +1,9 @@ import React from 'react'; const CompanionWindowButtonComponent = () => ( - Companion Window Button Component + + Companion Window Button Component + ); CompanionWindowButtonComponent.value = 'specialMiradorKey'; diff --git a/__tests__/integration/components/CompanionWindowComponent.jsx b/__tests__/integration/components/CompanionWindowComponent.jsx index 8fc8d5b84..bf38b576d 100644 --- a/__tests__/integration/components/CompanionWindowComponent.jsx +++ b/__tests__/integration/components/CompanionWindowComponent.jsx @@ -1,9 +1,7 @@ import React from 'react'; const CompanionWindowComponent = (props) => ( -
- Companion Window Component -
+
Companion Window Component
); export default CompanionWindowComponent; diff --git a/__tests__/integration/components/StateDependentComponent.jsx b/__tests__/integration/components/StateDependentComponent.jsx index eb5b66162..1ff8c4a62 100644 --- a/__tests__/integration/components/StateDependentComponent.jsx +++ b/__tests__/integration/components/StateDependentComponent.jsx @@ -1,7 +1,7 @@ /* eslint-disable react/prop-types */ const StateDependentComponent = ({ incSomeNumber, manifestId }) => ( ); diff --git a/__tests__/integration/components/WrapIconComponent.jsx b/__tests__/integration/components/WrapIconComponent.jsx index 077b87f5a..f16d86546 100644 --- a/__tests__/integration/components/WrapIconComponent.jsx +++ b/__tests__/integration/components/WrapIconComponent.jsx @@ -1,6 +1,13 @@ /* eslint-disable react/prop-types */ const CustomIcon = () => ( - + Umbrella Icon diff --git a/__tests__/integration/mirador-configs/collections.js b/__tests__/integration/mirador-configs/collections.js index b4f9aec8c..a29f80da7 100644 --- a/__tests__/integration/mirador-configs/collections.js +++ b/__tests__/integration/mirador-configs/collections.js @@ -1,7 +1,5 @@ export default { - catalog: [ - { manifestId: 'https://www.e-codices.unifr.ch/metadata/iiif/collection.json' }, - ], + catalog: [{ manifestId: 'https://www.e-codices.unifr.ch/metadata/iiif/collection.json' }], id: 'mirador', windows: [ { @@ -9,7 +7,8 @@ export default { 'https://www.e-codices.unifr.ch/metadata/iiif/collection.json', 'https://www.e-codices.unifr.ch/metadata/iiif/collection/stabs.json', ], - manifestId: 'https://www.e-codices.unifr.ch/metadata/iiif/stabs-StAlban-DD1-1580/manifest.json', + manifestId: + 'https://www.e-codices.unifr.ch/metadata/iiif/stabs-StAlban-DD1-1580/manifest.json', }, { manifestId: 'https://www.e-codices.unifr.ch/metadata/iiif/collection.json', diff --git a/__tests__/integration/mirador-configs/constants.js b/__tests__/integration/mirador-configs/constants.js index 1c299abf6..d1d83e332 100644 --- a/__tests__/integration/mirador-configs/constants.js +++ b/__tests__/integration/mirador-configs/constants.js @@ -1,2 +1,4 @@ -export const PRIMARY_MANIFEST_FIXTURE_URL = 'https://dms-data.stanford.edu/data/manifests/Parker/nb647fd0133/manifest.json'; -export const PRIMARY_CANVAS_FIXTURE_URL = 'https://dms-data.stanford.edu/data/manifests/Parker/nb647fd0133/canvas/canvas-1'; +export const PRIMARY_MANIFEST_FIXTURE_URL = + 'https://dms-data.stanford.edu/data/manifests/Parker/nb647fd0133/manifest.json'; +export const PRIMARY_CANVAS_FIXTURE_URL = + 'https://dms-data.stanford.edu/data/manifests/Parker/nb647fd0133/canvas/canvas-1'; diff --git a/__tests__/integration/mirador-configs/content-search.js b/__tests__/integration/mirador-configs/content-search.js index 7428db0a6..fdddbc513 100644 --- a/__tests__/integration/mirador-configs/content-search.js +++ b/__tests__/integration/mirador-configs/content-search.js @@ -1,14 +1,19 @@ export default { catalog: [ { manifestId: 'https://damsssl.llgc.org.uk/iiif/2.0/4566425/manifest.json', provider: 'LLGC' }, - { manifestId: 'https://wellcomelibrary.org/iiif/b18035723/manifest', provider: 'Wellcome Library' }, + { + manifestId: 'https://wellcomelibrary.org/iiif/b18035723/manifest', + provider: 'Wellcome Library', + }, { manifestId: 'https://scta.info/iiif/graciliscommentary/lon/manifest', provider: 'SCTA' }, { manifestId: 'https://purl.stanford.edu/zx429wp8334/iiif/manifest', provider: 'SUL' }, ], id: 'mirador', - windows: [{ - loadedManifest: 'https://purl.stanford.edu/fg165hz3589/iiif/manifest', - // defaultSearchQuery: 'NSF', - suggestedSearches: ['NSF'], - }], + windows: [ + { + loadedManifest: 'https://purl.stanford.edu/fg165hz3589/iiif/manifest', + // defaultSearchQuery: 'NSF', + suggestedSearches: ['NSF'], + }, + ], }; diff --git a/__tests__/integration/mirador-configs/fallback-image.js b/__tests__/integration/mirador-configs/fallback-image.js index 3e4cec017..5c57ca99b 100644 --- a/__tests__/integration/mirador-configs/fallback-image.js +++ b/__tests__/integration/mirador-configs/fallback-image.js @@ -10,5 +10,6 @@ export default { { manifestId: '/__tests__/fixtures/version-3/fallback-image.json', thumbnailNavigation: 'far-bottom', - }], + }, + ], }; diff --git a/__tests__/integration/mirador-configs/i18n.js b/__tests__/integration/mirador-configs/i18n.js index 90060e680..e8ae23d7d 100644 --- a/__tests__/integration/mirador-configs/i18n.js +++ b/__tests__/integration/mirador-configs/i18n.js @@ -3,24 +3,60 @@ import { PRIMARY_MANIFEST_FIXTURE_URL } from './constants'; export default { catalog: [ { manifestId: PRIMARY_MANIFEST_FIXTURE_URL }, - { manifestId: 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/e32a277e-91e2-4a6d-8ba6-cc4bad230410.json' }, - { manifestId: 'https://media.nga.gov/public/manifests/nga_highlights.json', provider: 'National Gallery of Art' }, - { manifestId: 'https://wellcomelibrary.org/iiif/b18035723/manifest', provider: 'Wellcome Library' }, - { manifestId: 'https://demos.biblissima.fr/iiif/metadata/florus-dispersus/manifest.json', provider: 'Biblissima' }, - { manifestId: 'https://www.e-codices.unifr.ch/metadata/iiif/gau-Fragment/manifest.json', provider: 'e-codices - Virtual Manuscript Library of Switzerland' }, - { manifestId: 'https://wellcomelibrary.org/iiif/collection/b18031511', provider: 'Wellcome Library' }, - { manifestId: 'https://gallica.bnf.fr/iiif/ark:/12148/btv1b10022508f/manifest.json', provider: 'Bibliothèque nationale de France' }, - { manifestId: 'https://manifests.britishart.yale.edu/Osbornfa1', provider: 'Beinecke Rare Book and Manuscript Library, Yale University' }, - { manifestId: 'https://iiif.biblissima.fr/chateauroux/B360446201_MS0005/manifest.json', provider: 'Biblissima' }, - { manifestId: 'https://iiif.durham.ac.uk/manifests/trifle/32150/t1/m4/q7/t1m4q77fr328/manifest', provider: 'Durham University Library' }, + { + manifestId: + 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/e32a277e-91e2-4a6d-8ba6-cc4bad230410.json', + }, + { + manifestId: 'https://media.nga.gov/public/manifests/nga_highlights.json', + provider: 'National Gallery of Art', + }, + { + manifestId: 'https://wellcomelibrary.org/iiif/b18035723/manifest', + provider: 'Wellcome Library', + }, + { + manifestId: 'https://demos.biblissima.fr/iiif/metadata/florus-dispersus/manifest.json', + provider: 'Biblissima', + }, + { + manifestId: 'https://www.e-codices.unifr.ch/metadata/iiif/gau-Fragment/manifest.json', + provider: 'e-codices - Virtual Manuscript Library of Switzerland', + }, + { + manifestId: 'https://wellcomelibrary.org/iiif/collection/b18031511', + provider: 'Wellcome Library', + }, + { + manifestId: 'https://gallica.bnf.fr/iiif/ark:/12148/btv1b10022508f/manifest.json', + provider: 'Bibliothèque nationale de France', + }, + { + manifestId: 'https://manifests.britishart.yale.edu/Osbornfa1', + provider: 'Beinecke Rare Book and Manuscript Library, Yale University', + }, + { + manifestId: 'https://iiif.biblissima.fr/chateauroux/B360446201_MS0005/manifest.json', + provider: 'Biblissima', + }, + { + manifestId: 'https://iiif.durham.ac.uk/manifests/trifle/32150/t1/m4/q7/t1m4q77fr328/manifest', + provider: 'Durham University Library', + }, // { manifestId: "https://iiif.vam.ac.uk/collections/O1023003/manifest.json", provider: "Ocean liners"}, - { manifestId: 'https://zavicajna.digitalna.rs/iiif/iiif/api/presentation/2/4aa44ad1-0b74-4590-ab09-534a38cb7c53%252F00000001%252Fostalo01%252F00000012/manifest', provider: "Библиотека 'Милутин Бојић'" }, + { + manifestId: + 'https://zavicajna.digitalna.rs/iiif/iiif/api/presentation/2/4aa44ad1-0b74-4590-ab09-534a38cb7c53%252F00000001%252Fostalo01%252F00000012/manifest', + provider: "Библиотека 'Милутин Бојић'", + }, ], id: 'mirador', language: 'fr', - windows: [{ - manifestId: 'https://iiif.io/api/cookbook/recipe/0006-text-language/manifest.json', - showLocalePicker: true, - thumbnailNavigationPosition: 'far-bottom', - }], + windows: [ + { + manifestId: 'https://iiif.io/api/cookbook/recipe/0006-text-language/manifest.json', + showLocalePicker: true, + thumbnailNavigationPosition: 'far-bottom', + }, + ], }; diff --git a/__tests__/integration/mirador-configs/iiif-v3.js b/__tests__/integration/mirador-configs/iiif-v3.js index bc011a715..61e23ca6f 100644 --- a/__tests__/integration/mirador-configs/iiif-v3.js +++ b/__tests__/integration/mirador-configs/iiif-v3.js @@ -13,7 +13,10 @@ export default { window: { hideSearchPanel: false, }, - windows: [{ - manifestId: 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/e32a277e-91e2-4a6d-8ba6-cc4bad230410.json', - }], + windows: [ + { + manifestId: + 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/e32a277e-91e2-4a6d-8ba6-cc4bad230410.json', + }, + ], }; diff --git a/__tests__/integration/mirador-configs/index.js b/__tests__/integration/mirador-configs/index.js index 28ea07832..5d2babb7f 100644 --- a/__tests__/integration/mirador-configs/index.js +++ b/__tests__/integration/mirador-configs/index.js @@ -4,29 +4,67 @@ import { PRIMARY_CANVAS_FIXTURE_URL, PRIMARY_MANIFEST_FIXTURE_URL } from './cons export default { catalog: [ { manifestId: PRIMARY_MANIFEST_FIXTURE_URL }, - { manifestId: 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/e32a277e-91e2-4a6d-8ba6-cc4bad230410.json' }, - { manifestId: 'https://media.nga.gov/public/manifests/nga_highlights.json', provider: 'National Gallery of Art' }, - { manifestId: 'https://wellcomelibrary.org/iiif/b18035723/manifest', provider: 'Wellcome Library' }, - { manifestId: 'https://demos.biblissima.fr/iiif/metadata/florus-dispersus/manifest.json', provider: 'Biblissima' }, - { manifestId: 'https://www.e-codices.unifr.ch/metadata/iiif/gau-Fragment/manifest.json', provider: 'e-codices - Virtual Manuscript Library of Switzerland' }, - { manifestId: 'https://wellcomelibrary.org/iiif/collection/b18031511', provider: 'Wellcome Library' }, - { manifestId: 'https://gallica.bnf.fr/iiif/ark:/12148/btv1b10022508f/manifest.json', provider: 'Bibliothèque nationale de France' }, - { manifestId: 'https://manifests.britishart.yale.edu/Osbornfa1', provider: 'Beinecke Rare Book and Manuscript Library, Yale University' }, - { manifestId: 'https://iiif.biblissima.fr/chateauroux/B360446201_MS0005/manifest.json', provider: 'Biblissima' }, - { manifestId: 'https://iiif.durham.ac.uk/manifests/trifle/32150/t1/m4/q7/t1m4q77fr328/manifest', provider: 'Durham University Library' }, - { manifestId: 'https://zavicajna.digitalna.rs/iiif/api/presentation/3/96571949-03d6-478e-ab44-a2d5ad68f935%252F00000001%252Fostalo01%252F00000071/manifest', provider: "Библиотека 'Милутин Бојић'" }, + { + manifestId: + 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/e32a277e-91e2-4a6d-8ba6-cc4bad230410.json', + }, + { + manifestId: 'https://media.nga.gov/public/manifests/nga_highlights.json', + provider: 'National Gallery of Art', + }, + { + manifestId: 'https://wellcomelibrary.org/iiif/b18035723/manifest', + provider: 'Wellcome Library', + }, + { + manifestId: 'https://demos.biblissima.fr/iiif/metadata/florus-dispersus/manifest.json', + provider: 'Biblissima', + }, + { + manifestId: 'https://www.e-codices.unifr.ch/metadata/iiif/gau-Fragment/manifest.json', + provider: 'e-codices - Virtual Manuscript Library of Switzerland', + }, + { + manifestId: 'https://wellcomelibrary.org/iiif/collection/b18031511', + provider: 'Wellcome Library', + }, + { + manifestId: 'https://gallica.bnf.fr/iiif/ark:/12148/btv1b10022508f/manifest.json', + provider: 'Bibliothèque nationale de France', + }, + { + manifestId: 'https://manifests.britishart.yale.edu/Osbornfa1', + provider: 'Beinecke Rare Book and Manuscript Library, Yale University', + }, + { + manifestId: 'https://iiif.biblissima.fr/chateauroux/B360446201_MS0005/manifest.json', + provider: 'Biblissima', + }, + { + manifestId: 'https://iiif.durham.ac.uk/manifests/trifle/32150/t1/m4/q7/t1m4q77fr328/manifest', + provider: 'Durham University Library', + }, + { + manifestId: + 'https://zavicajna.digitalna.rs/iiif/api/presentation/3/96571949-03d6-478e-ab44-a2d5ad68f935%252F00000001%252Fostalo01%252F00000071/manifest', + provider: "Библиотека 'Милутин Бојић'", + }, ], id: 'mirador', theme: { transitions: {}, }, - windows: [{ - canvasId: PRIMARY_CANVAS_FIXTURE_URL, - manifestId: PRIMARY_MANIFEST_FIXTURE_URL, - }, - { - canvasId: 'https://iiif.bodleian.ox.ac.uk/iiif/canvas/e58b8c60-005c-4c41-a22f-07d49cb25ede.json', - manifestId: 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/e32a277e-91e2-4a6d-8ba6-cc4bad230410.json', - thumbnailNavigationPosition: 'far-bottom', - }], + windows: [ + { + canvasId: PRIMARY_CANVAS_FIXTURE_URL, + manifestId: PRIMARY_MANIFEST_FIXTURE_URL, + }, + { + canvasId: + 'https://iiif.bodleian.ox.ac.uk/iiif/canvas/e58b8c60-005c-4c41-a22f-07d49cb25ede.json', + manifestId: + 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/e32a277e-91e2-4a6d-8ba6-cc4bad230410.json', + thumbnailNavigationPosition: 'far-bottom', + }, + ], }; diff --git a/__tests__/integration/mirador-configs/initial-viewer-config.js b/__tests__/integration/mirador-configs/initial-viewer-config.js index 8c826cb83..754addd65 100644 --- a/__tests__/integration/mirador-configs/initial-viewer-config.js +++ b/__tests__/integration/mirador-configs/initial-viewer-config.js @@ -2,15 +2,17 @@ import { PRIMARY_MANIFEST_FIXTURE_URL, PRIMARY_CANVAS_FIXTURE_URL } from './cons export default { id: 'mirador', - windows: [{ - canvasId: PRIMARY_CANVAS_FIXTURE_URL, - initialViewerConfig: { - thumbnailNavigationPosition: 'far-bottom', - x: 934, - y: 782, - // you need to specify zoom for this to look good - zoom: 0.0007, + windows: [ + { + canvasId: PRIMARY_CANVAS_FIXTURE_URL, + initialViewerConfig: { + thumbnailNavigationPosition: 'far-bottom', + x: 934, + y: 782, + // you need to specify zoom for this to look good + zoom: 0.0007, + }, + manifestId: PRIMARY_MANIFEST_FIXTURE_URL, }, - manifestId: PRIMARY_MANIFEST_FIXTURE_URL, - }], + ], }; diff --git a/__tests__/integration/mirador-configs/layers.js b/__tests__/integration/mirador-configs/layers.js index 05d619851..cf0f13594 100644 --- a/__tests__/integration/mirador-configs/layers.js +++ b/__tests__/integration/mirador-configs/layers.js @@ -5,11 +5,20 @@ export default { { manifestId: 'https://prtd.app/aom/manifest.json' }, { manifestId: 'https://prtd.app/fv/manifest.json' }, { manifestId: 'https://dvp.prtd.app/hamilton/manifest.json' }, - { manifestId: 'https://iiif.io/api/cookbook/recipe/0036-composition-from-multiple-images/manifest.json' }, + { + manifestId: + 'https://iiif.io/api/cookbook/recipe/0036-composition-from-multiple-images/manifest.json', + }, { manifestId: 'https://iiif.io/api/cookbook/recipe/0033-choice/manifest.json' }, - { manifestId: 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/1fc3f35d-bbb5-4524-8fbe-a5bcb5468be2.json' }, + { + manifestId: + 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/1fc3f35d-bbb5-4524-8fbe-a5bcb5468be2.json', + }, { manifestId: 'https://data.getty.edu/media/manifest/bayard-custom' }, - { manifestId: 'https://heritage.tudelft.nl/iiif/manifests/ejection-seat-front-side/manifest.json' }, + { + manifestId: + 'https://heritage.tudelft.nl/iiif/manifests/ejection-seat-front-side/manifest.json', + }, { manifestId: 'https://iiif.ub.uni-leipzig.de/exp/manifests/layers2/manifest.json' }, ], id: 'mirador', @@ -19,16 +28,20 @@ export default { ...options, headers: { ...options.headers, - Accept: (url.includes('bodleian.ox.ac.uk') && (url.endsWith('/info.json') - ? 'application/ld+json;profile=http://iiif.io/api/image/3/context.json' - : 'application/ld+json;profile=http://iiif.io/api/presentation/3/context.json')) || '', + Accept: + (url.includes('bodleian.ox.ac.uk') && + (url.endsWith('/info.json') + ? 'application/ld+json;profile=http://iiif.io/api/image/3/context.json' + : 'application/ld+json;profile=http://iiif.io/api/presentation/3/context.json')) || + '', }, }), ], }, window: { defaultSideBarPanel: 'layers', - panels: { // Configure which panels are visible in WindowSideBarButtons + panels: { + // Configure which panels are visible in WindowSideBarButtons layers: true, search: true, }, @@ -36,6 +49,9 @@ export default { }, windows: [ { manifestId: 'https://dvp.prtd.app/hamilton/manifest.json' }, - { manifestId: 'https://iiif.io/api/cookbook/recipe/0036-composition-from-multiple-images/manifest.json' }, + { + manifestId: + 'https://iiif.io/api/cookbook/recipe/0036-composition-from-multiple-images/manifest.json', + }, ], }; diff --git a/__tests__/integration/mirador-configs/minimalist.js b/__tests__/integration/mirador-configs/minimalist.js index 33c379e33..3159fd8cf 100644 --- a/__tests__/integration/mirador-configs/minimalist.js +++ b/__tests__/integration/mirador-configs/minimalist.js @@ -10,12 +10,14 @@ export default { sideBarOpen: true, sideBarPanel: '', }, - windows: [{ - allowClose: false, - canvasId: PRIMARY_CANVAS_FIXTURE_URL, - manifestId: PRIMARY_MANIFEST_FIXTURE_URL, - thumbnailNavigationPosition: 'far-bottom', - }], + windows: [ + { + allowClose: false, + canvasId: PRIMARY_CANVAS_FIXTURE_URL, + manifestId: PRIMARY_MANIFEST_FIXTURE_URL, + thumbnailNavigationPosition: 'far-bottom', + }, + ], workspace: { type: 'not-mosaic-or-elastic', }, diff --git a/__tests__/integration/mirador-configs/multiple-sequences.js b/__tests__/integration/mirador-configs/multiple-sequences.js index d7b46a787..c5220fbeb 100644 --- a/__tests__/integration/mirador-configs/multiple-sequences.js +++ b/__tests__/integration/mirador-configs/multiple-sequences.js @@ -7,5 +7,6 @@ export default { { manifestId: '/__tests__/fixtures/version-2/multipleSequences.json', thumbnailNavigation: 'far-bottom', - }], + }, + ], }; diff --git a/__tests__/integration/mirador-configs/plugin-add.js b/__tests__/integration/mirador-configs/plugin-add.js index 692d08412..db0cf5c5e 100644 --- a/__tests__/integration/mirador-configs/plugin-add.js +++ b/__tests__/integration/mirador-configs/plugin-add.js @@ -1,6 +1,4 @@ -import { - addPluginA, addPluginB, addPluginC, addPluginD, wrapIconPlugin, -} from '../plugins/index'; +import { addPluginA, addPluginB, addPluginC, addPluginD, wrapIconPlugin } from '../plugins/index'; export default { config: { diff --git a/__tests__/integration/mirador-configs/plugin-companion-window.js b/__tests__/integration/mirador-configs/plugin-companion-window.js index cc0169ace..9271a32d1 100644 --- a/__tests__/integration/mirador-configs/plugin-companion-window.js +++ b/__tests__/integration/mirador-configs/plugin-companion-window.js @@ -1,6 +1,9 @@ import { companionWindowButtonPlugin, companionWindowPlugin } from '../plugins/index'; export default { - config: { id: 'mirador', windows: [{ manifestId: 'https://purl.stanford.edu/hg676jb4964/iiif/manifest' }] }, + config: { + id: 'mirador', + windows: [{ manifestId: 'https://purl.stanford.edu/hg676jb4964/iiif/manifest' }], + }, plugins: [companionWindowButtonPlugin, companionWindowPlugin], }; diff --git a/__tests__/integration/mirador-configs/plugin-priority.js b/__tests__/integration/mirador-configs/plugin-priority.js index 8b62a8687..941d23748 100644 --- a/__tests__/integration/mirador-configs/plugin-priority.js +++ b/__tests__/integration/mirador-configs/plugin-priority.js @@ -1,13 +1,6 @@ -import { - wrapPluginA, wrapPluginB, addPluginA, addPluginB, -} from '../plugins/index'; +import { wrapPluginA, wrapPluginB, addPluginA, addPluginB } from '../plugins/index'; export default { config: { id: 'mirador' }, - plugins: [ - addPluginA, - wrapPluginA, - addPluginB, - wrapPluginB, - ], + plugins: [addPluginA, wrapPluginA, addPluginB, wrapPluginB], }; diff --git a/__tests__/integration/mirador-configs/plugin-state.js b/__tests__/integration/mirador-configs/plugin-state.js index e37ffa2df..82c9e4cfc 100644 --- a/__tests__/integration/mirador-configs/plugin-state.js +++ b/__tests__/integration/mirador-configs/plugin-state.js @@ -4,11 +4,13 @@ import { PRIMARY_MANIFEST_FIXTURE_URL } from './constants'; export default { config: { id: 'mirador', - windows: [{ - canvasIndex: 2, - loadedManifest: PRIMARY_MANIFEST_FIXTURE_URL, - thumbnailNavigationPosition: 'far-bottom', - }], + windows: [ + { + canvasIndex: 2, + loadedManifest: PRIMARY_MANIFEST_FIXTURE_URL, + thumbnailNavigationPosition: 'far-bottom', + }, + ], }, plugins: [stateDependentPlugin], }; diff --git a/__tests__/integration/mirador-configs/rtl.js b/__tests__/integration/mirador-configs/rtl.js index 9dbb1df5f..0f7f9bc72 100644 --- a/__tests__/integration/mirador-configs/rtl.js +++ b/__tests__/integration/mirador-configs/rtl.js @@ -10,7 +10,8 @@ export const rtl1 = { }, windows: [ { - manifestId: 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/e800b13a-6699-49ae-9bc2-c9b8c35b7a25.json', + manifestId: + 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/e800b13a-6699-49ae-9bc2-c9b8c35b7a25.json', }, ], }; diff --git a/__tests__/integration/mirador-configs/single-bodleian.js b/__tests__/integration/mirador-configs/single-bodleian.js index bd832f565..8b7f7f53a 100644 --- a/__tests__/integration/mirador-configs/single-bodleian.js +++ b/__tests__/integration/mirador-configs/single-bodleian.js @@ -8,8 +8,11 @@ export default { }, windows: [ { - canvasId: 'https://iiif.bodleian.ox.ac.uk/iiif/canvas/e58b8c60-005c-4c41-a22f-07d49cb25ede.json', - manifestId: 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/e32a277e-91e2-4a6d-8ba6-cc4bad230410.json', + canvasId: + 'https://iiif.bodleian.ox.ac.uk/iiif/canvas/e58b8c60-005c-4c41-a22f-07d49cb25ede.json', + manifestId: + 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/e32a277e-91e2-4a6d-8ba6-cc4bad230410.json', thumbnailNavigation: 'far-bottom', - }], + }, + ], }; diff --git a/__tests__/integration/mirador-configs/single-van-gogh.js b/__tests__/integration/mirador-configs/single-van-gogh.js index 1a67e5b70..605aefec6 100644 --- a/__tests__/integration/mirador-configs/single-van-gogh.js +++ b/__tests__/integration/mirador-configs/single-van-gogh.js @@ -8,8 +8,10 @@ export default { thumbnailNavigation: { defaultPosition: 'far-bottom', }, - windows: [{ - canvasId: PRIMARY_CANVAS_FIXTURE_URL, - manifestId: PRIMARY_MANIFEST_FIXTURE_URL, - }], + windows: [ + { + canvasId: PRIMARY_CANVAS_FIXTURE_URL, + manifestId: PRIMARY_MANIFEST_FIXTURE_URL, + }, + ], }; diff --git a/__tests__/integration/mirador-configs/svg-annotations.js b/__tests__/integration/mirador-configs/svg-annotations.js index 69498ca67..9c2bfbd21 100644 --- a/__tests__/integration/mirador-configs/svg-annotations.js +++ b/__tests__/integration/mirador-configs/svg-annotations.js @@ -13,7 +13,8 @@ export default { }, { canvasIndex: 6, - manifestId: 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/748a9d50-5a3a-440e-ab9d-567dd68b6abb.json', + manifestId: + 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/748a9d50-5a3a-440e-ab9d-567dd68b6abb.json', }, ], }; diff --git a/__tests__/integration/mirador-configs/table-of-contents.js b/__tests__/integration/mirador-configs/table-of-contents.js index 46e24d254..38015b107 100644 --- a/__tests__/integration/mirador-configs/table-of-contents.js +++ b/__tests__/integration/mirador-configs/table-of-contents.js @@ -1,10 +1,23 @@ export default { catalog: [ - { manifestId: 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/390fd0e8-9eae-475d-9564-ed916ab9035c.json', provider: 'Bodleian Libraries' }, - { manifestId: 'http://dams.llgc.org.uk/iiif/newspaper/issue/3100021/manifest.json', provider: 'The National Library of Wales' }, - { manifestId: 'https://iiif.lib.harvard.edu/manifests/drs:5981093', provider: 'Houghton Library (Harvard University)' }, + { + manifestId: + 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/390fd0e8-9eae-475d-9564-ed916ab9035c.json', + provider: 'Bodleian Libraries', + }, + { + manifestId: 'http://dams.llgc.org.uk/iiif/newspaper/issue/3100021/manifest.json', + provider: 'The National Library of Wales', + }, + { + manifestId: 'https://iiif.lib.harvard.edu/manifests/drs:5981093', + provider: 'Houghton Library (Harvard University)', + }, { manifestId: 'https://cudl.lib.cam.ac.uk/iiif/MS-ADD-03965' }, - { manifestId: 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/ca3dc326-4a7b-479f-a754-5aed9d2f2cb4.json' }, + { + manifestId: + 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/ca3dc326-4a7b-479f-a754-5aed9d2f2cb4.json', + }, // 'https://gist.githubusercontent.com/jeffreycwitt/90b33c1c4e119e7a48b7a66ea41a48c1/raw/522b132409d6c67a78f8f26b0ceb7346a52cfe62/test-manifest-with-complicated-toc.json': {}, // 'https://gist.githubusercontent.com/jeffreycwitt/1a75fdb4a97e1c2a98bd35797aad263d/raw/859104cb6cd7bd99f3be668f064066f4b3ba2b29/manifest-with-three-level-deep-toc.json': {}, ], @@ -13,8 +26,12 @@ export default { defaultSideBarPanel: 'canvas', sideBarOpenByDefault: true, }, - windows: [{ - canvasId: 'https://iiif.bodleian.ox.ac.uk/iiif/canvas/a024a538-aef3-44b3-ad11-51c6a8b04ea2.json', - manifestId: 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/390fd0e8-9eae-475d-9564-ed916ab9035c.json', - }], + windows: [ + { + canvasId: + 'https://iiif.bodleian.ox.ac.uk/iiif/canvas/a024a538-aef3-44b3-ad11-51c6a8b04ea2.json', + manifestId: + 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/390fd0e8-9eae-475d-9564-ed916ab9035c.json', + }, + ], }; diff --git a/__tests__/integration/mirador-configs/video.js b/__tests__/integration/mirador-configs/video.js index 4420fca79..085c3e138 100644 --- a/__tests__/integration/mirador-configs/video.js +++ b/__tests__/integration/mirador-configs/video.js @@ -5,13 +5,15 @@ export default { manifestId: 'https://preview.iiif.io/cookbook/master/recipe/0003-mvm-video/manifest.json', }, { - manifestId: 'https://preview.iiif.io/cookbook/0026_0064_0065-opera-recipes/recipe/0064-opera-one-canvas/manifest.json', + manifestId: + 'https://preview.iiif.io/cookbook/0026_0064_0065-opera-recipes/recipe/0064-opera-one-canvas/manifest.json', }, { manifestId: 'https://iiif.io/api/cookbook/recipe/0014-accompanyingcanvas/manifest.json', }, { - manifestId: 'https://preview.iiif.io/cookbook/0219-using-caption-file/recipe/0219-using-caption-file/manifest.json', + manifestId: + 'https://preview.iiif.io/cookbook/0219-using-caption-file/recipe/0219-using-caption-file/manifest.json', }, ], }; diff --git a/__tests__/integration/plugins/invalidPluginA.jsx b/__tests__/integration/plugins/invalidPluginA.jsx index 8b7e4b8ba..d3da93110 100644 --- a/__tests__/integration/plugins/invalidPluginA.jsx +++ b/__tests__/integration/plugins/invalidPluginA.jsx @@ -1,5 +1,5 @@ export default { - component: props => (
), + component: (props) =>
, mode: 'LURK', // invalid name: 'invalidPluginA', target: 'WorkspaceControlPanelButtons', diff --git a/__tests__/integration/plugins/invalidPluginB.jsx b/__tests__/integration/plugins/invalidPluginB.jsx index 6b4e16d19..405779f3b 100644 --- a/__tests__/integration/plugins/invalidPluginB.jsx +++ b/__tests__/integration/plugins/invalidPluginB.jsx @@ -1,6 +1,6 @@ export default { - component: props => (
), + component: (props) =>
, mode: 'add', name: 'invalidPluginB', - target: x => x, // invalid + target: (x) => x, // invalid }; diff --git a/__tests__/integration/plugins/invalidPluginC.jsx b/__tests__/integration/plugins/invalidPluginC.jsx index ef29cd5e2..fee5d6c9d 100644 --- a/__tests__/integration/plugins/invalidPluginC.jsx +++ b/__tests__/integration/plugins/invalidPluginC.jsx @@ -1,5 +1,5 @@ export default { - component: props => (
), + component: (props) =>
, mapStateToProps: {}, // invalid mode: 'add', name: 'invalidPluginC', diff --git a/__tests__/integration/plugins/invalidPluginD.jsx b/__tests__/integration/plugins/invalidPluginD.jsx index 1ecbda83e..c000e85f9 100644 --- a/__tests__/integration/plugins/invalidPluginD.jsx +++ b/__tests__/integration/plugins/invalidPluginD.jsx @@ -1,5 +1,5 @@ export default { - component: props => (
), + component: (props) =>
, mapDispatchToProps: 'foo', // invalid mode: 'add', name: 'invalidPluginD', diff --git a/__tests__/integration/plugins/invalidPluginE.jsx b/__tests__/integration/plugins/invalidPluginE.jsx index 1c88aa446..56e91132e 100644 --- a/__tests__/integration/plugins/invalidPluginE.jsx +++ b/__tests__/integration/plugins/invalidPluginE.jsx @@ -1,5 +1,5 @@ export default { - component: props => (
), + component: (props) =>
, mode: 'add', name: 'invalidPluginE', reducers: 3, // invalid diff --git a/__tests__/integration/plugins/invalidPluginF.jsx b/__tests__/integration/plugins/invalidPluginF.jsx index 1fe3349c8..cbcb018f7 100644 --- a/__tests__/integration/plugins/invalidPluginF.jsx +++ b/__tests__/integration/plugins/invalidPluginF.jsx @@ -1,5 +1,5 @@ export default { - component: props => (
), + component: (props) =>
, mode: 'add', name: 'invalidPluginF', reducers: { diff --git a/__tests__/integration/plugins/stateDependentPlugin.jsx b/__tests__/integration/plugins/stateDependentPlugin.jsx index 45ebaa1ce..4d0eeba45 100644 --- a/__tests__/integration/plugins/stateDependentPlugin.jsx +++ b/__tests__/integration/plugins/stateDependentPlugin.jsx @@ -7,8 +7,10 @@ const initialState = { /** */ const pluginStateReducer = (state = initialState, action) => { - if (action.type === 'mirador/INC_SOME_NUMBER') return { ...state, someNumber: state.someNumber + 1 }; - if (action.type === 'mirador/SET_CANVAS') return { ...state, canvasChangeCount: state.canvasChangeCount + 1 }; + if (action.type === 'mirador/INC_SOME_NUMBER') + return { ...state, someNumber: state.someNumber + 1 }; + if (action.type === 'mirador/SET_CANVAS') + return { ...state, canvasChangeCount: state.canvasChangeCount + 1 }; return state; }; diff --git a/__tests__/integration/plugins/validPluginA.jsx b/__tests__/integration/plugins/validPluginA.jsx index 51fd1a8f5..78cdd3b2c 100644 --- a/__tests__/integration/plugins/validPluginA.jsx +++ b/__tests__/integration/plugins/validPluginA.jsx @@ -1,5 +1,5 @@ export default { - component: props => (
), + component: (props) =>
, mode: 'add', target: 'WorkspaceControlPanelButtons', }; diff --git a/__tests__/integration/plugins/validPluginB.jsx b/__tests__/integration/plugins/validPluginB.jsx index 2e1375f2a..1c727fe4d 100644 --- a/__tests__/integration/plugins/validPluginB.jsx +++ b/__tests__/integration/plugins/validPluginB.jsx @@ -1,5 +1,5 @@ export default { - component: props => (
), + component: (props) =>
, mapDispatchToProps: {}, mapStateToProps: () => ({}), mode: 'add', diff --git a/__tests__/integration/tests/basic.test.js b/__tests__/integration/tests/basic.test.js index 94c693779..4df6bb0e6 100644 --- a/__tests__/integration/tests/basic.test.js +++ b/__tests__/integration/tests/basic.test.js @@ -14,17 +14,27 @@ describe('Basic end to end Mirador', () => { fireEvent.click(screen.getByRole('button', { name: 'Add resource' })); // Input a manifest URL - fireEvent.change(document.getElementById('manifestURL'), { target: { value: 'https://iiif.io/api/cookbook/recipe/0266-full-canvas-annotation/manifest.json' } }); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + fireEvent.change(document.getElementById('manifestURL'), { + target: { + value: 'https://iiif.io/api/cookbook/recipe/0266-full-canvas-annotation/manifest.json', + }, + }); fireEvent.click(screen.getByText('Add')); // Click the added manifest item - const listItem = document.querySelector('[data-manifestid="https://iiif.io/api/cookbook/recipe/0266-full-canvas-annotation/manifest.json"]'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + const listItem = document.querySelector( + '[data-manifestid="https://iiif.io/api/cookbook/recipe/0266-full-canvas-annotation/manifest.json"]', + ); const button = await within(listItem).findByRole('button'); fireEvent.click(button); // The viewer is loaded with the manifest - const element = await screen.findByRole('heading', { name: /Picture of Göttingen taken during the 2019 IIIF Conference/i }); + const element = await screen.findByRole('heading', { + name: /Picture of Göttingen taken during the 2019 IIIF Conference/i, + }); expect(element).toBeInTheDocument(); }); }); diff --git a/__tests__/integration/tests/companion-windows.test.js b/__tests__/integration/tests/companion-windows.test.js index c10fc965d..41ab80024 100644 --- a/__tests__/integration/tests/companion-windows.test.js +++ b/__tests__/integration/tests/companion-windows.test.js @@ -11,19 +11,25 @@ describe('Basic end to end Mirador', () => { fireEvent.click(toggleButtons[0]); // Companion window is on the left - expect(await screen.findByRole('complementary', { name: /About this item/i })).toHaveClass('mirador-companion-window-left'); + expect(await screen.findByRole('complementary', { name: /About this item/i })).toHaveClass( + 'mirador-companion-window-left', + ); const openButton = screen.getByRole('button', { name: /Open in separate panel/i }); fireEvent.click(openButton); // Companion window is on the right - expect(await screen.findByRole('complementary', { name: /About this item/i })).toHaveClass('mirador-companion-window-right'); + expect(await screen.findByRole('complementary', { name: /About this item/i })).toHaveClass( + 'mirador-companion-window-right', + ); // Close the panel const closeButton = screen.getByRole('button', { name: /Close panel/i }); fireEvent.click(closeButton); // The companion window is removed - expect(screen.queryByRole('complementary', { name: /About this item/i })).not.toBeInTheDocument(); + expect( + screen.queryByRole('complementary', { name: /About this item/i }), + ).not.toBeInTheDocument(); }); }); diff --git a/__tests__/integration/tests/import-export.test.js b/__tests__/integration/tests/import-export.test.js index a07f5a945..5ed6f08c7 100644 --- a/__tests__/integration/tests/import-export.test.js +++ b/__tests__/integration/tests/import-export.test.js @@ -14,9 +14,7 @@ describe('Import/Export state', () => { zoom: 0.001, }; context.miradorInstance.store.dispatch({ state, type: 'mirador/IMPORT_MIRADOR_STATE' }); - expect(state.viewers[windows[0]]).toEqual( - { x: 1000, y: 1000, zoom: 0.001 }, - ); + expect(state.viewers[windows[0]]).toEqual({ x: 1000, y: 1000, zoom: 0.001 }); }); // TODO: test the bugfix for the OSD viewer somehow? diff --git a/__tests__/integration/tests/invalid-manifest.test.js b/__tests__/integration/tests/invalid-manifest.test.js index 4734d08cd..4a12e731a 100644 --- a/__tests__/integration/tests/invalid-manifest.test.js +++ b/__tests__/integration/tests/invalid-manifest.test.js @@ -25,7 +25,8 @@ describe('Invalid response while adding manifest', () => { await addManifest(invalidUrl); await waitFor(() => { - const listItem = document.querySelector(`[data-manifestid="${invalidUrl}"]`); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + const listItem = document.querySelector(`[data-manifestid="${invalidUrl}"]`); expect(listItem).toBeInTheDocument(); }); }, 2000); // Wait 2 seconds @@ -36,7 +37,8 @@ describe('Invalid response while adding manifest', () => { await addManifest('http://localhost:4444/__tests__/fixtures/version-2/broken.json'); // Try the added manifest item - const listItem = document.querySelector(`[data-manifestid="${uri}"]`); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + const listItem = document.querySelector(`[data-manifestid="${uri}"]`); expect(listItem).toBeInTheDocument(); const errorMessage = await screen.findByText('The resource cannot be added'); diff --git a/__tests__/integration/tests/minimalist.test.js b/__tests__/integration/tests/minimalist.test.js index 78b79cf43..8db950db6 100644 --- a/__tests__/integration/tests/minimalist.test.js +++ b/__tests__/integration/tests/minimalist.test.js @@ -7,7 +7,11 @@ describe('Minimalist configuration to Mirador', () => { setupIntegrationTestViewer(config); it('Loads a manifest and displays it without some of the default controls', async () => { - expect(await screen.findByRole('region', { name: /Window: Cambridge, Corpus Christi College, MS 640: Antiphoner Leaf/i })).toBeInTheDocument(); + expect( + await screen.findByRole('region', { + name: /Window: Cambridge, Corpus Christi College, MS 640: Antiphoner Leaf/i, + }), + ).toBeInTheDocument(); const infoButton = await screen.findByRole('tab', { name: /Information/i }); expect(infoButton).toBeInTheDocument(); diff --git a/__tests__/integration/tests/plugin-add.test.js b/__tests__/integration/tests/plugin-add.test.js index 90842c96c..e25055edb 100644 --- a/__tests__/integration/tests/plugin-add.test.js +++ b/__tests__/integration/tests/plugin-add.test.js @@ -1,7 +1,5 @@ import { expect, it } from 'vitest'; -import { - screen, waitFor, fireEvent, within, -} from '@testing-library/react'; +import { screen, waitFor, fireEvent, within } from '@testing-library/react'; import { setupIntegrationTestViewer } from '@tests/utils/test-utils'; import settings from '../mirador-configs/plugin-add'; @@ -17,7 +15,8 @@ describe('add two plugins to ', () => { it('wrapped and added plugins are present', async () => { const pluginDiv = screen.getByTestId('wrapped-plugin-with-adds'); // The umbrella icon that this component wraps - expect(pluginDiv.querySelector('.umbrella')).toBeInTheDocument(); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(pluginDiv.querySelector('.umbrella')).toBeInTheDocument(); const button = within(pluginDiv).getByRole('button'); fireEvent.click(button); diff --git a/__tests__/integration/tests/plugin-companion-window.test.js b/__tests__/integration/tests/plugin-companion-window.test.js index d0386cb82..503a23ca9 100644 --- a/__tests__/integration/tests/plugin-companion-window.test.js +++ b/__tests__/integration/tests/plugin-companion-window.test.js @@ -14,7 +14,10 @@ describe('add plugins for companion windows', () => { // Open sidebar where our custom plugin button will be await waitFor(async () => { - const companionWindowLeft = document.querySelector('.mirador-companion-window-left.mirador-window-sidebar-info-panel'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + const companionWindowLeft = document.querySelector( + '.mirador-companion-window-left.mirador-window-sidebar-info-panel', + ); expect(companionWindowLeft).toBeInTheDocument(); }); diff --git a/__tests__/integration/tests/plugin-state.test.js b/__tests__/integration/tests/plugin-state.test.js index 3b5792178..c108f9202 100644 --- a/__tests__/integration/tests/plugin-state.test.js +++ b/__tests__/integration/tests/plugin-state.test.js @@ -7,7 +7,8 @@ describe('how plugins relate to state', () => { setupIntegrationTestViewer(settings.config, settings.plugins); it('plugin can read from state', async () => { - const text = 'Plugin:https://dms-data.stanford.edu/data/manifests/Parker/nb647fd0133/manifest.json'; + const text = + 'Plugin:https://dms-data.stanford.edu/data/manifests/Parker/nb647fd0133/manifest.json'; const elementWithText = await screen.findByText(text); expect(elementWithText).toHaveTextContent(text); }); diff --git a/__tests__/integration/tests/sequence-switching.test.js b/__tests__/integration/tests/sequence-switching.test.js index fde268ba6..bc6cf5fef 100644 --- a/__tests__/integration/tests/sequence-switching.test.js +++ b/__tests__/integration/tests/sequence-switching.test.js @@ -11,7 +11,9 @@ describe('Window Sidebar Sequence Dropdown', () => { // See mirador-configs/multiple-sequences.js for the form of manifest used in this test. it.skip('allows the user to switch the sequence', async () => { // Make sure we have the manifest - const element = await screen.findByRole('heading', { name: /Urnäsch, Gemeindearchiv Urnäsch, Fragment/i }); + const element = await screen.findByRole('heading', { + name: /Urnäsch, Gemeindearchiv Urnäsch, Fragment/i, + }); expect(element).toBeInTheDocument(); // Open the index tab @@ -23,13 +25,23 @@ describe('Window Sidebar Sequence Dropdown', () => { // Confirm initial sequence (1740) is loaded const sequenceWrapper = await screen.findByTestId('sequence-select'); - const sequenceInput = sequenceWrapper.querySelector('input[name="sequenceId"]'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + const sequenceInput = sequenceWrapper.querySelector('input[name="sequenceId"]'); - expect(sequenceInput).toHaveValue('https://www.e-codices.unifr.ch/metadata/iiif/gau-Fragment/sequence/Sequence-1740.json'); + expect(sequenceInput).toHaveValue( + 'https://www.e-codices.unifr.ch/metadata/iiif/gau-Fragment/sequence/Sequence-1740.json', + ); // Change the sequence (1741) - fireEvent.change(sequenceInput, { target: { value: 'https://www.e-codices.unifr.ch/metadata/iiif/gau-Fragment/sequence/Sequence-1741.json' } }); - - expect(sequenceInput).toHaveValue('https://www.e-codices.unifr.ch/metadata/iiif/gau-Fragment/sequence/Sequence-1741.json'); + fireEvent.change(sequenceInput, { + target: { + value: + 'https://www.e-codices.unifr.ch/metadata/iiif/gau-Fragment/sequence/Sequence-1741.json', + }, + }); + + expect(sequenceInput).toHaveValue( + 'https://www.e-codices.unifr.ch/metadata/iiif/gau-Fragment/sequence/Sequence-1741.json', + ); }); }); diff --git a/__tests__/integration/tests/thumbnail-navigation.test.js b/__tests__/integration/tests/thumbnail-navigation.test.js index 0f7f8d91e..739a1e39f 100644 --- a/__tests__/integration/tests/thumbnail-navigation.test.js +++ b/__tests__/integration/tests/thumbnail-navigation.test.js @@ -10,14 +10,17 @@ describe('Canvas navigation by clicking thumbnails', () => { it.skip('navigates a manifest using thumbnail navigation', async (context) => { // Make sure we have the manifest - const windowElement = await screen.findByRole('region', { name: /Window: Bodleian Library MS. Ind. Inst. Misc. 22/i }); + const windowElement = await screen.findByRole('region', { + name: /Window: Bodleian Library MS. Ind. Inst. Misc. 22/i, + }); expect(windowElement).toBeInTheDocument(); const windowId = windowElement.getAttribute('id'); const storedCanvasId = context.miradorInstance.store.getState().windows[windowId].canvasId; const thumbnailsContainer = await screen.findByLabelText('Thumbnails'); - const thumbnailButtons = thumbnailsContainer.querySelectorAll('.mirador-thumbnail-nav-canvas'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + const thumbnailButtons = thumbnailsContainer.querySelectorAll('.mirador-thumbnail-nav-canvas'); fireEvent.click(thumbnailButtons[4]); }); }); diff --git a/__tests__/integration/tests/viewer-config.test.js b/__tests__/integration/tests/viewer-config.test.js index d56056258..249f8eb2c 100644 --- a/__tests__/integration/tests/viewer-config.test.js +++ b/__tests__/integration/tests/viewer-config.test.js @@ -8,14 +8,21 @@ describe('initialViewerConfig', () => { describe('initialViewerConfig', () => { it('allows initialViewerConfig to be passed', async (context) => { - expect(await screen.findByRole('region', { name: /Window: Cambridge, Corpus Christi College, MS 640: Antiphoner Leaf/i })).toBeInTheDocument(); + expect( + await screen.findByRole('region', { + name: /Window: Cambridge, Corpus Christi College, MS 640: Antiphoner Leaf/i, + }), + ).toBeInTheDocument(); let viewerObject; - await waitFor(() => { - const { viewers = {} } = context.miradorInstance.store.getState(); - viewerObject = viewers[Object.keys(viewers)[0]]; - expect(viewerObject?.x).toBe(934); - }, { timeout: 3000 }); + await waitFor( + () => { + const { viewers = {} } = context.miradorInstance.store.getState(); + viewerObject = viewers[Object.keys(viewers)[0]]; + expect(viewerObject?.x).toBe(934); + }, + { timeout: 3000 }, + ); expect(viewerObject.x).toBe(934); expect(viewerObject.y).toBe(782); diff --git a/__tests__/integration/tests/window-actions.test.js b/__tests__/integration/tests/window-actions.test.js index dc758d321..53e862890 100644 --- a/__tests__/integration/tests/window-actions.test.js +++ b/__tests__/integration/tests/window-actions.test.js @@ -7,10 +7,20 @@ describe('Window actions', () => { setupIntegrationTestViewer(config); it('Closes a Mirador window', async () => { - expect(await screen.findByRole('region', { name: /Window: Cambridge, Corpus Christi College, MS 640: Antiphoner Leaf/i })).toBeInTheDocument(); + expect( + await screen.findByRole('region', { + name: /Window: Cambridge, Corpus Christi College, MS 640: Antiphoner Leaf/i, + }), + ).toBeInTheDocument(); const closeButton = screen.getByRole('button', { name: /Close window/i }); fireEvent.click(closeButton); - await waitFor(() => expect(screen.queryByRole('region', { name: /Window: Cambridge, Corpus Christi College, MS 640: Antiphoner Leaf/i })).not.toBeInTheDocument()); + await waitFor(() => + expect( + screen.queryByRole('region', { + name: /Window: Cambridge, Corpus Christi College, MS 640: Antiphoner Leaf/i, + }), + ).not.toBeInTheDocument(), + ); // No windows should be present expect(screen.queryByRole('region')).not.toBeInTheDocument(); diff --git a/__tests__/src/actions/auth.test.js b/__tests__/src/actions/auth.test.js index a37062cc0..47b1a4c01 100644 --- a/__tests__/src/actions/auth.test.js +++ b/__tests__/src/actions/auth.test.js @@ -39,9 +39,9 @@ describe('auth actions', () => { type: ActionTypes.RESOLVE_AUTHENTICATION_REQUEST, }; - expect( - actions.resolveAuthenticationRequest(authId, tokenServiceId, { ok: false }), - ).toEqual(expectedAction); + expect(actions.resolveAuthenticationRequest(authId, tokenServiceId, { ok: false })).toEqual( + expectedAction, + ); }); }); @@ -100,11 +100,12 @@ describe('auth actions', () => { const serviceId = 'abc123'; const json = { accessToken: 1 }; - expect(actions.resolveAccessTokenRequest(authId, serviceId, json)).toEqual( - { - authId, json, serviceId, type: ActionTypes.RECEIVE_ACCESS_TOKEN, - }, - ); + expect(actions.resolveAccessTokenRequest(authId, serviceId, json)).toEqual({ + authId, + json, + serviceId, + type: ActionTypes.RECEIVE_ACCESS_TOKEN, + }); }); it('without an access token, resolves the auth request unsuccessfully', () => { @@ -112,11 +113,12 @@ describe('auth actions', () => { const serviceId = 'abc123'; const json = { error: 'xyz' }; - expect(actions.resolveAccessTokenRequest(authId, serviceId, json)).toEqual( - { - authId, error: json, serviceId, type: ActionTypes.RECEIVE_ACCESS_TOKEN_FAILURE, - }, - ); + expect(actions.resolveAccessTokenRequest(authId, serviceId, json)).toEqual({ + authId, + error: json, + serviceId, + type: ActionTypes.RECEIVE_ACCESS_TOKEN_FAILURE, + }); }); }); }); diff --git a/__tests__/src/actions/catalog.test.js b/__tests__/src/actions/catalog.test.js index 4c32b21b4..b96e905bd 100644 --- a/__tests__/src/actions/catalog.test.js +++ b/__tests__/src/actions/catalog.test.js @@ -9,11 +9,13 @@ describe('addResource', () => { }); it('dispatches ADD_RESOURCE with the manifest and payload', () => { - expect(actions.addResource( - 'https://purl.stanford.edu/sn904cj3429/iiif/manifest', - { id: 'x' }, - { provider: 'file' }, - )).toEqual({ + expect( + actions.addResource( + 'https://purl.stanford.edu/sn904cj3429/iiif/manifest', + { id: 'x' }, + { provider: 'file' }, + ), + ).toEqual({ manifestId: 'https://purl.stanford.edu/sn904cj3429/iiif/manifest', manifestJson: { id: 'x' }, payload: { provider: 'file' }, diff --git a/__tests__/src/actions/companionWindow.test.js b/__tests__/src/actions/companionWindow.test.js index 5ffc1b60f..05717b5fb 100644 --- a/__tests__/src/actions/companionWindow.test.js +++ b/__tests__/src/actions/companionWindow.test.js @@ -18,9 +18,7 @@ describe('companionWindow actions', () => { const action = actions.addCompanionWindow('abc123', payload); expect(action.type).toBe(ActionTypes.ADD_COMPANION_WINDOW); - expect(action.id).toEqual( - expect.stringMatching(/^cw-\w+-\w+/), - ); + expect(action.id).toEqual(expect.stringMatching(/^cw-\w+-\w+/)); expect(action.windowId).toEqual('abc123'); expect(action.payload).toMatchObject(payload); expect(action.payload.id).toEqual(action.id); @@ -76,7 +74,11 @@ describe('companionWindow actions', () => { expect(action.id).toBe('cw1'); expect(action.windowId).toBe('window1'); expect(action.type).toBe(ActionTypes.TOGGLE_TOC_NODE); - expect(action.payload).toMatchObject({ a: { expanded: true }, b: { expanded: true }, c: { expanded: true } }); + expect(action.payload).toMatchObject({ + a: { expanded: true }, + b: { expanded: true }, + c: { expanded: true }, + }); }); it('marks currently expanded nodes as collapsed', () => { @@ -97,7 +99,11 @@ describe('companionWindow actions', () => { expect(action.id).toBe('cw1'); expect(action.windowId).toBe('window1'); expect(action.type).toBe(ActionTypes.TOGGLE_TOC_NODE); - expect(action.payload).toMatchObject({ a: { expanded: true }, b: { expanded: false }, c: { expanded: false } }); + expect(action.payload).toMatchObject({ + a: { expanded: true }, + b: { expanded: false }, + c: { expanded: false }, + }); }); }); diff --git a/__tests__/src/actions/elasticLayout.test.js b/__tests__/src/actions/elasticLayout.test.js index c8e4b871e..ae948e50d 100644 --- a/__tests__/src/actions/elasticLayout.test.js +++ b/__tests__/src/actions/elasticLayout.test.js @@ -12,9 +12,11 @@ describe('updateElasticWindowLayout', () => { type: ActionTypes.UPDATE_ELASTIC_WINDOW_LAYOUT, windowId: id, }; - expect(actions.updateElasticWindowLayout(id, { - x: 20, - y: 20, - })).toEqual(expectedAction); + expect( + actions.updateElasticWindowLayout(id, { + x: 20, + y: 20, + }), + ).toEqual(expectedAction); }); }); diff --git a/__tests__/src/actions/infoResponse.test.js b/__tests__/src/actions/infoResponse.test.js index be101d4d5..12259f10e 100644 --- a/__tests__/src/actions/infoResponse.test.js +++ b/__tests__/src/actions/infoResponse.test.js @@ -30,7 +30,9 @@ describe('infoResponse actions', () => { describe('fetchInfoResponse', () => { describe('success response', () => { it('dispatches the REQUEST_INFO_RESPONSE action', () => { - const imageResource = { getServices: () => [{ getIIIFResourceType: () => 'ImageService2', getProfile: () => '' }] }; + const imageResource = { + getServices: () => [{ getIIIFResourceType: () => 'ImageService2', getProfile: () => '' }], + }; expect(actions.fetchInfoResponse({ imageId: 'someUrl', imageResource })).toMatchObject({ infoId: 'someUrl', type: 'mirador/REQUEST_INFO_RESPONSE', diff --git a/__tests__/src/actions/search.test.js b/__tests__/src/actions/search.test.js index d1c732348..d85b6f134 100644 --- a/__tests__/src/actions/search.test.js +++ b/__tests__/src/actions/search.test.js @@ -15,9 +15,9 @@ describe('search actions', () => { type: ActionTypes.REQUEST_SEARCH, windowId, }; - expect( - actions.requestSearch(windowId, companionWindowId, searchId, query), - ).toEqual(expectedAction); + expect(actions.requestSearch(windowId, companionWindowId, searchId, query)).toEqual( + expectedAction, + ); }); }); describe('receiveSearch', () => { @@ -36,9 +36,9 @@ describe('search actions', () => { type: ActionTypes.RECEIVE_SEARCH, windowId, }; - expect( - actions.receiveSearch(windowId, companionWindowId, searchId, json), - ).toEqual(expectedAction); + expect(actions.receiveSearch(windowId, companionWindowId, searchId, json)).toEqual( + expectedAction, + ); }); it('provides the first annotation id and its canvas', () => { @@ -53,9 +53,7 @@ describe('search actions', () => { }, ], }; - expect( - actions.receiveSearch(windowId, companionWindowId, searchId, json), - ).toEqual({ + expect(actions.receiveSearch(windowId, companionWindowId, searchId, json)).toEqual({ companionWindowId, searchId, searchJson: json, diff --git a/__tests__/src/actions/window.test.js b/__tests__/src/actions/window.test.js index 71863188f..73cc1c2cf 100644 --- a/__tests__/src/actions/window.test.js +++ b/__tests__/src/actions/window.test.js @@ -92,10 +92,12 @@ describe('window actions', () => { it('creates a new window with additional companion windows', () => { const options = { canvasIndex: 1, - companionWindows: [{ - content: 'attribution', - position: 'right', - }], + companionWindows: [ + { + content: 'attribution', + position: 'right', + }, + ], id: 'helloworld', }; @@ -120,7 +122,10 @@ describe('window actions', () => { expect(action.window.companionWindowIds.length).toEqual(3); expect(action.window.companionWindowIds[2]).toEqual(action.companionWindows[2].id); - expect(action.companionWindows[2]).toMatchObject({ content: 'attribution', position: 'right' }); + expect(action.companionWindows[2]).toMatchObject({ + content: 'attribution', + position: 'right', + }); }); it('creates a new window without a default sidebar', () => { const options = { diff --git a/__tests__/src/actions/workspace.test.js b/__tests__/src/actions/workspace.test.js index 28158e00d..43affa25b 100644 --- a/__tests__/src/actions/workspace.test.js +++ b/__tests__/src/actions/workspace.test.js @@ -53,10 +53,12 @@ describe('workspace actions', () => { }, type: ActionTypes.SET_WORKSPACE_VIEWPORT_POSITION, }; - expect(actions.setWorkspaceViewportDimensions({ - height: 25, - width: 20, - })).toEqual(expectedAction); + expect( + actions.setWorkspaceViewportDimensions({ + height: 25, + width: 20, + }), + ).toEqual(expectedAction); }); }); describe('setWorkspaceViewportPosition', () => { @@ -70,10 +72,12 @@ describe('workspace actions', () => { }, type: ActionTypes.SET_WORKSPACE_VIEWPORT_POSITION, }; - expect(actions.setWorkspaceViewportPosition({ - x: 20, - y: 20, - })).toEqual(expectedAction); + expect( + actions.setWorkspaceViewportPosition({ + x: 20, + y: 20, + }), + ).toEqual(expectedAction); }); }); describe('toggleDraggingEnabled', () => { diff --git a/__tests__/src/components/AccessTokenSender.test.js b/__tests__/src/components/AccessTokenSender.test.js index a0cb575f7..76f7028d5 100644 --- a/__tests__/src/components/AccessTokenSender.test.js +++ b/__tests__/src/components/AccessTokenSender.test.js @@ -5,12 +5,7 @@ import { AccessTokenSender } from '../../../src/components/AccessTokenSender'; * Helper function to create a shallow wrapper around ErrorDialog */ function createWrapper(props) { - return render( - {}} - {...props} - />, - ); + return render( {}} {...props} />); } describe('AccessTokenSender', () => { @@ -22,20 +17,28 @@ describe('AccessTokenSender', () => { it('renders properly', () => { const { container } = createWrapper({ url: 'http://example.com' }); - expect(container.querySelector('iframe')).toHaveAttribute('src', 'http://example.com/?origin=http%3A%2F%2Flocalhost&messageId=http%3A%2F%2Fexample.com'); // eslint-disable-line testing-library/no-node-access, testing-library/no-container + // eslint-disable-next-line testing-library/no-node-access, testing-library/no-container + expect(container.querySelector('iframe')).toHaveAttribute( + 'src', + 'http://example.com/?origin=http%3A%2F%2Flocalhost&messageId=http%3A%2F%2Fexample.com', + ); }); it('triggers an action when the iframe sends a message', () => { const handleAccessTokenMessage = vi.fn(); createWrapper({ handleAccessTokenMessage, url: 'http://example.com' }); - window.dispatchEvent(new MessageEvent('message', { data: { messageId: 'http://example.com' } })); + window.dispatchEvent( + new MessageEvent('message', { data: { messageId: 'http://example.com' } }), + ); expect(handleAccessTokenMessage).toHaveBeenCalledWith({ messageId: 'http://example.com' }); }); it('ignores iframe messages with the wrong messageId', () => { const handleAccessTokenMessage = vi.fn(); createWrapper({ handleAccessTokenMessage, url: 'http://example.com' }); - window.dispatchEvent(new MessageEvent('message', { data: { messageId: 'http://example.com/123' } })); + window.dispatchEvent( + new MessageEvent('message', { data: { messageId: 'http://example.com/123' } }), + ); expect(handleAccessTokenMessage).not.toHaveBeenCalled(); }); }); diff --git a/__tests__/src/components/App.test.js b/__tests__/src/components/App.test.js index 1dc5d5ac5..4bae0a139 100644 --- a/__tests__/src/components/App.test.js +++ b/__tests__/src/components/App.test.js @@ -4,11 +4,7 @@ import { App } from '../../../src/components/App'; /** */ function createWrapper(props) { - return render( - , - ); + return render(); } describe('App', () => { diff --git a/__tests__/src/components/AppProviders.test.js b/__tests__/src/components/AppProviders.test.js index 9ce6017d3..93236029a 100644 --- a/__tests__/src/components/AppProviders.test.js +++ b/__tests__/src/components/AppProviders.test.js @@ -42,7 +42,9 @@ function createWrapper(props = {}) { }} {...props} > - + , diff --git a/__tests__/src/components/AttributionPanel.test.js b/__tests__/src/components/AttributionPanel.test.js index 5219ebb35..7f168ca3a 100644 --- a/__tests__/src/components/AttributionPanel.test.js +++ b/__tests__/src/components/AttributionPanel.test.js @@ -9,21 +9,14 @@ import { AttributionPanel } from '../../../src/components/AttributionPanel'; * Helper function to create a shallow wrapper around AttributionPanel */ function createWrapper(props) { - return render( - , - { preloadedState: { companionWindows: { xyz: { content: 'attribution' } } } }, - ); + return render(, { + preloadedState: { companionWindows: { xyz: { content: 'attribution' } } }, + }); } describe('AttributionPanel', () => { it('renders the required statement', () => { - const requiredStatement = [ - { label: 'required statement', values: ['must be shown'] }, - ]; + const requiredStatement = [{ label: 'required statement', values: ['must be shown'] }]; createWrapper({ requiredStatement }); expect(screen.getByText('required statement')).toBeInTheDocument(); @@ -34,8 +27,14 @@ describe('AttributionPanel', () => { createWrapper({ rights: ['http://example.com', 'http://stanford.edu'] }); expect(screen.getByText('License')).toBeInTheDocument(); - expect(screen.getByRole('link', { name: 'http://example.com' })).toHaveAttribute('href', 'http://example.com'); - expect(screen.getByRole('link', { name: 'http://stanford.edu' })).toHaveAttribute('href', 'http://stanford.edu'); + expect(screen.getByRole('link', { name: 'http://example.com' })).toHaveAttribute( + 'href', + 'http://example.com', + ); + expect(screen.getByRole('link', { name: 'http://stanford.edu' })).toHaveAttribute( + 'href', + 'http://stanford.edu', + ); }); it('does not render the rights statement if it is empty', () => { @@ -45,11 +44,16 @@ describe('AttributionPanel', () => { // Requires canvas to handle img loading. it.skip('renders the manifest logo', async () => { - const manifestLogo = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mMMDQmtBwADgwF/Op8FmAAAAABJRU5ErkJggg=='; + const manifestLogo = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mMMDQmtBwADgwF/Op8FmAAAAABJRU5ErkJggg=='; const { container } = createWrapper({ manifestLogo }); - await waitFor(() => { expect(container.querySelector('img')).toBeInTheDocument(); }); // eslint-disable-line testing-library/no-container, testing-library/no-node-access + await waitFor(() => { + // eslint-disable-next-line testing-library/no-container, testing-library/no-node-access + expect(container.querySelector('img')).toBeInTheDocument(); + }); - expect(container.querySelector('img')).toHaveAttribute('src', manifestLogo); // eslint-disable-line testing-library/no-container, testing-library/no-node-access + // eslint-disable-next-line testing-library/no-container, testing-library/no-node-access + expect(container.querySelector('img')).toHaveAttribute('src', manifestLogo); }); }); diff --git a/__tests__/src/components/AudioViewer.test.js b/__tests__/src/components/AudioViewer.test.js index aca98d37e..500e17526 100644 --- a/__tests__/src/components/AudioViewer.test.js +++ b/__tests__/src/components/AudioViewer.test.js @@ -16,36 +16,41 @@ function createWrapper(props, suspenseFallback) { describe('AudioViewer', () => { describe('render', () => { it('audioResources', () => { - createWrapper({ - audioResources: [ - { getFormat: () => 'video/mp4', id: 1 }, - { getFormat: () => 'video/mp4', id: 2 }, - ], - }, true); + createWrapper( + { + audioResources: [ + { getFormat: () => 'video/mp4', id: 1 }, + { getFormat: () => 'video/mp4', id: 2 }, + ], + }, + true, + ); const audio = screen.getByTestId('audio'); expect(audio.querySelector('source:nth-of-type(1)')).toHaveAttribute('src', '1'); expect(audio.querySelector('source:nth-of-type(2)')).toHaveAttribute('src', '2'); }); it('passes through configurable options', () => { - createWrapper({ - audioResources: [ - { getFormat: () => 'audio/mp3', id: 1 }, - ], - }, true); + createWrapper( + { + audioResources: [{ getFormat: () => 'audio/mp3', id: 1 }], + }, + true, + ); expect(screen.getByTestId('audio')).toHaveAttribute('crossOrigin', 'anonymous'); }); it('captions', () => { - createWrapper({ - audioResources: [ - { getFormat: () => 'video/mp4', id: 1 }, - ], - captions: [ - { getDefaultLabel: () => 'English', getProperty: () => 'en', id: 1 }, - { getDefaultLabel: () => 'French', getProperty: () => 'fr', id: 2 }, - ], - }, true); + createWrapper( + { + audioResources: [{ getFormat: () => 'video/mp4', id: 1 }], + captions: [ + { getDefaultLabel: () => 'English', getProperty: () => 'en', id: 1 }, + { getDefaultLabel: () => 'French', getProperty: () => 'fr', id: 2 }, + ], + }, + true, + ); const audio = screen.getByTestId('audio'); expect(audio.querySelector('track:nth-of-type(1)')).toHaveAttribute('srcLang', 'en'); diff --git a/__tests__/src/components/BackgroundPluginArea.test.js b/__tests__/src/components/BackgroundPluginArea.test.js index e26f36226..0f91d9dce 100644 --- a/__tests__/src/components/BackgroundPluginArea.test.js +++ b/__tests__/src/components/BackgroundPluginArea.test.js @@ -5,9 +5,7 @@ import { usePlugins } from '../../../src/extend/usePlugins'; vi.mock('../../../src/extend/usePlugins'); /** */ -const mockComponent = () => ( -
-); +const mockComponent = () =>
; describe('BackgroundPluginArea', () => { it('renders the component', () => { diff --git a/__tests__/src/components/CanvasInfo.test.js b/__tests__/src/components/CanvasInfo.test.js index 94ac9082d..4dcce89a0 100644 --- a/__tests__/src/components/CanvasInfo.test.js +++ b/__tests__/src/components/CanvasInfo.test.js @@ -43,9 +43,7 @@ describe('CanvasInfo', () => { describe('when metadata is not present', () => { beforeEach(() => { - render( - , - ); + render(); }); it('does not render empty elements elements', () => { diff --git a/__tests__/src/components/CanvasLayers.test.js b/__tests__/src/components/CanvasLayers.test.js index b679700ae..3d5a735f1 100644 --- a/__tests__/src/components/CanvasLayers.test.js +++ b/__tests__/src/components/CanvasLayers.test.js @@ -27,15 +27,27 @@ describe('CanvasLayers', () => { it('displays the canvas label', () => { createWrapper({ totalSize: 2 }); - expect(screen.getByText('Left: [A Canvas Label]', { container: '.MuiTypography-overline' })).toBeInTheDocument(); + expect( + screen.getByText('Left: [A Canvas Label]', { container: '.MuiTypography-overline' }), + ).toBeInTheDocument(); }); }); it('renders canvas layers in a list', () => { // TODO clean up this test once manifesto.js provides info about Choice options - const res1 = new Resource({ id: 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PSC/full/862,1024/0/default.jpg' }, {}); + const res1 = new Resource( + { + id: 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PSC/full/862,1024/0/default.jpg', + }, + {}, + ); res1.preferred = true; - const res2 = new Resource({ id: 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_TS_Blue/full/862,1024/0/default.png' }, {}); + const res2 = new Resource( + { + id: 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_TS_Blue/full/862,1024/0/default.png', + }, + {}, + ); res2.preferred = true; createWrapper({ canvasId: 'https://prtd.app/hamilton/canvas/p1.json', @@ -55,15 +67,12 @@ describe('CanvasLayers', () => { const updateLayers = vi.fn(); createWrapper({ canvasId: 'foo', - layers: [ - new Resource({ id: 'a' }, {}), - new Resource({ id: 'b' }, {}), - ], + layers: [new Resource({ id: 'a' }, {}), new Resource({ id: 'b' }, {})], updateLayers, }); const buttons = screen.getAllByRole('button'); - const layer = buttons.find(b => b.getAttribute('data-rfd-drag-handle-draggable-id') === 'b'); + const layer = buttons.find((b) => b.getAttribute('data-rfd-drag-handle-draggable-id') === 'b'); layer.focus(); @@ -91,8 +100,18 @@ describe('CanvasLayers', () => { updateLayers = vi.fn(); user = userEvent.setup(); // TODO clean up this test setup once manifesto.js provides info about Choice options - const res1 = new Resource({ id: 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PSC/full/862,1024/0/default.jpg' }, {}); - const res2 = new Resource({ id: 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_TS_Blue/full/862,1024/0/default.png' }, {}); + const res1 = new Resource( + { + id: 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PSC/full/862,1024/0/default.jpg', + }, + {}, + ); + const res2 = new Resource( + { + id: 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_TS_Blue/full/862,1024/0/default.png', + }, + {}, + ); res1.preferred = true; res2.preferred = true; @@ -110,9 +129,10 @@ describe('CanvasLayers', () => { 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PSC/full/862,1024/0/default.jpg': { index: 1, }, - 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_TS_Blue/full/862,1024/0/default.png': { - index: 0, - }, + 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_TS_Blue/full/862,1024/0/default.png': + { + index: 0, + }, }); }); @@ -123,9 +143,10 @@ describe('CanvasLayers', () => { 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PSC/full/862,1024/0/default.jpg': { index: 1, }, - 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_TS_Blue/full/862,1024/0/default.png': { - index: 0, - }, + 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_TS_Blue/full/862,1024/0/default.png': + { + index: 0, + }, }); }); @@ -133,9 +154,10 @@ describe('CanvasLayers', () => { await user.click(screen.getAllByLabelText('Hide layer')[1]); expect(updateLayers).toHaveBeenCalledWith('abc', 'https://prtd.app/hamilton/canvas/p1.json', { - 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_TS_Blue/full/862,1024/0/default.png': { - visibility: false, - }, + 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_TS_Blue/full/862,1024/0/default.png': + { + visibility: false, + }, }); }); @@ -146,9 +168,10 @@ describe('CanvasLayers', () => { await user.type(target, '{ArrowLeft}'); expect(updateLayers).toHaveBeenCalledWith('abc', 'https://prtd.app/hamilton/canvas/p1.json', { - 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_TS_Blue/full/862,1024/0/default.png': { - opacity: 0.5, - }, + 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_TS_Blue/full/862,1024/0/default.png': + { + opacity: 0.5, + }, }); }); @@ -156,9 +179,10 @@ describe('CanvasLayers', () => { fireEvent.change(screen.getAllByRole('spinbutton')[1], { target: { value: '90' } }); expect(updateLayers).toHaveBeenCalledWith('abc', 'https://prtd.app/hamilton/canvas/p1.json', { - 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_TS_Blue/full/862,1024/0/default.png': { - opacity: 0.9, - }, + 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_TS_Blue/full/862,1024/0/default.png': + { + opacity: 0.9, + }, }); }); }); diff --git a/__tests__/src/components/CollapsibleSection.test.js b/__tests__/src/components/CollapsibleSection.test.js index 6c157ed0b..2a911c8f8 100644 --- a/__tests__/src/components/CollapsibleSection.test.js +++ b/__tests__/src/components/CollapsibleSection.test.js @@ -7,12 +7,7 @@ import { CollapsibleSection } from '../../../src/components/CollapsibleSection'; */ function createWrapper(props) { return render( - + Child content , ); @@ -28,9 +23,15 @@ describe('CollapsibleSection', () => { }); it('renders the appropriate i18n label based on open state', async () => { - expect(screen.getByRole('button')).toHaveAttribute('aria-label', 'Collapse "The Section Label" section'); + expect(screen.getByRole('button')).toHaveAttribute( + 'aria-label', + 'Collapse "The Section Label" section', + ); await userEvent.click(screen.getByRole('button')); - expect(screen.getByRole('button')).toHaveAttribute('aria-label', 'Expand "The Section Label" section'); + expect(screen.getByRole('button')).toHaveAttribute( + 'aria-label', + 'Expand "The Section Label" section', + ); }); it('displays children based on the open state', async () => { diff --git a/__tests__/src/components/CollectionDialog.test.js b/__tests__/src/components/CollectionDialog.test.js index 1c77e5228..474acd505 100644 --- a/__tests__/src/components/CollectionDialog.test.js +++ b/__tests__/src/components/CollectionDialog.test.js @@ -36,7 +36,9 @@ describe('CollectionDialog', () => { expect(screen.getByRole('dialog')).toBeInTheDocument(); expect(screen.getAllByRole('menuitem')).toHaveLength(55); - expect(screen.getByRole('menuitem', { name: 'Test 1 Manifest: Minimum Required Fields' })).toBeInTheDocument(); + expect( + screen.getByRole('menuitem', { name: 'Test 1 Manifest: Minimum Required Fields' }), + ).toBeInTheDocument(); }); it('when not ready returns placeholder skeleton', () => { @@ -44,7 +46,8 @@ describe('CollectionDialog', () => { expect(screen.queryByRole('menuitem')).not.toBeInTheDocument(); - expect(screen.getByRole('dialog').querySelectorAll('.MuiSkeleton-root')).toHaveLength(3); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(screen.getByRole('dialog').querySelectorAll('.MuiSkeleton-root')).toHaveLength(3); }); it('clicking the hide button fires hideCollectionDialog', async () => { @@ -64,10 +67,18 @@ describe('CollectionDialog', () => { expect(screen.getByRole('dialog')).toBeInTheDocument(); expect(screen.getAllByRole('menuitem')).toHaveLength(1); - expect(screen.getByRole('menuitem', { name: 'Collection of Test Cases - label for parent' })).toBeInTheDocument(); - - await user.click(screen.getByRole('menuitem', { name: 'Collection of Test Cases - label for parent' })); - expect(showCollectionDialog).toHaveBeenCalledWith(collection['@id'], [parentCollection['@id']], 'window'); + expect( + screen.getByRole('menuitem', { name: 'Collection of Test Cases - label for parent' }), + ).toBeInTheDocument(); + + await user.click( + screen.getByRole('menuitem', { name: 'Collection of Test Cases - label for parent' }), + ); + expect(showCollectionDialog).toHaveBeenCalledWith( + collection['@id'], + [parentCollection['@id']], + 'window', + ); }); it('fires correct showCollectionDialog when the parent collection is clicked', async () => { @@ -82,7 +93,9 @@ describe('CollectionDialog', () => { }); expect(screen.getByRole('dialog')).toBeInTheDocument(); - expect(screen.getByRole('button', { name: 'Parent Collection of Collection' })).toBeInTheDocument(); + expect( + screen.getByRole('button', { name: 'Parent Collection of Collection' }), + ).toBeInTheDocument(); await user.click(screen.getByRole('button', { name: 'Parent Collection of Collection' })); expect(showCollectionDialog).toHaveBeenCalledWith(parentCollection['@id'], [], 'window'); @@ -106,11 +119,15 @@ describe('CollectionDialog', () => { expect(screen.getByRole('dialog')).toBeInTheDocument(); - await user.click(screen.getByRole('menuitem', { name: 'Test 1 Manifest: Minimum Required Fields' })); + await user.click( + screen.getByRole('menuitem', { name: 'Test 1 Manifest: Minimum Required Fields' }), + ); expect(hideCollectionDialog).toHaveBeenCalledWith('window'); expect(setWorkspaceAddVisibility).toHaveBeenCalledWith(false); expect(updateWindow).toHaveBeenCalledWith('window', { - canvasId: null, collectionPath: [parentCollection['@id'], collection['@id']], manifestId, + canvasId: null, + collectionPath: [parentCollection['@id'], collection['@id']], + manifestId, }); }); }); diff --git a/__tests__/src/components/CollectionInfo.test.js b/__tests__/src/components/CollectionInfo.test.js index b147614bb..f645400aa 100644 --- a/__tests__/src/components/CollectionInfo.test.js +++ b/__tests__/src/components/CollectionInfo.test.js @@ -5,11 +5,7 @@ import { CollectionInfo } from '../../../src/components/CollectionInfo'; /** */ function createWrapper(props) { return render( - {}} - {...props} - />, + {}} {...props} />, ); } diff --git a/__tests__/src/components/CompanionArea.test.js b/__tests__/src/components/CompanionArea.test.js index 2f3213437..1b11ca4e7 100644 --- a/__tests__/src/components/CompanionArea.test.js +++ b/__tests__/src/components/CompanionArea.test.js @@ -15,7 +15,11 @@ function createWrapper(props) { companionWindowIds={['foo', 'baz']} {...props} />, - { preloadedState: { companionWindows: { baz: { content: 'attribution' }, foo: { content: 'info' } } } }, + { + preloadedState: { + companionWindows: { baz: { content: 'attribution' }, foo: { content: 'info' } }, + }, + }, ); } @@ -29,7 +33,8 @@ describe('CompanionArea', () => { it('should add the appropriate classes when the companion area fills the full width', () => { const { container } = createWrapper({ position: 'bottom' }); - expect(container.querySelector('.mirador-companion-area-bottom')).toBeInTheDocument(); // eslint-disable-line testing-library/no-node-access, testing-library/no-container + // eslint-disable-next-line testing-library/no-node-access, testing-library/no-container + expect(container.querySelector('.mirador-companion-area-bottom')).toBeInTheDocument(); }); it('renders the appropriate components', () => { @@ -50,7 +55,10 @@ describe('CompanionArea', () => { sideBarOpen: true, }); - expect(screen.getByRole('button', { name: 'Expand sidebar' })).toHaveAttribute('aria-expanded', 'false'); + expect(screen.getByRole('button', { name: 'Expand sidebar' })).toHaveAttribute( + 'aria-expanded', + 'false', + ); expect(screen.queryByRole('complementary')).not.toBeInTheDocument(); await user.click(screen.getByRole('button', { name: 'Expand sidebar' })); @@ -69,7 +77,10 @@ describe('CompanionArea', () => { sideBarOpen: true, }); - expect(screen.getByRole('button', { name: 'Collapse sidebar' })).toHaveAttribute('aria-expanded', 'true'); + expect(screen.getByRole('button', { name: 'Collapse sidebar' })).toHaveAttribute( + 'aria-expanded', + 'true', + ); await user.click(screen.getByRole('button', { name: 'Collapse sidebar' })); expect(setCompanionAreaOpen).toHaveBeenCalledWith('abc123', false); diff --git a/__tests__/src/components/CompanionWindow.test.js b/__tests__/src/components/CompanionWindow.test.js index b43a4a857..74cd14dfc 100644 --- a/__tests__/src/components/CompanionWindow.test.js +++ b/__tests__/src/components/CompanionWindow.test.js @@ -68,11 +68,14 @@ describe('CompanionWindow', () => { /** Some child component */ const Button = ({ parentactions, ...props }) => ( - + ); Button.propTypes = { - parentactions: PropTypes.shape({ closeCompanionWindow: PropTypes.func.isRequired }).isRequired, + parentactions: PropTypes.shape({ closeCompanionWindow: PropTypes.func.isRequired }) + .isRequired, }; createWrapper({ @@ -130,14 +133,24 @@ describe('CompanionWindow', () => { it('has a resize handler', () => { const { container } = createWrapper(); - expect(container.querySelector('.react-draggable')).toHaveStyle({ height: '100%', width: '235px' }); // eslint-disable-line testing-library/no-node-access, testing-library/no-container - expect(container.querySelector('[style*="cursor: col-resize;"]')).toHaveStyle({ left: '-5px' }); // eslint-disable-line testing-library/no-node-access, testing-library/no-container + // eslint-disable-next-line testing-library/no-node-access, testing-library/no-container + expect(container.querySelector('.react-draggable')).toHaveStyle({ + height: '100%', + width: '235px', + }); + // eslint-disable-next-line testing-library/no-node-access, testing-library/no-container + expect(container.querySelector('[style*="cursor: col-resize;"]')).toHaveStyle({ left: '-5px' }); }); it('has a vertical resize handle when position is bottom', () => { const { container } = createWrapper({ position: 'bottom' }); - expect(container.querySelector('.react-draggable')).toHaveStyle({ height: '201px', width: 'auto' }); // eslint-disable-line testing-library/no-node-access, testing-library/no-container - expect(container.querySelector('[style*="cursor: row-resize;"]')).toHaveStyle({ top: '-5px' }); // eslint-disable-line testing-library/no-node-access, testing-library/no-container + // eslint-disable-next-line testing-library/no-node-access, testing-library/no-container + expect(container.querySelector('.react-draggable')).toHaveStyle({ + height: '201px', + width: 'auto', + }); + // eslint-disable-next-line testing-library/no-node-access, testing-library/no-container + expect(container.querySelector('[style*="cursor: row-resize;"]')).toHaveStyle({ top: '-5px' }); }); }); diff --git a/__tests__/src/components/CompanionWindowFactory.test.js b/__tests__/src/components/CompanionWindowFactory.test.js index 1416fa356..7d8b5359e 100644 --- a/__tests__/src/components/CompanionWindowFactory.test.js +++ b/__tests__/src/components/CompanionWindowFactory.test.js @@ -4,15 +4,12 @@ import { CompanionWindowFactory } from '../../../src/components/CompanionWindowF /** create wrapper */ function createWrapper({ content = 'closed', ...props }) { - return render( - , - { preloadedState: { companionWindows: { 123: { content }, thumb: {} }, windows: { x: { thumbnailNavigationId: 'thumb' } } } }, - ); + return render(, { + preloadedState: { + companionWindows: { 123: { content }, thumb: {} }, + windows: { x: { thumbnailNavigationId: 'thumb' } }, + }, + }); } describe('CompanionWindowFactory', () => { diff --git a/__tests__/src/components/ErrorContent.test.js b/__tests__/src/components/ErrorContent.test.js index 27618b60d..e8025f7d6 100644 --- a/__tests__/src/components/ErrorContent.test.js +++ b/__tests__/src/components/ErrorContent.test.js @@ -29,7 +29,8 @@ describe('ErrorContent', () => { expect(screen.getByRole('alert')).toBeInTheDocument(); expect(screen.getByText('An error occurred')).toBeInTheDocument(); expect(screen.getByText('Technical details')).toBeInTheDocument(); - expect(document.querySelector('pre')).toHaveTextContent('Invalid JSON'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(document.querySelector('pre')).toHaveTextContent('Invalid JSON'); }); it('does not render the alert when showJsError is false ', async () => { render( diff --git a/__tests__/src/components/ErrorDialog.test.js b/__tests__/src/components/ErrorDialog.test.js index 836287e2f..94a0a74c4 100644 --- a/__tests__/src/components/ErrorDialog.test.js +++ b/__tests__/src/components/ErrorDialog.test.js @@ -6,11 +6,7 @@ import { ErrorDialog } from '../../../src/components/ErrorDialog'; * Helper function to create a shallow wrapper around ErrorDialog */ function createWrapper(props) { - return render( - , - ); + return render(); } describe('ErrorDialog', () => { diff --git a/__tests__/src/components/FullScreenButton.test.js b/__tests__/src/components/FullScreenButton.test.js index f3a70cff8..0d276e7b6 100644 --- a/__tests__/src/components/FullScreenButton.test.js +++ b/__tests__/src/components/FullScreenButton.test.js @@ -7,11 +7,7 @@ import { FullScreenButton } from '../../../src/components/FullScreenButton'; function createWrapper(props, contextProps = { active: false }) { return render( {}, exit: () => {}, ...contextProps }}> - + , ); } diff --git a/__tests__/src/components/GalleryView.test.js b/__tests__/src/components/GalleryView.test.js index 852f216de..ce29df588 100644 --- a/__tests__/src/components/GalleryView.test.js +++ b/__tests__/src/components/GalleryView.test.js @@ -23,7 +23,8 @@ describe('GalleryView', () => { }); it('renders the component', () => { const { container } = createWrapper({ setCanvas }); - expect(container.querySelector('section')).toBeInTheDocument(); // eslint-disable-line testing-library/no-node-access, testing-library/no-container + // eslint-disable-next-line testing-library/no-node-access, testing-library/no-container + expect(container.querySelector('section')).toBeInTheDocument(); }); it('renders gallery items for all canvases', () => { createWrapper({ setCanvas }); @@ -37,7 +38,8 @@ describe('GalleryView', () => { viewingDirection: 'right-to-left', }); const buttons = screen.queryAllByRole('button'); - expect(buttons[0].closest('section')).toHaveAttribute('dir', 'rtl'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(buttons[0].closest('section')).toHaveAttribute('dir', 'rtl'); }); }); }); diff --git a/__tests__/src/components/GalleryViewThumbnail.test.js b/__tests__/src/components/GalleryViewThumbnail.test.js index e4c58fb2f..8ad7764ef 100644 --- a/__tests__/src/components/GalleryViewThumbnail.test.js +++ b/__tests__/src/components/GalleryViewThumbnail.test.js @@ -32,7 +32,9 @@ describe('GalleryView', () => { createWrapper({ setCanvas }); const user = userEvent.setup(); await user.click(screen.getByRole('button')); - expect(setCanvas).toHaveBeenCalledWith('http://iiif.io/api/presentation/2.0/example/fixtures/canvas/24/c1.json'); + expect(setCanvas).toHaveBeenCalledWith( + 'http://iiif.io/api/presentation/2.0/example/fixtures/canvas/24/c1.json', + ); }); it('sets the window mode if the selected canvas is clicked', async () => { @@ -67,10 +69,12 @@ describe('GalleryView', () => { const button = screen.getByRole('button'); button.focus(); fireEvent.keyUp(button, { code: 'd', key: 'd' }); - expect(setCanvas).toHaveBeenCalledWith('http://iiif.io/api/presentation/2.0/example/fixtures/canvas/24/c1.json'); + expect(setCanvas).toHaveBeenCalledWith( + 'http://iiif.io/api/presentation/2.0/example/fixtures/canvas/24/c1.json', + ); }); - it('scrolls into view when selected prop changes to true', () => { + it('scrolls into view when selected prop changes to true', () => { const { rerender } = createWrapper({ selected: false }); expect(window.HTMLElement.prototype.scrollIntoView).not.toHaveBeenCalled(); @@ -99,7 +103,9 @@ describe('GalleryView', () => { }; let requestCanvasAnnotations; - beforeEach(() => { requestCanvasAnnotations = vi.fn(); }); + beforeEach(() => { + requestCanvasAnnotations = vi.fn(); + }); it('triggers requestCanvasAnnotations when there is an intersection and no annotions ', () => { createWrapper({ annotationsCount: 0, canvas, requestCanvasAnnotations }); mockAllIsIntersecting(true); @@ -119,26 +125,32 @@ describe('GalleryView', () => { describe('annotation count chip', () => { it('hides the chip if there are no annotations', () => { const { container } = createWrapper({ annotationsCount: 0 }); - expect(container.querySelector('.MuiChip-root')).not.toBeInTheDocument(); // eslint-disable-line testing-library/no-node-access, testing-library/no-container + // eslint-disable-next-line testing-library/no-node-access, testing-library/no-container + expect(container.querySelector('.MuiChip-root')).not.toBeInTheDocument(); }); it('shows the number of search annotations on a canvas', () => { const { container } = createWrapper({ annotationsCount: 50 }); - expect(container.querySelector('.MuiChip-root')).toBeInTheDocument(); // eslint-disable-line testing-library/no-node-access, testing-library/no-container - expect(container.querySelector('.MuiChip-root')).toHaveTextContent('50'); // eslint-disable-line testing-library/no-node-access, testing-library/no-container + // eslint-disable-next-line testing-library/no-node-access, testing-library/no-container + expect(container.querySelector('.MuiChip-root')).toBeInTheDocument(); + // eslint-disable-next-line testing-library/no-node-access, testing-library/no-container + expect(container.querySelector('.MuiChip-root')).toHaveTextContent('50'); }); }); describe('search annotation count chip', () => { it('hides the chip if there are no annotations', () => { const { container } = createWrapper({ searchAnnotationsCount: 0 }); - expect(container.querySelector('.MuiChip-root')).not.toBeInTheDocument(); // eslint-disable-line testing-library/no-node-access, testing-library/no-container + // eslint-disable-next-line testing-library/no-node-access, testing-library/no-container + expect(container.querySelector('.MuiChip-root')).not.toBeInTheDocument(); }); it('shows the number of search annotations on a canvas', () => { const { container } = createWrapper({ searchAnnotationsCount: 50 }); - expect(container.querySelector('.MuiChip-root')).toBeInTheDocument(); // eslint-disable-line testing-library/no-node-access, testing-library/no-container - expect(container.querySelector('.MuiChip-root')).toHaveTextContent('50'); // eslint-disable-line testing-library/no-node-access, testing-library/no-container + // eslint-disable-next-line testing-library/no-node-access, testing-library/no-container + expect(container.querySelector('.MuiChip-root')).toBeInTheDocument(); + // eslint-disable-next-line testing-library/no-node-access, testing-library/no-container + expect(container.querySelector('.MuiChip-root')).toHaveTextContent('50'); }); }); }); diff --git a/__tests__/src/components/IIIFAuthentication.test.js b/__tests__/src/components/IIIFAuthentication.test.js index 4ad4e55a9..a8eb8dab7 100644 --- a/__tests__/src/components/IIIFAuthentication.test.js +++ b/__tests__/src/components/IIIFAuthentication.test.js @@ -65,7 +65,10 @@ describe('IIIFAuthentication', () => { it('renders with an error message', async () => { const handleAuthInteraction = vi.fn(); createWrapper({ - accessTokenServiceId: null, handleAuthInteraction, isInteractive: false, status: 'failed', + accessTokenServiceId: null, + handleAuthInteraction, + isInteractive: false, + status: 'failed', }); expect(screen.getByText('Login failed')).toBeInTheDocument(); expect(screen.getByText('... and this is why.')).toBeInTheDocument(); @@ -74,12 +77,16 @@ describe('IIIFAuthentication', () => { describe('in the middle of authenticating', () => { it('does the IIIF access cookie behavior', async () => { const mockWindow = { close: vi.fn(), closed: false }; - const mockWindowOpen = vi.fn(() => (mockWindow)); + const mockWindowOpen = vi.fn(() => mockWindow); window.open = mockWindowOpen; const resolveCookieMock = vi.fn(); createWrapper({ resolveAuthenticationRequest: resolveCookieMock, status: 'cookie' }); expect(screen.getByRole('button', { name: 'Log in' })).toBeInTheDocument(); - expect(mockWindowOpen).toHaveBeenCalledWith(`http://example.com/auth?origin=${window.origin}`, 'IiifLoginSender', 'centerscreen'); + expect(mockWindowOpen).toHaveBeenCalledWith( + `http://example.com/auth?origin=${window.origin}`, + 'IiifLoginSender', + 'centerscreen', + ); mockWindow.closed = true; await waitFor(() => expect(resolveCookieMock).toHaveBeenCalledTimes(1)); }); @@ -87,16 +94,24 @@ describe('IIIFAuthentication', () => { const resolveTokenMock = vi.fn(); createWrapper({ resolveAccessTokenRequest: resolveTokenMock, status: 'token' }); expect(screen.getByRole('button', { name: 'Log in' })).toBeInTheDocument(); - window.dispatchEvent(new MessageEvent('message', { - data: { messageId: 'http://example.com/token' }, - })); - await waitFor(() => expect(resolveTokenMock).toHaveBeenCalledWith('http://example.com/auth', 'http://example.com/token', { messageId: 'http://example.com/token' })); + window.dispatchEvent( + new MessageEvent('message', { + data: { messageId: 'http://example.com/token' }, + }), + ); + await waitFor(() => + expect(resolveTokenMock).toHaveBeenCalledWith( + 'http://example.com/auth', + 'http://example.com/token', + { messageId: 'http://example.com/token' }, + ), + ); }); }); describe('when logged in', () => { it('renders a logout button', async () => { const mockWindow = { open: vi.fn() }; - const mockWindowOpen = vi.fn(() => (mockWindow)); + const mockWindowOpen = vi.fn(() => mockWindow); window.open = mockWindowOpen; const resetAuthenticationState = vi.fn(); createWrapper({ @@ -107,9 +122,12 @@ describe('IIIFAuthentication', () => { }); const confirmBtn = await screen.findByRole('button', { name: 'exit' }); await user.click(confirmBtn); - await waitFor(() => expect(resetAuthenticationState).toHaveBeenCalledWith({ - authServiceId: 'http://example.com/auth', tokenServiceId: 'http://example.com/token', - })); + await waitFor(() => + expect(resetAuthenticationState).toHaveBeenCalledWith({ + authServiceId: 'http://example.com/auth', + tokenServiceId: 'http://example.com/token', + }), + ); }); }); }); diff --git a/__tests__/src/components/IIIFDropTarget.test.js b/__tests__/src/components/IIIFDropTarget.test.js index 8b390ff32..ffbe8c01f 100644 --- a/__tests__/src/components/IIIFDropTarget.test.js +++ b/__tests__/src/components/IIIFDropTarget.test.js @@ -4,9 +4,14 @@ const monitor = vi.fn(); // jsdom doesn't load images, so we mock an implementation vi.mock('../../../src/lib/readImageMetadata', () => ({ - readImageMetadata: file => Promise.resolve({ - height: 105, name: file.name, type: file.type, url: 'data:blah', width: 100, - }), + readImageMetadata: (file) => + Promise.resolve({ + height: 105, + name: file.name, + type: file.type, + url: 'data:blah', + width: 100, + }), })); describe('handleDrop', () => { @@ -26,16 +31,22 @@ describe('handleDrop', () => { const props = { onDrop }; handleDrop(item, monitor, props); - expect(onDrop).toHaveBeenCalledWith({ canvasId: null, manifestId: 'http://example.com/iiif/1.json' }, props, monitor); - expect(onDrop).toHaveBeenCalledWith({ canvasId: 'url', manifestId: 'http://example.com/iiif/2.json' }, props, monitor); + expect(onDrop).toHaveBeenCalledWith( + { canvasId: null, manifestId: 'http://example.com/iiif/1.json' }, + props, + monitor, + ); + expect(onDrop).toHaveBeenCalledWith( + { canvasId: 'url', manifestId: 'http://example.com/iiif/2.json' }, + props, + monitor, + ); }); it('handles manifests', () => { const file = new File(['{ "data": 123 }'], 'manifest.json', { type: 'application/json' }); const item = { - files: [ - file, - ], + files: [file], }; const props = { onDrop }; @@ -54,9 +65,7 @@ describe('handleDrop', () => { it('handles images by fabricating a temporary manifest', () => { const file = new File(['image data'], 'image.gif', { type: 'image/gif' }); const item = { - files: [ - file, - ], + files: [file], }; const props = { onDrop }; @@ -74,7 +83,9 @@ describe('handleDrop', () => { items: [ expect.objectContaining({ body: { - format: 'image/gif', id: 'data:blah', type: 'Image', + format: 'image/gif', + id: 'data:blah', + type: 'Image', }, height: 105, width: 100, @@ -115,7 +126,12 @@ describe('handleDrop', () => { handleDrop(item, monitor, props); expect(onDrop).toHaveBeenCalledWith( - { canvasId: 'https://digitalcollections.universiteitleiden.nl/iiif_manifest/item:1607203/canvas/default', manifestId: 'https://digitalcollections.universiteitleiden.nl/iiif_manifest/item%3A1607191/manifest' }, + { + canvasId: + 'https://digitalcollections.universiteitleiden.nl/iiif_manifest/item:1607203/canvas/default', + manifestId: + 'https://digitalcollections.universiteitleiden.nl/iiif_manifest/item%3A1607191/manifest', + }, props, monitor, ); diff --git a/__tests__/src/components/IIIFThumbnail.test.js b/__tests__/src/components/IIIFThumbnail.test.js index 4d8cead69..0855d72f1 100644 --- a/__tests__/src/components/IIIFThumbnail.test.js +++ b/__tests__/src/components/IIIFThumbnail.test.js @@ -7,12 +7,7 @@ import FailedImageContext from '../../../src/contexts/FailedImageContext'; * Helper function to create a shallow wrapper around IIIFThumbnail */ function createWrapper(props) { - return render( - , - ); + return render(); } /* eslint-disable testing-library/no-node-access, testing-library/no-container */ @@ -74,7 +69,10 @@ describe('IIIFThumbnail', () => { it('renders a provided label', () => { createWrapper({ - classes: { label: 'label' }, label: 'Some label', labelled: true, thumbnail, + classes: { label: 'label' }, + label: 'Some label', + labelled: true, + thumbnail, }); expect(screen.getByText('Some label')).toBeInTheDocument(); @@ -86,7 +84,7 @@ describe('IIIFThumbnail', () => { expect(screen.getByTestId('hi')).toBeInTheDocument(); }); - it('handles image load failure correctly', () => { + it('handles image load failure correctly', () => { const notifyFailure = vi.fn(); const fallbackImage = 'data:image/svg+xml,fallback'; const mockContext = { diff --git a/__tests__/src/components/LabelValueMetadata.test.js b/__tests__/src/components/LabelValueMetadata.test.js index 487351670..103c8da06 100644 --- a/__tests__/src/components/LabelValueMetadata.test.js +++ b/__tests__/src/components/LabelValueMetadata.test.js @@ -3,11 +3,7 @@ import { LabelValueMetadata } from '../../../src/components/LabelValueMetadata'; /** */ function createWrapper(props) { - return render( - , - ); + return render(); } /* eslint-disable testing-library/no-node-access */ diff --git a/__tests__/src/components/LanguageSettings.test.js b/__tests__/src/components/LanguageSettings.test.js index 3d89b8852..cd249813a 100644 --- a/__tests__/src/components/LanguageSettings.test.js +++ b/__tests__/src/components/LanguageSettings.test.js @@ -6,13 +6,7 @@ import { LanguageSettings } from '../../../src/components/LanguageSettings'; * Helper function to create a shallow wrapper around LanguageSettings */ function createWrapper(props) { - return render( - {}} - languages={{}} - {...props} - />, - ); + return render( {}} languages={{}} {...props} />); } describe('LanguageSettings', () => { @@ -38,8 +32,14 @@ describe('LanguageSettings', () => { it('renders the check icon when the active prop returns true', () => { createWrapper({ languages }); - expect(screen.getByRole('menuitem', { name: 'Deutsch' }).querySelector('svg')).toBeInTheDocument(); // eslint-disable-line testing-library/no-node-access - expect(screen.getByRole('menuitem', { name: 'English' }).querySelector('svg')).not.toBeInTheDocument(); // eslint-disable-line testing-library/no-node-access, testing-library/prefer-presence-queries + expect( + // eslint-disable-next-line testing-library/no-node-access + screen.getByRole('menuitem', { name: 'Deutsch' }).querySelector('svg'), + ).toBeInTheDocument(); + expect( + // eslint-disable-next-line testing-library/no-node-access, testing-library/prefer-presence-queries + screen.getByRole('menuitem', { name: 'English' }).querySelector('svg'), + ).not.toBeInTheDocument(); }); it('renders the language value in an Typography element wrapped in a ListItemText', () => { diff --git a/__tests__/src/components/LayersPanel.test.js b/__tests__/src/components/LayersPanel.test.js index 980828060..1f0a8c2c5 100644 --- a/__tests__/src/components/LayersPanel.test.js +++ b/__tests__/src/components/LayersPanel.test.js @@ -6,14 +6,9 @@ import { LayersPanel } from '../../../src/components/LayersPanel'; * Helper function to create a shallow wrapper around AttributionPanel */ function createWrapper(props) { - return render( - , - { preloadedState: { companionWindows: { xyz: { content: 'layers' } } } }, - ); + return render(, { + preloadedState: { companionWindows: { xyz: { content: 'layers' } } }, + }); } describe('LayersPanel', () => { diff --git a/__tests__/src/components/LocalePicker.test.js b/__tests__/src/components/LocalePicker.test.js index 448354cb7..ba8ad27ea 100644 --- a/__tests__/src/components/LocalePicker.test.js +++ b/__tests__/src/components/LocalePicker.test.js @@ -7,12 +7,7 @@ import { LocalePicker } from '../../../src/components/LocalePicker'; */ function createWrapper(props) { return render( - {}} - {...props} - />, + {}} {...props} />, ); } @@ -20,7 +15,8 @@ describe('LocalePicker', () => { it('hides the control if there are not locales to switch to', () => { const { container } = createWrapper({ availableLocales: ['en'] }); - expect(container).toBeEmptyDOMElement(); // eslint-disable-line testing-library/no-container + // eslint-disable-next-line testing-library/no-container + expect(container).toBeEmptyDOMElement(); }); it('renders a select with the current value', () => { @@ -39,7 +35,8 @@ describe('LocalePicker', () => { // The dropddown menu is not nested within the combobox, it is a sibling in the DOM, an MuiMenu const menu = screen.getByRole('listbox'); // Assert that the menu element has 2 children (2 options) - expect(menu.children).toHaveLength(2); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(menu.children).toHaveLength(2); // Verify that the select element has the correct value ('de') const deOption = screen.getByRole('option', { name: 'Deutsch' }); expect(deOption).toHaveAttribute('aria-selected', 'true'); diff --git a/__tests__/src/components/ManifestForm.test.js b/__tests__/src/components/ManifestForm.test.js index 237e32322..f0e96401d 100644 --- a/__tests__/src/components/ManifestForm.test.js +++ b/__tests__/src/components/ManifestForm.test.js @@ -4,12 +4,7 @@ import { ManifestForm } from '../../../src/components/ManifestForm'; /** create wrapper */ function createWrapper(props) { - return render( - {}} - {...props} - />, - ); + return render( {}} {...props} />); } describe('ManifestForm', () => { @@ -44,7 +39,10 @@ describe('ManifestForm', () => { const addResource = vi.fn(); const onSubmit = vi.fn(); createWrapper({ addResource, addResourcesOpen: true, onSubmit }); - await user.type(screen.getByRole('textbox', { name: 'Resource location' }), 'http://example.com/iiif'); + await user.type( + screen.getByRole('textbox', { name: 'Resource location' }), + 'http://example.com/iiif', + ); await user.click(screen.getByRole('button', { name: 'Add' })); expect(addResource).toHaveBeenCalledWith('http://example.com/iiif'); diff --git a/__tests__/src/components/ManifestInfo.test.js b/__tests__/src/components/ManifestInfo.test.js index 3479e3a49..f4a8766a2 100644 --- a/__tests__/src/components/ManifestInfo.test.js +++ b/__tests__/src/components/ManifestInfo.test.js @@ -40,9 +40,7 @@ describe('ManifestInfo', () => { describe('when metadata is not present', () => { beforeEach(() => { - render( - , - ); + render(); }); it('does not render empty elements elements', () => { diff --git a/__tests__/src/components/ManifestListItem.test.js b/__tests__/src/components/ManifestListItem.test.js index fb032b9e4..2039bbcbd 100644 --- a/__tests__/src/components/ManifestListItem.test.js +++ b/__tests__/src/components/ManifestListItem.test.js @@ -37,7 +37,8 @@ describe('ManifestListItem', () => { const { container } = createWrapper({ ready: false }); expect(screen.queryByRole('button')).not.toBeInTheDocument(); - expect(container.querySelectorAll('.MuiSkeleton-rectangular').length).toBeGreaterThan(0); // eslint-disable-line testing-library/no-node-access, testing-library/no-container + // eslint-disable-next-line testing-library/no-node-access, testing-library/no-container + expect(container.querySelectorAll('.MuiSkeleton-rectangular').length).toBeGreaterThan(0); }); it('renders an error message if fetching the manifest failed', () => { createWrapper({ error: 'This is an error message' }); @@ -71,7 +72,9 @@ describe('ManifestListItem', () => { it('displays the provider information', () => { createWrapper({ provider: 'ACME' }); - expect(screen.getByText('ACME', { container: '.mirador-manifest-list-item-provider' })).toHaveTextContent('ACME'); + expect( + screen.getByText('ACME', { container: '.mirador-manifest-list-item-provider' }), + ).toHaveTextContent('ACME'); }); it('displays a collection label for collections', () => { diff --git a/__tests__/src/components/ManifestListItemError.test.js b/__tests__/src/components/ManifestListItemError.test.js index 237e1e3ed..67ecbed6f 100644 --- a/__tests__/src/components/ManifestListItemError.test.js +++ b/__tests__/src/components/ManifestListItemError.test.js @@ -4,7 +4,7 @@ import { ManifestListItemError } from '../../../src/components/ManifestListItemE /** * Helper function to wrap creating a ManifestListItemError component -*/ + */ function createWrapper(props) { return render( { it('renders manifest homepage information', () => { expect(screen.getByText('About this resource').tagName).toEqual('DT'); - expect(screen.getByRole('link', { name: 'Home page' })).toHaveAttribute('href', 'http://example.com/'); + expect(screen.getByRole('link', { name: 'Home page' })).toHaveAttribute( + 'href', + 'http://example.com/', + ); }); it('renders manifest renderings information', () => { expect(screen.getByText('Alternate formats').tagName).toEqual('DT'); - expect(screen.getByRole('link', { name: 'PDF Version' })).toHaveAttribute('href', 'http://example.com/pdf'); + expect(screen.getByRole('link', { name: 'PDF Version' })).toHaveAttribute( + 'href', + 'http://example.com/pdf', + ); }); it('renders related information', () => { expect(screen.getAllByText('Related')[1].tagName).toEqual('DT'); - expect(screen.getByRole('link', { name: 'http://example.com/related' })).toHaveAttribute('href', 'http://example.com/related'); - expect(screen.getByRole('link', { name: 'Video' })).toHaveAttribute('href', 'http://example.com/video'); + expect(screen.getByRole('link', { name: 'http://example.com/related' })).toHaveAttribute( + 'href', + 'http://example.com/related', + ); + expect(screen.getByRole('link', { name: 'Video' })).toHaveAttribute( + 'href', + 'http://example.com/video', + ); expect(screen.getByText('(video/ogg)')).toBeInTheDocument(); }); it('renders manifest seeAlso information', () => { expect(screen.getByText('See also').tagName).toEqual('DT'); - expect(screen.getByRole('link', { name: 'A' })).toHaveAttribute('href', 'http://example.com/a'); + expect(screen.getByRole('link', { name: 'A' })).toHaveAttribute( + 'href', + 'http://example.com/a', + ); expect(screen.getByText('(text/html)')).toBeInTheDocument(); - expect(screen.getByRole('link', { name: 'http://example.com/b' })).toHaveAttribute('href', 'http://example.com/b'); + expect(screen.getByRole('link', { name: 'http://example.com/b' })).toHaveAttribute( + 'href', + 'http://example.com/b', + ); }); it('renders manifest links', () => { expect(screen.getByText('IIIF manifest').tagName).toEqual('DT'); - expect(screen.getByRole('link', { name: 'http://example.com/' })).toHaveAttribute('href', 'http://example.com/'); + expect(screen.getByRole('link', { name: 'http://example.com/' })).toHaveAttribute( + 'href', + 'http://example.com/', + ); }); }); }); diff --git a/__tests__/src/components/MiradorMenuButton.test.js b/__tests__/src/components/MiradorMenuButton.test.js index 32eaa546b..fb8842685 100644 --- a/__tests__/src/components/MiradorMenuButton.test.js +++ b/__tests__/src/components/MiradorMenuButton.test.js @@ -4,7 +4,7 @@ import { MiradorMenuButton } from '../../../src/components/MiradorMenuButton'; /** * Helper function to wrap creating a MiradorMenuButton component -*/ + */ function createWrapper(props) { return render( diff --git a/__tests__/src/components/MosaicRenderPreview.test.js b/__tests__/src/components/MosaicRenderPreview.test.js index f47fbaa8c..e35999144 100644 --- a/__tests__/src/components/MosaicRenderPreview.test.js +++ b/__tests__/src/components/MosaicRenderPreview.test.js @@ -4,12 +4,7 @@ import { MosaicRenderPreview } from '../../../src/components/MosaicRenderPreview describe('MosaicRenderPreview', () => { it('it renders the given title prop passed through the t prop function', () => { - render( - , - ); + render(); expect(screen.getByRole('heading')).toHaveTextContent('The Title Prop'); }); diff --git a/__tests__/src/components/NestedMenu.test.js b/__tests__/src/components/NestedMenu.test.js index 1e48489d6..70a7605d8 100644 --- a/__tests__/src/components/NestedMenu.test.js +++ b/__tests__/src/components/NestedMenu.test.js @@ -4,14 +4,10 @@ import { NestedMenu } from '../../../src/components/NestedMenu'; /** * Helper function to wrap creating a NestedMenu component -*/ + */ function createWrapper(props) { return render( - + GivenChildren , ); diff --git a/__tests__/src/components/NewBrowserWindow.test.js b/__tests__/src/components/NewBrowserWindow.test.js index 24a7b4a7c..9a0db05ec 100644 --- a/__tests__/src/components/NewBrowserWindow.test.js +++ b/__tests__/src/components/NewBrowserWindow.test.js @@ -5,13 +5,7 @@ import { NewBrowserWindow } from '../../../src/components/NewBrowserWindow'; * Helper function to create a shallow wrapper around ErrorDialog */ function createWrapper(props) { - return render( - {}} - {...props} - />, - ); + return render( {}} {...props} />); } describe('NewBrowserWindow', () => { diff --git a/__tests__/src/components/OpenSeadragonTileSource.test.js b/__tests__/src/components/OpenSeadragonTileSource.test.js index d2798173e..2344c400e 100644 --- a/__tests__/src/components/OpenSeadragonTileSource.test.js +++ b/__tests__/src/components/OpenSeadragonTileSource.test.js @@ -26,7 +26,9 @@ describe('OpenSeadragonTileSource', () => { it('updates the opacity when the prop changes', async () => { const mockOsdItem = { setOpacity: vi.fn() }; const viewer = { - addTiledImage: vi.fn().mockImplementation(({ success }) => { success({ item: mockOsdItem }); }), + addTiledImage: vi.fn().mockImplementation(({ success }) => { + success({ item: mockOsdItem }); + }), world: { removeItem: vi.fn(), }, @@ -41,7 +43,8 @@ describe('OpenSeadragonTileSource', () => { , ); - await act(async () => { // eslint-disable-line testing-library/no-unnecessary-act + // eslint-disable-next-line testing-library/no-unnecessary-act + await act(async () => { rerender( @@ -58,7 +61,9 @@ describe('OpenSeadragonTileSource', () => { it('updates the index when the prop changes', async () => { const mockOsdItem = vi.fn(); const viewer = { - addTiledImage: vi.fn().mockImplementation(({ success }) => { success({ item: mockOsdItem }); }), + addTiledImage: vi.fn().mockImplementation(({ success }) => { + success({ item: mockOsdItem }); + }), world: { removeItem: vi.fn(), setItemIndex: vi.fn(), @@ -75,7 +80,8 @@ describe('OpenSeadragonTileSource', () => { , ); - await act(async () => { // eslint-disable-line testing-library/no-unnecessary-act + // eslint-disable-next-line testing-library/no-unnecessary-act + await act(async () => { rerender( @@ -92,7 +98,9 @@ describe('OpenSeadragonTileSource', () => { it('updates the rendered bounds when the prop changes', async () => { const mockOsdItem = { fitBounds: vi.fn() }; const viewer = { - addTiledImage: vi.fn().mockImplementation(({ success }) => { success({ item: mockOsdItem }); }), + addTiledImage: vi.fn().mockImplementation(({ success }) => { + success({ item: mockOsdItem }); + }), world: { removeItem: vi.fn(), setItemIndex: vi.fn(), @@ -109,7 +117,8 @@ describe('OpenSeadragonTileSource', () => { , ); - await act(async () => { // eslint-disable-line testing-library/no-unnecessary-act + // eslint-disable-next-line testing-library/no-unnecessary-act + await act(async () => { rerender( @@ -126,7 +135,9 @@ describe('OpenSeadragonTileSource', () => { it('deletes the item from the world when the item is unmounted', async () => { const mockOsdItem = vi.fn(); const viewer = { - addTiledImage: ({ success }) => { success({ item: mockOsdItem }); }, + addTiledImage: ({ success }) => { + success({ item: mockOsdItem }); + }, world: { removeItem: vi.fn(), }, @@ -142,7 +153,8 @@ describe('OpenSeadragonTileSource', () => { , ); - await act(async () => { // eslint-disable-line testing-library/no-unnecessary-act + // eslint-disable-next-line testing-library/no-unnecessary-act + await act(async () => { rerender( @@ -182,4 +194,4 @@ describe('OpenSeadragonTileSource', () => { expect(addTiledImage).toHaveBeenCalledTimes(2); expect(addTiledImage.mock.calls[1][0].tileSource.type).toBe('image'); }); -}); \ No newline at end of file +}); diff --git a/__tests__/src/components/OpenSeadragonViewer.test.js b/__tests__/src/components/OpenSeadragonViewer.test.js index 89e744016..a54a65cca 100644 --- a/__tests__/src/components/OpenSeadragonViewer.test.js +++ b/__tests__/src/components/OpenSeadragonViewer.test.js @@ -14,7 +14,11 @@ const canvases = Utils.parseManifest(fixture).getSequences()[0].getCanvases(); */ function createWrapper(props) { /** Stub child component for testing child props passing */ - const Child = ({ testId, zoomToWorld }) => ; + const Child = ({ testId, zoomToWorld }) => ( + + ); Child.propTypes = { testId: PropTypes.string.isRequired, zoomToWorld: PropTypes.func.isRequired, @@ -67,9 +71,16 @@ describe('OpenSeadragonViewer', () => { vi.spyOn(viewer, 'viewport', 'get').mockReturnValue({ fitBounds }); await user.click(screen.getByTestId('foo')); - expect(fitBounds).toHaveBeenCalledWith({ - degrees: 0, height: 1800, width: 5041, x: 0, y: 0, - }, expect.anything()); + expect(fitBounds).toHaveBeenCalledWith( + { + degrees: 0, + height: 1800, + width: 5041, + x: 0, + y: 0, + }, + expect.anything(), + ); }); }); @@ -89,12 +100,13 @@ describe('OpenSeadragonViewer', () => { viewer.raiseEvent('animation-finish'); - expect(updateViewport).toHaveBeenCalledWith( - 'base', - { - flip: false, rotation: 90, x: 1, y: 0, zoom: 0.5, - }, - ); + expect(updateViewport).toHaveBeenCalledWith('base', { + flip: false, + rotation: 90, + x: 1, + y: 0, + zoom: 0.5, + }); }); }); diff --git a/__tests__/src/components/PluginHook.test.js b/__tests__/src/components/PluginHook.test.js index e70e444d4..97eeed975 100644 --- a/__tests__/src/components/PluginHook.test.js +++ b/__tests__/src/components/PluginHook.test.js @@ -5,14 +5,10 @@ import { usePlugins } from '../../../src/extend/usePlugins'; vi.mock('../../../src/extend/usePlugins'); /** */ -const mockComponentA = () => ( -
-); +const mockComponentA = () =>
; /** */ -const mockComponentB = () => ( -
-); +const mockComponentB = () =>
; describe('WindowTopBarPluginArea', () => { it('renders nothing when no plugins passed', () => { @@ -31,11 +27,7 @@ describe('WindowTopBarPluginArea', () => { it('does not pass classes to PluginComponents (which will throw warnings for styles plugins)', () => { vi.mocked(usePlugins).mockReturnValue({ PluginComponents: [mockComponentA] }); - render( - , - ); + render(); // if called with nothing passed as args, .toHaveClass checks for existence of any classes expect(screen.getByTestId('testA')).not.toHaveClass(); }); diff --git a/__tests__/src/components/PrimaryWindow.test.js b/__tests__/src/components/PrimaryWindow.test.js index 9c0de369e..7dc9c5011 100644 --- a/__tests__/src/components/PrimaryWindow.test.js +++ b/__tests__/src/components/PrimaryWindow.test.js @@ -5,22 +5,19 @@ import { PrimaryWindow } from '../../../src/components/PrimaryWindow'; /** create wrapper */ function createWrapper(props) { - return render( - , - { preloadedState: { windows: { xyz: { collectionPath: [{}], companionWindowIds: [] } } } }, - ); + return render(, { + preloadedState: { windows: { xyz: { collectionPath: [{}], companionWindowIds: [] } } }, + }); } describe('PrimaryWindow', () => { it('should render expected elements', async () => { createWrapper({ isFetching: false }); await screen.findByTestId('test-window'); - expect(document.querySelector('.mirador-primary-window')).toBeInTheDocument(); // eslint-disable-line testing-library/no-node-access - expect(document.querySelector('.mirador-companion-area-left')).toBeInTheDocument(); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(document.querySelector('.mirador-primary-window')).toBeInTheDocument(); + // eslint-disable-next-line testing-library/no-node-access + expect(document.querySelector('.mirador-companion-area-left')).toBeInTheDocument(); }); it('should render children when available', () => { createWrapper({ children: hi, isFetching: false }); @@ -34,20 +31,15 @@ describe('PrimaryWindow', () => { createWrapper({ isFetching: false, view: 'gallery' }); await screen.findByTestId('test-window'); await waitFor(() => { - expect(document.querySelector('#xyz-gallery')).toBeInTheDocument(); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(document.querySelector('#xyz-gallery')).toBeInTheDocument(); }); }); it('should render and if manifest is collection and isCollectionDialogVisible', async () => { render(
); - render( - , - { preloadedState: { windows: { xyz: { collectionPath: [{}] } } } }, - ); + render(, { + preloadedState: { windows: { xyz: { collectionPath: [{}] } } }, + }); await screen.findByRole('button', { accessibleName: 'show collection' }); }); it('should render a TextViewer when window has textResources but not audio, video or image', async () => { @@ -65,16 +57,15 @@ describe('PrimaryWindow', () => { visibleCanvases: ['https://iiif.io/api/cookbook/recipe/0001-text-pdf/canvas'], }; - render( - , - { preloadedState: { manifests, windows: { xyz } } }, - ); + render(, { + preloadedState: { manifests, windows: { xyz } }, + }); await waitFor(() => { - expect(document.querySelector('source:nth-of-type(1)')).toHaveAttribute('type', 'application/pdf'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(document.querySelector('source:nth-of-type(1)')).toHaveAttribute( + 'type', + 'application/pdf', + ); }); }); }); diff --git a/__tests__/src/components/SanitizedHtml.test.js b/__tests__/src/components/SanitizedHtml.test.js index 940ba60be..f3278c418 100644 --- a/__tests__/src/components/SanitizedHtml.test.js +++ b/__tests__/src/components/SanitizedHtml.test.js @@ -24,8 +24,9 @@ describe('SanitizedHtml', () => { }); it('should pass sanitized html string to dangerouslySetInnerHTML attribute', () => { - expect(screen.getByTestId('subject').querySelector('script')).not.toBeInTheDocument(); // eslint-disable-line testing-library/no-node-access, testing-library/prefer-presence-queries - expect(screen.getByText('Don\'t worry!')).toBeInTheDocument(); + // eslint-disable-next-line testing-library/no-node-access, testing-library/prefer-presence-queries + expect(screen.getByTestId('subject').querySelector('script')).not.toBeInTheDocument(); + expect(screen.getByText("Don't worry!")).toBeInTheDocument(); expect(screen.getByText('Some link')).toHaveAttribute('target', '_blank'); expect(screen.getByText('Some link')).toHaveAttribute('rel', 'noopener noreferrer'); }); diff --git a/__tests__/src/components/ScrollIndicatedDialogContent.test.js b/__tests__/src/components/ScrollIndicatedDialogContent.test.js index c5d3c24d9..203b24697 100644 --- a/__tests__/src/components/ScrollIndicatedDialogContent.test.js +++ b/__tests__/src/components/ScrollIndicatedDialogContent.test.js @@ -3,12 +3,7 @@ import { ScrollIndicatedDialogContent } from '../../../src/components/ScrollIndi /** Utility function to wrap */ function createWrapper(props) { - return render( - , - ); + return render(); } describe('ScrollIndicatedDialogContent', () => { diff --git a/__tests__/src/components/ScrollTo.test.js b/__tests__/src/components/ScrollTo.test.js index da2cdcf13..29745cfbf 100644 --- a/__tests__/src/components/ScrollTo.test.js +++ b/__tests__/src/components/ScrollTo.test.js @@ -26,7 +26,11 @@ describe('ScrollTo', () => { }); it('renders the children', () => { - render(
); + render( + +
+ , + ); expect(screen.getByTestId('a')).toBeInTheDocument(); }); @@ -35,11 +39,29 @@ describe('ScrollTo', () => { const containerRef = createRef(); render( -
-
-
-
-
+
+
+ +
+ + +
+ + +
+
, ); @@ -51,11 +73,29 @@ describe('ScrollTo', () => { const containerRef = createRef(); render( -
-
-
-
-
+
+
+ +
+ + +
+ + +
+
, ); diff --git a/__tests__/src/components/SearchHit.test.js b/__tests__/src/components/SearchHit.test.js index 2c5911eac..d48185b50 100644 --- a/__tests__/src/components/SearchHit.test.js +++ b/__tests__/src/components/SearchHit.test.js @@ -2,12 +2,10 @@ import { render, screen } from '@tests/utils/test-utils'; import userEvent from '@testing-library/user-event'; import { SearchHit } from '../../../src/components/SearchHit'; -vi.mock( - '../../../src/components/ScrollTo', - () => ({ - ScrollTo: ({ children }) => (
{children}
), // eslint-disable-line react/prop-types - }), -); +vi.mock('../../../src/components/ScrollTo', () => ({ + // eslint-disable-next-line react/prop-types + ScrollTo: ({ children }) =>
{children}
, +})); /** * Helper function to create a shallow wrapper around SearchResults @@ -38,7 +36,9 @@ describe('SearchHit', () => { render(); expect(screen.getByRole('listitem')).toHaveClass('windowSelected'); - expect(screen.getByRole('listitem')).toHaveTextContent('1Light up the moose , and start the chai more'); + expect(screen.getByRole('listitem')).toHaveTextContent( + '1Light up the moose , and start the chai more', + ); await user.click(screen.getByRole('button')); expect(selectAnnotation).toHaveBeenCalledWith('foo'); diff --git a/__tests__/src/components/SearchPanel.test.js b/__tests__/src/components/SearchPanel.test.js index b211e4575..68493edbc 100644 --- a/__tests__/src/components/SearchPanel.test.js +++ b/__tests__/src/components/SearchPanel.test.js @@ -68,10 +68,15 @@ describe('SearchPanel', () => { const user = userEvent.setup(); const fetchSearch = vi.fn(); createWrapper({ - fetchSearch, query: '', suggestedSearches: ['abc'], t, + fetchSearch, + query: '', + suggestedSearches: ['abc'], + t, }); - expect(screen.getByRole('button', { name: 'Search this document for "abc"' })).toBeInTheDocument(); + expect( + screen.getByRole('button', { name: 'Search this document for "abc"' }), + ).toBeInTheDocument(); await user.click(screen.getByRole('button', { name: 'Search this document for "abc"' })); expect(fetchSearch).toHaveBeenCalledWith('http://example.com/search?q=abc', 'abc'); }); @@ -80,6 +85,8 @@ describe('SearchPanel', () => { const fetchSearch = vi.fn(); createWrapper({ fetchSearch, query: 'blah', suggestedSearches: ['abc'] }); - expect(screen.queryByRole('button', { name: 'Search this document for "abc"' })).not.toBeInTheDocument(); + expect( + screen.queryByRole('button', { name: 'Search this document for "abc"' }), + ).not.toBeInTheDocument(); }); }); diff --git a/__tests__/src/components/SearchPanelControls.test.js b/__tests__/src/components/SearchPanelControls.test.js index 0c9705eff..34fee4163 100644 --- a/__tests__/src/components/SearchPanelControls.test.js +++ b/__tests__/src/components/SearchPanelControls.test.js @@ -40,7 +40,12 @@ describe('SearchPanelControls', () => { await user.click(screen.getByRole('combobox')); await user.keyboard('somestring'); await user.click(await screen.findByText('somestring 12345')); - expect(fetchSearch).toHaveBeenCalledWith('window', 'cw', 'http://example.com/search?q=somestring+12345', 'somestring 12345'); + expect(fetchSearch).toHaveBeenCalledWith( + 'window', + 'cw', + 'http://example.com/search?q=somestring+12345', + 'somestring 12345', + ); fetch.resetMocks(); }); it('should fetch result only once', async () => { @@ -66,7 +71,8 @@ describe('SearchPanelControls', () => { }); it('endAdornment is a SearchIcon (with no CircularProgress indicator)', () => { createWrapper(); - expect(screen.getByRole('button').querySelector('svg')).toBeInTheDocument(); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(screen.getByRole('button').querySelector('svg')).toBeInTheDocument(); expect(screen.queryByRole('progressbar')).not.toBeInTheDocument(); }); @@ -89,7 +95,12 @@ describe('SearchPanelControls', () => { await user.keyboard('yolo'); await user.click(screen.getByRole('button')); - expect(fetchSearch).toHaveBeenCalledWith('window', 'cw', 'http://www.example.com/search?q=yolo', 'yolo'); + expect(fetchSearch).toHaveBeenCalledWith( + 'window', + 'cw', + 'http://www.example.com/search?q=yolo', + 'yolo', + ); }); it('does not submit an empty search', async () => { diff --git a/__tests__/src/components/SearchPanelNavigation.test.js b/__tests__/src/components/SearchPanelNavigation.test.js index 9da777818..92a1e6b10 100644 --- a/__tests__/src/components/SearchPanelNavigation.test.js +++ b/__tests__/src/components/SearchPanelNavigation.test.js @@ -7,12 +7,7 @@ import { SearchPanelNavigation } from '../../../src/components/SearchPanelNaviga */ function createWrapper(props) { return render( - , + , ); } diff --git a/__tests__/src/components/SearchResults.test.js b/__tests__/src/components/SearchResults.test.js index c9ffce0af..e6165871c 100644 --- a/__tests__/src/components/SearchResults.test.js +++ b/__tests__/src/components/SearchResults.test.js @@ -96,7 +96,9 @@ describe('SearchResults', () => { }); expect(screen.getByRole('heading', { level: 4, name: 'The Anno Label' })).toBeInTheDocument(); - expect(screen.getByRole('heading', { level: 4, name: 'Annother Anno Label' })).toBeInTheDocument(); + expect( + screen.getByRole('heading', { level: 4, name: 'Annother Anno Label' }), + ).toBeInTheDocument(); }); }); diff --git a/__tests__/src/components/SidebarIndexItem.test.js b/__tests__/src/components/SidebarIndexItem.test.js index 44ba2b8e4..b13432c78 100644 --- a/__tests__/src/components/SidebarIndexItem.test.js +++ b/__tests__/src/components/SidebarIndexItem.test.js @@ -3,13 +3,7 @@ import { SidebarIndexItem } from '../../../src/components/SidebarIndexItem'; /** */ function createWrapper(props) { - return render( - , - ); + return render(); } describe('SidebarIndexItem', () => { diff --git a/__tests__/src/components/SidebarIndexList.test.js b/__tests__/src/components/SidebarIndexList.test.js index ad2dc725d..b04629912 100644 --- a/__tests__/src/components/SidebarIndexList.test.js +++ b/__tests__/src/components/SidebarIndexList.test.js @@ -41,7 +41,8 @@ describe('SidebarIndexList', () => { expect(screen.getByRole('menuitem', { name: 'Image 1' })).toBeInTheDocument(); expect(screen.getByRole('menuitem', { name: 'Image 2' })).toBeInTheDocument(); - expect(container.querySelectorAll('img').length).toBe(3); // eslint-disable-line testing-library/no-node-access, testing-library/no-container + // eslint-disable-next-line testing-library/no-node-access, testing-library/no-container + expect(container.querySelectorAll('img').length).toBe(3); expect(screen.getByRole('menuitem', { name: 'Image 1' })).toHaveClass('Mui-selected'); }); @@ -58,6 +59,9 @@ describe('SidebarIndexList', () => { createWrapper({ setCanvas }); await user.click(screen.getByRole('menuitem', { name: 'Image 2' })); - expect(setCanvas).toHaveBeenCalledWith('xyz', 'https://purl.stanford.edu/rz176rt6531/iiif/canvas/rz176rt6531_1'); + expect(setCanvas).toHaveBeenCalledWith( + 'xyz', + 'https://purl.stanford.edu/rz176rt6531/iiif/canvas/rz176rt6531_1', + ); }); }); diff --git a/__tests__/src/components/SidebarIndexTableOfContents.test.js b/__tests__/src/components/SidebarIndexTableOfContents.test.js index 6c7174a39..42ff9fdb1 100644 --- a/__tests__/src/components/SidebarIndexTableOfContents.test.js +++ b/__tests__/src/components/SidebarIndexTableOfContents.test.js @@ -33,30 +33,23 @@ function createWrapper(props) { * write a reasonable test for it) */ function createInteractiveWrapper({ manifest = manifestVersion3, ...props }) { - return render( - , - { - preloadedState: { - companionWindows: { - something: { - id: 'something', - }, + return render(, { + preloadedState: { + companionWindows: { + something: { + id: 'something', }, - manifests: { - 'http://example.com/manifest.json': { - json: manifest, - }, - }, - windows: { - a: { manifestId: 'http://example.com/manifest.json' }, + }, + manifests: { + 'http://example.com/manifest.json': { + json: manifest, }, }, + windows: { + a: { manifestId: 'http://example.com/manifest.json' }, + }, }, - ); + }); } describe('SidebarIndexTableOfContents', () => { @@ -122,10 +115,12 @@ describe('SidebarIndexTableOfContents', () => { expect(screen.getByRole('treeitem')).toBeInTheDocument(); const root = screen.getByRole('treeitem'); - await user.click(root.querySelector('.MuiTreeItem-iconContainer')); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + await user.click(root.querySelector('.MuiTreeItem-iconContainer')); expect(screen.getAllByRole('treeitem')).toHaveLength(5); - await user.click(root.querySelector('.MuiTreeItem-iconContainer')); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + await user.click(root.querySelector('.MuiTreeItem-iconContainer')); await waitFor(() => { expect(screen.getByRole('treeitem')).toBeInTheDocument(); @@ -198,7 +193,7 @@ describe('SidebarIndexTableOfContents', () => { it('sets the canvas to a start canvas if present (IIIF v2)', async () => { const user = userEvent.setup(); createWrapper({ - expandItems: () => { }, + expandItems: () => {}, manifest: manifestVersion2, setCanvas, windowId: 'a', diff --git a/__tests__/src/components/SidebarIndexThumbnail.test.js b/__tests__/src/components/SidebarIndexThumbnail.test.js index b8ff1549a..614c64756 100644 --- a/__tests__/src/components/SidebarIndexThumbnail.test.js +++ b/__tests__/src/components/SidebarIndexThumbnail.test.js @@ -27,6 +27,7 @@ describe('SidebarIndexThumbnail', () => { it('contains a IIIFThumbnail', () => { const { container } = createWrapper(); - expect(container.querySelector('img')).toBeInTheDocument(); // eslint-disable-line testing-library/no-node-access, testing-library/no-container + // eslint-disable-next-line testing-library/no-node-access, testing-library/no-container + expect(container.querySelector('img')).toBeInTheDocument(); }); }); diff --git a/__tests__/src/components/TextViewer.test.js b/__tests__/src/components/TextViewer.test.js index 4dece398c..0ac2f2533 100644 --- a/__tests__/src/components/TextViewer.test.js +++ b/__tests__/src/components/TextViewer.test.js @@ -15,33 +15,41 @@ function createWrapper(props, suspenseFallback) { describe('TextViewer', () => { describe('render', () => { it('textResources as source elements', () => { - createWrapper({ - textResources: [ - { getFormat: () => 'application/pdf', getType: () => 'Text', id: 1 }, - ], - windowId: 'a', - }, true); + createWrapper( + { + textResources: [{ getFormat: () => 'application/pdf', getType: () => 'Text', id: 1 }], + windowId: 'a', + }, + true, + ); const text = screen.getByTestId('text'); - expect(text.querySelector('source:nth-of-type(1)')).toHaveAttribute('type', 'application/pdf'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(text.querySelector('source:nth-of-type(1)')).toHaveAttribute( + 'type', + 'application/pdf', + ); }); it('passes through configurable options', () => { - createWrapper({ - textResources: [ - { getFormat: () => 'application/pdf', getType: () => 'Text', id: 1 }, - ], - windowId: 'a', - }, true); + createWrapper( + { + textResources: [{ getFormat: () => 'application/pdf', getType: () => 'Text', id: 1 }], + windowId: 'a', + }, + true, + ); expect(screen.getByTestId('text')).toHaveAttribute('crossOrigin', 'anonymous'); }); it('canvas navigation', () => { - createWrapper({ - textResources: [ - { getFormat: () => 'application/pdf', getType: () => 'Text', id: 1 }, - ], - windowId: 'a', - }, true); + createWrapper( + { + textResources: [{ getFormat: () => 'application/pdf', getType: () => 'Text', id: 1 }], + windowId: 'a', + }, + true, + ); const text = screen.getByTestId('text'); - expect(text.querySelector('.mirador-canvas-nav')).toBeDefined(); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(text.querySelector('.mirador-canvas-nav')).toBeDefined(); }); }); }); diff --git a/__tests__/src/components/ThumbnailCanvasGrouping.test.js b/__tests__/src/components/ThumbnailCanvasGrouping.test.js index 6618e6e44..ba72ffb49 100644 --- a/__tests__/src/components/ThumbnailCanvasGrouping.test.js +++ b/__tests__/src/components/ThumbnailCanvasGrouping.test.js @@ -52,10 +52,13 @@ describe('ThumbnailCanvasGrouping', () => { wrapper.unmount(); const user = userEvent.setup(); wrapper = createWrapper({ index: 0, setCanvas }); - await user.click(wrapper.container.querySelector('.mirador-thumbnail-nav-canvas-0')); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + await user.click(wrapper.container.querySelector('.mirador-thumbnail-nav-canvas-0')); expect(spyCurrentCanvasClass).toHaveBeenCalledWith([0]); expect(spyCurrentCanvasClass).toHaveReturnedWith('current-canvas-grouping'); - expect(setCanvas).toHaveBeenCalledWith('http://iiif.io/api/presentation/2.0/example/fixtures/canvas/24/c1.json'); + expect(setCanvas).toHaveBeenCalledWith( + 'http://iiif.io/api/presentation/2.0/example/fixtures/canvas/24/c1.json', + ); }); describe('attributes based off far-bottom position', () => { it('in button div', () => { diff --git a/__tests__/src/components/ThumbnailNavigation.test.js b/__tests__/src/components/ThumbnailNavigation.test.js index 36c8daaa8..00a23ac38 100644 --- a/__tests__/src/components/ThumbnailNavigation.test.js +++ b/__tests__/src/components/ThumbnailNavigation.test.js @@ -27,7 +27,8 @@ function Subject({ fixture = manifestJson, ...props }) { } Subject.propTypes = { - fixture: PropTypes.object, // eslint-disable-line react/forbid-prop-types + // eslint-disable-next-line react/forbid-prop-types + fixture: PropTypes.object, }; describe('ThumbnailNavigation', () => { @@ -70,7 +71,11 @@ describe('ThumbnailNavigation', () => { expect(screen.getByLabelText('Thumbnails')).toHaveStyle({ height: '150px', width: '100%' }); rerender(); - expect(screen.getByLabelText('Thumbnails')).toHaveStyle({ height: '100%', minHeight: 0, width: '127px' }); + expect(screen.getByLabelText('Thumbnails')).toHaveStyle({ + height: '100%', + minHeight: 0, + width: '127px', + }); }); it('roughly doubles the width of the grid in book view', () => { @@ -117,21 +122,41 @@ describe('ThumbnailNavigation', () => { expect(setNextCanvas).toHaveBeenCalled(); }); it('handles down arrow by advancing the current canvas when the canvas is on the right', () => { - render(); + render( + , + ); screen.getByLabelText('Thumbnails').focus(); - fireEvent.keyDown(screen.getByLabelText('Thumbnails'), { code: 'ArrowDown', key: 'ArrowDown' }); + fireEvent.keyDown(screen.getByLabelText('Thumbnails'), { + code: 'ArrowDown', + key: 'ArrowDown', + }); expect(setNextCanvas).toHaveBeenCalled(); }); it('handles left arrow by selecting the previous canvas', () => { render(); screen.getByLabelText('Thumbnails').focus(); - fireEvent.keyDown(screen.getByLabelText('Thumbnails'), { code: 'ArrowLeft', key: 'ArrowLeft' }); + fireEvent.keyDown(screen.getByLabelText('Thumbnails'), { + code: 'ArrowLeft', + key: 'ArrowLeft', + }); expect(setPreviousCanvas).toHaveBeenCalled(); }); it('handles up arrow by selecting the previous canvas when the canvas is on the right', () => { - render(); + render( + , + ); screen.getByLabelText('Thumbnails').focus(); fireEvent.keyDown(screen.getByLabelText('Thumbnails'), { code: 'ArrowUp', key: 'ArrowUp' }); @@ -144,7 +169,8 @@ describe('ThumbnailNavigation', () => { it('sets up react-window to be rtl', () => { render(); - expect(screen.getByRole('row').children[0]).toHaveStyle({ direction: 'rtl' }); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(screen.getByRole('row').children[0]).toHaveStyle({ direction: 'rtl' }); }); }); }); diff --git a/__tests__/src/components/VideoViewer.test.js b/__tests__/src/components/VideoViewer.test.js index 75055c740..ad6f59fe1 100644 --- a/__tests__/src/components/VideoViewer.test.js +++ b/__tests__/src/components/VideoViewer.test.js @@ -15,39 +15,50 @@ function createWrapper(props, suspenseFallback) { describe('VideoViewer', () => { describe('render', () => { it('videoResources', () => { - createWrapper({ - videoResources: [ - { getFormat: () => 'video/mp4', id: 1 }, - { getFormat: () => 'video/mp4', id: 2 }, - ], - }, true); + createWrapper( + { + videoResources: [ + { getFormat: () => 'video/mp4', id: 1 }, + { getFormat: () => 'video/mp4', id: 2 }, + ], + }, + true, + ); const video = screen.getByTestId('video'); - expect(video.querySelector('source:nth-of-type(1)')).toHaveAttribute('type', 'video/mp4'); // eslint-disable-line testing-library/no-node-access - expect(video.querySelector('source:nth-of-type(2)')).toHaveAttribute('type', 'video/mp4'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(video.querySelector('source:nth-of-type(1)')).toHaveAttribute('type', 'video/mp4'); + // eslint-disable-next-line testing-library/no-node-access + expect(video.querySelector('source:nth-of-type(2)')).toHaveAttribute('type', 'video/mp4'); }); it('passes through configurable options', () => { - createWrapper({ - videoResources: [ - { getFormat: () => 'video/mp4', id: 1 }, - ], - }, true); + createWrapper( + { + videoResources: [{ getFormat: () => 'video/mp4', id: 1 }], + }, + true, + ); expect(screen.getByTestId('video')).toHaveAttribute('crossOrigin', 'anonymous'); }); it('captions', () => { - createWrapper({ - captions: [ - { getDefaultLabel: () => 'English', getProperty: () => 'en', id: 1 }, - { getDefaultLabel: () => 'French', getProperty: () => 'fr', id: 2 }, - ], - videoResources: [ - { getFormat: () => 'video/mp4', id: 1 }, - ], - }, true); + createWrapper( + { + captions: [ + { getDefaultLabel: () => 'English', getProperty: () => 'en', id: 1 }, + { getDefaultLabel: () => 'French', getProperty: () => 'fr', id: 2 }, + ], + videoResources: [{ getFormat: () => 'video/mp4', id: 1 }], + }, + true, + ); const video = screen.getByTestId('video'); - expect(video.querySelector('track:nth-of-type(1)')).toHaveAttribute('srcLang', 'en'); // eslint-disable-line testing-library/no-node-access - expect(video.querySelector('track:nth-of-type(1)')).toHaveAttribute('label', 'English'); // eslint-disable-line testing-library/no-node-access - expect(video.querySelector('track:nth-of-type(2)')).toHaveAttribute('srcLang', 'fr'); // eslint-disable-line testing-library/no-node-access - expect(video.querySelector('track:nth-of-type(2)')).toHaveAttribute('label', 'French'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(video.querySelector('track:nth-of-type(1)')).toHaveAttribute('srcLang', 'en'); + // eslint-disable-next-line testing-library/no-node-access + expect(video.querySelector('track:nth-of-type(1)')).toHaveAttribute('label', 'English'); + // eslint-disable-next-line testing-library/no-node-access + expect(video.querySelector('track:nth-of-type(2)')).toHaveAttribute('srcLang', 'fr'); + // eslint-disable-next-line testing-library/no-node-access + expect(video.querySelector('track:nth-of-type(2)')).toHaveAttribute('label', 'French'); }); }); }); diff --git a/__tests__/src/components/ViewerInfo.test.js b/__tests__/src/components/ViewerInfo.test.js index 863d7a545..edb22e8c7 100644 --- a/__tests__/src/components/ViewerInfo.test.js +++ b/__tests__/src/components/ViewerInfo.test.js @@ -4,13 +4,7 @@ import { ViewerInfo } from '../../../src/components/ViewerInfo'; /** create wrapper */ function createWrapper(props) { return render( - , + , ); } diff --git a/__tests__/src/components/ViewerNavigation.test.js b/__tests__/src/components/ViewerNavigation.test.js index b108b434c..53342ee04 100644 --- a/__tests__/src/components/ViewerNavigation.test.js +++ b/__tests__/src/components/ViewerNavigation.test.js @@ -4,13 +4,7 @@ import { ViewerNavigation } from '../../../src/components/ViewerNavigation'; /** create wrapper */ function createWrapper(props) { - return render( - , - ); + return render(); } describe('ViewerNavigation', () => { @@ -28,7 +22,8 @@ describe('ViewerNavigation', () => { setPreviousCanvas, }); const buttons = screen.queryAllByRole('button'); - expect(buttons[0].closest('div')).toBeInTheDocument(); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(buttons[0].closest('div')).toBeInTheDocument(); }); describe('when next canvases are present', () => { it('nextCanvas button is not disabled', () => { @@ -107,8 +102,14 @@ describe('ViewerNavigation', () => { setPreviousCanvas, viewingDirection: 'right-to-left', }); - expect(screen.getByRole('button', { name: 'Previous item' }).querySelector('svg')).not.toHaveStyle('transform: rotate(180deg);'); // eslint-disable-line testing-library/no-node-access - expect(screen.getByRole('button', { name: 'Next item' }).querySelector('svg')).toHaveStyle('transform: rotate(180deg);'); // eslint-disable-line testing-library/no-node-access + expect( + // eslint-disable-next-line testing-library/no-node-access + screen.getByRole('button', { name: 'Previous item' }).querySelector('svg'), + ).not.toHaveStyle('transform: rotate(180deg);'); + // eslint-disable-next-line testing-library/no-node-access + expect(screen.getByRole('button', { name: 'Next item' }).querySelector('svg')).toHaveStyle( + 'transform: rotate(180deg);', + ); }); it('sets the dir="rtl"', () => { @@ -120,7 +121,8 @@ describe('ViewerNavigation', () => { viewingDirection: 'right-to-left', }); const buttons = screen.queryAllByRole('button'); - expect(buttons[0].closest('div')).toHaveAttribute('dir', 'rtl'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(buttons[0].closest('div')).toHaveAttribute('dir', 'rtl'); }); }); @@ -133,8 +135,14 @@ describe('ViewerNavigation', () => { setPreviousCanvas, viewingDirection: 'top-to-bottom', }); - expect(screen.getByRole('button', { name: 'Previous item' }).querySelector('svg')).toHaveStyle('transform: rotate(270deg);'); // eslint-disable-line testing-library/no-node-access - expect(screen.getByRole('button', { name: 'Next item' }).querySelector('svg')).toHaveStyle('transform: rotate(90deg);'); // eslint-disable-line testing-library/no-node-access + expect( + // eslint-disable-next-line testing-library/no-node-access + screen.getByRole('button', { name: 'Previous item' }).querySelector('svg'), + ).toHaveStyle('transform: rotate(270deg);'); + // eslint-disable-next-line testing-library/no-node-access + expect(screen.getByRole('button', { name: 'Next item' }).querySelector('svg')).toHaveStyle( + 'transform: rotate(90deg);', + ); }); }); describe('when viewingDirection is bottom-to-top', () => { @@ -146,8 +154,14 @@ describe('ViewerNavigation', () => { setPreviousCanvas, viewingDirection: 'bottom-to-top', }); - expect(screen.getByRole('button', { name: 'Previous item' }).querySelector('svg')).toHaveStyle('transform: rotate(90deg);'); // eslint-disable-line testing-library/no-node-access - expect(screen.getByRole('button', { name: 'Next item' }).querySelector('svg')).toHaveStyle('transform: rotate(270deg);'); // eslint-disable-line testing-library/no-node-access + expect( + // eslint-disable-next-line testing-library/no-node-access + screen.getByRole('button', { name: 'Previous item' }).querySelector('svg'), + ).toHaveStyle('transform: rotate(90deg);'); + // eslint-disable-next-line testing-library/no-node-access + expect(screen.getByRole('button', { name: 'Next item' }).querySelector('svg')).toHaveStyle( + 'transform: rotate(270deg);', + ); }); }); }); diff --git a/__tests__/src/components/Window.test.js b/__tests__/src/components/Window.test.js index 5e8160376..ddcb9d0cd 100644 --- a/__tests__/src/components/Window.test.js +++ b/__tests__/src/components/Window.test.js @@ -6,12 +6,7 @@ import { Window } from '../../../src/components/Window'; /** create wrapper */ function createWrapper(props, state, renderOptions) { return render( - , + , { preloadedState: { windows: { @@ -33,11 +28,14 @@ describe('Window', () => { }); it('should render ', () => { createWrapper(); - expect(screen.getByRole('navigation', { accessibleName: 'Window navigation' })).toBeInTheDocument(); + expect( + screen.getByRole('navigation', { accessibleName: 'Window navigation' }), + ).toBeInTheDocument(); }); it('should render ', () => { createWrapper(); - expect(document.querySelector('.mirador-primary-window')).toBeInTheDocument(); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(document.querySelector('.mirador-primary-window')).toBeInTheDocument(); }); // See ErrorContent.test.js for futher testing of this functionality it('renders alert box when there is an error', async () => { @@ -46,7 +44,7 @@ describe('Window', () => { }); describe('when workspaceType is mosaic', () => { it('calls the context mosaicWindowActions connectDragSource method to make WindowTopBar draggable', () => { - const connectDragSource = vi.fn(component => component); + const connectDragSource = vi.fn((component) => component); render( { expect(connectDragSource).toHaveBeenCalled(); }); it('does not call the context mosaicWindowActions connectDragSource when the windowDraggable is set to false', () => { - const connectDragSource = vi.fn(component => component); + const connectDragSource = vi.fn((component) => component); render( { expect(screen.getByLabelText('Previous item', { selector: 'button' })).toBeInTheDocument(); expect(screen.getByLabelText('Next item', { selector: 'button' })).toBeInTheDocument(); expect(screen.getByText(/1 of/)).toBeInTheDocument(); - expect(container.firstChild).not.toHaveClass('mirador-canvas-nav-stacked'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(container.firstChild).not.toHaveClass('mirador-canvas-nav-stacked'); }); it('renders only a screen-reader accessibile version when visible=false', () => { const { container } = render(); - expect(container.firstChild).toHaveStyle({ height: '1px', margin: '-1px', width: '1px' }); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(container.firstChild).toHaveStyle({ height: '1px', margin: '-1px', width: '1px' }); }); it.skip('stacks the nav controls on small width screens', () => { - const { container } = render(
); - expect(container.firstChild).toHaveClass('mirador-canvas-nav-stacked'); // eslint-disable-line testing-library/no-node-access + const { container } = render( +
+ +
, + ); + // eslint-disable-next-line testing-library/no-node-access + expect(container.firstChild).toHaveClass('mirador-canvas-nav-stacked'); }); it('shows the zoom control component when specified', () => { diff --git a/__tests__/src/components/WindowListButton.test.js b/__tests__/src/components/WindowListButton.test.js index 399051556..8ce6221b2 100644 --- a/__tests__/src/components/WindowListButton.test.js +++ b/__tests__/src/components/WindowListButton.test.js @@ -7,20 +7,18 @@ import { WindowListButton } from '../../../src/components/WindowListButton'; * Helper function to create a shallow wrapper around WindowListButton */ function createWrapper(props) { - return render( - , - { preloadedState: { workspace: { windowIds: ['abc123'] } } }, - ); + return render(, { + preloadedState: { workspace: { windowIds: ['abc123'] } }, + }); } describe('WindowListButton', () => { it('shows the window count as a badge on the button', () => { createWrapper(); - expect(within(screen.getByRole('button')).getByText('3', { container: '.MuiBadge-badge' })).toBeInTheDocument(); + expect( + within(screen.getByRole('button')).getByText('3', { container: '.MuiBadge-badge' }), + ).toBeInTheDocument(); }); it('disabled the MiradorMenuButton if the disabled prop is true', () => { @@ -34,10 +32,14 @@ describe('WindowListButton', () => { createWrapper(); await user.click(screen.getByRole('button')); - expect(screen.getByText('Current open windows', { container: '.MuiListSubheader-root' })).toBeInTheDocument(); + expect( + screen.getByText('Current open windows', { container: '.MuiListSubheader-root' }), + ).toBeInTheDocument(); await user.click(screen.getByRole('menuitem', { name: '[Untitled]' })); - expect(screen.queryByText('Current open windows', { container: '.MuiListSubheader-root' })).not.toBeInTheDocument(); + expect( + screen.queryByText('Current open windows', { container: '.MuiListSubheader-root' }), + ).not.toBeInTheDocument(); }); }); diff --git a/__tests__/src/components/WindowSideBar.test.js b/__tests__/src/components/WindowSideBar.test.js index e8e1db11b..e428551fb 100644 --- a/__tests__/src/components/WindowSideBar.test.js +++ b/__tests__/src/components/WindowSideBar.test.js @@ -3,41 +3,45 @@ import { WindowSideBar } from '../../../src/components/WindowSideBar'; /** create wrapper */ function createWrapper({ ...props }) { - return render( - , - { - preloadedState: { - windows: { - xyz: { - companionWindowIds: [], - suggestedSearches: null, - }, + return render(, { + preloadedState: { + windows: { + xyz: { + companionWindowIds: [], + suggestedSearches: null, }, }, }, - ); + }); } describe('WindowSideBar when closed', () => { it('renders without an error', () => { createWrapper({}); - expect(screen.queryByRole('navigation', { accessibleName: 'sidebarPanelsNavigation' })).not.toBeInTheDocument(); + expect( + screen.queryByRole('navigation', { accessibleName: 'sidebarPanelsNavigation' }), + ).not.toBeInTheDocument(); }); }); describe('WindowSideBar when open', () => { it('renders in an open state', () => { createWrapper({ sideBarOpen: true }); - expect(screen.getByRole('navigation', { accessibleName: 'sidebarPanelsNavigation' })).toBeInTheDocument(); + expect( + screen.getByRole('navigation', { accessibleName: 'sidebarPanelsNavigation' }), + ).toBeInTheDocument(); }); it('Renders drawer ltr by default', () => { createWrapper({ sideBarOpen: true }); - expect(screen.queryByRole('navigation', { accessibleName: 'sidebarPanelsNavigation' })).toHaveClass('MuiDrawer-paperAnchorLeft'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect( + screen.queryByRole('navigation', { accessibleName: 'sidebarPanelsNavigation' }), + ).toHaveClass('MuiDrawer-paperAnchorLeft'); }); it('Renders drawer rtl when specified', () => { createWrapper({ direction: 'rtl', sideBarOpen: true }); - expect(screen.queryByRole('navigation', { accessibleName: 'sidebarPanelsNavigation' })).toHaveClass('MuiDrawer-paperAnchorRight'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect( + screen.queryByRole('navigation', { accessibleName: 'sidebarPanelsNavigation' }), + ).toHaveClass('MuiDrawer-paperAnchorRight'); }); }); diff --git a/__tests__/src/components/WindowSideBarAnnotationsPanel.test.js b/__tests__/src/components/WindowSideBarAnnotationsPanel.test.js index 0f67d2ea1..55580cd3e 100644 --- a/__tests__/src/components/WindowSideBarAnnotationsPanel.test.js +++ b/__tests__/src/components/WindowSideBarAnnotationsPanel.test.js @@ -12,7 +12,13 @@ function createWrapper(props, state) { windowId="abc" {...props} />, - { preloadedState: { companionWindows: { xyz: { content: 'annotations' } }, windows: { abc: {} }, ...state } }, + { + preloadedState: { + companionWindows: { xyz: { content: 'annotations' } }, + windows: { abc: {} }, + ...state, + }, + }, ); } diff --git a/__tests__/src/components/WindowSideBarCanvasPanel.test.js b/__tests__/src/components/WindowSideBarCanvasPanel.test.js index d0fcdb79f..9ec8605ca 100644 --- a/__tests__/src/components/WindowSideBarCanvasPanel.test.js +++ b/__tests__/src/components/WindowSideBarCanvasPanel.test.js @@ -13,8 +13,10 @@ function createWrapper(props) { let sequences; if (props.multipleSequences) { - sequences = [{ getLabel: () => ({ getValue: () => undefined }), id: 'a', label: 'seq1' }, - { getLabel: () => ({ getValue: () => undefined }), id: 'b', label: 'seq2' }]; + sequences = [ + { getLabel: () => ({ getValue: () => undefined }), id: 'a', label: 'seq1' }, + { getLabel: () => ({ getValue: () => undefined }), id: 'b', label: 'seq2' }, + ]; } else { sequences = Utils.parseManifest(manifestJson).getSequences(); } diff --git a/__tests__/src/components/WindowSideBarInfoPanel.test.js b/__tests__/src/components/WindowSideBarInfoPanel.test.js index 77439f351..b14aff19a 100644 --- a/__tests__/src/components/WindowSideBarInfoPanel.test.js +++ b/__tests__/src/components/WindowSideBarInfoPanel.test.js @@ -4,14 +4,9 @@ import { WindowSideBarInfoPanel } from '../../../src/components/WindowSideBarInf /** create wrapper */ function createWrapper(props) { - return render( - , - { preloadedState: { companionWindows: { asdf: { content: 'info' } } } }, - ); + return render(, { + preloadedState: { companionWindows: { asdf: { content: 'info' } } }, + }); } describe('WindowSideBarInfoPanel', () => { describe('when metadata is present', () => { diff --git a/__tests__/src/components/WindowThumbnailSettings.test.js b/__tests__/src/components/WindowThumbnailSettings.test.js index 9112981a1..0782bd7e7 100644 --- a/__tests__/src/components/WindowThumbnailSettings.test.js +++ b/__tests__/src/components/WindowThumbnailSettings.test.js @@ -26,15 +26,33 @@ describe('WindowThumbnailSettings', () => { }); it('for far-bottom it should set the correct label active (by setting the secondary color)', () => { createWrapper({ thumbnailNavigationPosition: 'far-bottom' }); - expect(screen.getByRole('menuitemradio', { name: /Bottom/ }).querySelector('svg')).toHaveClass('MuiSvgIcon-colorSecondary'); // eslint-disable-line testing-library/no-node-access - expect(screen.getByRole('menuitemradio', { name: /Right/ }).querySelector('svg')).not.toHaveClass('MuiSvgIcon-colorSecondary'); // eslint-disable-line testing-library/no-node-access - expect(screen.getByRole('menuitemradio', { name: /Off/ }).querySelector('svg')).not.toHaveClass('MuiSvgIcon-colorSecondary'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(screen.getByRole('menuitemradio', { name: /Bottom/ }).querySelector('svg')).toHaveClass( + 'MuiSvgIcon-colorSecondary', + ); + expect( + // eslint-disable-next-line testing-library/no-node-access + screen.getByRole('menuitemradio', { name: /Right/ }).querySelector('svg'), + ).not.toHaveClass('MuiSvgIcon-colorSecondary'); + // eslint-disable-next-line testing-library/no-node-access + expect(screen.getByRole('menuitemradio', { name: /Off/ }).querySelector('svg')).not.toHaveClass( + 'MuiSvgIcon-colorSecondary', + ); }); it('for far-right it should set the correct label active (by setting the secondary color)', () => { createWrapper({ thumbnailNavigationPosition: 'far-right' }); - expect(screen.getByRole('menuitemradio', { name: /Right/ }).querySelector('svg')).toHaveClass('MuiSvgIcon-colorSecondary'); // eslint-disable-line testing-library/no-node-access - expect(screen.getByRole('menuitemradio', { name: /Off/ }).querySelector('svg')).not.toHaveClass('MuiSvgIcon-colorSecondary'); // eslint-disable-line testing-library/no-node-access - expect(screen.getByRole('menuitemradio', { name: /Bottom/ }).querySelector('svg')).not.toHaveClass('MuiSvgIcon-colorSecondary'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(screen.getByRole('menuitemradio', { name: /Right/ }).querySelector('svg')).toHaveClass( + 'MuiSvgIcon-colorSecondary', + ); + // eslint-disable-next-line testing-library/no-node-access + expect(screen.getByRole('menuitemradio', { name: /Off/ }).querySelector('svg')).not.toHaveClass( + 'MuiSvgIcon-colorSecondary', + ); + expect( + // eslint-disable-next-line testing-library/no-node-access + screen.getByRole('menuitemradio', { name: /Bottom/ }).querySelector('svg'), + ).not.toHaveClass('MuiSvgIcon-colorSecondary'); }); it('updates state when the thumbnail config selection changes', async () => { @@ -57,6 +75,9 @@ describe('WindowThumbnailSettings', () => { it('when rtl flips an icon', () => { createWrapper({ direction: 'rtl' }); - expect(screen.getByRole('menuitemradio', { name: /Right/ }).querySelector('svg')).toHaveStyle('transform: rotate(180deg);'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(screen.getByRole('menuitemradio', { name: /Right/ }).querySelector('svg')).toHaveStyle( + 'transform: rotate(180deg);', + ); }); }); diff --git a/__tests__/src/components/WindowTopBar.test.js b/__tests__/src/components/WindowTopBar.test.js index 5522ac0d6..8026a8226 100644 --- a/__tests__/src/components/WindowTopBar.test.js +++ b/__tests__/src/components/WindowTopBar.test.js @@ -32,22 +32,28 @@ describe('WindowTopBar', () => { render(); expect(screen.getByRole('navigation', { name: 'Window navigation' })).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Toggle sidebar' })).toBeInTheDocument(); - expect(screen.getByRole('button', { name: 'Window views & thumbnail display' })).toBeInTheDocument(); + expect( + screen.getByRole('button', { name: 'Window views & thumbnail display' }), + ).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Maximize window' })).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Close window' })).toBeInTheDocument(); expect(screen.queryByRole('button', { name: 'Full screen' })).not.toBeInTheDocument(); }); it('uses allow flags to override defaults', () => { - render(); + render( + , + ); expect(screen.queryByRole('button', { name: 'Toggle sidebar' })).not.toBeInTheDocument(); - expect(screen.queryByRole('button', { name: 'Window views & thumbnail display' })).not.toBeInTheDocument(); + expect( + screen.queryByRole('button', { name: 'Window views & thumbnail display' }), + ).not.toBeInTheDocument(); expect(screen.queryByRole('button', { name: 'Maximize window' })).not.toBeInTheDocument(); expect(screen.queryByRole('button', { name: 'Close window' })).not.toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Full screen' })).toBeInTheDocument(); @@ -56,7 +62,8 @@ describe('WindowTopBar', () => { it('triggers window focus when clicked', () => { const focusWindow = vi.fn(); render(); - const toolbar = screen.getByRole('navigation', { name: 'Window navigation' }).firstChild; // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + const toolbar = screen.getByRole('navigation', { name: 'Window navigation' }).firstChild; expect(toolbar).toBeInTheDocument(); // we specifically need mouseDown not click for MUI Toolbar here fireEvent.mouseDown(toolbar); @@ -65,10 +72,9 @@ describe('WindowTopBar', () => { it('passes correct callback to toggleWindowSideBar button', async () => { const toggleWindowSideBar = vi.fn(); - render( - , - { preloadedState: { windows: { xyz: { sideBarOpen: false } } } }, - ); + render(, { + preloadedState: { windows: { xyz: { sideBarOpen: false } } }, + }); const button = screen.getByRole('button', { name: 'Toggle sidebar' }); expect(button).toBeInTheDocument(); await user.click(button); diff --git a/__tests__/src/components/WindowTopBarPluginArea.test.js b/__tests__/src/components/WindowTopBarPluginArea.test.js index 231bc2cd5..768604314 100644 --- a/__tests__/src/components/WindowTopBarPluginArea.test.js +++ b/__tests__/src/components/WindowTopBarPluginArea.test.js @@ -5,9 +5,7 @@ import { usePlugins } from '../../../src/extend/usePlugins'; vi.mock('../../../src/extend/usePlugins'); /** */ -const mockComponent = () => ( -
-); +const mockComponent = () =>
; describe('WindowTopBarPluginArea', () => { it('renders the component', () => { diff --git a/__tests__/src/components/WindowTopBarPluginMenu.test.js b/__tests__/src/components/WindowTopBarPluginMenu.test.js index cf9deca90..1fb3205b3 100644 --- a/__tests__/src/components/WindowTopBarPluginMenu.test.js +++ b/__tests__/src/components/WindowTopBarPluginMenu.test.js @@ -9,21 +9,14 @@ vi.mock('../../../src/extend/usePlugins'); /** create wrapper */ function Subject({ ...props }) { - return ( - - ); + return ; } // needs to be a non-functional component to accept forwardRef the way we have it set up /** */ class mockComponentA extends React.Component { /** */ render() { - return ( -
- ); + return
; } } diff --git a/__tests__/src/components/WindowTopBarTitle.test.js b/__tests__/src/components/WindowTopBarTitle.test.js index 9e10ead69..8323d440c 100644 --- a/__tests__/src/components/WindowTopBarTitle.test.js +++ b/__tests__/src/components/WindowTopBarTitle.test.js @@ -5,12 +5,7 @@ import { WindowTopBarTitle } from '../../../src/components/WindowTopBarTitle'; /** create wrapper */ function createWrapper(props) { return render( - , + , ); } diff --git a/__tests__/src/components/WindowTopMenu.test.js b/__tests__/src/components/WindowTopMenu.test.js index f023e06cf..61efcb1ff 100644 --- a/__tests__/src/components/WindowTopMenu.test.js +++ b/__tests__/src/components/WindowTopMenu.test.js @@ -20,7 +20,9 @@ function Subject({ ...props }) { /** create anchor element */ function createAnchor() { return render( - , + , ); } @@ -63,12 +65,14 @@ describe('WindowTopMenu', () => { const toggleDraggingEnabled = vi.fn(); const anchorEl = screen.getByTestId('menu-trigger-button'); - render(); + render( + , + ); // click a menu item should close the menu const menuItems = screen.getAllByRole('menuitemradio'); diff --git a/__tests__/src/components/WindowTopMenuButton.test.js b/__tests__/src/components/WindowTopMenuButton.test.js index 3a85f88bc..ec866de95 100644 --- a/__tests__/src/components/WindowTopMenuButton.test.js +++ b/__tests__/src/components/WindowTopMenuButton.test.js @@ -40,13 +40,17 @@ describe('WindowTopMenuButton', () => { it('the open attribute of the button is null without being clicked', async () => { render(); // without a click, the button is not open and therefore doesn't have aria-owns attr - expect(screen.getByLabelText('Window views & thumbnail display')).not.toHaveAttribute('aria-owns'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(screen.getByLabelText('Window views & thumbnail display')).not.toHaveAttribute( + 'aria-owns', + ); }); it('the open attribute of the button is applied once it is clicked', async () => { render(); await user.click(screen.getByLabelText('Window views & thumbnail display')); // when 'open' is true, aria-owns is set to the id of the window - expect(screen.getByLabelText('Window views & thumbnail display')).toHaveAttribute('aria-owns'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(screen.getByLabelText('Window views & thumbnail display')).toHaveAttribute('aria-owns'); }); }); diff --git a/__tests__/src/components/WindowViewSettings.test.js b/__tests__/src/components/WindowViewSettings.test.js index 80e0cc627..84e774384 100644 --- a/__tests__/src/components/WindowViewSettings.test.js +++ b/__tests__/src/components/WindowViewSettings.test.js @@ -29,23 +29,47 @@ describe('WindowViewSettings', () => { }); it('single should set the correct label active (by setting the secondary color)', () => { createWrapper({ windowViewType: 'single' }); - expect(screen.getByRole('menuitemradio', { name: /Single/ }).querySelector('svg')).toHaveClass('MuiSvgIcon-colorSecondary'); // eslint-disable-line testing-library/no-node-access - expect(screen.getByRole('menuitemradio', { name: /Book/ }).querySelector('svg')).not.toHaveClass('MuiSvgIcon-colorSecondary'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(screen.getByRole('menuitemradio', { name: /Single/ }).querySelector('svg')).toHaveClass( + 'MuiSvgIcon-colorSecondary', + ); + expect( + // eslint-disable-next-line testing-library/no-node-access + screen.getByRole('menuitemradio', { name: /Book/ }).querySelector('svg'), + ).not.toHaveClass('MuiSvgIcon-colorSecondary'); }); it('book should set the correct label active (by setting the secondary color)', () => { createWrapper({ windowViewType: 'book' }); - expect(screen.getByRole('menuitemradio', { name: /Book/ }).querySelector('svg')).toHaveClass('MuiSvgIcon-colorSecondary'); // eslint-disable-line testing-library/no-node-access - expect(screen.getByRole('menuitemradio', { name: /Single/ }).querySelector('svg')).not.toHaveClass('MuiSvgIcon-colorSecondary'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(screen.getByRole('menuitemradio', { name: /Book/ }).querySelector('svg')).toHaveClass( + 'MuiSvgIcon-colorSecondary', + ); + expect( + // eslint-disable-next-line testing-library/no-node-access + screen.getByRole('menuitemradio', { name: /Single/ }).querySelector('svg'), + ).not.toHaveClass('MuiSvgIcon-colorSecondary'); }); it('scroll should set the correct label active (by setting the secondary color)', () => { createWrapper({ windowViewType: 'scroll' }); - expect(screen.getByRole('menuitemradio', { name: /Scroll/ }).querySelector('svg')).toHaveClass('MuiSvgIcon-colorSecondary'); // eslint-disable-line testing-library/no-node-access - expect(screen.getByRole('menuitemradio', { name: /Single/ }).querySelector('svg')).not.toHaveClass('MuiSvgIcon-colorSecondary'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(screen.getByRole('menuitemradio', { name: /Scroll/ }).querySelector('svg')).toHaveClass( + 'MuiSvgIcon-colorSecondary', + ); + expect( + // eslint-disable-next-line testing-library/no-node-access + screen.getByRole('menuitemradio', { name: /Single/ }).querySelector('svg'), + ).not.toHaveClass('MuiSvgIcon-colorSecondary'); }); it('gallery should set the correct label active (by setting the secondary color)', () => { createWrapper({ windowViewType: 'gallery' }); - expect(screen.getByRole('menuitemradio', { name: /Gallery/ }).querySelector('svg')).toHaveClass('MuiSvgIcon-colorSecondary'); // eslint-disable-line testing-library/no-node-access - expect(screen.getByRole('menuitemradio', { name: /Single/ }).querySelector('svg')).not.toHaveClass('MuiSvgIcon-colorSecondary'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + expect(screen.getByRole('menuitemradio', { name: /Gallery/ }).querySelector('svg')).toHaveClass( + 'MuiSvgIcon-colorSecondary', + ); + expect( + // eslint-disable-next-line testing-library/no-node-access + screen.getByRole('menuitemradio', { name: /Single/ }).querySelector('svg'), + ).not.toHaveClass('MuiSvgIcon-colorSecondary'); }); it('updates state when the view config selection changes', async () => { const setWindowViewType = vi.fn(); diff --git a/__tests__/src/components/WindowViewer.test.js b/__tests__/src/components/WindowViewer.test.js index d9693d16d..1bc094e76 100644 --- a/__tests__/src/components/WindowViewer.test.js +++ b/__tests__/src/components/WindowViewer.test.js @@ -3,11 +3,7 @@ import { WindowViewer } from '../../../src/components/WindowViewer'; /** create wrapper */ function createWrapper(props) { - return render( - , - ); + return render(); } describe('WindowViewer', () => { diff --git a/__tests__/src/components/Workspace.test.js b/__tests__/src/components/Workspace.test.js index 0b32b2018..314f030c2 100644 --- a/__tests__/src/components/Workspace.test.js +++ b/__tests__/src/components/Workspace.test.js @@ -1,6 +1,4 @@ -import { - render, screen, fireEvent, waitFor, -} from '@tests/utils/test-utils'; +import { render, screen, fireEvent, waitFor } from '@tests/utils/test-utils'; import { DndProvider } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; @@ -9,7 +7,7 @@ import { Workspace } from '../../../src/components/Workspace'; /** * Utility function to create a Worksapce * component with all required props set -*/ + */ function createWrapper(props) { return render( @@ -27,7 +25,10 @@ function createWrapper(props) { windows: { 1: {}, 2: {} }, workspace: { viewportPosition: { - height: 10, width: 10, x: 0, y: 0, + height: 10, + width: 10, + x: 0, + y: 0, }, }, }, @@ -102,7 +103,12 @@ describe('Workspace', () => { fireEvent.dragOver(dropTarget, { dataTransfer }); fireEvent.drop(dropTarget, { dataTransfer }); - await waitFor(() => expect(addWindow).toHaveBeenCalledWith({ manifest: manifestJson, manifestId: expect.stringMatching(/^[0-9a-f-]+$/) })); + await waitFor(() => + expect(addWindow).toHaveBeenCalledWith({ + manifest: manifestJson, + manifestId: expect.stringMatching(/^[0-9a-f-]+$/), + }), + ); }); it('adds a new catalog entry from a IIIF drag and drop icon', () => { diff --git a/__tests__/src/components/WorkspaceAdd.test.js b/__tests__/src/components/WorkspaceAdd.test.js index a922ec928..f788fc984 100644 --- a/__tests__/src/components/WorkspaceAdd.test.js +++ b/__tests__/src/components/WorkspaceAdd.test.js @@ -1,6 +1,4 @@ -import { - render, screen, fireEvent, waitFor, -} from '@tests/utils/test-utils'; +import { render, screen, fireEvent, waitFor } from '@tests/utils/test-utils'; import userEvent from '@testing-library/user-event'; import { DndProvider } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; @@ -15,15 +13,19 @@ function createWrapper(props) { {}} - catalog={[ - { manifestId: 'bar' }, - { manifestId: 'foo' }, - ]} + catalog={[{ manifestId: 'bar' }, { manifestId: 'foo' }]} classes={{}} {...props} /> , - { preloadedState: { manifests: { bar: { id: 'bar', isFetching: false, json: manifestFixture001 }, foo: { id: 'foo', isFetching: false, json: manifestFixture002 } } } }, + { + preloadedState: { + manifests: { + bar: { id: 'bar', isFetching: false, json: manifestFixture001 }, + foo: { id: 'foo', isFetching: false, json: manifestFixture002 }, + }, + }, + }, ); } @@ -37,7 +39,9 @@ describe('WorkspaceAdd', () => { it('focuses on the first manifest item', () => { createWrapper(); - expect(screen.getByRole('button', { name: 'Bodleian Library Human Freaks 2 (33)' })).toHaveFocus(); + expect( + screen.getByRole('button', { name: 'Bodleian Library Human Freaks 2 (33)' }), + ).toHaveFocus(); }); it('without manifests, renders an empty message', () => { @@ -92,7 +96,10 @@ describe('WorkspaceAdd', () => { const scrollTo = vi.fn(); - vi.spyOn(container.querySelector('.mirador-workspace-add'), 'scrollTo').mockImplementation(scrollTo); // eslint-disable-line testing-library/no-node-access, testing-library/no-container + // eslint-disable-next-line testing-library/no-node-access, testing-library/no-container + vi.spyOn(container.querySelector('.mirador-workspace-add'), 'scrollTo').mockImplementation( + scrollTo, + ); await user.click(screen.getByRole('button', { name: 'Add resource' })); @@ -134,7 +141,13 @@ describe('WorkspaceAdd', () => { fireEvent.dragOver(dropTarget, { dataTransfer }); fireEvent.drop(dropTarget, { dataTransfer }); - await waitFor(() => expect(addResource).toHaveBeenCalledWith(expect.stringMatching(/^[0-9a-f-]+$/), manifestJson, { provider: 'file' })); + await waitFor(() => + expect(addResource).toHaveBeenCalledWith( + expect.stringMatching(/^[0-9a-f-]+$/), + manifestJson, + { provider: 'file' }, + ), + ); }); it('adds a new catalog entry from a IIIF drag and drop icon', () => { diff --git a/__tests__/src/components/WorkspaceArea.test.js b/__tests__/src/components/WorkspaceArea.test.js index 91378f0cd..f2d0d58ec 100644 --- a/__tests__/src/components/WorkspaceArea.test.js +++ b/__tests__/src/components/WorkspaceArea.test.js @@ -8,12 +8,7 @@ import { WorkspaceArea } from '../../../src/components/WorkspaceArea'; function createWrapper(props) { return render( - + , ); } @@ -36,7 +31,8 @@ describe('WorkspaceArea', () => { expect(screen.getByRole('heading', { level: 1 })).toHaveTextContent('Mirador viewer'); expect(screen.getByRole('main')).toHaveTextContent('Welcome to Mirador'); - expect(container.querySelector('.mirador-background-plugin-area')).toBeInTheDocument(); // eslint-disable-line testing-library/no-node-access, testing-library/no-container + // eslint-disable-next-line testing-library/no-node-access, testing-library/no-container + expect(container.querySelector('.mirador-background-plugin-area')).toBeInTheDocument(); }); it('should not render WorkspaceControlPanel when isWorkspaceControlPanelVisible is false', () => { @@ -51,9 +47,13 @@ describe('WorkspaceArea', () => { it('should render WorkspaceAdd when isWorkspaceAddVisible is true', () => { createWrapper({ isWorkspaceAddVisible: true }); - expect(screen.queryByRole('heading', { level: 1, name: 'Mirador viewer' })).not.toBeInTheDocument(); + expect( + screen.queryByRole('heading', { level: 1, name: 'Mirador viewer' }), + ).not.toBeInTheDocument(); expect(screen.getByRole('main')).toHaveTextContent('Your resource list is empty'); - expect(within(screen.getByRole('main')).getByRole('button', { name: 'Add resource' })).toBeInTheDocument(); + expect( + within(screen.getByRole('main')).getByRole('button', { name: 'Add resource' }), + ).toBeInTheDocument(); }); }); }); diff --git a/__tests__/src/components/WorkspaceControlPanel.test.js b/__tests__/src/components/WorkspaceControlPanel.test.js index 394d9edc0..4a9e0483c 100644 --- a/__tests__/src/components/WorkspaceControlPanel.test.js +++ b/__tests__/src/components/WorkspaceControlPanel.test.js @@ -4,14 +4,11 @@ import { WorkspaceControlPanel } from '../../../src/components/WorkspaceControlP describe('WorkspaceControlPanel', () => { beforeEach(() => { - render( - , - { - preloadedState: { - workspace: { windowIds: ['xyz'] }, - }, + render(, { + preloadedState: { + workspace: { windowIds: ['xyz'] }, }, - ); + }); }); it('renders without an error', () => { @@ -20,6 +17,9 @@ describe('WorkspaceControlPanel', () => { expect(screen.getByRole('button', { name: 'Jump to window' })).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Workspace settings' })).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Workspace options' })).toBeInTheDocument(); - expect(screen.getByRole('link', { name: 'About Project Mirador' })).toHaveAttribute('href', 'https://projectmirador.org'); + expect(screen.getByRole('link', { name: 'About Project Mirador' })).toHaveAttribute( + 'href', + 'https://projectmirador.org', + ); }); }); diff --git a/__tests__/src/components/WorkspaceElasticWindow.test.js b/__tests__/src/components/WorkspaceElasticWindow.test.js index 4e165dda9..4ddee6a6c 100644 --- a/__tests__/src/components/WorkspaceElasticWindow.test.js +++ b/__tests__/src/components/WorkspaceElasticWindow.test.js @@ -24,7 +24,13 @@ function createWrapper(props) { {...props} /> , - { preloadedState: { companionWindows: {}, windows: { 1: { companionWindowIds: [] } }, workspace: {} } }, + { + preloadedState: { + companionWindows: {}, + windows: { 1: { companionWindowIds: [] } }, + workspace: {}, + }, + }, ); } @@ -43,7 +49,11 @@ describe('WorkspaceElasticWindow', () => { const el = container.firstChild; expect(el).toHaveClass('react-draggable'); - expect(el).toHaveStyle({ height: '200px', transform: 'translate(5040px,5040px)', width: '200px' }); + expect(el).toHaveStyle({ + height: '200px', + transform: 'translate(5040px,5040px)', + width: '200px', + }); }); describe('focuses the window', () => { it('calls focusWindow when clicked', async () => { @@ -97,7 +107,9 @@ describe('WorkspaceElasticWindow', () => { top: -2500, }); - const el = container.querySelector('[style="position: absolute; user-select: none; width: 20px; height: 20px; z-index: 1; right: -10px; bottom: -10px; cursor: se-resize;"]'); + const el = container.querySelector( + '[style="position: absolute; user-select: none; width: 20px; height: 20px; z-index: 1; right: -10px; bottom: -10px; cursor: se-resize;"]', + ); const oldCoords = { x: 0, @@ -114,10 +126,13 @@ describe('WorkspaceElasticWindow', () => { { coords }, { coords, keys: '[/MouseLeft]', target: el }, ]); - expect(mockOnResize).toHaveBeenCalledWith('1', expect.objectContaining({ - height: 200, - width: 400, - })); + expect(mockOnResize).toHaveBeenCalledWith( + '1', + expect.objectContaining({ + height: 200, + width: 400, + }), + ); }); }); }); diff --git a/__tests__/src/components/WorkspaceImport.test.js b/__tests__/src/components/WorkspaceImport.test.js index 39b510d5e..b552f5878 100644 --- a/__tests__/src/components/WorkspaceImport.test.js +++ b/__tests__/src/components/WorkspaceImport.test.js @@ -7,12 +7,7 @@ describe('WorkspaceImport', () => { beforeEach(() => { handleClose = vi.fn(); - render( - , - ); + render(); }); it('renders without an error', () => { diff --git a/__tests__/src/components/WorkspaceMenu.test.js b/__tests__/src/components/WorkspaceMenu.test.js index d5752ae86..54fce843d 100644 --- a/__tests__/src/components/WorkspaceMenu.test.js +++ b/__tests__/src/components/WorkspaceMenu.test.js @@ -7,12 +7,7 @@ function createShallow(props) { render(
); return render( - , + , ); } @@ -41,10 +36,16 @@ describe('Workspace settings', () => { it('disables zoom controls if the workspaceAdd UI is visible', () => { createShallow({ - handleClose, isWorkspaceAddVisible: true, showZoomControls, toggleZoomControls, + handleClose, + isWorkspaceAddVisible: true, + showZoomControls, + toggleZoomControls, }); - expect(screen.getByRole('menuitem', { name: 'Show zoom controls' })).toHaveAttribute('aria-disabled', 'true'); + expect(screen.getByRole('menuitem', { name: 'Show zoom controls' })).toHaveAttribute( + 'aria-disabled', + 'true', + ); }); describe('handleZoomToggleClick', () => { diff --git a/__tests__/src/components/WorkspaceMenuButton.test.js b/__tests__/src/components/WorkspaceMenuButton.test.js index b64299864..ef3d7fc2e 100644 --- a/__tests__/src/components/WorkspaceMenuButton.test.js +++ b/__tests__/src/components/WorkspaceMenuButton.test.js @@ -7,9 +7,7 @@ describe('WorkspaceMenuButton', () => { let user; beforeEach(() => { user = userEvent.setup(); - render( - , - ); + render(); }); it('renders the button', () => { diff --git a/__tests__/src/components/WorkspaceMosaic.test.js b/__tests__/src/components/WorkspaceMosaic.test.js index 84da54a1b..6a22fc06a 100644 --- a/__tests__/src/components/WorkspaceMosaic.test.js +++ b/__tests__/src/components/WorkspaceMosaic.test.js @@ -36,10 +36,16 @@ describe('WorkspaceMosaic', () => { expect(tiles).toHaveLength(2); expect(tiles[0]).toHaveStyle({ - bottom: '0%', left: '0%', right: '50%', top: '0%', + bottom: '0%', + left: '0%', + right: '50%', + top: '0%', }); expect(tiles[1]).toHaveStyle({ - bottom: '0%', left: '50%', right: '0%', top: '0%', + bottom: '0%', + left: '50%', + right: '0%', + top: '0%', }); }); @@ -52,7 +58,12 @@ describe('WorkspaceMosaic', () => { }); wrapper.rerender( - , + , ); expect(updateWorkspaceMosaicLayout).toHaveBeenCalled(); @@ -68,9 +79,7 @@ describe('WorkspaceMosaic', () => { }; wrapper = createWrapper(props); - wrapper.rerender( - , - ); + wrapper.rerender(); expect(updateWorkspaceMosaicLayout).toHaveBeenLastCalledWith('1'); }); @@ -82,7 +91,13 @@ describe('WorkspaceMosaic', () => { }); wrapper.rerender( - , + , ); expect(updateWorkspaceMosaicLayout).toHaveBeenLastCalledWith(null); }); @@ -95,7 +110,13 @@ describe('WorkspaceMosaic', () => { }); wrapper.rerender( - , + , ); expect(updateWorkspaceMosaicLayout).toHaveBeenCalledTimes(0); @@ -105,13 +126,22 @@ describe('WorkspaceMosaic', () => { it('when window is available', () => { wrapper = createWrapper({ windowIds }); - expect(screen.getAllByLabelText('Window:', { container: 'section' })[0]).toHaveAttribute('id', '1'); - expect(screen.getAllByLabelText('Window:', { container: 'section' })[1]).toHaveAttribute('id', '2'); + expect(screen.getAllByLabelText('Window:', { container: 'section' })[0]).toHaveAttribute( + 'id', + '1', + ); + expect(screen.getAllByLabelText('Window:', { container: 'section' })[1]).toHaveAttribute( + 'id', + '2', + ); expect(wrapper.container.querySelector('.mosaic-window-title')).toBeEmptyDOMElement(); expect(wrapper.container.querySelector('.mosaic-window-controls')).toBeEmptyDOMElement(); expect(wrapper.container.querySelectorAll('.mosaic-preview')).toHaveLength(2); - expect(wrapper.container.querySelector('.mosaic-preview')).toHaveAttribute('aria-hidden', 'true'); + expect(wrapper.container.querySelector('.mosaic-preview')).toHaveAttribute( + 'aria-hidden', + 'true', + ); }); }); describe('mosaicChange', () => { @@ -142,7 +172,10 @@ describe('WorkspaceMosaic', () => { ); const dragTarget = screen.getAllByLabelText('Window navigation')[0]; - const dropTarget = container.querySelector('.mirador-mosaic > .drop-target-container > .drop-target.top'); // eslint-disable-line testing-library/no-container + // eslint-disable-next-line testing-library/no-container + const dropTarget = container.querySelector( + '.mirador-mosaic > .drop-target-container > .drop-target.top', + ); fireEvent.dragStart(dragTarget); fireEvent.drag(dragTarget); diff --git a/__tests__/src/components/WorkspaceOptionsButton.test.js b/__tests__/src/components/WorkspaceOptionsButton.test.js index 41f79e3bb..fa61373cb 100644 --- a/__tests__/src/components/WorkspaceOptionsButton.test.js +++ b/__tests__/src/components/WorkspaceOptionsButton.test.js @@ -6,12 +6,7 @@ import { WorkspaceOptionsButton } from '../../../src/components/WorkspaceOptions function Subject({ ...props }) { return (
- - , - , + , ,
); } diff --git a/__tests__/src/components/WorkspaceOptionsMenu.test.js b/__tests__/src/components/WorkspaceOptionsMenu.test.js index 64da09529..8eab67eb7 100644 --- a/__tests__/src/components/WorkspaceOptionsMenu.test.js +++ b/__tests__/src/components/WorkspaceOptionsMenu.test.js @@ -6,12 +6,7 @@ import { WorkspaceOptionsMenu } from '../../../src/components/WorkspaceOptionsMe function Subject({ ...props }) { return (
- {}} - {...props} - /> - , - , + {}} {...props} />, ,
); } @@ -19,7 +14,9 @@ function Subject({ ...props }) { /** create anchor element */ function createAnchor() { return render( - , + , ); } @@ -64,7 +61,13 @@ describe('WorkspaceOptionsMenu', () => { it('fires the correct callbacks on menu close', async () => { const handleClose = vi.fn(); - render(); + render( + , + ); // click a menu item should close the menu const menuItems = screen.getAllByRole('menuitem'); diff --git a/__tests__/src/components/WorkspaceSelectionDialog.test.js b/__tests__/src/components/WorkspaceSelectionDialog.test.js index 56ce55490..c5b45a4a6 100644 --- a/__tests__/src/components/WorkspaceSelectionDialog.test.js +++ b/__tests__/src/components/WorkspaceSelectionDialog.test.js @@ -1,6 +1,4 @@ -import { - render, screen, waitFor, -} from '@tests/utils/test-utils'; +import { render, screen, waitFor } from '@tests/utils/test-utils'; import userEvent from '@testing-library/user-event'; import { WorkspaceSelectionDialog } from '../../../src/components/WorkspaceSelectionDialog'; diff --git a/__tests__/src/components/ZoomControls.test.js b/__tests__/src/components/ZoomControls.test.js index ae55b883a..77b2fd23d 100644 --- a/__tests__/src/components/ZoomControls.test.js +++ b/__tests__/src/components/ZoomControls.test.js @@ -4,13 +4,7 @@ import { ZoomControls } from '../../../src/components/ZoomControls'; /** Utility function to create a shallow rendering */ function createWrapper(props) { - return render( - {}} - {...props} - />, - ); + return render( {}} {...props} />); } describe('ZoomControls', () => { @@ -23,7 +17,9 @@ describe('ZoomControls', () => { user = userEvent.setup(); updateViewport = vi.fn(); createWrapper({ - updateViewport, viewer, zoomToWorld, + updateViewport, + viewer, + zoomToWorld, }); }); diff --git a/__tests__/src/extend/pluginMapping.test.js b/__tests__/src/extend/pluginMapping.test.js index 2d699e3f6..444dc458a 100644 --- a/__tests__/src/extend/pluginMapping.test.js +++ b/__tests__/src/extend/pluginMapping.test.js @@ -11,7 +11,7 @@ describe('createTargetToPluginMapping', () => { it('should create a mapping from targets to plugins and modes', () => { /** */ - const component = props => null; + const component = (props) => null; const plugins = [ { component, mode: 'wrap', target: 'Window' }, @@ -53,16 +53,22 @@ describe('createTargetToPluginMapping', () => { describe('connectPluginsToStore', () => { it('returns plugins with components connected to store', () => { /** */ - const ComponentA = props => null; + const ComponentA = (props) => null; /** */ - const ComponentB = props => null; + const ComponentB = (props) => null; const plugins = [ { - component: ComponentA, mapStateToProps: {}, mode: 'wrap', target: 'Window', + component: ComponentA, + mapStateToProps: {}, + mode: 'wrap', + target: 'Window', }, { - component: ComponentB, mapDispatchToProps: {}, mode: 'add', target: 'TopBar', + component: ComponentB, + mapDispatchToProps: {}, + mode: 'add', + target: 'TopBar', }, ]; @@ -74,11 +80,13 @@ describe('connectPluginsToStore', () => { it('returns plugins unchanged that do not need a connection to the store', () => { /** */ - const ComponentA = props => null; + const ComponentA = (props) => null; const plugins = [ { - component: ComponentA, mode: 'wrap', target: 'Window', + component: ComponentA, + mode: 'wrap', + target: 'Window', }, ]; @@ -90,7 +98,7 @@ describe('connectPluginsToStore', () => { describe('addPluginsToCompanionWindowsRegistry', () => { it('adds plugin references to the companion window registry', () => { /** */ - const ComponentA = props => null; + const ComponentA = (props) => null; const plugins = [ { diff --git a/__tests__/src/extend/pluginPreprocessing.test.js b/__tests__/src/extend/pluginPreprocessing.test.js index a71c620d5..bc1479a06 100644 --- a/__tests__/src/extend/pluginPreprocessing.test.js +++ b/__tests__/src/extend/pluginPreprocessing.test.js @@ -1,6 +1,4 @@ -import { - filterValidPlugins, -} from '../../../src/extend/pluginPreprocessing'; +import { filterValidPlugins } from '../../../src/extend/pluginPreprocessing'; describe('filterValidPlugins', () => { it('returns empty array if plugin array is empty', () => { @@ -10,13 +8,13 @@ describe('filterValidPlugins', () => { it('returns only valid plugins', () => { const plugins = [ { - component: props => null, + component: (props) => null, mode: 'add', name: 'valid plugin 1', target: 'Window', }, { - component: props => null, + component: (props) => null, mode: 'wrap', name: 'valid plugin 2', target: 'Window', @@ -31,7 +29,7 @@ describe('filterValidPlugins', () => { target: 'missing-mode', }, { - component: props => null, + component: (props) => null, mode: 'wrap', name: 'valid plugin, grouped with an invalid one', target: 'WindowTopBar', @@ -39,6 +37,6 @@ describe('filterValidPlugins', () => { ], ]; const result = filterValidPlugins(plugins); - expect(result.map(r => r.name)).toEqual(['valid plugin 1', 'valid plugin 2']); + expect(result.map((r) => r.name)).toEqual(['valid plugin 1', 'valid plugin 2']); }); }); diff --git a/__tests__/src/extend/pluginValidation.test.js b/__tests__/src/extend/pluginValidation.test.js index deddf6212..3be68ee54 100644 --- a/__tests__/src/extend/pluginValidation.test.js +++ b/__tests__/src/extend/pluginValidation.test.js @@ -1,15 +1,15 @@ import { validatePlugin } from '../../../src/extend/pluginValidation'; /** */ -const createPlugin = props => ({ - component: x => x, - mapDispatchToProps: x => x, - mapStateToProps: x => x, +const createPlugin = (props) => ({ + component: (x) => x, + mapDispatchToProps: (x) => x, + mapStateToProps: (x) => x, mode: 'add', name: 'test', reducers: { - bar: x => x, - foo: x => x, + bar: (x) => x, + foo: (x) => x, }, target: 'Window', ...props, @@ -58,7 +58,7 @@ describe('validatePlugin', () => { it('mapStateToProps must be undefined, null or function', () => { let plugin = createPlugin({ mapStateToProps: undefined }); expect(validatePlugin(plugin)).toBe(true); - plugin = createPlugin({ mapStateToProps: x => x }); + plugin = createPlugin({ mapStateToProps: (x) => x }); expect(validatePlugin(plugin)).toBe(true); plugin = createPlugin({ mapStateToProps: null }); expect(validatePlugin(plugin)).toBe(true); @@ -69,7 +69,7 @@ describe('validatePlugin', () => { it('mapDispatchToProps must be undefined, null, function or object', () => { let plugin = createPlugin({ mapDispatchToProps: undefined }); expect(validatePlugin(plugin)).toBe(true); - plugin = createPlugin({ mapDispatchToProps: x => x }); + plugin = createPlugin({ mapDispatchToProps: (x) => x }); expect(validatePlugin(plugin)).toBe(true); plugin = createPlugin({ mapDispatchToProps: {} }); expect(validatePlugin(plugin)).toBe(true); @@ -89,10 +89,10 @@ describe('validatePlugin', () => { }); it('each reducer must be a function', () => { - let reducers = { bar: x => x, foo: x => x }; + let reducers = { bar: (x) => x, foo: (x) => x }; let plugin = createPlugin({ reducers }); expect(validatePlugin(plugin)).toBe(true); - reducers = { bar: x => x, foo: undefined }; + reducers = { bar: (x) => x, foo: undefined }; plugin = createPlugin({ reducers }); expect(validatePlugin(plugin)).toBe(false); }); diff --git a/__tests__/src/extend/withPlugins.test.js b/__tests__/src/extend/withPlugins.test.js index ffab103ef..dc6678b31 100644 --- a/__tests__/src/extend/withPlugins.test.js +++ b/__tests__/src/extend/withPlugins.test.js @@ -32,8 +32,7 @@ describe('withPlugins', () => { }); it('displayName prop of returned function is based on target name argument', () => { - expect(withPlugins('Bubu', Target).displayName) - .toBe('WithPlugins(Bubu)'); + expect(withPlugins('Bubu', Target).displayName).toBe('WithPlugins(Bubu)'); }); }); @@ -48,12 +47,12 @@ describe('PluginHoc: if no plugin exists for the target', () => { describe('PluginHoc: if wrap plugins exist for target', () => { it('renders the first wrap plugin', () => { - /** */ const WrapPluginComponentA = props =>
look i am a plugin
; + /** */ const WrapPluginComponentA = (props) => ( +
look i am a plugin
+ ); const pluginMap = { Target: { - wrap: [ - { component: WrapPluginComponentA, mode: 'wrap', target: 'Target' }, - ], + wrap: [{ component: WrapPluginComponentA, mode: 'wrap', target: 'Target' }], }, }; createPluginHoc(pluginMap); @@ -63,9 +62,13 @@ describe('PluginHoc: if wrap plugins exist for target', () => { }); it('passes the whole wrapped stack to the plugins', () => { - /** */ const WrapPluginComponentA = ({ children }) =>
{children}
; + /** */ const WrapPluginComponentA = ({ children }) => ( +
{children}
+ ); WrapPluginComponentA.propTypes = { children: PropTypes.node.isRequired }; - /** */ const WrapPluginComponentB = props =>
look i am a plugin
; + /** */ const WrapPluginComponentB = (props) => ( +
look i am a plugin
+ ); const pluginMap = { Target: { wrap: [ diff --git a/__tests__/src/lib/AnnotationFactory.test.js b/__tests__/src/lib/AnnotationFactory.test.js index 4d0fea83f..f72d946f7 100644 --- a/__tests__/src/lib/AnnotationFactory.test.js +++ b/__tests__/src/lib/AnnotationFactory.test.js @@ -11,16 +11,20 @@ describe('AnnotationFactory', () => { }); describe('when Presentation v3', () => { it('returns an AnnotationPage', () => { - expect(AnnotationFactory.determineAnnotation({ - type: 'AnnotationPage', - })).toBeInstanceOf(AnnotationPage); + expect( + AnnotationFactory.determineAnnotation({ + type: 'AnnotationPage', + }), + ).toBeInstanceOf(AnnotationPage); }); }); describe('when Presentation v2', () => { it('returns an AnnotationPage', () => { - expect(AnnotationFactory.determineAnnotation({ - '@type': 'AnnotationList', - })).toBeInstanceOf(AnnotationList); + expect( + AnnotationFactory.determineAnnotation({ + '@type': 'AnnotationList', + }), + ).toBeInstanceOf(AnnotationList); }); }); }); diff --git a/__tests__/src/lib/AnnotationItem.test.js b/__tests__/src/lib/AnnotationItem.test.js index 8a783076e..a61ee647f 100644 --- a/__tests__/src/lib/AnnotationItem.test.js +++ b/__tests__/src/lib/AnnotationItem.test.js @@ -14,25 +14,31 @@ describe('AnnotationItem', () => { describe('isOnlyTag', () => { it('when the only motivation is tagging', () => { - expect(new AnnotationItem({ motivation: 'tagging' }).isOnlyTag()) - .toBe(true); + expect(new AnnotationItem({ motivation: 'tagging' }).isOnlyTag()).toBe(true); }); it('when there are other motivations besides tagging', () => { - expect(new AnnotationItem({ motivation: ['commenting', 'tagging'] }).isOnlyTag()) - .toBe(false); + expect(new AnnotationItem({ motivation: ['commenting', 'tagging'] }).isOnlyTag()).toBe(false); }); }); describe('tags', () => { it('when only motivation', () => { expect( - new AnnotationItem({ body: [{ purpose: 'tagging', value: 'yo' }, { purpose: 'tagging', value: 'lo' }] }).tags, + new AnnotationItem({ + body: [ + { purpose: 'tagging', value: 'yo' }, + { purpose: 'tagging', value: 'lo' }, + ], + }).tags, ).toEqual(['yo', 'lo']); }); it('when multiple motivations', () => { expect( new AnnotationItem({ - body: [{ purpose: 'commenting', value: 'yo' }, { purpose: 'tagging', value: 'lo' }], + body: [ + { purpose: 'commenting', value: 'yo' }, + { purpose: 'tagging', value: 'lo' }, + ], motivation: ['commenting', 'tagging'], }).tags, ).toEqual(['lo']); @@ -51,9 +57,7 @@ describe('AnnotationItem', () => { }); it('supports a source id', () => { - expect( - new AnnotationItem({ target: { source: { id: 'foo' } } }).targetId, - ).toEqual('foo'); + expect(new AnnotationItem({ target: { source: { id: 'foo' } } }).targetId).toEqual('foo'); }); }); @@ -62,12 +66,13 @@ describe('AnnotationItem', () => { expect(new AnnotationItem().motivations).toEqual([]); }); it('with a single motivation', () => { - expect(new AnnotationItem({ motivation: 'commenting' }) - .motivations).toEqual(['commenting']); + expect(new AnnotationItem({ motivation: 'commenting' }).motivations).toEqual(['commenting']); }); it('with multiple motivations', () => { - expect(new AnnotationItem({ motivation: ['commenting', 'funstuff'] }) - .motivations).toEqual(['commenting', 'funstuff']); + expect(new AnnotationItem({ motivation: ['commenting', 'funstuff'] }).motivations).toEqual([ + 'commenting', + 'funstuff', + ]); }); }); describe('resources/body', () => { @@ -76,16 +81,12 @@ describe('AnnotationItem', () => { expect(new AnnotationItem().body).toEqual([]); }); it('with a single body', () => { - expect(new AnnotationItem({ body: 'foo' }) - .resources).toEqual(['foo']); - expect(new AnnotationItem({ body: 'foo' }) - .body).toEqual(['foo']); + expect(new AnnotationItem({ body: 'foo' }).resources).toEqual(['foo']); + expect(new AnnotationItem({ body: 'foo' }).body).toEqual(['foo']); }); it('with multiple bodies', () => { - expect(new AnnotationItem({ body: ['foo', 'bar'] }) - .resources).toEqual(['foo', 'bar']); - expect(new AnnotationItem({ body: ['foo', 'bar'] }) - .body).toEqual(['foo', 'bar']); + expect(new AnnotationItem({ body: ['foo', 'bar'] }).resources).toEqual(['foo', 'bar']); + expect(new AnnotationItem({ body: ['foo', 'bar'] }).body).toEqual(['foo', 'bar']); }); }); describe('target', () => { @@ -93,12 +94,10 @@ describe('AnnotationItem', () => { expect(new AnnotationItem().target).toEqual([]); }); it('with a single target', () => { - expect(new AnnotationItem({ target: 'foo' }) - .target).toEqual(['foo']); + expect(new AnnotationItem({ target: 'foo' }).target).toEqual(['foo']); }); it('with multiple target', () => { - expect(new AnnotationItem({ target: ['foo', 'bar'] }) - .target).toEqual(['foo', 'bar']); + expect(new AnnotationItem({ target: ['foo', 'bar'] }).target).toEqual(['foo', 'bar']); }); }); describe('selector', () => { @@ -109,7 +108,10 @@ describe('AnnotationItem', () => { expect(new AnnotationItem({ target: { selector: 'yolo' } }).selector).toEqual(['yolo']); }); it('handles multiple selectors', () => { - expect(new AnnotationItem({ target: { selector: ['yolo', 'foo'] } }).selector).toEqual(['yolo', 'foo']); + expect(new AnnotationItem({ target: { selector: ['yolo', 'foo'] } }).selector).toEqual([ + 'yolo', + 'foo', + ]); }); }); describe('chars', () => { @@ -117,42 +119,46 @@ describe('AnnotationItem', () => { expect(new AnnotationItem().chars).toEqual(''); }); it('with a single body', () => { - expect(new AnnotationItem({ body: { value: 'foo' } }) - .chars).toEqual('foo'); + expect(new AnnotationItem({ body: { value: 'foo' } }).chars).toEqual('foo'); }); it('with multiple bodies', () => { - expect(new AnnotationItem({ body: [{ value: 'foo' }, { value: 'bar' }] }) - .chars).toEqual('foo bar'); + expect(new AnnotationItem({ body: [{ value: 'foo' }, { value: 'bar' }] }).chars).toEqual( + 'foo bar', + ); }); }); describe('fragmentSelector', () => { it('simple string', () => { - expect(new AnnotationItem({ target: 'www.example.com/#xywh=10,10,100,200' }) - .fragmentSelector).toEqual([10, 10, 100, 200]); + expect( + new AnnotationItem({ target: 'www.example.com/#xywh=10,10,100,200' }).fragmentSelector, + ).toEqual([10, 10, 100, 200]); }); it('multiple selectors', () => { - expect(new AnnotationItem({ target: { selector: [{ type: 'FragmentSelector', value: '#xywh=10,10,100,200' }] } }) - .fragmentSelector).toEqual([10, 10, 100, 200]); + expect( + new AnnotationItem({ + target: { selector: [{ type: 'FragmentSelector', value: '#xywh=10,10,100,200' }] }, + }).fragmentSelector, + ).toEqual([10, 10, 100, 200]); }); it('url without a fragment', () => { - expect(new AnnotationItem({ target: 'www.example.com' }) - .fragmentSelector).toEqual(null); + expect(new AnnotationItem({ target: 'www.example.com' }).fragmentSelector).toEqual(null); }); }); describe('svgSelector', () => { it('simple string', () => { - expect(new AnnotationItem({ target: 'www.example.com/#xywh=10,10,100,200' }) - .svgSelector).toEqual(null); + expect( + new AnnotationItem({ target: 'www.example.com/#xywh=10,10,100,200' }).svgSelector, + ).toEqual(null); }); it('specified SvgSelector', () => { - expect(new AnnotationItem({ target: { selector: { type: 'SvgSelector' } } }) - .svgSelector).toEqual({ type: 'SvgSelector' }); + expect( + new AnnotationItem({ target: { selector: { type: 'SvgSelector' } } }).svgSelector, + ).toEqual({ type: 'SvgSelector' }); }); it('without specified type', () => { - expect(new AnnotationItem({ target: { selector: { } } }) - .svgSelector).toEqual(undefined); + expect(new AnnotationItem({ target: { selector: {} } }).svgSelector).toEqual(undefined); }); }); }); diff --git a/__tests__/src/lib/AnnotationList.test.js b/__tests__/src/lib/AnnotationList.test.js index 15ff47e06..145881db6 100644 --- a/__tests__/src/lib/AnnotationList.test.js +++ b/__tests__/src/lib/AnnotationList.test.js @@ -18,15 +18,15 @@ describe('AnnotationList', () => { }); describe('resources', () => { it('maps resources to AnnotationResource', () => { - new AnnotationList( - { resources: [{ foo: 'bar' }] }, - ).resources.forEach(resource => expect(resource).toBeInstanceOf(AnnotationResource)); + new AnnotationList({ resources: [{ foo: 'bar' }] }).resources.forEach((resource) => + expect(resource).toBeInstanceOf(AnnotationResource), + ); }); it('handles resources that are just a single object instead of an array of objects', () => { - new AnnotationList( - { resources: { foo: 'bar' } }, - ).resources.forEach(resource => expect(resource).toBeInstanceOf(AnnotationResource)); + new AnnotationList({ resources: { foo: 'bar' } }).resources.forEach((resource) => + expect(resource).toBeInstanceOf(AnnotationResource), + ); }); }); }); diff --git a/__tests__/src/lib/AnnotationPage.test.js b/__tests__/src/lib/AnnotationPage.test.js index 87b1f9c4f..741b1a86d 100644 --- a/__tests__/src/lib/AnnotationPage.test.js +++ b/__tests__/src/lib/AnnotationPage.test.js @@ -18,16 +18,16 @@ describe('AnnotationPage', () => { }); describe('items', () => { it('returns items', () => { - new AnnotationPage( - { items: [{ foo: 'bar' }] }, - ).items.forEach(resource => expect(resource).toBeInstanceOf(AnnotationItem)); + new AnnotationPage({ items: [{ foo: 'bar' }] }).items.forEach((resource) => + expect(resource).toBeInstanceOf(AnnotationItem), + ); }); }); describe('resources', () => { it('returns items', () => { - new AnnotationPage( - { items: [{ foo: 'bar' }] }, - ).items.forEach(resource => expect(resource).toBeInstanceOf(AnnotationItem)); + new AnnotationPage({ items: [{ foo: 'bar' }] }).items.forEach((resource) => + expect(resource).toBeInstanceOf(AnnotationItem), + ); }); }); }); diff --git a/__tests__/src/lib/AnnotationResource.test.js b/__tests__/src/lib/AnnotationResource.test.js index 96c469a3c..4f318bd42 100644 --- a/__tests__/src/lib/AnnotationResource.test.js +++ b/__tests__/src/lib/AnnotationResource.test.js @@ -17,26 +17,34 @@ describe('AnnotationResource', () => { describe('isOnlyTag', () => { it('when the only motivation is tagging', () => { - expect(new AnnotationResource({ motivation: 'oa:tagging' }).isOnlyTag()) - .toBe(true); + expect(new AnnotationResource({ motivation: 'oa:tagging' }).isOnlyTag()).toBe(true); }); it('when there are other motivations besides tagging', () => { - expect(new AnnotationResource({ motivation: ['oa:commenting', 'oa:tagging'] }).isOnlyTag()) - .toBe(false); + expect( + new AnnotationResource({ motivation: ['oa:commenting', 'oa:tagging'] }).isOnlyTag(), + ).toBe(false); }); }); describe('tags', () => { it('when only motivation', () => { expect( - new AnnotationResource({ resource: [{ '@type': 'oa:Tag', chars: 'yo' }, { '@type': 'oa:Tag', chars: 'lo' }] }).tags, + new AnnotationResource({ + resource: [ + { '@type': 'oa:Tag', chars: 'yo' }, + { '@type': 'oa:Tag', chars: 'lo' }, + ], + }).tags, ).toEqual(['yo', 'lo']); }); it('when multiple motivations', () => { expect( new AnnotationResource({ motivation: ['oa:commenting', 'oa:tagging'], - resource: [{ '@type': 'oa:commenting', chars: 'yo' }, { '@type': 'oa:Tag', chars: 'lo' }], + resource: [ + { '@type': 'oa:commenting', chars: 'yo' }, + { '@type': 'oa:Tag', chars: 'lo' }, + ], }).tags, ).toEqual(['lo']); }); @@ -71,12 +79,14 @@ describe('AnnotationResource', () => { expect(new AnnotationResource().motivations).toEqual([]); }); it('with a single motivation', () => { - expect(new AnnotationResource({ motivation: 'oa:commenting' }) - .motivations).toEqual(['oa:commenting']); + expect(new AnnotationResource({ motivation: 'oa:commenting' }).motivations).toEqual([ + 'oa:commenting', + ]); }); it('with multiple motivations', () => { - expect(new AnnotationResource({ motivation: ['oa:commenting', 'sc:funstuff'] }) - .motivations).toEqual(['oa:commenting', 'sc:funstuff']); + expect( + new AnnotationResource({ motivation: ['oa:commenting', 'sc:funstuff'] }).motivations, + ).toEqual(['oa:commenting', 'sc:funstuff']); }); }); describe('resources', () => { @@ -84,12 +94,13 @@ describe('AnnotationResource', () => { expect(new AnnotationResource().resources).toEqual([]); }); it('with a single resource', () => { - expect(new AnnotationResource({ resource: 'foo' }) - .resources).toEqual(['foo']); + expect(new AnnotationResource({ resource: 'foo' }).resources).toEqual(['foo']); }); it('with multiple resources', () => { - expect(new AnnotationResource({ resource: ['foo', 'bar'] }) - .resources).toEqual(['foo', 'bar']); + expect(new AnnotationResource({ resource: ['foo', 'bar'] }).resources).toEqual([ + 'foo', + 'bar', + ]); }); }); describe('on', () => { @@ -97,12 +108,10 @@ describe('AnnotationResource', () => { expect(new AnnotationResource().on).toEqual([]); }); it('with a single on', () => { - expect(new AnnotationResource({ on: 'foo' }) - .on).toEqual(['foo']); + expect(new AnnotationResource({ on: 'foo' }).on).toEqual(['foo']); }); it('with multiple on', () => { - expect(new AnnotationResource({ on: ['foo', 'bar'] }) - .on).toEqual(['foo', 'bar']); + expect(new AnnotationResource({ on: ['foo', 'bar'] }).on).toEqual(['foo', 'bar']); }); }); describe('selector', () => { @@ -110,12 +119,23 @@ describe('AnnotationResource', () => { expect(new AnnotationResource({ on: 'yolo' }).selector).toEqual('yolo'); }); it('picks the default selector when given a choice', () => { - expect(new AnnotationResource({ on: { selector: { '@type': 'oa:Choice', default: { value: 'www.example.com/#xywh=10,10,100,200' } } } }) - .selector).toEqual({ value: 'www.example.com/#xywh=10,10,100,200' }); + expect( + new AnnotationResource({ + on: { + selector: { + '@type': 'oa:Choice', + default: { value: 'www.example.com/#xywh=10,10,100,200' }, + }, + }, + }).selector, + ).toEqual({ value: 'www.example.com/#xywh=10,10,100,200' }); }); it('returns the selector when not given a choice', () => { - expect(new AnnotationResource({ on: { selector: { value: 'www.example.com/#xywh=10,10,100,200' } } }) - .selector).toEqual({ value: 'www.example.com/#xywh=10,10,100,200' }); + expect( + new AnnotationResource({ + on: { selector: { value: 'www.example.com/#xywh=10,10,100,200' } }, + }).selector, + ).toEqual({ value: 'www.example.com/#xywh=10,10,100,200' }); }); }); describe('chars', () => { @@ -123,54 +143,74 @@ describe('AnnotationResource', () => { expect(new AnnotationResource().chars).toEqual(''); }); it('with a single resource', () => { - expect(new AnnotationResource({ resource: { chars: 'foo' } }) - .chars).toEqual('foo'); + expect(new AnnotationResource({ resource: { chars: 'foo' } }).chars).toEqual('foo'); }); it('with multiple resources', () => { - expect(new AnnotationResource({ resource: [{ chars: 'foo' }, { chars: 'bar' }] }) - .chars).toEqual('foo bar'); + expect( + new AnnotationResource({ resource: [{ chars: 'foo' }, { chars: 'bar' }] }).chars, + ).toEqual('foo bar'); }); }); describe('fragmentSelector', () => { it('simple string', () => { - expect(new AnnotationResource({ on: 'www.example.com/#xywh=10,10,100,200' }) - .fragmentSelector).toEqual([10, 10, 100, 200]); + expect( + new AnnotationResource({ on: 'www.example.com/#xywh=10,10,100,200' }).fragmentSelector, + ).toEqual([10, 10, 100, 200]); }); it('array of selectors', () => { - expect(new AnnotationResource({ on: [{ selector: { value: 'www.example.com/#xywh=10,10,100,200' } }] }) - .fragmentSelector).toEqual([10, 10, 100, 200]); + expect( + new AnnotationResource({ + on: [{ selector: { value: 'www.example.com/#xywh=10,10,100,200' } }], + }).fragmentSelector, + ).toEqual([10, 10, 100, 200]); }); it('more complex selector', () => { - expect(new AnnotationResource({ on: { selector: { value: 'www.example.com/#xywh=10,10,100,200' } } }) - .fragmentSelector).toEqual([10, 10, 100, 200]); + expect( + new AnnotationResource({ + on: { selector: { value: 'www.example.com/#xywh=10,10,100,200' } }, + }).fragmentSelector, + ).toEqual([10, 10, 100, 200]); }); it('choice selector', () => { - expect(new AnnotationResource({ on: { selector: { '@type': 'oa:Choice', default: { value: 'www.example.com/#xywh=10,10,100,200' } } } }) - .fragmentSelector).toEqual([10, 10, 100, 200]); + expect( + new AnnotationResource({ + on: { + selector: { + '@type': 'oa:Choice', + default: { value: 'www.example.com/#xywh=10,10,100,200' }, + }, + }, + }).fragmentSelector, + ).toEqual([10, 10, 100, 200]); }); it('url without a fragment', () => { - expect(new AnnotationResource({ on: { selector: { value: 'www.example.com' } } }) - .fragmentSelector).toEqual(null); + expect( + new AnnotationResource({ on: { selector: { value: 'www.example.com' } } }).fragmentSelector, + ).toEqual(null); }); }); describe('svgSelector', () => { it('simple string', () => { - expect(new AnnotationResource({ on: 'www.example.com/#xywh=10,10,100,200' }) - .svgSelector).toEqual(null); + expect( + new AnnotationResource({ on: 'www.example.com/#xywh=10,10,100,200' }).svgSelector, + ).toEqual(null); }); it('array of selectors', () => { - expect(new AnnotationResource({ on: [{ selector: { item: { '@type': 'oa:SvgSelector' } } }] }) - .svgSelector).toEqual({ '@type': 'oa:SvgSelector' }); + expect( + new AnnotationResource({ on: [{ selector: { item: { '@type': 'oa:SvgSelector' } } }] }) + .svgSelector, + ).toEqual({ '@type': 'oa:SvgSelector' }); }); it('without specified type', () => { - expect(new AnnotationResource({ on: [{ selector: { item: {} } }] }) - .svgSelector).toEqual(null); + expect(new AnnotationResource({ on: [{ selector: { item: {} } }] }).svgSelector).toEqual( + null, + ); }); }); }); diff --git a/__tests__/src/lib/CanvasWorld.test.js b/__tests__/src/lib/CanvasWorld.test.js index a07f51b36..f5de9c8d4 100644 --- a/__tests__/src/lib/CanvasWorld.test.js +++ b/__tests__/src/lib/CanvasWorld.test.js @@ -10,7 +10,7 @@ const canvasSubset = [canvases[1], canvases[2]]; describe('CanvasWorld', () => { describe('constructor', () => { it('sets canvases', () => { - expect(new CanvasWorld([wrapCanvas(1)]).canvases.map(c => c.canvas)).toEqual([1]); + expect(new CanvasWorld([wrapCanvas(1)]).canvases.map((c) => c.canvas)).toEqual([1]); }); }); describe('hasDimensions', () => { @@ -27,124 +27,149 @@ describe('CanvasWorld', () => { }); describe('contentResourceToWorldCoordinates', () => { it('converts canvas coordinates to world offset by location', () => { - expect(new CanvasWorld([canvases[1]]).contentResourceToWorldCoordinates({ id: 'https://stacks.stanford.edu/image/iiif/fr426cg9537%2FSC1094_s3_b14_f17_Cats_1976_0005/full/full/0/default.jpg' })) - .toEqual([0, 0, 6501, 4421]); - expect(new CanvasWorld(canvasSubset).contentResourceToWorldCoordinates({ id: 'https://stacks.stanford.edu/image/iiif/rz176rt6531%2FPC0170_s3_Tree_Calendar_20081101_152516_0410/full/full/0/default.jpg' })) - .toEqual([6305, 0, 2848, 4288]); + expect( + new CanvasWorld([canvases[1]]).contentResourceToWorldCoordinates({ + id: 'https://stacks.stanford.edu/image/iiif/fr426cg9537%2FSC1094_s3_b14_f17_Cats_1976_0005/full/full/0/default.jpg', + }), + ).toEqual([0, 0, 6501, 4421]); + expect( + new CanvasWorld(canvasSubset).contentResourceToWorldCoordinates({ + id: 'https://stacks.stanford.edu/image/iiif/rz176rt6531%2FPC0170_s3_Tree_Calendar_20081101_152516_0410/full/full/0/default.jpg', + }), + ).toEqual([6305, 0, 2848, 4288]); }); it('supports RTL orientations', () => { - expect(new CanvasWorld(canvasSubset, null, 'right-to-left').contentResourceToWorldCoordinates({ id: 'https://stacks.stanford.edu/image/iiif/rz176rt6531%2FPC0170_s3_Tree_Calendar_20081101_152516_0410/full/full/0/default.jpg' })) - .toEqual([0, 0, 2848, 4288]); + expect( + new CanvasWorld(canvasSubset, null, 'right-to-left').contentResourceToWorldCoordinates({ + id: 'https://stacks.stanford.edu/image/iiif/rz176rt6531%2FPC0170_s3_Tree_Calendar_20081101_152516_0410/full/full/0/default.jpg', + }), + ).toEqual([0, 0, 2848, 4288]); }); it('supports TTB orientations', () => { - expect(new CanvasWorld(canvasSubset, null, 'top-to-bottom').contentResourceToWorldCoordinates({ id: 'https://stacks.stanford.edu/image/iiif/rz176rt6531%2FPC0170_s3_Tree_Calendar_20081101_152516_0410/full/full/0/default.jpg' })) - .toEqual([0, 1936, 2848, 4288]); + expect( + new CanvasWorld(canvasSubset, null, 'top-to-bottom').contentResourceToWorldCoordinates({ + id: 'https://stacks.stanford.edu/image/iiif/rz176rt6531%2FPC0170_s3_Tree_Calendar_20081101_152516_0410/full/full/0/default.jpg', + }), + ).toEqual([0, 1936, 2848, 4288]); }); it('supports BTT orientations', () => { - expect(new CanvasWorld(canvasSubset, null, 'bottom-to-top').contentResourceToWorldCoordinates({ id: 'https://stacks.stanford.edu/image/iiif/rz176rt6531%2FPC0170_s3_Tree_Calendar_20081101_152516_0410/full/full/0/default.jpg' })) - .toEqual([0, 0, 2848, 4288]); + expect( + new CanvasWorld(canvasSubset, null, 'bottom-to-top').contentResourceToWorldCoordinates({ + id: 'https://stacks.stanford.edu/image/iiif/rz176rt6531%2FPC0170_s3_Tree_Calendar_20081101_152516_0410/full/full/0/default.jpg', + }), + ).toEqual([0, 0, 2848, 4288]); }); it('when placed by a fragment contains the offset', () => { const subject = new CanvasWorld( [Utils.parseManifest(fragmentFixture).getSequences()[0].getCanvases()[0]].map(wrapCanvas), ); - expect(subject.contentResourceToWorldCoordinates({ id: 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PC17/full/739,521/0/default.jpg' })) - .toEqual([552, 1584, 3360, 2368]); + expect( + subject.contentResourceToWorldCoordinates({ + id: 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PC17/full/739,521/0/default.jpg', + }), + ).toEqual([552, 1584, 3360, 2368]); }); }); describe('canvasToWorldCoordinates', () => { it('converts canvas coordinates to world offset by location', () => { - expect(new CanvasWorld([canvases[1]]).canvasToWorldCoordinates('https://purl.stanford.edu/fr426cg9537/iiif/canvas/fr426cg9537_1')) - .toEqual([0, 0, 6501, 4421]); - expect(new CanvasWorld(canvasSubset).canvasToWorldCoordinates('https://purl.stanford.edu/rz176rt6531/iiif/canvas/rz176rt6531_1')) - .toEqual([6305, 0, 2848, 4288]); + expect( + new CanvasWorld([canvases[1]]).canvasToWorldCoordinates( + 'https://purl.stanford.edu/fr426cg9537/iiif/canvas/fr426cg9537_1', + ), + ).toEqual([0, 0, 6501, 4421]); + expect( + new CanvasWorld(canvasSubset).canvasToWorldCoordinates( + 'https://purl.stanford.edu/rz176rt6531/iiif/canvas/rz176rt6531_1', + ), + ).toEqual([6305, 0, 2848, 4288]); }); it('supports RTL orientations', () => { - expect(new CanvasWorld(canvasSubset, null, 'right-to-left').canvasToWorldCoordinates('https://purl.stanford.edu/rz176rt6531/iiif/canvas/rz176rt6531_1')) - .toEqual([0, 0, 2848, 4288]); + expect( + new CanvasWorld(canvasSubset, null, 'right-to-left').canvasToWorldCoordinates( + 'https://purl.stanford.edu/rz176rt6531/iiif/canvas/rz176rt6531_1', + ), + ).toEqual([0, 0, 2848, 4288]); }); }); describe('offsetByCanvas', () => { it('calculates an offset that can be used to translate annotations', () => { expect( - new CanvasWorld(canvasSubset).offsetByCanvas('https://purl.stanford.edu/fr426cg9537/iiif/canvas/fr426cg9537_1'), + new CanvasWorld(canvasSubset).offsetByCanvas( + 'https://purl.stanford.edu/fr426cg9537/iiif/canvas/fr426cg9537_1', + ), ).toEqual({ x: 0, y: 0 }); expect( - new CanvasWorld(canvasSubset).offsetByCanvas('https://purl.stanford.edu/rz176rt6531/iiif/canvas/rz176rt6531_1'), + new CanvasWorld(canvasSubset).offsetByCanvas( + 'https://purl.stanford.edu/rz176rt6531/iiif/canvas/rz176rt6531_1', + ), ).toEqual({ x: 6305, y: 0 }); }); }); describe('layerOpacityOfImageResource', () => { - const tileSource1 = { id: 'https://stacks.stanford.edu/image/iiif/fr426cg9537%2FSC1094_s3_b14_f17_Cats_1976_0005/full/full/0/default.jpg' }; + const tileSource1 = { + id: 'https://stacks.stanford.edu/image/iiif/fr426cg9537%2FSC1094_s3_b14_f17_Cats_1976_0005/full/full/0/default.jpg', + }; it('returns 0 if the layer is currently hidden', () => { const layers = { 'https://purl.stanford.edu/fr426cg9537/iiif/canvas/fr426cg9537_1': { - 'https://stacks.stanford.edu/image/iiif/fr426cg9537%2FSC1094_s3_b14_f17_Cats_1976_0005/full/full/0/default.jpg': { - visibility: false, - }, + 'https://stacks.stanford.edu/image/iiif/fr426cg9537%2FSC1094_s3_b14_f17_Cats_1976_0005/full/full/0/default.jpg': + { + visibility: false, + }, }, }; - expect( - new CanvasWorld(canvases, layers).layerOpacityOfImageResource(tileSource1), - ).toEqual(0); + expect(new CanvasWorld(canvases, layers).layerOpacityOfImageResource(tileSource1)).toEqual(0); }); it('returns 1 if there is no opacity configuration for the layer', () => { - expect( - new CanvasWorld(canvases).layerOpacityOfImageResource(tileSource1), - ).toEqual(1); + expect(new CanvasWorld(canvases).layerOpacityOfImageResource(tileSource1)).toEqual(1); - expect( - new CanvasWorld(canvases, {}).layerOpacityOfImageResource(tileSource1), - ).toEqual(1); + expect(new CanvasWorld(canvases, {}).layerOpacityOfImageResource(tileSource1)).toEqual(1); const layers = { - 'https://purl.stanford.edu/fr426cg9537/iiif/canvas/fr426cg9537_1': { - }, + 'https://purl.stanford.edu/fr426cg9537/iiif/canvas/fr426cg9537_1': {}, }; - expect( - new CanvasWorld(canvases, layers).layerOpacityOfImageResource(tileSource1), - ).toEqual(1); + expect(new CanvasWorld(canvases, layers).layerOpacityOfImageResource(tileSource1)).toEqual(1); }); it('returns the configured opacity value for the layer', () => { const layers = { 'https://purl.stanford.edu/fr426cg9537/iiif/canvas/fr426cg9537_1': { - 'https://stacks.stanford.edu/image/iiif/fr426cg9537%2FSC1094_s3_b14_f17_Cats_1976_0005/full/full/0/default.jpg': { - opacity: 0.5, - }, + 'https://stacks.stanford.edu/image/iiif/fr426cg9537%2FSC1094_s3_b14_f17_Cats_1976_0005/full/full/0/default.jpg': + { + opacity: 0.5, + }, }, }; - expect( - new CanvasWorld(canvases, layers).layerOpacityOfImageResource(tileSource1), - ).toEqual(0.5); + expect(new CanvasWorld(canvases, layers).layerOpacityOfImageResource(tileSource1)).toEqual( + 0.5, + ); }); }); describe('layerIndexOfImageResource', () => { - const tileSource0 = { id: 'https://stacks.stanford.edu/image/iiif/hg676jb4964%2F0380_796-44/full/full/0/default.jpg' }; + const tileSource0 = { + id: 'https://stacks.stanford.edu/image/iiif/hg676jb4964%2F0380_796-44/full/full/0/default.jpg', + }; it('returns actual index of the image annotation', () => { - expect( - new CanvasWorld(canvases).layerIndexOfImageResource(tileSource0), - ).toEqual(0); + expect(new CanvasWorld(canvases).layerIndexOfImageResource(tileSource0)).toEqual(0); }); it('returns the inverse of the configured index', () => { const layers = { 'http://iiif.io/api/presentation/2.0/example/fixtures/canvas/24/c1.json': { - 'https://stacks.stanford.edu/image/iiif/hg676jb4964%2F0380_796-44/full/full/0/default.jpg': { - index: 0, - }, + 'https://stacks.stanford.edu/image/iiif/hg676jb4964%2F0380_796-44/full/full/0/default.jpg': + { + index: 0, + }, }, }; - expect( - new CanvasWorld(canvases, layers).layerIndexOfImageResource(tileSource0), - ).toEqual(0); + expect(new CanvasWorld(canvases, layers).layerIndexOfImageResource(tileSource0)).toEqual(0); }); }); describe('canvasAtPoint', () => { diff --git a/__tests__/src/lib/MiradorCanvas.test.js b/__tests__/src/lib/MiradorCanvas.test.js index de4dc1375..ef6618ae0 100644 --- a/__tests__/src/lib/MiradorCanvas.test.js +++ b/__tests__/src/lib/MiradorCanvas.test.js @@ -14,9 +14,7 @@ import videoWithAnnoCaptions from '../../fixtures/version-3/video_with_annotatio describe('MiradorCanvas', () => { let instance; beforeEach(() => { - instance = new MiradorCanvas( - Utils.parseManifest(fixture).getSequences()[0].getCanvases()[0], - ); + instance = new MiradorCanvas(Utils.parseManifest(fixture).getSequences()[0].getCanvases()[0]); }); describe('annotationListUris', () => { describe('when no annotationLists are present', () => { @@ -74,7 +72,9 @@ describe('MiradorCanvas', () => { Utils.parseManifest(fragmentFixture).getSequences()[0].getCanvases()[0], ); expect( - instance.resourceAnnotation('https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PC17/full/739,521/0/default.jpg').id, + instance.resourceAnnotation( + 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PC17/full/739,521/0/default.jpg', + ).id, ).toEqual('https://prtd.app/hamilton/canvas/p1/anno-02.json'); }); it('returns the containing Annotation for a given contentResource id v3', () => { @@ -82,7 +82,9 @@ describe('MiradorCanvas', () => { Utils.parseManifest(fragmentFixtureV3).getSequences()[0].getCanvases()[0], ); expect( - instance.resourceAnnotation('https://images.prtd.app/iiif/2/hamilton%2fHL_524_1r_00_PC17/full/739,521/0/default.jpg').id, + instance.resourceAnnotation( + 'https://images.prtd.app/iiif/2/hamilton%2fHL_524_1r_00_PC17/full/739,521/0/default.jpg', + ).id, ).toEqual('https://dvp.prtd.app/hamilton/canvas/p1/anno-02.json'); }); }); @@ -92,7 +94,9 @@ describe('MiradorCanvas', () => { Utils.parseManifest(fragmentFixture).getSequences()[0].getCanvases()[0], ); expect( - instance.onFragment('https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PC17/full/739,521/0/default.jpg'), + instance.onFragment( + 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PC17/full/739,521/0/default.jpg', + ), ).toEqual([552, 1584, 3360, 2368]); }); it('when a fragment selector exists for a given contentResources id, returns that fragment v3', () => { @@ -100,7 +104,9 @@ describe('MiradorCanvas', () => { Utils.parseManifest(fragmentFixtureV3).getSequences()[0].getCanvases()[0], ); expect( - instance.onFragment('https://images.prtd.app/iiif/2/hamilton%2fHL_524_1r_00_PC17/full/739,521/0/default.jpg'), + instance.onFragment( + 'https://images.prtd.app/iiif/2/hamilton%2fHL_524_1r_00_PC17/full/739,521/0/default.jpg', + ), ).toEqual([552, 1584, 3360, 2368]); }); }); @@ -136,9 +142,7 @@ describe('MiradorCanvas', () => { }); describe('IIIF image annotations', () => { it('sets preferred=true for prezi v2 image annotations without Choices', () => { - instance = new MiradorCanvas( - Utils.parseManifest(fixture).getSequences()[0].getCanvases()[0], - ); + instance = new MiradorCanvas(Utils.parseManifest(fixture).getSequences()[0].getCanvases()[0]); expect(instance.imageResources[0].preferred).toBe(true); }); @@ -146,9 +150,17 @@ describe('MiradorCanvas', () => { instance = new MiradorCanvas( Utils.parseManifest(fragmentFixtureV3).getSequences()[0].getCanvases()[0], ); - const firstImgWithoutChoice = instance.imageResources.find((resource) => resource.id === 'https://images.prtd.app/iiif/2/hamilton%2fHL_524_1r_00_PC17/full/739,521/0/default.jpg'); + const firstImgWithoutChoice = instance.imageResources.find( + (resource) => + resource.id === + 'https://images.prtd.app/iiif/2/hamilton%2fHL_524_1r_00_PC17/full/739,521/0/default.jpg', + ); expect(firstImgWithoutChoice.preferred).toBe(true); - const lastImgWithoutChoice = instance.imageResources.find((resource) => resource.id === 'https://images.prtd.app/iiif/2/hamilton%2fHL_524_1r_00_PCA_RGB-1-3-5_gradi/full/739,521/0/default.jpg'); + const lastImgWithoutChoice = instance.imageResources.find( + (resource) => + resource.id === + 'https://images.prtd.app/iiif/2/hamilton%2fHL_524_1r_00_PCA_RGB-1-3-5_gradi/full/739,521/0/default.jpg', + ); expect(lastImgWithoutChoice.preferred).toBe(true); }); @@ -156,7 +168,11 @@ describe('MiradorCanvas', () => { instance = new MiradorCanvas( Utils.parseManifest(fragmentFixture).getSequences()[0].getCanvases()[0], ); - const preferredOption = instance.imageResources.find((resource) => resource.id === 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PSC/full/862,1024/0/default.jpg'); + const preferredOption = instance.imageResources.find( + (resource) => + resource.id === + 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PSC/full/862,1024/0/default.jpg', + ); expect(preferredOption.preferred).toBe(true); }); @@ -164,7 +180,11 @@ describe('MiradorCanvas', () => { instance = new MiradorCanvas( Utils.parseManifest(fragmentFixtureV3).getSequences()[0].getCanvases()[0], ); - const preferredOption = instance.imageResources.find((resource) => resource.id === 'https://images.prtd.app/iiif/2/hamilton%2fHL_524_1r_00_PSC/full/,800/0/default.jpg'); + const preferredOption = instance.imageResources.find( + (resource) => + resource.id === + 'https://images.prtd.app/iiif/2/hamilton%2fHL_524_1r_00_PSC/full/,800/0/default.jpg', + ); expect(preferredOption.preferred).toBe(true); }); @@ -172,9 +192,17 @@ describe('MiradorCanvas', () => { instance = new MiradorCanvas( Utils.parseManifest(fragmentFixture).getSequences()[0].getCanvases()[0], ); - const firstAlternative = instance.imageResources.find((img) => img.id === 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_TS_Blue/full/862,1024/0/default.png'); + const firstAlternative = instance.imageResources.find( + (img) => + img.id === + 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_TS_Blue/full/862,1024/0/default.png', + ); expect(firstAlternative.preferred).toBe(false); - const lastAlternative = instance.imageResources.find((img) => img.id === 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_017_F/full/862,1024/0/default.jpg'); + const lastAlternative = instance.imageResources.find( + (img) => + img.id === + 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_017_F/full/862,1024/0/default.jpg', + ); expect(lastAlternative.preferred).toBe(false); }); @@ -182,9 +210,17 @@ describe('MiradorCanvas', () => { instance = new MiradorCanvas( Utils.parseManifest(fragmentFixtureV3).getSequences()[0].getCanvases()[0], ); - const firstAlternative = instance.imageResources.find((img) => img.id === 'https://images.prtd.app/iiif/2/hamilton%2fHL_524_1r_00_TS_Blue/full/862,1024/0/default.png'); + const firstAlternative = instance.imageResources.find( + (img) => + img.id === + 'https://images.prtd.app/iiif/2/hamilton%2fHL_524_1r_00_TS_Blue/full/862,1024/0/default.png', + ); expect(firstAlternative.preferred).toBe(false); - const lastAlternative = instance.imageResources.find((img) => img.id === 'https://images.prtd.app/iiif/2/hamilton%2fHL_524_1r_00_017_F/full/,800/0/default.jpg'); + const lastAlternative = instance.imageResources.find( + (img) => + img.id === + 'https://images.prtd.app/iiif/2/hamilton%2fHL_524_1r_00_017_F/full/,800/0/default.jpg', + ); expect(lastAlternative.preferred).toBe(false); }); }); diff --git a/__tests__/src/lib/MiradorManifest.test.js b/__tests__/src/lib/MiradorManifest.test.js index 7832fa97e..13c16f8c5 100644 --- a/__tests__/src/lib/MiradorManifest.test.js +++ b/__tests__/src/lib/MiradorManifest.test.js @@ -11,20 +11,21 @@ describe('MiradorCanvas', () => { it('gets the startCanvas index for a IIIF v2 manifest', () => { const manifest = { '@context': 'http://iiif.io/api/presentation/2/context.json', - '@id': - 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', + '@id': 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', '@type': 'sc:Manifest', - sequences: [{ - canvases: [ - { - '@id': 'http://example.com/1', - }, - { - '@id': 'http://example.com/2', - }, - ], - startCanvas: 'http://example.com/2', - }], + sequences: [ + { + canvases: [ + { + '@id': 'http://example.com/1', + }, + { + '@id': 'http://example.com/2', + }, + ], + startCanvas: 'http://example.com/2', + }, + ], }; expect(getSubject(manifest).startCanvas.id).toEqual('http://example.com/2'); }); @@ -32,19 +33,20 @@ describe('MiradorCanvas', () => { it('gets the start data for a IIIF v3 manifest', () => { const manifest = { '@context': 'http://iiif.io/api/presentation/2/context.json', - '@id': - 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', + '@id': 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', '@type': 'sc:Manifest', - sequences: [{ - canvases: [ - { - '@id': 'http://example.com/1', - }, - { - '@id': 'http://example.com/2', - }, - ], - }], + sequences: [ + { + canvases: [ + { + '@id': 'http://example.com/1', + }, + { + '@id': 'http://example.com/2', + }, + ], + }, + ], start: { source: 'http://example.com/2' }, }; expect(getSubject(manifest).startCanvas.id).toEqual('http://example.com/2'); @@ -55,20 +57,21 @@ describe('MiradorCanvas', () => { it('gets the canvas at the specified index', () => { const manifest = { '@context': 'http://iiif.io/api/presentation/2/context.json', - '@id': - 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', + '@id': 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', '@type': 'sc:Manifest', - sequences: [{ - canvases: [ - { - '@id': 'http://example.com/1', - }, - { - '@id': 'http://example.com/2', - }, - ], - startCanvas: 'http://example.com/2', - }], + sequences: [ + { + canvases: [ + { + '@id': 'http://example.com/1', + }, + { + '@id': 'http://example.com/2', + }, + ], + startCanvas: 'http://example.com/2', + }, + ], }; expect(getSubject(manifest).canvasAt(1).id).toEqual('http://example.com/2'); }); diff --git a/__tests__/src/lib/MiradorViewer.test.js b/__tests__/src/lib/MiradorViewer.test.js index ef4e801d2..7082c5a94 100644 --- a/__tests__/src/lib/MiradorViewer.test.js +++ b/__tests__/src/lib/MiradorViewer.test.js @@ -16,14 +16,18 @@ describe('MiradorViewer', () => { const instance = new MiradorViewer({}); // eslint-disable-next-line testing-library/no-unnecessary-act - act(() => { instance.renderInto(container); }); + act(() => { + instance.renderInto(container); + }); expect(instance.store.dispatch).toBeDefined(); }); it('renders via ReactDOM', () => { const instance = new MiradorViewer({}); // eslint-disable-next-line testing-library/no-unnecessary-act - act(() => { instance.renderInto(container); }); + act(() => { + instance.renderInto(container); + }); expect(screen.getByTestId('container')).not.toBeEmptyDOMElement(); }); @@ -33,11 +37,15 @@ describe('MiradorViewer', () => { const instance = new MiradorViewer( { catalog: [ - { manifestId: 'http://media.nga.gov/public/manifests/nga_highlights.json', provider: 'National Gallery of Art' }, + { + manifestId: 'http://media.nga.gov/public/manifests/nga_highlights.json', + provider: 'National Gallery of Art', + }, ], windows: [ { - canvasId: 'https://iiif.harvardartmuseums.org/manifests/object/299843/canvas/canvas-47174892', + canvasId: + 'https://iiif.harvardartmuseums.org/manifests/object/299843/canvas/canvas-47174892', loadedManifest: 'https://iiif.harvardartmuseums.org/manifests/object/299843', thumbnailNavigationPosition: 'far-bottom', }, @@ -48,24 +56,30 @@ describe('MiradorViewer', () => { ], }, { - plugins: [{ - component: DummyPlugin, - config: { - foo: 'bar', + plugins: [ + { + component: DummyPlugin, + config: { + foo: 'bar', + }, + mode: 'add', + target: 'WindowTopBarPluginArea', }, - mode: 'add', - target: 'WindowTopBarPluginArea', - }], + ], }, ); // eslint-disable-next-line testing-library/no-unnecessary-act - act(() => { instance.renderInto(container); }); + act(() => { + instance.renderInto(container); + }); const { windows, catalog, config } = instance.store.getState(); const windowIds = Object.keys(windows); expect(Object.keys(windowIds).length).toBe(2); - expect(windows[windowIds[0]].canvasId).toBe('https://iiif.harvardartmuseums.org/manifests/object/299843/canvas/canvas-47174892'); + expect(windows[windowIds[0]].canvasId).toBe( + 'https://iiif.harvardartmuseums.org/manifests/object/299843/canvas/canvas-47174892', + ); expect(windows[windowIds[1]].canvasId).toBe(undefined); expect(windows[windowIds[0]].thumbnailNavigationPosition).toBe('far-bottom'); expect(windows[windowIds[1]].thumbnailNavigationPosition).toBe(undefined); @@ -73,8 +87,12 @@ describe('MiradorViewer', () => { expect(windows[windowIds[1]].view).toBe('book'); expect(catalog.length).toBe(2); - expect(catalog[0].manifestId).toBe('https://iiif.harvardartmuseums.org/manifests/object/299843'); - expect(catalog[1].manifestId).toBe('http://media.nga.gov/public/manifests/nga_highlights.json'); + expect(catalog[0].manifestId).toBe( + 'https://iiif.harvardartmuseums.org/manifests/object/299843', + ); + expect(catalog[1].manifestId).toBe( + 'http://media.nga.gov/public/manifests/nga_highlights.json', + ); expect(catalog[1].provider).toBe('National Gallery of Art'); expect(config.foo).toBe('bar'); }); @@ -114,21 +132,25 @@ describe('MiradorViewer', () => { const { config } = instance.store.getState(); - expect(config.translations.en).toEqual(expect.objectContaining({ - bat: 'bar', - foo: 'bar', - })); + expect(config.translations.en).toEqual( + expect.objectContaining({ + bat: 'bar', + foo: 'bar', + }), + ); }); }); describe('render', () => { it('passes props through to the App component', async () => { const instance = new MiradorViewer({}); - const plugins = [{ - component: DummyPlugin, - mode: 'wrap', - target: 'AppProviders', - }]; + const plugins = [ + { + component: DummyPlugin, + mode: 'wrap', + target: 'AppProviders', + }, + ]; render(instance.render({ plugins })); @@ -141,10 +163,14 @@ describe('MiradorViewer', () => { const instance = new MiradorViewer({}); // eslint-disable-next-line testing-library/no-unnecessary-act - act(() => { instance.renderInto(container); }); + act(() => { + instance.renderInto(container); + }); expect(container).not.toBeEmptyDOMElement(); // eslint-disable-next-line testing-library/no-unnecessary-act - act(() => { instance.unmount(); }); + act(() => { + instance.unmount(); + }); expect(container).toBeEmptyDOMElement(); }); }); diff --git a/__tests__/src/lib/OpenSeadragonCanvasOverlay.test.js b/__tests__/src/lib/OpenSeadragonCanvasOverlay.test.js index 49f212444..64338e80c 100644 --- a/__tests__/src/lib/OpenSeadragonCanvasOverlay.test.js +++ b/__tests__/src/lib/OpenSeadragonCanvasOverlay.test.js @@ -58,7 +58,8 @@ describe('OpenSeadragonCanvasOverlay', () => { getContext: contextMock, }, }; - canvasOverlay.context2d; // eslint-disable-line no-unused-expressions + // eslint-disable-next-line no-unused-expressions + canvasOverlay.context2d; expect(contextMock).toHaveBeenCalledTimes(1); }); }); diff --git a/__tests__/src/lib/ThumbnailFactory.test.js b/__tests__/src/lib/ThumbnailFactory.test.js index 6f0cc3cfe..6b9ca0a92 100644 --- a/__tests__/src/lib/ThumbnailFactory.test.js +++ b/__tests__/src/lib/ThumbnailFactory.test.js @@ -1,6 +1,4 @@ -import { - ManifestResource, Resource, Service, Utils, -} from 'manifesto.js'; +import { ManifestResource, Resource, Service, Utils } from 'manifesto.js'; import getThumbnail, { ThumbnailFactory } from '../../../src/lib/ThumbnailFactory'; import fixture from '../../fixtures/version-2/019.json'; @@ -22,7 +20,7 @@ function createImageSubject(jsonld, iiifOpts) { /** */ function iiifService(url, props = {}, serviceProps = {}) { - return ({ + return { id: 'arbitrary-url', ...props, service: [ @@ -33,7 +31,7 @@ function iiifService(url, props = {}, serviceProps = {}) { ...serviceProps, }, ], - }); + }; } describe('getThumbnail', () => { @@ -52,32 +50,61 @@ describe('getThumbnail', () => { for (const type of ['Collection', 'Manifest', 'Canvas', 'Image']) { describe('with a thumbnail', () => { it('return the thumbnail and metadata', () => { - expect(createSubject({ '@id': 'xyz', '@type': type, thumbnail: { '@id': url, height: 70, width: 50 } }, type)).toMatchObject({ height: 70, url, width: 50 }); + expect( + createSubject( + { '@id': 'xyz', '@type': type, thumbnail: { '@id': url, height: 70, width: 50 } }, + type, + ), + ).toMatchObject({ height: 70, url, width: 50 }); }); it('return the IIIF service of the thumbnail', () => { - expect(createSubject({ '@id': 'xyz', '@type': type, thumbnail: iiifLevel1Service }, type)).toMatchObject({ url: `${url}/full/,120/0/default.jpg` }); + expect( + createSubject({ '@id': 'xyz', '@type': type, thumbnail: iiifLevel1Service }, type), + ).toMatchObject({ url: `${url}/full/,120/0/default.jpg` }); }); describe('with image size constraints', () => { it('does nothing with a static resource', () => { - expect(createSubject({ '@id': 'xyz', '@type': type, thumbnail: { '@id': url } }, type, { maxWidth: 50 })).toMatchObject({ url }); + expect( + createSubject({ '@id': 'xyz', '@type': type, thumbnail: { '@id': url } }, type, { + maxWidth: 50, + }), + ).toMatchObject({ url }); }); it('does nothing with a IIIF level 0 service', () => { - expect(createSubject({ '@id': 'xyz', '@type': type, thumbnail: iiifLevel0Service }, type, { maxWidth: 50 })).toMatchObject({ url: 'arbitrary-url' }); + expect( + createSubject({ '@id': 'xyz', '@type': type, thumbnail: iiifLevel0Service }, type, { + maxWidth: 50, + }), + ).toMatchObject({ url: 'arbitrary-url' }); }); it('calculates constraints for a IIIF level 1 service', () => { - expect(createSubject({ '@id': 'xyz', '@type': type, thumbnail: iiifLevel1Service }, type, { maxWidth: 150 })).toMatchObject({ height: 300, url: `${url}/full/150,/0/default.jpg`, width: 150 }); + expect( + createSubject({ '@id': 'xyz', '@type': type, thumbnail: iiifLevel1Service }, type, { + maxWidth: 150, + }), + ).toMatchObject({ height: 300, url: `${url}/full/150,/0/default.jpg`, width: 150 }); }); it('calculates constraints for a IIIF level 2 service', () => { - expect(createSubject({ '@id': 'xyz', '@type': type, thumbnail: iiifLevel2Service }, type, { maxHeight: 200, maxWidth: 150 })).toMatchObject({ height: 200, url: `${url}/full/!150,200/0/default.jpg`, width: 100 }); + expect( + createSubject({ '@id': 'xyz', '@type': type, thumbnail: iiifLevel2Service }, type, { + maxHeight: 200, + maxWidth: 150, + }), + ).toMatchObject({ height: 200, url: `${url}/full/!150,200/0/default.jpg`, width: 100 }); }); it('applies a minumum size to image constraints to encourage asset reuse', () => { - expect(createSubject({ '@id': 'xyz', '@type': type, thumbnail: iiifLevel2Service }, type, { maxHeight: 100, maxWidth: 100 })).toMatchObject({ height: 120, url: `${url}/full/!120,120/0/default.jpg`, width: 60 }); + expect( + createSubject({ '@id': 'xyz', '@type': type, thumbnail: iiifLevel2Service }, type, { + maxHeight: 100, + maxWidth: 100, + }), + ).toMatchObject({ height: 120, url: `${url}/full/!120,120/0/default.jpg`, width: 60 }); }); }); }); @@ -87,58 +114,76 @@ describe('getThumbnail', () => { describe('with an image resource', () => { describe('without a IIIF service', () => { it('uses the thumbnail', () => { - expect(createImageSubject({ '@id': 'xyz', '@type': 'Image', thumbnail: { '@id': url, height: 70, width: 50 } })).toMatchObject({ height: 70, url, width: 50 }); + expect( + createImageSubject({ + '@id': 'xyz', + '@type': 'Image', + thumbnail: { '@id': url, height: 70, width: 50 }, + }), + ).toMatchObject({ height: 70, url, width: 50 }); }); }); describe('with a level 0 IIIF service', () => { it('returns the image', () => { - expect(createImageSubject({ - ...iiifLevel0Service, - id: 'xyz', - type: 'Image', - })).toMatchObject({ url: 'xyz' }); + expect( + createImageSubject({ + ...iiifLevel0Service, + id: 'xyz', + type: 'Image', + }), + ).toMatchObject({ url: 'xyz' }); }); it('uses embedded sizes to find an appropriate size', () => { const obj = { - ...(iiifService('some-url', {}, { profile: 'level0', sizes })), + ...iiifService('some-url', {}, { profile: 'level0', sizes }), id: 'xyz', type: 'Image', }; - expect(createImageSubject(obj, { maxHeight: 120, maxWidth: 120 })) - .toMatchObject({ height: 125, width: 125 }); + expect(createImageSubject(obj, { maxHeight: 120, maxWidth: 120 })).toMatchObject({ + height: 125, + width: 125, + }); }); }); describe('with a IIIF service', () => { it('prefers the image service over a non-IIIF thumbnail', () => { - expect(createImageSubject({ - ...iiifLevel1Service, - id: 'xyz', - thumbnail: { '@id': 'some-url', height: 70, width: 50 }, - type: 'Image', - })).toMatchObject({ url: `${url}/full/,120/0/default.jpg` }); + expect( + createImageSubject({ + ...iiifLevel1Service, + id: 'xyz', + thumbnail: { '@id': 'some-url', height: 70, width: 50 }, + type: 'Image', + }), + ).toMatchObject({ url: `${url}/full/,120/0/default.jpg` }); }); it('prefers a IIIF thumbnail over the image service', () => { - expect(createImageSubject({ - ...(iiifService('some-url', {}, { profile: 'level1' })), - id: 'xyz', - thumbnail: { ...iiifLevel1Service }, - type: 'Image', - })).toMatchObject({ url: `${url}/full/,120/0/default.jpg` }); + expect( + createImageSubject({ + ...iiifService('some-url', {}, { profile: 'level1' }), + id: 'xyz', + thumbnail: { ...iiifLevel1Service }, + type: 'Image', + }), + ).toMatchObject({ url: `${url}/full/,120/0/default.jpg` }); }); }); }); describe('with a canvas', () => { it('uses the thumbnail', () => { - expect(createSubject({ ...canvas.__jsonld, thumbnail: { ...iiifLevel1Service } }, 'Canvas')).toMatchObject({ url: `${url}/full/,120/0/default.jpg` }); + expect( + createSubject({ ...canvas.__jsonld, thumbnail: { ...iiifLevel1Service } }, 'Canvas'), + ).toMatchObject({ url: `${url}/full/,120/0/default.jpg` }); }); it('uses the first image resource', () => { - expect(getThumbnail(canvas)).toMatchObject({ url: 'https://stacks.stanford.edu/image/iiif/hg676jb4964%2F0380_796-44/full/,120/0/default.jpg' }); + expect(getThumbnail(canvas)).toMatchObject({ + url: 'https://stacks.stanford.edu/image/iiif/hg676jb4964%2F0380_796-44/full/,120/0/default.jpg', + }); }); it('uses the width and height of a thumbnail without a IIIF Image API service', () => { @@ -150,7 +195,11 @@ describe('getThumbnail', () => { width: 180, }, }; - expect(createSubject(myCanvas, 'Canvas')).toMatchObject({ height: 240, url: 'arbitrary-url', width: 180 }); + expect(createSubject(myCanvas, 'Canvas')).toMatchObject({ + height: 240, + url: 'arbitrary-url', + width: 180, + }); }); it('uses embedded sizes of a IIIF Image API service to find an appropriate size', () => { @@ -159,17 +208,22 @@ describe('getThumbnail', () => { thumbnail: { height: 100, id: 'arbitrary-url', - service: [{ - id: url, - profile: 'level2', - sizes, - type: 'ImageService3', - }], + service: [ + { + id: url, + profile: 'level2', + sizes, + type: 'ImageService3', + }, + ], width: 100, }, }; - expect(createSubject(myCanvas, 'Canvas', { maxHeight: 120, maxWidth: 120 })) - .toMatchObject({ height: 125, url: `${url}/full/125,125/0/default.jpg`, width: 125 }); + expect(createSubject(myCanvas, 'Canvas', { maxHeight: 120, maxWidth: 120 })).toMatchObject({ + height: 125, + url: `${url}/full/125,125/0/default.jpg`, + width: 125, + }); }); }); @@ -189,16 +243,25 @@ describe('getThumbnail', () => { thumbnail: { ...iiifLevel1Service }, }); - expect(getThumbnail(manifestWithThumbnail)).toMatchObject({ url: `${url}/full/,120/0/default.jpg` }); + expect(getThumbnail(manifestWithThumbnail)).toMatchObject({ + url: `${url}/full/,120/0/default.jpg`, + }); }); it('uses the startCanvas', () => { - const manifestWithStartCanvas = Utils.parseManifest({ ...manifest.__jsonld, start: { id: 'https://purl.stanford.edu/fr426cg9537/iiif/canvas/fr426cg9537_1' } }); - expect(getThumbnail(manifestWithStartCanvas)).toMatchObject({ url: 'https://stacks.stanford.edu/image/iiif/fr426cg9537%2FSC1094_s3_b14_f17_Cats_1976_0005/full/,120/0/default.jpg' }); + const manifestWithStartCanvas = Utils.parseManifest({ + ...manifest.__jsonld, + start: { id: 'https://purl.stanford.edu/fr426cg9537/iiif/canvas/fr426cg9537_1' }, + }); + expect(getThumbnail(manifestWithStartCanvas)).toMatchObject({ + url: 'https://stacks.stanford.edu/image/iiif/fr426cg9537%2FSC1094_s3_b14_f17_Cats_1976_0005/full/,120/0/default.jpg', + }); }); it('uses the first canvas', () => { - expect(getThumbnail(manifest)).toMatchObject({ url: 'https://stacks.stanford.edu/image/iiif/hg676jb4964%2F0380_796-44/full/,120/0/default.jpg' }); + expect(getThumbnail(manifest)).toMatchObject({ + url: 'https://stacks.stanford.edu/image/iiif/hg676jb4964%2F0380_796-44/full/,120/0/default.jpg', + }); }); }); @@ -243,7 +306,9 @@ describe('getThumbnail', () => { ], type: 'Collection', }); - expect(getThumbnail(collection)).toMatchObject({ url: 'https://example.org/manifest1/thumbnail.jpg' }); + expect(getThumbnail(collection)).toMatchObject({ + url: 'https://example.org/manifest1/thumbnail.jpg', + }); }); }); }); @@ -257,16 +322,19 @@ describe('picking the best format', () => { thumbnail: { height: 100, id: 'arbitrary-url', - service: [{ - id: url, - profile: 'level2', - type: 'ImageService3', - }], + service: [ + { + id: url, + profile: 'level2', + type: 'ImageService3', + }, + ], width: 100, }, }; - expect(createSubject(myCanvas, 'Canvas')) - .toMatchObject({ url: `${url}/full/,120/0/default.jpg` }); + expect(createSubject(myCanvas, 'Canvas')).toMatchObject({ + url: `${url}/full/,120/0/default.jpg`, + }); }); it('uses the preferred format of the service', () => { @@ -275,17 +343,20 @@ describe('picking the best format', () => { thumbnail: { height: 100, id: 'arbitrary-url', - service: [{ - id: url, - preferredFormats: ['webp'], - profile: 'level2', - type: 'ImageService3', - }], + service: [ + { + id: url, + preferredFormats: ['webp'], + profile: 'level2', + type: 'ImageService3', + }, + ], width: 100, }, }; - expect(createSubject(myCanvas, 'Canvas')) - .toMatchObject({ url: `${url}/full/,120/0/default.webp` }); + expect(createSubject(myCanvas, 'Canvas')).toMatchObject({ + url: `${url}/full/,120/0/default.webp`, + }); }); it('can be filtered by application preferred formats', () => { @@ -294,17 +365,20 @@ describe('picking the best format', () => { thumbnail: { height: 100, id: 'arbitrary-url', - service: [{ - id: url, - preferredFormats: ['webp', 'png'], - profile: 'level2', - type: 'ImageService3', - }], + service: [ + { + id: url, + preferredFormats: ['webp', 'png'], + profile: 'level2', + type: 'ImageService3', + }, + ], width: 100, }, }; - expect(createSubject(myCanvas, 'Canvas', { preferredFormats: ['png', 'jpg'] })) - .toMatchObject({ url: `${url}/full/,120/0/default.png` }); + expect(createSubject(myCanvas, 'Canvas', { preferredFormats: ['png', 'jpg'] })).toMatchObject({ + url: `${url}/full/,120/0/default.png`, + }); }); }); @@ -325,8 +399,9 @@ describe('selectBestImageSize', () => { type: 'ImageService3', }); - expect(ThumbnailFactory.selectBestImageSize(service, targetWidth * targetHeight)) - .toEqual(sizes[1]); + expect(ThumbnailFactory.selectBestImageSize(service, targetWidth * targetHeight)).toEqual( + sizes[1], + ); }); it('selects the largest size smaller than the target, if none larger are available', () => { @@ -342,7 +417,8 @@ describe('selectBestImageSize', () => { type: 'ImageService3', }); - expect(ThumbnailFactory.selectBestImageSize(service, targetWidth * targetHeight)) - .toEqual(sizes[2]); + expect(ThumbnailFactory.selectBestImageSize(service, targetWidth * targetHeight)).toEqual( + sizes[2], + ); }); }); diff --git a/__tests__/src/lib/TruncatedHit.test.js b/__tests__/src/lib/TruncatedHit.test.js index e7bdf3e21..7382f1ec8 100644 --- a/__tests__/src/lib/TruncatedHit.test.js +++ b/__tests__/src/lib/TruncatedHit.test.js @@ -2,9 +2,15 @@ import TruncatedHit from '../../../src/lib/TruncatedHit'; describe('TruncatedHit', () => { const annotation = { resource: { resource: { chars: 'xyz' } } }; - const th = new TruncatedHit({ - after: 'aaaaa', before: 'bbbbb', match: 'four', - }, annotation, { maxChars: 10, minimum: 1 }); + const th = new TruncatedHit( + { + after: 'aaaaa', + before: 'bbbbb', + match: 'four', + }, + annotation, + { maxChars: 10, minimum: 1 }, + ); const matchOnly = new TruncatedHit({ match: 'four' }, annotation, { maxChars: 10 }); describe('charsOnSide', () => { @@ -12,9 +18,15 @@ describe('TruncatedHit', () => { expect(th.charsOnSide).toEqual(3); }); it('uses a minimum value for each side to account for beginning/end', () => { - const min = new TruncatedHit({ - after: 'aaaaa', before: 'bbbbb', match: 'four', - }, undefined, { maxChars: 10, minimum: 10 }); + const min = new TruncatedHit( + { + after: 'aaaaa', + before: 'bbbbb', + match: 'four', + }, + undefined, + { maxChars: 10, minimum: 10 }, + ); expect(min.charsOnSide).toEqual(10); }); it('with only a match', () => { diff --git a/__tests__/src/reducers/accessTokens.test.js b/__tests__/src/reducers/accessTokens.test.js index 020c450f6..20bee40b2 100644 --- a/__tests__/src/reducers/accessTokens.test.js +++ b/__tests__/src/reducers/accessTokens.test.js @@ -3,11 +3,16 @@ import ActionTypes from '../../../src/state/actions/action-types'; describe('access tokens response reducer', () => { it('should handle REQUEST_ACCESS_TOKEN', () => { - expect(accessTokensReducer({}, { - authId: 'auth123', - serviceId: 'abc123', - type: ActionTypes.REQUEST_ACCESS_TOKEN, - })).toEqual({ + expect( + accessTokensReducer( + {}, + { + authId: 'auth123', + serviceId: 'abc123', + type: ActionTypes.REQUEST_ACCESS_TOKEN, + }, + ), + ).toEqual({ abc123: { authId: 'auth123', id: 'abc123', @@ -16,19 +21,21 @@ describe('access tokens response reducer', () => { }); }); it('should handle RECEIVE_ACCESS_TOKEN', () => { - expect(accessTokensReducer( - { - abc123: { - id: 'abc123', - isFetching: true, + expect( + accessTokensReducer( + { + abc123: { + id: 'abc123', + isFetching: true, + }, }, - }, - { - json: { data: true }, - serviceId: 'abc123', - type: ActionTypes.RECEIVE_ACCESS_TOKEN, - }, - )).toMatchObject({ + { + json: { data: true }, + serviceId: 'abc123', + type: ActionTypes.RECEIVE_ACCESS_TOKEN, + }, + ), + ).toMatchObject({ abc123: { id: 'abc123', isFetching: false, @@ -37,19 +44,21 @@ describe('access tokens response reducer', () => { }); }); it('should handle RECEIVE_INFO_RESPONSE_FAILURE', () => { - expect(accessTokensReducer( - { - abc123: { - id: 'abc123', - isFetching: true, + expect( + accessTokensReducer( + { + abc123: { + id: 'abc123', + isFetching: true, + }, }, - }, - { - error: "This institution didn't enable CORS.", - serviceId: 'abc123', - type: ActionTypes.RECEIVE_ACCESS_TOKEN_FAILURE, - }, - )).toMatchObject({ + { + error: "This institution didn't enable CORS.", + serviceId: 'abc123', + type: ActionTypes.RECEIVE_ACCESS_TOKEN_FAILURE, + }, + ), + ).toMatchObject({ abc123: { error: "This institution didn't enable CORS.", id: 'abc123', @@ -59,18 +68,28 @@ describe('access tokens response reducer', () => { }); describe('should handle RESET_AUTHENTICATION_STATE', () => { it('does nothing if tokenServiceId is not present', () => { - expect(accessTokensReducer({}, { - tokenServiceId: 'foo', - type: ActionTypes.RESET_AUTHENTICATION_STATE, - })).toEqual({}); + expect( + accessTokensReducer( + {}, + { + tokenServiceId: 'foo', + type: ActionTypes.RESET_AUTHENTICATION_STATE, + }, + ), + ).toEqual({}); }); it('removes tokenServiceId', () => { - expect(accessTokensReducer({ - foo: 'otherStuff', - }, { - tokenServiceId: 'foo', - type: ActionTypes.RESET_AUTHENTICATION_STATE, - })).toEqual({}); + expect( + accessTokensReducer( + { + foo: 'otherStuff', + }, + { + tokenServiceId: 'foo', + type: ActionTypes.RESET_AUTHENTICATION_STATE, + }, + ), + ).toEqual({}); }); }); }); diff --git a/__tests__/src/reducers/annotations.test.js b/__tests__/src/reducers/annotations.test.js index 7a76ee279..e7763c4e1 100644 --- a/__tests__/src/reducers/annotations.test.js +++ b/__tests__/src/reducers/annotations.test.js @@ -3,11 +3,16 @@ import ActionTypes from '../../../src/state/actions/action-types'; describe('annotation reducer', () => { it('should handle REQUEST_ANNOTATION', () => { - expect(annotationsReducer({}, { - annotationId: 'abc123', - targetId: 'foo', - type: ActionTypes.REQUEST_ANNOTATION, - })).toEqual({ + expect( + annotationsReducer( + {}, + { + annotationId: 'abc123', + targetId: 'foo', + type: ActionTypes.REQUEST_ANNOTATION, + }, + ), + ).toEqual({ foo: { abc123: { id: 'abc123', @@ -17,26 +22,28 @@ describe('annotation reducer', () => { }); }); it('should handle RECEIVE_ANNOTATION', () => { - expect(annotationsReducer( - { - foo: { - abc123: { - id: 'abc123', - isFetching: true, + expect( + annotationsReducer( + { + foo: { + abc123: { + id: 'abc123', + isFetching: true, + }, }, }, - }, - { - annotationId: 'abc123', - annotationJson: { - '@type': 'sc:AnnotationList', - content: 'anno stuff', - id: 'abc123', + { + annotationId: 'abc123', + annotationJson: { + '@type': 'sc:AnnotationList', + content: 'anno stuff', + id: 'abc123', + }, + targetId: 'foo', + type: ActionTypes.RECEIVE_ANNOTATION, }, - targetId: 'foo', - type: ActionTypes.RECEIVE_ANNOTATION, - }, - )).toMatchObject({ + ), + ).toMatchObject({ foo: { abc123: { id: 'abc123', @@ -83,19 +90,16 @@ describe('annotation reducer', () => { }, }, }); - const secondReduction = annotationsReducer( - firstReduction, - { - annotationId: 'abc123', - annotationJson: { - '@type': 'sc:AnnotationList', - content: 'anno stuff', - id: 'abc123', - }, - targetId: 'foo', - type: ActionTypes.RECEIVE_ANNOTATION, + const secondReduction = annotationsReducer(firstReduction, { + annotationId: 'abc123', + annotationJson: { + '@type': 'sc:AnnotationList', + content: 'anno stuff', + id: 'abc123', }, - ); + targetId: 'foo', + type: ActionTypes.RECEIVE_ANNOTATION, + }); expect(secondReduction).toMatchObject({ foo: { abc123: { @@ -119,22 +123,24 @@ describe('annotation reducer', () => { }); }); it('should handle RECEIVE_ANNOTATION_FAILURE', () => { - expect(annotationsReducer( - { - foo: { - abc123: { - id: 'abc123', - isFetching: true, + expect( + annotationsReducer( + { + foo: { + abc123: { + id: 'abc123', + isFetching: true, + }, }, }, - }, - { - annotationId: 'abc123', - error: "This institution didn't enable CORS.", - targetId: 'foo', - type: ActionTypes.RECEIVE_ANNOTATION_FAILURE, - }, - )).toEqual({ + { + annotationId: 'abc123', + error: "This institution didn't enable CORS.", + targetId: 'foo', + type: ActionTypes.RECEIVE_ANNOTATION_FAILURE, + }, + ), + ).toEqual({ foo: { abc123: { error: "This institution didn't enable CORS.", @@ -145,9 +151,14 @@ describe('annotation reducer', () => { }); }); it('should handle IMPORT_MIRADOR_STATE setting to clean state', () => { - expect(annotationsReducer({}, { - state: { annotations: { new: 'stuff' } }, - type: ActionTypes.IMPORT_MIRADOR_STATE, - })).toEqual({}); + expect( + annotationsReducer( + {}, + { + state: { annotations: { new: 'stuff' } }, + type: ActionTypes.IMPORT_MIRADOR_STATE, + }, + ), + ).toEqual({}); }); }); diff --git a/__tests__/src/reducers/auth.test.js b/__tests__/src/reducers/auth.test.js index 9817c15c1..77833b38d 100644 --- a/__tests__/src/reducers/auth.test.js +++ b/__tests__/src/reducers/auth.test.js @@ -3,12 +3,17 @@ import ActionTypes from '../../../src/state/actions/action-types'; describe('auth response reducer', () => { it('should handle ADD_AUTHENTICATION_REQUEST', () => { - expect(authReducer({}, { - id: 'abc123', - profile: 'iiif/login', - type: ActionTypes.ADD_AUTHENTICATION_REQUEST, - windowId: 'main', - })).toEqual({ + expect( + authReducer( + {}, + { + id: 'abc123', + profile: 'iiif/login', + type: ActionTypes.ADD_AUTHENTICATION_REQUEST, + windowId: 'main', + }, + ), + ).toEqual({ abc123: { id: 'abc123', isFetching: true, @@ -18,19 +23,21 @@ describe('auth response reducer', () => { }); }); it('should handle RESOLVE_AUTHENTICATION_REQUEST', () => { - expect(authReducer( - { - abc123: { + expect( + authReducer( + { + abc123: { + id: 'abc123', + isFetching: true, + }, + }, + { id: 'abc123', - isFetching: true, + ok: true, + type: ActionTypes.RESOLVE_AUTHENTICATION_REQUEST, }, - }, - { - id: 'abc123', - ok: true, - type: ActionTypes.RESOLVE_AUTHENTICATION_REQUEST, - }, - )).toMatchObject({ + ), + ).toMatchObject({ abc123: { id: 'abc123', isFetching: false, @@ -40,26 +47,41 @@ describe('auth response reducer', () => { }); describe('should handle RECEIVE_ACCESS_TOKEN', () => { it('does nothing if id is not present', () => { - expect(authReducer({ foo: {} }, { - authId: 'foo', - type: ActionTypes.RECEIVE_ACCESS_TOKEN, - })).toMatchObject({ foo: { ok: true } }); + expect( + authReducer( + { foo: {} }, + { + authId: 'foo', + type: ActionTypes.RECEIVE_ACCESS_TOKEN, + }, + ), + ).toMatchObject({ foo: { ok: true } }); }); }); describe('should handle RESET_AUTHENTICATION_STATE', () => { it('does nothing if id is not present', () => { - expect(authReducer({}, { - id: 'foo', - type: ActionTypes.RESET_AUTHENTICATION_STATE, - })).toEqual({}); + expect( + authReducer( + {}, + { + id: 'foo', + type: ActionTypes.RESET_AUTHENTICATION_STATE, + }, + ), + ).toEqual({}); }); it('removes id', () => { - expect(authReducer({ - foo: 'otherStuff', - }, { - id: 'foo', - type: ActionTypes.RESET_AUTHENTICATION_STATE, - })).toEqual({}); + expect( + authReducer( + { + foo: 'otherStuff', + }, + { + id: 'foo', + type: ActionTypes.RESET_AUTHENTICATION_STATE, + }, + ), + ).toEqual({}); }); }); }); diff --git a/__tests__/src/reducers/catalog.test.js b/__tests__/src/reducers/catalog.test.js index b232590e9..c91ac994d 100644 --- a/__tests__/src/reducers/catalog.test.js +++ b/__tests__/src/reducers/catalog.test.js @@ -4,91 +4,91 @@ import ActionTypes from '../../../src/state/actions/action-types'; describe('catalog reducer', () => { describe('ADD_MANIFEST', () => { it('adds new manifests to the state', () => { - expect(catalogReducer([], { - manifestId: '1', - type: ActionTypes.ADD_RESOURCE, - })).toEqual([ - { manifestId: '1' }, - ]); + expect( + catalogReducer([], { + manifestId: '1', + type: ActionTypes.ADD_RESOURCE, + }), + ).toEqual([{ manifestId: '1' }]); }); it('adds new manifests to the top of state', () => { - expect(catalogReducer([{ manifestId: '2' }], { - manifestId: '1', - type: ActionTypes.ADD_RESOURCE, - })).toEqual([ - { manifestId: '1' }, - { manifestId: '2' }, - ]); + expect( + catalogReducer([{ manifestId: '2' }], { + manifestId: '1', + type: ActionTypes.ADD_RESOURCE, + }), + ).toEqual([{ manifestId: '1' }, { manifestId: '2' }]); }); it('deduplicate manifests', () => { - expect(catalogReducer([{ manifestId: '1' }], { - manifestId: '1', - type: ActionTypes.ADD_RESOURCE, - })).toEqual([ - { manifestId: '1' }, - ]); + expect( + catalogReducer([{ manifestId: '1' }], { + manifestId: '1', + type: ActionTypes.ADD_RESOURCE, + }), + ).toEqual([{ manifestId: '1' }]); }); it('includes payload data', () => { - expect(catalogReducer([], { - manifestId: '1', - payload: { provider: 'file' }, - type: ActionTypes.ADD_RESOURCE, - })).toEqual([ - { manifestId: '1', provider: 'file' }, - ]); + expect( + catalogReducer([], { + manifestId: '1', + payload: { provider: 'file' }, + type: ActionTypes.ADD_RESOURCE, + }), + ).toEqual([{ manifestId: '1', provider: 'file' }]); }); }); describe('ADD_WINDOW', () => { it('adds new manifests to the state', () => { - expect(catalogReducer([], { - type: ActionTypes.ADD_WINDOW, - window: { manifestId: '1' }, - })).toEqual([ - { manifestId: '1' }, - ]); + expect( + catalogReducer([], { + type: ActionTypes.ADD_WINDOW, + window: { manifestId: '1' }, + }), + ).toEqual([{ manifestId: '1' }]); }); it('adds new manifests to the top of state', () => { - expect(catalogReducer([{ manifestId: '2' }], { - type: ActionTypes.ADD_WINDOW, - window: { manifestId: '1' }, - })).toEqual([ - { manifestId: '1' }, - { manifestId: '2' }, - ]); + expect( + catalogReducer([{ manifestId: '2' }], { + type: ActionTypes.ADD_WINDOW, + window: { manifestId: '1' }, + }), + ).toEqual([{ manifestId: '1' }, { manifestId: '2' }]); }); it('deduplicate manifests', () => { - expect(catalogReducer([{ manifestId: '1' }], { - type: ActionTypes.ADD_WINDOW, - window: { manifestId: '1' }, - })).toEqual([ - { manifestId: '1' }, - ]); + expect( + catalogReducer([{ manifestId: '1' }], { + type: ActionTypes.ADD_WINDOW, + window: { manifestId: '1' }, + }), + ).toEqual([{ manifestId: '1' }]); }); }); it('should handle REMOVE_RESOURCE', () => { - expect(catalogReducer([{ manifestId: '1' }], { - manifestId: '1', - type: ActionTypes.REMOVE_RESOURCE, - })).toEqual([]); + expect( + catalogReducer([{ manifestId: '1' }], { + manifestId: '1', + type: ActionTypes.REMOVE_RESOURCE, + }), + ).toEqual([]); }); it('should handle IMPORT_MIRADOR_STATE', () => { - expect(catalogReducer([], { - state: { catalog: [{ manifestId: '1' }] }, - type: ActionTypes.IMPORT_MIRADOR_STATE, - })).toEqual([ - { manifestId: '1' }, - ]); + expect( + catalogReducer([], { + state: { catalog: [{ manifestId: '1' }] }, + type: ActionTypes.IMPORT_MIRADOR_STATE, + }), + ).toEqual([{ manifestId: '1' }]); }); it('should handle IMPORT_CONFIG', () => { - expect(catalogReducer([], { - config: { catalog: [{ manifestId: '1' }] }, - type: ActionTypes.IMPORT_CONFIG, - })).toEqual([ - { manifestId: '1' }, - ]); + expect( + catalogReducer([], { + config: { catalog: [{ manifestId: '1' }] }, + type: ActionTypes.IMPORT_CONFIG, + }), + ).toEqual([{ manifestId: '1' }]); }); }); diff --git a/__tests__/src/reducers/companionWindows.test.js b/__tests__/src/reducers/companionWindows.test.js index d46632148..d2c2ba157 100644 --- a/__tests__/src/reducers/companionWindows.test.js +++ b/__tests__/src/reducers/companionWindows.test.js @@ -23,15 +23,18 @@ describe('companionWindowsReducer', () => { describe('ADD_WINDOW', () => { it('adds default companion window(s)', () => { const action = { - companionWindows: [{ - content: 'info', - id: 'banana', - position: 'left', - }, { - content: 'canvas', - id: 'Banane', - position: 'right', - }], + companionWindows: [ + { + content: 'info', + id: 'banana', + position: 'left', + }, + { + content: 'canvas', + id: 'Banane', + position: 'right', + }, + ], type: ActionTypes.ADD_WINDOW, }; const beforeState = {}; @@ -196,9 +199,14 @@ describe('companionWindowsReducer', () => { }); it('should handle IMPORT_MIRADOR_STATE', () => { - expect(companionWindowsReducer({}, { - state: { companionWindows: { new: 'stuff' } }, - type: ActionTypes.IMPORT_MIRADOR_STATE, - })).toEqual({ new: 'stuff' }); + expect( + companionWindowsReducer( + {}, + { + state: { companionWindows: { new: 'stuff' } }, + type: ActionTypes.IMPORT_MIRADOR_STATE, + }, + ), + ).toEqual({ new: 'stuff' }); }); }); diff --git a/__tests__/src/reducers/config.test.js b/__tests__/src/reducers/config.test.js index 66271ebe7..b058c1d97 100644 --- a/__tests__/src/reducers/config.test.js +++ b/__tests__/src/reducers/config.test.js @@ -6,39 +6,59 @@ import settings from '../../../src/config/settings'; describe('config reducer', () => { describe('SET_CONFIG', () => { it('should handle SET_CONFIG', () => { - expect(configReducer({}, { - config: { manifestVersion: 'v3' }, - type: ActionTypes.SET_CONFIG, - })).toEqual({ + expect( + configReducer( + {}, + { + config: { manifestVersion: 'v3' }, + type: ActionTypes.SET_CONFIG, + }, + ), + ).toEqual({ manifestVersion: 'v3', }); }); it('does not deep merge', () => { - expect(configReducer({ stuff: { foo: 'bar' } }, { - config: { stuff: { foo: 'bat' } }, - type: ActionTypes.SET_CONFIG, - })).toEqual({ + expect( + configReducer( + { stuff: { foo: 'bar' } }, + { + config: { stuff: { foo: 'bat' } }, + type: ActionTypes.SET_CONFIG, + }, + ), + ).toEqual({ stuff: { foo: 'bat' }, }); }); }); describe('UPDATE_CONFIG', () => { it('should handle UPDATE_CONFIG', () => { - expect(configReducer({}, { - config: { manifestVersion: 'v3' }, - type: ActionTypes.UPDATE_CONFIG, - })).toEqual({ + expect( + configReducer( + {}, + { + config: { manifestVersion: 'v3' }, + type: ActionTypes.UPDATE_CONFIG, + }, + ), + ).toEqual({ manifestVersion: 'v3', }); }); it('does a deep merge', () => { - expect(configReducer({ - hello: 'world', - stuff: { foo: 'bar' }, - }, { - config: { stuff: { foo: 'bat' } }, - type: ActionTypes.UPDATE_CONFIG, - })).toEqual({ + expect( + configReducer( + { + hello: 'world', + stuff: { foo: 'bar' }, + }, + { + config: { stuff: { foo: 'bat' } }, + type: ActionTypes.UPDATE_CONFIG, + }, + ), + ).toEqual({ hello: 'world', stuff: { foo: 'bat' }, }); @@ -46,17 +66,24 @@ describe('config reducer', () => { }); describe('IMPORT_CONFIG', () => { it('should handle IMPORT_CONFIG', () => { - expect(configReducer([], { - config: configFixture, - type: ActionTypes.IMPORT_CONFIG, - })).toEqual(configFixture); + expect( + configReducer([], { + config: configFixture, + type: ActionTypes.IMPORT_CONFIG, + }), + ).toEqual(configFixture); }); }); it('should handle IMPORT_MIRADOR_STATE', () => { - expect(configReducer({}, { - state: { config: { new: 'stuff' } }, - type: ActionTypes.IMPORT_MIRADOR_STATE, - })).toMatchObject({ new: 'stuff' }); + expect( + configReducer( + {}, + { + state: { config: { new: 'stuff' } }, + type: ActionTypes.IMPORT_MIRADOR_STATE, + }, + ), + ).toMatchObject({ new: 'stuff' }); }); it('handles pre-existing functions in IMPORT_MIRADOR_STATE by deep merging those stems', () => { const actual = configReducer(settings, { @@ -64,6 +91,8 @@ describe('config reducer', () => { type: ActionTypes.IMPORT_MIRADOR_STATE, }); - expect(actual).toMatchObject({ theme: { ...settings.theme, palette: { ...settings.theme.palette, mode: 'dark' } } }); + expect(actual).toMatchObject({ + theme: { ...settings.theme, palette: { ...settings.theme.palette, mode: 'dark' } }, + }); }); }); diff --git a/__tests__/src/reducers/elasticLayout.test.js b/__tests__/src/reducers/elasticLayout.test.js index 5a5b538d9..f64ccf60d 100644 --- a/__tests__/src/reducers/elasticLayout.test.js +++ b/__tests__/src/reducers/elasticLayout.test.js @@ -3,11 +3,16 @@ import ActionTypes from '../../../src/state/actions/action-types'; describe('elastic layout reducer', () => { it('should handle ADD_WINDOW', () => { - expect(elasticLayoutReducer({}, { - elasticLayout: { x: 1, y: 2 }, - type: ActionTypes.ADD_WINDOW, - window: { id: 'abc123' }, - })).toEqual({ + expect( + elasticLayoutReducer( + {}, + { + elasticLayout: { x: 1, y: 2 }, + type: ActionTypes.ADD_WINDOW, + window: { id: 'abc123' }, + }, + ), + ).toEqual({ abc123: { windowId: 'abc123', x: 1, @@ -16,35 +21,45 @@ describe('elastic layout reducer', () => { }); }); it('should handle REMOVE_WINDOW', () => { - expect(elasticLayoutReducer({ - abc123: { - windowId: 'abc123', - }, - def456: { - windowId: 'def456', - }, - }, { - type: ActionTypes.REMOVE_WINDOW, - windowId: 'abc123', - })).toEqual({ + expect( + elasticLayoutReducer( + { + abc123: { + windowId: 'abc123', + }, + def456: { + windowId: 'def456', + }, + }, + { + type: ActionTypes.REMOVE_WINDOW, + windowId: 'abc123', + }, + ), + ).toEqual({ def456: { windowId: 'def456', }, }); }); it('should handle UPDATE_ELASTIC_WINDOW_LAYOUT', () => { - expect(elasticLayoutReducer({ - abc123: { - windowId: 'abc123', - }, - }, { - payload: { - x: 1, - y: 2, - }, - type: ActionTypes.UPDATE_ELASTIC_WINDOW_LAYOUT, - windowId: 'abc123', - })).toEqual({ + expect( + elasticLayoutReducer( + { + abc123: { + windowId: 'abc123', + }, + }, + { + payload: { + x: 1, + y: 2, + }, + type: ActionTypes.UPDATE_ELASTIC_WINDOW_LAYOUT, + windowId: 'abc123', + }, + ), + ).toEqual({ abc123: { windowId: 'abc123', x: 1, @@ -54,9 +69,14 @@ describe('elastic layout reducer', () => { }); it('should handle IMPORT_MIRADOR_STATE', () => { - expect(elasticLayoutReducer({}, { - state: { elasticLayout: { new: 'stuff' } }, - type: ActionTypes.IMPORT_MIRADOR_STATE, - })).toEqual({ new: 'stuff' }); + expect( + elasticLayoutReducer( + {}, + { + state: { elasticLayout: { new: 'stuff' } }, + type: ActionTypes.IMPORT_MIRADOR_STATE, + }, + ), + ).toEqual({ new: 'stuff' }); }); }); diff --git a/__tests__/src/reducers/errors.test.js b/__tests__/src/reducers/errors.test.js index f65c3b4af..fa3a9cbf5 100644 --- a/__tests__/src/reducers/errors.test.js +++ b/__tests__/src/reducers/errors.test.js @@ -13,7 +13,6 @@ describe('ADD_ERROR', () => { const ret = errorsReducer(undefined, { type: ActionTypes.ADD_ERROR, ...error, - }); expect(ret.items).toEqual([error.id]); expect(ret).toHaveProperty(error.id); @@ -28,7 +27,6 @@ describe('ADD_ERROR', () => { const ret = errorsReducer(undefined, { type: ActionTypes.RECEIVE_INFO_RESPONSE_FAILURE, ...error, - }); expect(ret.items).toEqual([error.infoId]); expect(ret).toHaveProperty(error.infoId); @@ -46,7 +44,6 @@ describe('ADD_ERROR', () => { const ret = errorsReducer(undefined, { type: ActionTypes.RECEIVE_SEARCH_FAILURE, ...error, - }); expect(ret.items).toEqual([error.searchId]); expect(ret).toHaveProperty(error.searchId); @@ -69,15 +66,22 @@ describe('ADD_ERROR', () => { Only the id is removed from the 'items' array. The error itself remains part of the state, so we are able to provide an error history or some kind of logs later on */ - expect(errorsReducer(stateBefore, { - id: errorId, - type: ActionTypes.REMOVE_ERROR, - })).toHaveProperty('items', []); + expect( + errorsReducer(stateBefore, { + id: errorId, + type: ActionTypes.REMOVE_ERROR, + }), + ).toHaveProperty('items', []); }); it('should handle IMPORT_MIRADOR_STATE setting default state', () => { - expect(errorsReducer({}, { - state: { errors: { new: 'stuff' } }, - type: ActionTypes.IMPORT_MIRADOR_STATE, - })).toEqual({ items: [] }); + expect( + errorsReducer( + {}, + { + state: { errors: { new: 'stuff' } }, + type: ActionTypes.IMPORT_MIRADOR_STATE, + }, + ), + ).toEqual({ items: [] }); }); }); diff --git a/__tests__/src/reducers/infoResponse.test.js b/__tests__/src/reducers/infoResponse.test.js index 73237ebac..1f21321c6 100644 --- a/__tests__/src/reducers/infoResponse.test.js +++ b/__tests__/src/reducers/infoResponse.test.js @@ -3,10 +3,15 @@ import ActionTypes from '../../../src/state/actions/action-types'; describe('info response reducer', () => { it('should handle REQUEST_INFO_RESPONSE', () => { - expect(infoResponsesReducer({}, { - infoId: 'abc123', - type: ActionTypes.REQUEST_INFO_RESPONSE, - })).toEqual({ + expect( + infoResponsesReducer( + {}, + { + infoId: 'abc123', + type: ActionTypes.REQUEST_INFO_RESPONSE, + }, + ), + ).toEqual({ abc123: { id: 'abc123', isFetching: true, @@ -14,24 +19,26 @@ describe('info response reducer', () => { }); }); it('should handle RECEIVE_INFO_RESPONSE', () => { - expect(infoResponsesReducer( - { - abc123: { - id: 'abc123', - isFetching: true, + expect( + infoResponsesReducer( + { + abc123: { + id: 'abc123', + isFetching: true, + }, }, - }, - { - infoId: 'abc123', - infoJson: { - '@type': 'sc:Manifest', - content: 'lots of canvases and metadata and such', - id: 'abc123', + { + infoId: 'abc123', + infoJson: { + '@type': 'sc:Manifest', + content: 'lots of canvases and metadata and such', + id: 'abc123', + }, + tokenServiceId: 'efg456', + type: ActionTypes.RECEIVE_INFO_RESPONSE, }, - tokenServiceId: 'efg456', - type: ActionTypes.RECEIVE_INFO_RESPONSE, - }, - )).toMatchObject({ + ), + ).toMatchObject({ abc123: { id: 'abc123', isFetching: false, @@ -41,20 +48,22 @@ describe('info response reducer', () => { }); }); it('should handle RECEIVE_INFO_RESPONSE_FAILURE', () => { - expect(infoResponsesReducer( - { - abc123: { - id: 'abc123', - isFetching: true, + expect( + infoResponsesReducer( + { + abc123: { + id: 'abc123', + isFetching: true, + }, }, - }, - { - error: "This institution didn't enable CORS.", - infoId: 'abc123', - tokenServiceId: 'efg456', - type: ActionTypes.RECEIVE_INFO_RESPONSE_FAILURE, - }, - )).toEqual({ + { + error: "This institution didn't enable CORS.", + infoId: 'abc123', + tokenServiceId: 'efg456', + type: ActionTypes.RECEIVE_INFO_RESPONSE_FAILURE, + }, + ), + ).toEqual({ abc123: { error: "This institution didn't enable CORS.", id: 'abc123', @@ -64,22 +73,24 @@ describe('info response reducer', () => { }); }); it('should handle REMOVE_INFO_RESPONSE', () => { - expect(infoResponsesReducer( - { - abc123: { - id: 'abc123', - stuff: 'foo', + expect( + infoResponsesReducer( + { + abc123: { + id: 'abc123', + stuff: 'foo', + }, + def456: { + id: 'def456', + stuff: 'foo', + }, }, - def456: { - id: 'def456', - stuff: 'foo', + { + infoId: 'abc123', + type: ActionTypes.REMOVE_INFO_RESPONSE, }, - }, - { - infoId: 'abc123', - type: ActionTypes.REMOVE_INFO_RESPONSE, - }, - )).toEqual({ + ), + ).toEqual({ def456: { id: 'def456', stuff: 'foo', @@ -87,9 +98,14 @@ describe('info response reducer', () => { }); }); it('should handle IMPORT_MIRADOR_STATE setting to clean state', () => { - expect(infoResponsesReducer({}, { - state: { infoResponses: { new: 'stuff' } }, - type: ActionTypes.IMPORT_MIRADOR_STATE, - })).toEqual({}); + expect( + infoResponsesReducer( + {}, + { + state: { infoResponses: { new: 'stuff' } }, + type: ActionTypes.IMPORT_MIRADOR_STATE, + }, + ), + ).toEqual({}); }); }); diff --git a/__tests__/src/reducers/layers.test.js b/__tests__/src/reducers/layers.test.js index 3314269c6..4aa8b436e 100644 --- a/__tests__/src/reducers/layers.test.js +++ b/__tests__/src/reducers/layers.test.js @@ -6,12 +6,17 @@ describe('layers reducer', () => { const canvasId = 'bar'; describe('UPDATE_LAYERS', () => { it('should handle UPDATE_LAYERS', () => { - expect(layersReducer({}, { - canvasId, - payload: { some: 'data' }, - type: ActionTypes.UPDATE_LAYERS, - windowId, - })).toEqual({ + expect( + layersReducer( + {}, + { + canvasId, + payload: { some: 'data' }, + type: ActionTypes.UPDATE_LAYERS, + windowId, + }, + ), + ).toEqual({ foo: { bar: { some: 'data', @@ -30,12 +35,14 @@ describe('layers reducer', () => { }, }; - expect(layersReducer(originalState, { - canvasId, - payload: { some: 'data' }, - type: ActionTypes.UPDATE_LAYERS, - windowId, - })).toEqual({ + expect( + layersReducer(originalState, { + canvasId, + payload: { some: 'data' }, + type: ActionTypes.UPDATE_LAYERS, + windowId, + }), + ).toEqual({ baz: { whatever: {}, }, diff --git a/__tests__/src/reducers/manifests.test.js b/__tests__/src/reducers/manifests.test.js index 31ce91188..b50b373b0 100644 --- a/__tests__/src/reducers/manifests.test.js +++ b/__tests__/src/reducers/manifests.test.js @@ -3,34 +3,41 @@ import ActionTypes from '../../../src/state/actions/action-types'; describe('manifests reducer', () => { it('should handle REQUEST_MANIFEST', () => { - expect(manifestsReducer({}, { - manifestId: 'abc123', - type: ActionTypes.REQUEST_MANIFEST, - })).toEqual({ + expect( + manifestsReducer( + {}, + { + manifestId: 'abc123', + type: ActionTypes.REQUEST_MANIFEST, + }, + ), + ).toEqual({ abc123: { id: 'abc123', }, }); }); it('should handle RECEIVE_MANIFEST', () => { - expect(manifestsReducer( - { - abc123: { - error: 'Error fetching manifest', - id: 'abc123', - isFetching: true, + expect( + manifestsReducer( + { + abc123: { + error: 'Error fetching manifest', + id: 'abc123', + isFetching: true, + }, }, - }, - { - manifestId: 'abc123', - manifestJson: { - '@type': 'sc:Manifest', - content: 'lots of canvases and metadata and such', - id: 'abc123', + { + manifestId: 'abc123', + manifestJson: { + '@type': 'sc:Manifest', + content: 'lots of canvases and metadata and such', + id: 'abc123', + }, + type: ActionTypes.RECEIVE_MANIFEST, }, - type: ActionTypes.RECEIVE_MANIFEST, - }, - )).toMatchObject({ + ), + ).toMatchObject({ abc123: { error: null, id: 'abc123', @@ -45,19 +52,21 @@ describe('manifests reducer', () => { }); it('should handle RECEIVE_MANIFEST_FAILURE', () => { - expect(manifestsReducer( - { - abc123: { - id: 'abc123', - isFetching: true, + expect( + manifestsReducer( + { + abc123: { + id: 'abc123', + isFetching: true, + }, }, - }, - { - error: "This institution didn't enable CORS.", - manifestId: 'abc123', - type: ActionTypes.RECEIVE_MANIFEST_FAILURE, - }, - )).toEqual({ + { + error: "This institution didn't enable CORS.", + manifestId: 'abc123', + type: ActionTypes.RECEIVE_MANIFEST_FAILURE, + }, + ), + ).toEqual({ abc123: { error: "This institution didn't enable CORS.", id: 'abc123', @@ -66,22 +75,24 @@ describe('manifests reducer', () => { }); }); it('should handle REMOVE_MANIFEST', () => { - expect(manifestsReducer( - { - abc123: { - id: 'abc123', - stuff: 'foo', + expect( + manifestsReducer( + { + abc123: { + id: 'abc123', + stuff: 'foo', + }, + def456: { + id: 'def456', + stuff: 'foo', + }, }, - def456: { - id: 'def456', - stuff: 'foo', + { + manifestId: 'abc123', + type: ActionTypes.REMOVE_MANIFEST, }, - }, - { - manifestId: 'abc123', - type: ActionTypes.REMOVE_MANIFEST, - }, - )).toEqual({ + ), + ).toEqual({ def456: { id: 'def456', stuff: 'foo', @@ -89,9 +100,14 @@ describe('manifests reducer', () => { }); }); it('should handle IMPORT_MIRADOR_STATE setting to clean state', () => { - expect(manifestsReducer({ old: 'stuff' }, { - state: { manifests: { new: 'stuff' } }, - type: ActionTypes.IMPORT_MIRADOR_STATE, - })).toEqual({ new: 'stuff' }); + expect( + manifestsReducer( + { old: 'stuff' }, + { + state: { manifests: { new: 'stuff' } }, + type: ActionTypes.IMPORT_MIRADOR_STATE, + }, + ), + ).toEqual({ new: 'stuff' }); }); }); diff --git a/__tests__/src/reducers/search.test.js b/__tests__/src/reducers/search.test.js index 2b642cd1e..aed791c89 100644 --- a/__tests__/src/reducers/search.test.js +++ b/__tests__/src/reducers/search.test.js @@ -3,13 +3,18 @@ import ActionTypes from '../../../src/state/actions/action-types'; describe('search reducer', () => { it('should handle REQUEST_SEARCH', () => { - expect(searchesReducer({}, { - companionWindowId: 'abc123', - query: 'search terms', - searchId: 'search?page=1', - type: ActionTypes.REQUEST_SEARCH, - windowId: 'foo', - })).toEqual({ + expect( + searchesReducer( + {}, + { + companionWindowId: 'abc123', + query: 'search terms', + searchId: 'search?page=1', + type: ActionTypes.REQUEST_SEARCH, + windowId: 'foo', + }, + ), + ).toEqual({ foo: { abc123: { data: { @@ -24,24 +29,29 @@ describe('search reducer', () => { }); }); it('should removes previous search requests with REQUEST_SEARCH', () => { - expect(searchesReducer({ - foo: { - abc123: { - data: { - 'search?page=xyz': { - json: { }, + expect( + searchesReducer( + { + foo: { + abc123: { + data: { + 'search?page=xyz': { + json: {}, + }, + }, + query: 'initial search terms', }, }, - query: 'initial search terms', }, - }, - }, { - companionWindowId: 'abc123', - query: 'search terms', - searchId: 'search?page=1', - type: ActionTypes.REQUEST_SEARCH, - windowId: 'foo', - })).toEqual({ + { + companionWindowId: 'abc123', + query: 'search terms', + searchId: 'search?page=1', + type: ActionTypes.REQUEST_SEARCH, + windowId: 'foo', + }, + ), + ).toEqual({ foo: { abc123: { data: { @@ -56,29 +66,31 @@ describe('search reducer', () => { }); }); it('should handle RECEIVE_SEARCH', () => { - expect(searchesReducer( - { - foo: { - abc123: { - data: { - 'search?page=1': { - isFetching: true, + expect( + searchesReducer( + { + foo: { + abc123: { + data: { + 'search?page=1': { + isFetching: true, + }, }, + query: 'search terms', }, - query: 'search terms', }, }, - }, - { - companionWindowId: 'abc123', - searchId: 'search?page=1', - searchJson: { - content: 'anno stuff', - }, - type: ActionTypes.RECEIVE_SEARCH, - windowId: 'foo', - }, - )).toMatchObject({ + { + companionWindowId: 'abc123', + searchId: 'search?page=1', + searchJson: { + content: 'anno stuff', + }, + type: ActionTypes.RECEIVE_SEARCH, + windowId: 'foo', + }, + ), + ).toMatchObject({ foo: { abc123: { data: { @@ -93,27 +105,29 @@ describe('search reducer', () => { }); }); it('should handle RECEIVE_SEARCH_FAILURE', () => { - expect(searchesReducer( - { - foo: { - abc123: { - data: { - 'search?page=1': { - isFetching: true, + expect( + searchesReducer( + { + foo: { + abc123: { + data: { + 'search?page=1': { + isFetching: true, + }, }, + query: 'search terms', }, - query: 'search terms', }, }, - }, - { - companionWindowId: 'abc123', - error: "This institution didn't enable CORS.", - searchId: 'search?page=1', - type: ActionTypes.RECEIVE_SEARCH_FAILURE, - windowId: 'foo', - }, - )).toEqual({ + { + companionWindowId: 'abc123', + error: "This institution didn't enable CORS.", + searchId: 'search?page=1', + type: ActionTypes.RECEIVE_SEARCH_FAILURE, + windowId: 'foo', + }, + ), + ).toEqual({ foo: { abc123: { data: { @@ -129,25 +143,27 @@ describe('search reducer', () => { }); it('should handle REMOVE_SEARCH', () => { - expect(searchesReducer( - { - foo: { - abc123: { - isFetching: false, - json: {}, - }, - xyz321: { - isFetching: false, - json: {}, + expect( + searchesReducer( + { + foo: { + abc123: { + isFetching: false, + json: {}, + }, + xyz321: { + isFetching: false, + json: {}, + }, }, }, - }, - { - companionWindowId: 'abc123', - type: ActionTypes.REMOVE_SEARCH, - windowId: 'foo', - }, - )).toEqual({ + { + companionWindowId: 'abc123', + type: ActionTypes.REMOVE_SEARCH, + windowId: 'foo', + }, + ), + ).toEqual({ foo: { xyz321: { isFetching: false, @@ -158,50 +174,56 @@ describe('search reducer', () => { }); it('should handle IMPORT_MIRADOR_STATE setting to clean state', () => { - expect(searchesReducer( - { - foo: { - abc123: { - isFetching: true, + expect( + searchesReducer( + { + foo: { + abc123: { + isFetching: true, + }, }, }, - }, - { - state: { whatever: true }, - type: ActionTypes.IMPORT_MIRADOR_STATE, - }, - )).toEqual({}); + { + state: { whatever: true }, + type: ActionTypes.IMPORT_MIRADOR_STATE, + }, + ), + ).toEqual({}); }); it('should handle REMOVE_WINDOW setting to clean state', () => { - expect(searchesReducer( - { - foo: { - abc123: { - isFetching: true, + expect( + searchesReducer( + { + foo: { + abc123: { + isFetching: true, + }, }, }, - }, - { - type: ActionTypes.REMOVE_WINDOW, - windowId: 'foo', - }, - )).toEqual({}); + { + type: ActionTypes.REMOVE_WINDOW, + windowId: 'foo', + }, + ), + ).toEqual({}); }); it('should handle REMOVE_COMPANION_WINDOW setting to clean state', () => { - expect(searchesReducer( - { - foo: { - abc123: { - isFetching: true, + expect( + searchesReducer( + { + foo: { + abc123: { + isFetching: true, + }, }, }, - }, - { - id: 'abc123', - type: ActionTypes.REMOVE_COMPANION_WINDOW, - windowId: 'foo', - }, - )).toEqual({ foo: {} }); + { + id: 'abc123', + type: ActionTypes.REMOVE_COMPANION_WINDOW, + windowId: 'foo', + }, + ), + ).toEqual({ foo: {} }); }); it('handles SELECT_ANNOTATION using selectedContentSearchAnnotationIds for relevant searches', () => { const irrelevantSearch = { @@ -211,25 +233,30 @@ describe('search reducer', () => { selectedContentSearchAnnotationIds: ['not the id'], }; - expect(searchesReducer({ - foo: { - abc123: { - data: { - 'search?page=xyz': { - json: { - resources: [{ '@id': 'someAnnotationId' }], + expect( + searchesReducer( + { + foo: { + abc123: { + data: { + 'search?page=xyz': { + json: { + resources: [{ '@id': 'someAnnotationId' }], + }, + }, }, + selectedContentSearchAnnotationIds: ['whatever'], }, + irrelevantSearch, }, - selectedContentSearchAnnotationIds: ['whatever'], }, - irrelevantSearch, - }, - }, { - annotationId: 'someAnnotationId', - type: ActionTypes.SELECT_ANNOTATION, - windowId: 'foo', - })).toEqual({ + { + annotationId: 'someAnnotationId', + type: ActionTypes.SELECT_ANNOTATION, + windowId: 'foo', + }, + ), + ).toEqual({ foo: { abc123: { data: { diff --git a/__tests__/src/reducers/utils.test.js b/__tests__/src/reducers/utils.test.js index 1ee47ebfb..3beb1cd2b 100644 --- a/__tests__/src/reducers/utils.test.js +++ b/__tests__/src/reducers/utils.test.js @@ -41,7 +41,7 @@ describe('updateItem', () => { it('updates an item based on the function passed', () => { const object = { bar: { b: 2, c: 3 }, foo: { a: 1 } }; - /** */ const fn = props => ({ ...props, c: props.c + 1 }); + /** */ const fn = (props) => ({ ...props, c: props.c + 1 }); const result = update(object, 'bar', fn); expect(result).toEqual({ bar: { b: 2, c: 4 }, diff --git a/__tests__/src/reducers/viewers.test.js b/__tests__/src/reducers/viewers.test.js index a0e7ebb7f..ea8f8cedc 100644 --- a/__tests__/src/reducers/viewers.test.js +++ b/__tests__/src/reducers/viewers.test.js @@ -3,19 +3,24 @@ import ActionTypes from '../../../src/state/actions/action-types'; describe('viewers reducer', () => { it('should handle UPDATE_VIEWPORT', () => { - expect(viewersReducer({ - abc123: { - whatever: true, - x: 1, - }, - def456: { - y: 1, - }, - }, { - payload: { x: 0, y: 1, zoom: 0.5 }, - type: ActionTypes.UPDATE_VIEWPORT, - windowId: 'abc123', - })).toEqual({ + expect( + viewersReducer( + { + abc123: { + whatever: true, + x: 1, + }, + def456: { + y: 1, + }, + }, + { + payload: { x: 0, y: 1, zoom: 0.5 }, + type: ActionTypes.UPDATE_VIEWPORT, + windowId: 'abc123', + }, + ), + ).toEqual({ abc123: { whatever: true, x: 0, @@ -28,34 +33,44 @@ describe('viewers reducer', () => { }); }); it('should handle REMOVE_WINDOW', () => { - expect(viewersReducer({ - abc123: { - foo: 'bar', - }, - def456: { - foo: 'bar', - }, - }, { - type: ActionTypes.REMOVE_WINDOW, - windowId: 'abc123', - })).toEqual({ + expect( + viewersReducer( + { + abc123: { + foo: 'bar', + }, + def456: { + foo: 'bar', + }, + }, + { + type: ActionTypes.REMOVE_WINDOW, + windowId: 'abc123', + }, + ), + ).toEqual({ def456: { foo: 'bar', }, }); }); it('should handle SET_WINDOW_VIEW_TYPE', () => { - expect(viewersReducer({ - abc123: { - foo: 'bar', - }, - def456: { - foo: 'bar', - }, - }, { - type: ActionTypes.SET_WINDOW_VIEW_TYPE, - windowId: 'abc123', - })).toEqual({ + expect( + viewersReducer( + { + abc123: { + foo: 'bar', + }, + def456: { + foo: 'bar', + }, + }, + { + type: ActionTypes.SET_WINDOW_VIEW_TYPE, + windowId: 'abc123', + }, + ), + ).toEqual({ abc123: null, def456: { foo: 'bar', @@ -63,17 +78,22 @@ describe('viewers reducer', () => { }); }); it('should handle SET_CANVAS and throwaway if !preserveViewport', () => { - expect(viewersReducer({ - abc123: { - foo: 'bar', - }, - def456: { - foo: 'bar', - }, - }, { - type: ActionTypes.SET_CANVAS, - windowId: 'abc123', - })).toEqual({ + expect( + viewersReducer( + { + abc123: { + foo: 'bar', + }, + def456: { + foo: 'bar', + }, + }, + { + type: ActionTypes.SET_CANVAS, + windowId: 'abc123', + }, + ), + ).toEqual({ abc123: null, def456: { foo: 'bar', @@ -81,18 +101,23 @@ describe('viewers reducer', () => { }); }); it('should handle SET_CANVAS and not throwaway viewports if preserveViewport', () => { - expect(viewersReducer({ - abc123: { - foo: 'bar', - }, - def456: { - foo: 'bar', - }, - }, { - preserveViewport: true, - type: ActionTypes.SET_CANVAS, - windowId: 'abc123', - })).toEqual({ + expect( + viewersReducer( + { + abc123: { + foo: 'bar', + }, + def456: { + foo: 'bar', + }, + }, + { + preserveViewport: true, + type: ActionTypes.SET_CANVAS, + windowId: 'abc123', + }, + ), + ).toEqual({ abc123: { foo: 'bar', }, @@ -102,16 +127,26 @@ describe('viewers reducer', () => { }); }); it('should handle IMPORT_MIRADOR_STATE', () => { - expect(viewersReducer({}, { - state: { viewers: { new: 'stuff' } }, - type: ActionTypes.IMPORT_MIRADOR_STATE, - })).toEqual({ new: 'stuff' }); + expect( + viewersReducer( + {}, + { + state: { viewers: { new: 'stuff' } }, + type: ActionTypes.IMPORT_MIRADOR_STATE, + }, + ), + ).toEqual({ new: 'stuff' }); }); it('should handle ADD_WINDOW', () => { - expect(viewersReducer({}, { - type: ActionTypes.ADD_WINDOW, - window: { id: 'abc123', initialViewerConfig: { x: 5, y: 15 } }, - })).toEqual({ + expect( + viewersReducer( + {}, + { + type: ActionTypes.ADD_WINDOW, + window: { id: 'abc123', initialViewerConfig: { x: 5, y: 15 } }, + }, + ), + ).toEqual({ abc123: { x: 5, y: 15, diff --git a/__tests__/src/reducers/windows.test.js b/__tests__/src/reducers/windows.test.js index 181fcc370..88977d3ea 100644 --- a/__tests__/src/reducers/windows.test.js +++ b/__tests__/src/reducers/windows.test.js @@ -3,27 +3,37 @@ import ActionTypes from '../../../src/state/actions/action-types'; describe('windows reducer', () => { it('should handle ADD_WINDOW', () => { - expect(windowsReducer({}, { - type: ActionTypes.ADD_WINDOW, - window: { id: 'abc123' }, - })).toEqual({ + expect( + windowsReducer( + {}, + { + type: ActionTypes.ADD_WINDOW, + window: { id: 'abc123' }, + }, + ), + ).toEqual({ abc123: { id: 'abc123', }, }); }); it('should handle REMOVE_WINDOW', () => { - expect(windowsReducer({ - abc123: { - id: 'abc123', - }, - def456: { - id: 'def456', - }, - }, { - type: ActionTypes.REMOVE_WINDOW, - windowId: 'abc123', - })).toEqual({ + expect( + windowsReducer( + { + abc123: { + id: 'abc123', + }, + def456: { + id: 'def456', + }, + }, + { + type: ActionTypes.REMOVE_WINDOW, + windowId: 'abc123', + }, + ), + ).toEqual({ def456: { id: 'def456', }, @@ -97,22 +107,27 @@ describe('windows reducer', () => { }); it('should handle SET_CANVAS', () => { - expect(windowsReducer({ - abc123: { - canvasId: 'http://example.com/canvas/1', - id: 'abc123', - visibleCanvases: ['http://example.com/canvas/1'], - }, - def456: { - canvasId: 'http://example.com/canvas/1', - id: 'def456', - }, - }, { - canvasId: 'http://example.com/canvas/5', - type: ActionTypes.SET_CANVAS, - visibleCanvases: ['http://example.com/canvas/5'], - windowId: 'abc123', - })).toEqual({ + expect( + windowsReducer( + { + abc123: { + canvasId: 'http://example.com/canvas/1', + id: 'abc123', + visibleCanvases: ['http://example.com/canvas/1'], + }, + def456: { + canvasId: 'http://example.com/canvas/1', + id: 'def456', + }, + }, + { + canvasId: 'http://example.com/canvas/5', + type: ActionTypes.SET_CANVAS, + visibleCanvases: ['http://example.com/canvas/5'], + windowId: 'abc123', + }, + ), + ).toEqual({ abc123: { canvasId: 'http://example.com/canvas/5', id: 'abc123', @@ -153,25 +168,30 @@ describe('windows reducer', () => { }); it('should handle SET_WINDOW_SIZE', () => { - expect(windowsReducer({ - abc123: { - id: 'abc123', - }, - def456: { - id: 'def456', - }, - }, { - payload: { - size: { - height: 200, - width: 200, - x: 20, - y: 20, + expect( + windowsReducer( + { + abc123: { + id: 'abc123', + }, + def456: { + id: 'def456', + }, }, - windowId: 'abc123', - }, - type: ActionTypes.SET_WINDOW_SIZE, - })).toEqual({ + { + payload: { + size: { + height: 200, + width: 200, + x: 20, + y: 20, + }, + windowId: 'abc123', + }, + type: ActionTypes.SET_WINDOW_SIZE, + }, + ), + ).toEqual({ abc123: { height: 200, id: 'abc123', @@ -186,23 +206,28 @@ describe('windows reducer', () => { }); it('should handle UPDATE_WINDOW_POSITION', () => { - expect(windowsReducer({ - abc123: { - id: 'abc123', - }, - def456: { - id: 'def456', - }, - }, { - payload: { - position: { - x: 20, - y: 20, + expect( + windowsReducer( + { + abc123: { + id: 'abc123', + }, + def456: { + id: 'def456', + }, }, - windowId: 'abc123', - }, - type: ActionTypes.UPDATE_WINDOW_POSITION, - })).toEqual({ + { + payload: { + position: { + x: 20, + y: 20, + }, + windowId: 'abc123', + }, + type: ActionTypes.UPDATE_WINDOW_POSITION, + }, + ), + ).toEqual({ abc123: { id: 'abc123', x: 20, @@ -216,19 +241,24 @@ describe('windows reducer', () => { it('should handle ADD_COMPANION_WINDOW', () => { // on the right, just tacks the new id on - expect(windowsReducer({ - abc123: { - companionWindowIds: ['123'], - id: 'abc123', - }, - }, { - id: 'xyz', - payload: { - position: 'right', - }, - type: ActionTypes.ADD_COMPANION_WINDOW, - windowId: 'abc123', - })).toEqual({ + expect( + windowsReducer( + { + abc123: { + companionWindowIds: ['123'], + id: 'abc123', + }, + }, + { + id: 'xyz', + payload: { + position: 'right', + }, + type: ActionTypes.ADD_COMPANION_WINDOW, + windowId: 'abc123', + }, + ), + ).toEqual({ abc123: { companionWindowIds: ['123', 'xyz'], id: 'abc123', @@ -236,20 +266,25 @@ describe('windows reducer', () => { }); // on the left, sets some additional properties - expect(windowsReducer({ - abc123: { - companionWindowIds: [], - id: 'abc123', - }, - }, { - id: 'xyz', - payload: { - content: 'content', - position: 'left', - }, - type: ActionTypes.ADD_COMPANION_WINDOW, - windowId: 'abc123', - })).toEqual({ + expect( + windowsReducer( + { + abc123: { + companionWindowIds: [], + id: 'abc123', + }, + }, + { + id: 'xyz', + payload: { + content: 'content', + position: 'left', + }, + type: ActionTypes.ADD_COMPANION_WINDOW, + windowId: 'abc123', + }, + ), + ).toEqual({ abc123: { companionAreaOpen: true, companionWindowIds: ['xyz'], @@ -261,36 +296,46 @@ describe('windows reducer', () => { it('should handle UPDATE_COMPANION_WINDOW', () => { // opens the companion area to if the companion window was on the left - expect(windowsReducer({ - abc123: { - companionAreaOpen: false, - }, - }, { - id: 'xyz', - payload: { - position: 'left', - }, - type: ActionTypes.UPDATE_COMPANION_WINDOW, - windowId: 'abc123', - })).toEqual({ + expect( + windowsReducer( + { + abc123: { + companionAreaOpen: false, + }, + }, + { + id: 'xyz', + payload: { + position: 'left', + }, + type: ActionTypes.UPDATE_COMPANION_WINDOW, + windowId: 'abc123', + }, + ), + ).toEqual({ abc123: { companionAreaOpen: true, }, }); // does nothing if the companion window wasn't on the left - expect(windowsReducer({ - abc123: { - companionAreaOpen: false, - }, - }, { - id: 'xyz', - payload: { - position: 'right', - }, - type: ActionTypes.UPDATE_COMPANION_WINDOW, - windowId: 'abc123', - })).toEqual({ + expect( + windowsReducer( + { + abc123: { + companionAreaOpen: false, + }, + }, + { + id: 'xyz', + payload: { + position: 'right', + }, + type: ActionTypes.UPDATE_COMPANION_WINDOW, + windowId: 'abc123', + }, + ), + ).toEqual({ abc123: { companionAreaOpen: false, }, @@ -299,16 +344,21 @@ describe('windows reducer', () => { it('should handle REMOVE_COMPANION_WINDOW', () => { // on the right, just tacks the new id on - expect(windowsReducer({ - abc123: { - companionWindowIds: ['123', 'xyz'], - id: 'abc123', - }, - }, { - id: 'xyz', - type: ActionTypes.REMOVE_COMPANION_WINDOW, - windowId: 'abc123', - })).toEqual({ + expect( + windowsReducer( + { + abc123: { + companionWindowIds: ['123', 'xyz'], + id: 'abc123', + }, + }, + { + id: 'xyz', + type: ActionTypes.REMOVE_COMPANION_WINDOW, + windowId: 'abc123', + }, + ), + ).toEqual({ abc123: { companionWindowIds: ['123'], id: 'abc123', @@ -348,10 +398,11 @@ describe('windows reducer', () => { }); describe('TOGGLE_ANNOTATION_DISPLAY', () => { - it('handles TOGGLE_ANNOTATION_DISPLAY by toggling the given window\'s displayAllAnnotation value', () => { + it("handles TOGGLE_ANNOTATION_DISPLAY by toggling the given window's displayAllAnnotation value", () => { const beforeState = { abc123: { highlightAllAnnotations: false } }; const action = { - type: ActionTypes.TOGGLE_ANNOTATION_DISPLAY, windowId: 'abc123', + type: ActionTypes.TOGGLE_ANNOTATION_DISPLAY, + windowId: 'abc123', }; const expectedState = { abc123: { highlightAllAnnotations: true }, @@ -365,7 +416,9 @@ describe('windows reducer', () => { it('sets the highlightedAnnotation attribute on the given window', () => { const beforeState = { abc123: {} }; const action = { - annotationIds: ['aaa123'], type: ActionTypes.HOVER_ANNOTATION, windowId: 'abc123', + annotationIds: ['aaa123'], + type: ActionTypes.HOVER_ANNOTATION, + windowId: 'abc123', }; const expectedState = { abc123: { hoveredAnnotationIds: ['aaa123'] }, @@ -376,20 +429,32 @@ describe('windows reducer', () => { }); it('should handle IMPORT_MIRADOR_STATE', () => { - expect(windowsReducer({}, { - state: { windows: { new: 'stuff' } }, - type: ActionTypes.IMPORT_MIRADOR_STATE, - })).toEqual({ new: 'stuff' }); + expect( + windowsReducer( + {}, + { + state: { windows: { new: 'stuff' } }, + type: ActionTypes.IMPORT_MIRADOR_STATE, + }, + ), + ).toEqual({ new: 'stuff' }); }); describe('SHOW_COLLECTION_DIALOG', () => { - it('handles SHOW_COLLECTION_DIALOG by toggling the given window\'s collection dialog', () => { + it("handles SHOW_COLLECTION_DIALOG by toggling the given window's collection dialog", () => { const beforeState = { abc123: { collectionDialogOn: false } }; const action = { - dialogCollectionPath: [], manifestId: 'def456', type: ActionTypes.SHOW_COLLECTION_DIALOG, windowId: 'abc123', + dialogCollectionPath: [], + manifestId: 'def456', + type: ActionTypes.SHOW_COLLECTION_DIALOG, + windowId: 'abc123', }; const expectedState = { - abc123: { collectionDialogOn: true, collectionManifestId: 'def456', dialogCollectionPath: [] }, + abc123: { + collectionDialogOn: true, + collectionManifestId: 'def456', + dialogCollectionPath: [], + }, }; expect(windowsReducer(beforeState, action)).toEqual(expectedState); @@ -397,10 +462,13 @@ describe('windows reducer', () => { }); describe('HIDE_COLLECTION_DIALOG', () => { - it('handles HIDE_COLLECTION_DIALOG by toggling the given window\'s collection dialog', () => { + it("handles HIDE_COLLECTION_DIALOG by toggling the given window's collection dialog", () => { const beforeState = { abc123: { - collectionDialogOn: true, collectionManifestId: 'def456', collectionPath: [], dialogCollectionPath: ['x'], + collectionDialogOn: true, + collectionManifestId: 'def456', + collectionPath: [], + dialogCollectionPath: ['x'], }, }; const action = { @@ -410,7 +478,10 @@ describe('windows reducer', () => { const expectedState = { abc123: { - collectionDialogOn: false, collectionManifestId: 'def456', collectionPath: [], dialogCollectionPath: ['x'], + collectionDialogOn: false, + collectionManifestId: 'def456', + collectionPath: [], + dialogCollectionPath: ['x'], }, }; diff --git a/__tests__/src/reducers/workspace.test.js b/__tests__/src/reducers/workspace.test.js index 69652855b..90ea897b1 100644 --- a/__tests__/src/reducers/workspace.test.js +++ b/__tests__/src/reducers/workspace.test.js @@ -3,103 +3,140 @@ import ActionTypes from '../../../src/state/actions/action-types'; describe('workspace reducer', () => { it('should handle UPDATE_WORKSPACE', () => { - expect(workspaceReducer({}, { - config: { type: 'mosaic' }, - type: ActionTypes.UPDATE_WORKSPACE, - })).toEqual({ + expect( + workspaceReducer( + {}, + { + config: { type: 'mosaic' }, + type: ActionTypes.UPDATE_WORKSPACE, + }, + ), + ).toEqual({ type: 'mosaic', }); }); it('should handle FOCUS_WINDOW without position coordinates', () => { - expect(workspaceReducer([], { - type: ActionTypes.FOCUS_WINDOW, - windowId: 'abc123', - })).toEqual({ + expect( + workspaceReducer([], { + type: ActionTypes.FOCUS_WINDOW, + windowId: 'abc123', + }), + ).toEqual({ focusedWindowId: 'abc123', viewportPosition: {}, }); }); it('should handle FOCUS_WINDOW', () => { - expect(workspaceReducer([], { - position: { x: 10, y: 50 }, - type: ActionTypes.FOCUS_WINDOW, - windowId: 'abc123', - })).toEqual({ + expect( + workspaceReducer([], { + position: { x: 10, y: 50 }, + type: ActionTypes.FOCUS_WINDOW, + windowId: 'abc123', + }), + ).toEqual({ focusedWindowId: 'abc123', viewportPosition: { x: 10, y: 50 }, }); }); it('should handle ADD_WINDOW', () => { - expect(workspaceReducer({ windowIds: ['asdf'] }, { - type: ActionTypes.ADD_WINDOW, - window: { id: 'abc123' }, - })).toEqual({ + expect( + workspaceReducer( + { windowIds: ['asdf'] }, + { + type: ActionTypes.ADD_WINDOW, + window: { id: 'abc123' }, + }, + ), + ).toEqual({ focusedWindowId: 'abc123', windowIds: ['asdf', 'abc123'], }); }); it('should handle REMOVE_WINDOW (by doing nothing if multiple windows remain)', () => { - expect(workspaceReducer({ focusedWindowId: 'asdf', windowIds: ['abc123', 'asdf'] }, { - type: ActionTypes.REMOVE_WINDOW, - windowId: 'abc123', - })).toEqual({ + expect( + workspaceReducer( + { focusedWindowId: 'asdf', windowIds: ['abc123', 'asdf'] }, + { + type: ActionTypes.REMOVE_WINDOW, + windowId: 'abc123', + }, + ), + ).toEqual({ focusedWindowId: 'asdf', windowIds: ['asdf'], }); }); it('should handle REMOVE_WINDOW (by focusing the window if it is the last one remaining)', () => { - expect(workspaceReducer({ focusedWindowId: 'abc123', windowIds: ['abc123', 'def123'] }, { - type: ActionTypes.REMOVE_WINDOW, - windowId: 'abc123', - })).toEqual({ + expect( + workspaceReducer( + { focusedWindowId: 'abc123', windowIds: ['abc123', 'def123'] }, + { + type: ActionTypes.REMOVE_WINDOW, + windowId: 'abc123', + }, + ), + ).toEqual({ focusedWindowId: 'def123', windowIds: ['def123'], }); }); it('should handle SET_WORKSPACE_FULLSCREEN', () => { - expect(workspaceReducer([], { - isFullscreenEnabled: true, - type: ActionTypes.SET_WORKSPACE_FULLSCREEN, - })).toEqual({ + expect( + workspaceReducer([], { + isFullscreenEnabled: true, + type: ActionTypes.SET_WORKSPACE_FULLSCREEN, + }), + ).toEqual({ isFullscreenEnabled: true, }); }); it('should handle TOGGLE_ZOOM_CONTROLS', () => { - expect(workspaceReducer([], { - showZoomControls: true, - type: ActionTypes.TOGGLE_ZOOM_CONTROLS, - })).toEqual({ + expect( + workspaceReducer([], { + showZoomControls: true, + type: ActionTypes.TOGGLE_ZOOM_CONTROLS, + }), + ).toEqual({ showZoomControls: true, }); }); it('should handle UPDATE_WORKSPACE_MOSAIC_LAYOUT', () => { - expect(workspaceReducer([], { - layout: { foo: 'bar' }, - type: ActionTypes.UPDATE_WORKSPACE_MOSAIC_LAYOUT, - })).toEqual({ + expect( + workspaceReducer([], { + layout: { foo: 'bar' }, + type: ActionTypes.UPDATE_WORKSPACE_MOSAIC_LAYOUT, + }), + ).toEqual({ layout: { foo: 'bar' }, }); }); it('should handle SET_WORKSPACE_ADD_VISIBILITY', () => { - expect(workspaceReducer([], { - isWorkspaceAddVisible: true, - type: ActionTypes.SET_WORKSPACE_ADD_VISIBILITY, - })).toEqual({ + expect( + workspaceReducer([], { + isWorkspaceAddVisible: true, + type: ActionTypes.SET_WORKSPACE_ADD_VISIBILITY, + }), + ).toEqual({ isWorkspaceAddVisible: true, }); }); it('should handle SET_WORKSPACE_VIEWPORT_POSITION', () => { - expect(workspaceReducer({ height: 5000, width: 5000 }, { - payload: { - position: { - height: 50, - width: 50, - x: 50, - y: 50, + expect( + workspaceReducer( + { height: 5000, width: 5000 }, + { + payload: { + position: { + height: 50, + width: 50, + x: 50, + y: 50, + }, + }, + type: ActionTypes.SET_WORKSPACE_VIEWPORT_POSITION, }, - }, - type: ActionTypes.SET_WORKSPACE_VIEWPORT_POSITION, - })).toEqual({ + ), + ).toEqual({ height: 5000, viewportPosition: { height: 50, @@ -111,17 +148,22 @@ describe('workspace reducer', () => { }); }); it('resizes the workspace if the SET_WORKSPACE_VIEWPORT_POSITION are beyond outside the workspace', () => { - expect(workspaceReducer({ height: 500, width: 500 }, { - payload: { - position: { - height: 50, - width: 50, - x: -255, - y: 0, + expect( + workspaceReducer( + { height: 500, width: 500 }, + { + payload: { + position: { + height: 50, + width: 50, + x: -255, + y: 0, + }, + }, + type: ActionTypes.SET_WORKSPACE_VIEWPORT_POSITION, }, - }, - type: ActionTypes.SET_WORKSPACE_VIEWPORT_POSITION, - })).toEqual({ + ), + ).toEqual({ height: 1000, viewportPosition: { height: 50, @@ -133,20 +175,35 @@ describe('workspace reducer', () => { }); }); it('should handle SET_CONFIG', () => { - expect(workspaceReducer({}, { - config: { workspace: { new: 'stuff' } }, - type: ActionTypes.SET_CONFIG, - })).toEqual({ new: 'stuff' }); + expect( + workspaceReducer( + {}, + { + config: { workspace: { new: 'stuff' } }, + type: ActionTypes.SET_CONFIG, + }, + ), + ).toEqual({ new: 'stuff' }); }); it('should handle IMPORT_MIRADOR_STATE', () => { - expect(workspaceReducer({}, { - state: { workspace: { new: 'stuff' } }, - type: ActionTypes.IMPORT_MIRADOR_STATE, - })).toEqual({ new: 'stuff' }); + expect( + workspaceReducer( + {}, + { + state: { workspace: { new: 'stuff' } }, + type: ActionTypes.IMPORT_MIRADOR_STATE, + }, + ), + ).toEqual({ new: 'stuff' }); }); it('should handle ActionTypes.TOGGLE_DRAGGING', () => { - expect(workspaceReducer({ draggingEnabled: true }, { - type: ActionTypes.TOGGLE_DRAGGING, - })).toEqual({ draggingEnabled: false }); + expect( + workspaceReducer( + { draggingEnabled: true }, + { + type: ActionTypes.TOGGLE_DRAGGING, + }, + ), + ).toEqual({ draggingEnabled: false }); }); }); diff --git a/__tests__/src/sagas/annotations.test.js b/__tests__/src/sagas/annotations.test.js index e9573d262..518a3bbd4 100644 --- a/__tests__/src/sagas/annotations.test.js +++ b/__tests__/src/sagas/annotations.test.js @@ -14,7 +14,8 @@ describe('annotation sagas', () => { return expectSaga(fetchCanvasAnnotations, action) .provide([ - [select(getCanvas, { canvasId: 'a', windowId: 'foo' }), + [ + select(getCanvas, { canvasId: 'a', windowId: 'foo' }), { __jsonld: { otherContent: 'annoId' }, id: 'a' }, ], [select(getAnnotations), { a: {} }], @@ -34,7 +35,8 @@ describe('annotation sagas', () => { return expectSaga(fetchCanvasAnnotations, action) .provide([ - [select(getCanvas, { canvasId: 'a', windowId: 'foo' }), + [ + select(getCanvas, { canvasId: 'a', windowId: 'foo' }), { __jsonld: { otherContent: ['annoId'] }, id: 'a' }, ], [select(getAnnotations), { a: { annoId: {} } }], @@ -49,7 +51,8 @@ describe('annotation sagas', () => { return expectSaga(fetchCanvasAnnotations, action) .provide([ - [select(getCanvas, { canvasId: 'a', windowId: 'foo' }), + [ + select(getCanvas, { canvasId: 'a', windowId: 'foo' }), { __jsonld: { annotations: { id: 'annoId', type: 'AnnotationPage' } }, id: 'a' }, ], [select(getAnnotations), { a: {} }], @@ -71,7 +74,8 @@ describe('annotation sagas', () => { return expectSaga(fetchCanvasAnnotations, action) .provide([ - [select(getCanvas, { canvasId: 'a', windowId: 'foo' }), + [ + select(getCanvas, { canvasId: 'a', windowId: 'foo' }), { __jsonld: { annotations }, id: 'a' }, ], [select(getAnnotations), { a: {} }], diff --git a/__tests__/src/sagas/app.test.js b/__tests__/src/sagas/app.test.js index 011299222..8cd124a7d 100644 --- a/__tests__/src/sagas/app.test.js +++ b/__tests__/src/sagas/app.test.js @@ -36,9 +36,7 @@ describe('app-level sagas', () => { testSaga(importState, action) .next() - .all([ - call(fetchManifests, 'x'), - ]); + .all([call(fetchManifests, 'x')]); }); it('does not fetchManifest if the manifest json was provided', () => { const action = { @@ -48,9 +46,7 @@ describe('app-level sagas', () => { }, }; - testSaga(importState, action) - .next() - .all([]); + testSaga(importState, action).next().all([]); }); }); @@ -68,12 +64,22 @@ describe('app-level sagas', () => { return expectSaga(importConfig, action) .provide([ - [call(addWindow, { - id: 'x', manifestId: 'a', thumbnailNavigationPosition: undefined, - }), { type: 'thunk1' }], - [call(addWindow, { - id: 'y', manifestId: 'b', thumbnailNavigationPosition: undefined, - }), { type: 'thunk2' }], + [ + call(addWindow, { + id: 'x', + manifestId: 'a', + thumbnailNavigationPosition: undefined, + }), + { type: 'thunk1' }, + ], + [ + call(addWindow, { + id: 'y', + manifestId: 'b', + thumbnailNavigationPosition: undefined, + }), + { type: 'thunk2' }, + ], ]) .put({ type: 'thunk1' }) .put({ type: 'thunk2' }) diff --git a/__tests__/src/sagas/auth.test.js b/__tests__/src/sagas/auth.test.js index 8d31a5b44..7c168da58 100644 --- a/__tests__/src/sagas/auth.test.js +++ b/__tests__/src/sagas/auth.test.js @@ -11,9 +11,7 @@ import { rerequestOnAccessTokenFailure, invalidateInvalidAuth, } from '../../../src/state/sagas/auth'; -import { - fetchInfoResponse, -} from '../../../src/state/sagas/iiif'; +import { fetchInfoResponse } from '../../../src/state/sagas/iiif'; import { getAccessTokens, getWindows, @@ -28,7 +26,7 @@ describe('IIIF Authentication sagas', () => { it('delays and then refetches info responses', () => { const tokenServiceId = 'whatever'; /** stub out delay... ugh. */ - const provideDelay = ({ fn }, next) => ((fn.name === 'delayP') ? null : next()); + const provideDelay = ({ fn }, next) => (fn.name === 'delayP' ? null : next()); return expectSaga(refetchInfoResponsesOnLogout, { tokenServiceId }) .provide([ @@ -45,17 +43,19 @@ describe('IIIF Authentication sagas', () => { const tokenService = { id: serviceId }; const authStanza = { - service: [{ - '@context': 'http://iiif.io/api/auth/1/context.json', - '@id': 'https://authentication.example.org/login', - profile: 'http://iiif.io/api/auth/1/login', - service: [ - { - '@id': serviceId, - profile: 'http://iiif.io/api/auth/1/token', - }, - ], - }], + service: [ + { + '@context': 'http://iiif.io/api/auth/1/context.json', + '@id': 'https://authentication.example.org/login', + profile: 'http://iiif.io/api/auth/1/login', + service: [ + { + '@id': serviceId, + profile: 'http://iiif.io/api/auth/1/token', + }, + ], + }, + ], }; const x = { @@ -88,17 +88,19 @@ describe('IIIF Authentication sagas', () => { const tokenService = { id: serviceId }; const authStanza = { - service: [{ - '@context': 'http://iiif.io/api/auth/1/context.json', - '@id': 'https://authentication.example.org/login', - profile: 'http://iiif.io/api/auth/1/login', - service: [ - { - '@id': 'https://authentication.example.org/some-other-token-service', - profile: 'http://iiif.io/api/auth/1/token', - }, - ], - }], + service: [ + { + '@context': 'http://iiif.io/api/auth/1/context.json', + '@id': 'https://authentication.example.org/login', + profile: 'http://iiif.io/api/auth/1/login', + service: [ + { + '@id': 'https://authentication.example.org/some-other-token-service', + profile: 'http://iiif.io/api/auth/1/token', + }, + ], + }, + ], }; const wrongService = { @@ -134,23 +136,23 @@ describe('IIIF Authentication sagas', () => { const tokenService = { id: serviceId }; const authStanza = { - service: [{ - '@context': 'http://iiif.io/api/auth/1/context.json', - '@id': 'https://authentication.example.org/login', - profile: 'http://iiif.io/api/auth/1/login', - service: [ - { - '@id': serviceId, - profile: 'http://iiif.io/api/auth/1/token', - }, - ], - }], + service: [ + { + '@context': 'http://iiif.io/api/auth/1/context.json', + '@id': 'https://authentication.example.org/login', + profile: 'http://iiif.io/api/auth/1/login', + service: [ + { + '@id': serviceId, + profile: 'http://iiif.io/api/auth/1/token', + }, + ], + }, + ], }; const window = {}; - const canvases = [ - Utils.parseManifest(serviceFixture).getSequences()[0].getCanvases()[0], - ]; + const canvases = [Utils.parseManifest(serviceFixture).getSequences()[0].getCanvases()[0]]; const iiifInfoId = 'https://api.digitale-sammlungen.de/iiif/image/v2/bsb00122140_00001'; const infoResponse = { @@ -175,17 +177,19 @@ describe('IIIF Authentication sagas', () => { describe('doAuthWorkflow', () => { it('kicks off the first external auth from the info.json', () => { const infoJson = { - service: [{ - '@context': 'http://iiif.io/api/auth/1/context.json', - '@id': 'https://authentication.example.com/external', - profile: 'http://iiif.io/api/auth/1/external', - service: [ - { - '@id': 'https://authentication.example.com/token', - profile: 'http://iiif.io/api/auth/1/token', - }, - ], - }], + service: [ + { + '@context': 'http://iiif.io/api/auth/1/context.json', + '@id': 'https://authentication.example.com/external', + profile: 'http://iiif.io/api/auth/1/external', + service: [ + { + '@id': 'https://authentication.example.com/token', + profile: 'http://iiif.io/api/auth/1/token', + }, + ], + }, + ], }; const windowId = 'window'; return expectSaga(doAuthWorkflow, { infoJson, windowId }) @@ -208,17 +212,19 @@ describe('IIIF Authentication sagas', () => { it('does nothing if the auth service has been tried already', () => { const infoJson = { - service: [{ - '@context': 'http://iiif.io/api/auth/1/context.json', - '@id': 'https://authentication.example.com/external', - profile: 'http://iiif.io/api/auth/1/external', - service: [ - { - '@id': 'https://authentication.example.com/token', - profile: 'http://iiif.io/api/auth/1/token', - }, - ], - }], + service: [ + { + '@context': 'http://iiif.io/api/auth/1/context.json', + '@id': 'https://authentication.example.com/external', + profile: 'http://iiif.io/api/auth/1/external', + service: [ + { + '@id': 'https://authentication.example.com/token', + profile: 'http://iiif.io/api/auth/1/token', + }, + ], + }, + ], }; const windowId = 'window'; return expectSaga(doAuthWorkflow, { infoJson, windowId }) @@ -233,17 +239,19 @@ describe('IIIF Authentication sagas', () => { it('does nothing if the auth service is "interactive"', () => { const infoJson = { - service: [{ - '@context': 'http://iiif.io/api/auth/1/context.json', - '@id': 'https://authentication.example.com/login', - profile: 'http://iiif.io/api/auth/1/login', - service: [ - { - '@id': 'https://authentication.example.com/token', - profile: 'http://iiif.io/api/auth/1/token', - }, - ], - }], + service: [ + { + '@context': 'http://iiif.io/api/auth/1/context.json', + '@id': 'https://authentication.example.com/login', + profile: 'http://iiif.io/api/auth/1/login', + service: [ + { + '@id': 'https://authentication.example.com/token', + profile: 'http://iiif.io/api/auth/1/token', + }, + ], + }, + ], }; const windowId = 'window'; return expectSaga(doAuthWorkflow, { infoJson, windowId }) @@ -258,17 +266,19 @@ describe('IIIF Authentication sagas', () => { it('kicks off the kiosk auth from the info.json', () => { const infoJson = { - service: [{ - '@context': 'http://iiif.io/api/auth/1/context.json', - '@id': 'https://authentication.example.com/kiosk', - profile: 'http://iiif.io/api/auth/1/kiosk', - service: [ - { - '@id': 'https://authentication.example.com/token', - profile: 'http://iiif.io/api/auth/1/token', - }, - ], - }], + service: [ + { + '@context': 'http://iiif.io/api/auth/1/context.json', + '@id': 'https://authentication.example.com/kiosk', + profile: 'http://iiif.io/api/auth/1/kiosk', + service: [ + { + '@id': 'https://authentication.example.com/token', + profile: 'http://iiif.io/api/auth/1/token', + }, + ], + }, + ], }; const windowId = 'window'; return expectSaga(doAuthWorkflow, { infoJson, windowId }) @@ -292,57 +302,55 @@ describe('IIIF Authentication sagas', () => { const windowId = 'window'; const tokenServiceId = undefined; return expectSaga(rerequestOnAccessTokenFailure, { infoJson, tokenServiceId, windowId }) - .provide([ - [select(getAccessTokens), {}], - ]) + .provide([[select(getAccessTokens), {}]]) .not.put.like({ type: ActionTypes.REQUEST_ACCESS_TOKEN }) .run(); }); it('does nothing if the access token has never worked', () => { const infoJson = { - service: [{ - '@context': 'http://iiif.io/api/auth/1/context.json', - '@id': 'https://authentication.example.com/kiosk', - profile: 'http://iiif.io/api/auth/1/kiosk', - service: [ - { - '@id': 'https://authentication.example.com/token', - profile: 'http://iiif.io/api/auth/1/token', - }, - ], - }], + service: [ + { + '@context': 'http://iiif.io/api/auth/1/context.json', + '@id': 'https://authentication.example.com/kiosk', + profile: 'http://iiif.io/api/auth/1/kiosk', + service: [ + { + '@id': 'https://authentication.example.com/token', + profile: 'http://iiif.io/api/auth/1/token', + }, + ], + }, + ], }; const windowId = 'window'; const tokenServiceId = 'https://authentication.example.com/token'; return expectSaga(rerequestOnAccessTokenFailure, { infoJson, tokenServiceId, windowId }) - .provide([ - [select(getAccessTokens), { [tokenServiceId]: { success: false } }], - ]) + .provide([[select(getAccessTokens), { [tokenServiceId]: { success: false } }]]) .not.put.like({ type: ActionTypes.REQUEST_ACCESS_TOKEN }) .run(); }); it('re-requests the access token if it might be reneweable', () => { const infoJson = { - service: [{ - '@context': 'http://iiif.io/api/auth/1/context.json', - '@id': 'https://authentication.example.com/kiosk', - profile: 'http://iiif.io/api/auth/1/kiosk', - service: [ - { - '@id': 'https://authentication.example.com/token', - profile: 'http://iiif.io/api/auth/1/token', - }, - ], - }], + service: [ + { + '@context': 'http://iiif.io/api/auth/1/context.json', + '@id': 'https://authentication.example.com/kiosk', + profile: 'http://iiif.io/api/auth/1/kiosk', + service: [ + { + '@id': 'https://authentication.example.com/token', + profile: 'http://iiif.io/api/auth/1/token', + }, + ], + }, + ], }; const windowId = 'window'; const tokenServiceId = 'https://authentication.example.com/token'; return expectSaga(rerequestOnAccessTokenFailure, { infoJson, tokenServiceId, windowId }) - .provide([ - [select(getAccessTokens), { [tokenServiceId]: { success: true } }], - ]) + .provide([[select(getAccessTokens), { [tokenServiceId]: { success: true } }]]) .put({ authId: 'https://authentication.example.com/kiosk', serviceId: 'https://authentication.example.com/token', diff --git a/__tests__/src/sagas/iiif.test.js b/__tests__/src/sagas/iiif.test.js index bb6ed3722..60d4fe7c7 100644 --- a/__tests__/src/sagas/iiif.test.js +++ b/__tests__/src/sagas/iiif.test.js @@ -24,9 +24,7 @@ describe('IIIF sagas', () => { }; return expectSaga(fetchManifest, action) - .provide([ - [select(getConfig), {}], - ]) + .provide([[select(getConfig), {}]]) .put({ manifestId: 'manifestId', manifestJson: { data: '12345' }, @@ -42,26 +40,29 @@ describe('IIIF sagas', () => { }; return expectSaga(fetchManifest, action) - .provide([ - [select(getConfig), {}], - ]) + .provide([[select(getConfig), {}]]) .put.actionType('mirador/RECEIVE_MANIFEST_FAILURE') .run(); }); it('supports request configuration preprocessors', () => { - fetch.once(req => Promise.resolve(JSON.stringify({ data: req.headers.get('customheader') }))); + fetch.once((req) => + Promise.resolve(JSON.stringify({ data: req.headers.get('customheader') })), + ); const action = { manifestId: 'manifestId', }; return expectSaga(fetchManifest, action) .provide([ - [select(getRequestsConfig), { - preprocessors: [ - (url, options) => ({ ...options, headers: { CustomHeader: 'config injected' } }), - ], - }], + [ + select(getRequestsConfig), + { + preprocessors: [ + (url, options) => ({ ...options, headers: { CustomHeader: 'config injected' } }), + ], + }, + ], ]) .put({ manifestId: 'manifestId', @@ -72,20 +73,26 @@ describe('IIIF sagas', () => { }); it('supports response postprocessors', () => { - fetch.once(req => Promise.resolve(JSON.stringify({ data: req.headers.get('customheader') }))); + fetch.once((req) => + Promise.resolve(JSON.stringify({ data: req.headers.get('customheader') })), + ); const action = { manifestId: 'manifestId', }; return expectSaga(fetchManifest, action) .provide([ - [select(getRequestsConfig), { - postprocessors: [ - (url, responseAction) => { - responseAction.manifestJson = { foo: 'modified!' }; // eslint-disable-line no-param-reassign - }, - ], - }], + [ + select(getRequestsConfig), + { + postprocessors: [ + (url, responseAction) => { + // eslint-disable-next-line no-param-reassign + responseAction.manifestJson = { foo: 'modified!' }; + }, + ], + }, + ], ]) .put({ manifestId: 'manifestId', @@ -122,23 +129,30 @@ describe('IIIF sagas', () => { }; const infoResponse = { id: 'degradedInfoId', - service: [{ - '@context': 'http://iiif.io/api/auth/1/context.json', - '@id': 'https://authentication.example.org/login', - profile: 'http://iiif.io/api/auth/1/login', - service: [ - { - '@id': 'https://authentication.example.org/token', - profile: 'http://iiif.io/api/auth/1/token', - }, - ], - }], + service: [ + { + '@context': 'http://iiif.io/api/auth/1/context.json', + '@id': 'https://authentication.example.org/login', + profile: 'http://iiif.io/api/auth/1/login', + service: [ + { + '@id': 'https://authentication.example.org/token', + profile: 'http://iiif.io/api/auth/1/token', + }, + ], + }, + ], }; return expectSaga(fetchInfoResponse, action) .provide([ [select(selectInfoResponse, { infoId: 'infoId' }), infoResponse], - [select(getAccessTokens), { 'https://authentication.example.org/token': { id: 'x', json: { accessToken: '123' } } }], + [ + select(getAccessTokens), + { + 'https://authentication.example.org/token': { id: 'x', json: { accessToken: '123' } }, + }, + ], ]) .put({ infoId: 'infoId', @@ -184,17 +198,19 @@ describe('IIIF sagas', () => { it('rerequests documents if the authoritative response suggests a different access token service', () => { const degradedInfoResponse = { id: 'degradedInfoId', - service: [{ - '@context': 'http://iiif.io/api/auth/1/context.json', - '@id': 'https://authentication.example.org/login', - profile: 'http://iiif.io/api/auth/1/login', - service: [ - { - '@id': 'https://authentication.example.org/token', - profile: 'http://iiif.io/api/auth/1/token', - }, - ], - }], + service: [ + { + '@context': 'http://iiif.io/api/auth/1/context.json', + '@id': 'https://authentication.example.org/login', + profile: 'http://iiif.io/api/auth/1/login', + service: [ + { + '@id': 'https://authentication.example.org/token', + profile: 'http://iiif.io/api/auth/1/token', + }, + ], + }, + ], }; fetch.once(JSON.stringify(degradedInfoResponse)).once(JSON.stringify({ id: 'infoId' })); const action = { @@ -205,7 +221,12 @@ describe('IIIF sagas', () => { return expectSaga(fetchInfoResponse, action) .provide([ [select(selectInfoResponse, { infoId: 'infoId' }), undefined], - [select(getAccessTokens), { 'https://authentication.example.org/token': { id: 'x', json: { accessToken: '123' } } }], + [ + select(getAccessTokens), + { + 'https://authentication.example.org/token': { id: 'x', json: { accessToken: '123' } }, + }, + ], ]) .put({ infoId: 'infoId', @@ -332,7 +353,8 @@ describe('IIIF sagas', () => { [select(getConfig), {}], [select(getManifests), { manifestId: {} }], ]) - .run().then(({ allEffects }) => allEffects.length === 0); + .run() + .then(({ allEffects }) => allEffects.length === 0); }); }); }); diff --git a/__tests__/src/sagas/windows.test.js b/__tests__/src/sagas/windows.test.js index 12cf16e57..780ac3aae 100644 --- a/__tests__/src/sagas/windows.test.js +++ b/__tests__/src/sagas/windows.test.js @@ -5,15 +5,21 @@ import { Utils } from 'manifesto.js'; import ActionTypes from '../../../src/state/actions/action-types'; import { setCanvas } from '../../../src/state/actions'; import { - getManifests, getManifestoInstance, - getManifestSearchService, getCompanionWindowIdsForPosition, + getManifests, + getManifestoInstance, + getManifestSearchService, + getCompanionWindowIdsForPosition, getSearchForWindow, - getWorkspace, getElasticLayout, - getWindow, getCanvasGrouping, + getWorkspace, + getElasticLayout, + getWindow, + getCanvasGrouping, getSelectedContentSearchAnnotationIds, getSortedSearchAnnotationsForCompanionWindow, - getVisibleCanvasIds, getCanvasForAnnotation, - getCanvases, selectInfoResponses, + getVisibleCanvasIds, + getCanvasForAnnotation, + getCanvases, + selectInfoResponses, getWindowConfig, } from '../../../src/state/selectors'; import { fetchManifests } from '../../../src/state/sagas/iiif'; @@ -104,8 +110,7 @@ describe('window-level sagas', () => { }; return expectSaga(setCanvasOnNewSequence, action) - .provide([ - ]) + .provide([]) .run() .then(({ allEffects }) => allEffects.length === 0); }); @@ -124,7 +129,10 @@ describe('window-level sagas', () => { return expectSaga(setWindowStartingCanvas, action) .provide([ [select(getManifests), { 'manifest.json': {} }], - [call(setCanvas, 'x', '1', null, { preserveViewport: false }), { type: 'setCanvasThunk' }], + [ + call(setCanvas, 'x', '1', null, { preserveViewport: false }), + { type: 'setCanvasThunk' }, + ], ]) .put({ type: 'setCanvasThunk' }) .run(); @@ -179,13 +187,19 @@ describe('window-level sagas', () => { }, }; - const manifest = Utils.parseManifest({ ...fixture, start: { id: 'https://purl.stanford.edu/fr426cg9537/iiif/canvas/fr426cg9537_1' } }); + const manifest = Utils.parseManifest({ + ...fixture, + start: { id: 'https://purl.stanford.edu/fr426cg9537/iiif/canvas/fr426cg9537_1' }, + }); return expectSaga(fetchWindowManifest, action) .provide([ [select(getManifests), { 'manifest.json': {} }], [select(getManifestoInstance, { manifestId: 'manifest.json' }), manifest], - [call(setCanvas, 'x', 'https://purl.stanford.edu/fr426cg9537/iiif/canvas/fr426cg9537_1'), { type: 'setCanvasThunk' }], + [ + call(setCanvas, 'x', 'https://purl.stanford.edu/fr426cg9537/iiif/canvas/fr426cg9537_1'), + { type: 'setCanvasThunk' }, + ], ]) .put({ type: 'setCanvasThunk' }) .run(); @@ -202,7 +216,8 @@ describe('window-level sagas', () => { }; return expectSaga(setWindowDefaultSearchQuery, action) - .run().then(({ allEffects }) => allEffects.length === 0); + .run() + .then(({ allEffects }) => allEffects.length === 0); }); it('initiates a search', () => { @@ -240,12 +255,7 @@ describe('window-level sagas', () => { }; return expectSaga(setCurrentAnnotationsOnCurrentCanvas, action) - .provide([ - [select( - getSearchForWindow, - { windowId: 'abc123' }, - ), {}], - ]) + .provide([[select(getSearchForWindow, { windowId: 'abc123' }), {}]]) .run() .then(({ allEffects }) => allEffects.length === 0); }); @@ -257,21 +267,26 @@ describe('window-level sagas', () => { windowId: 'abc123', }; - return expectSaga(setCurrentAnnotationsOnCurrentCanvas, action) - .provide([ - [select( - getSearchForWindow, - { windowId: 'abc123' }, - ), { cwid: { } }], - [select(getAnnotationsBySearch, { canvasIds: ['a', 'b'], companionWindowIds: ['cwid'], windowId: 'abc123' }), - { }], - ]) - .run() - // Assert that nothing did happen, see https://github.com/jfairbank/redux-saga-test-plan/issues/137 - .then(({ effects }) => { - expect(effects.select.length).toEqual(2); - expect(effects.put).toBeUndefined(); - }); + return ( + expectSaga(setCurrentAnnotationsOnCurrentCanvas, action) + .provide([ + [select(getSearchForWindow, { windowId: 'abc123' }), { cwid: {} }], + [ + select(getAnnotationsBySearch, { + canvasIds: ['a', 'b'], + companionWindowIds: ['cwid'], + windowId: 'abc123', + }), + {}, + ], + ]) + .run() + // Assert that nothing did happen, see https://github.com/jfairbank/redux-saga-test-plan/issues/137 + .then(({ effects }) => { + expect(effects.select.length).toEqual(2); + expect(effects.put).toBeUndefined(); + }) + ); }); it('selects content search annotations for the current searches', () => { @@ -283,18 +298,26 @@ describe('window-level sagas', () => { return expectSaga(setCurrentAnnotationsOnCurrentCanvas, action) .provide([ - [select( - getSearchForWindow, - { windowId: 'abc123' }, - ), { cwid: { } }], - [select(getAnnotationsBySearch, { canvasIds: ['a', 'b'], companionWindowIds: ['cwid'], windowId: 'abc123' }), - { cwid: ['annoId'] }], + [select(getSearchForWindow, { windowId: 'abc123' }), { cwid: {} }], + [ + select(getAnnotationsBySearch, { + canvasIds: ['a', 'b'], + companionWindowIds: ['cwid'], + windowId: 'abc123', + }), + { cwid: ['annoId'] }, + ], ]) .put({ - annotationIds: ['annoId'], companionWindowId: 'cwid', type: ActionTypes.SET_CONTENT_SEARCH_CURRENT_ANNOTATIONS, windowId: 'abc123', + annotationIds: ['annoId'], + companionWindowId: 'cwid', + type: ActionTypes.SET_CONTENT_SEARCH_CURRENT_ANNOTATIONS, + windowId: 'abc123', }) .put({ - annotationId: 'annoId', type: ActionTypes.SELECT_ANNOTATION, windowId: 'abc123', + annotationId: 'annoId', + type: ActionTypes.SELECT_ANNOTATION, + windowId: 'abc123', }) .run(); }); @@ -308,7 +331,8 @@ describe('window-level sagas', () => { }; return expectSaga(panToFocusedWindow, action) - .run().then(({ allEffects }) => allEffects.length === 0); + .run() + .then(({ allEffects }) => allEffects.length === 0); }); it('sets the viewport position to the newly focused window', () => { @@ -318,14 +342,23 @@ describe('window-level sagas', () => { }; return expectSaga(panToFocusedWindow, action) .provide([ - [select(getWorkspace), { - viewportPosition: { height: 100, width: 100 }, - }], - [select(getElasticLayout), { - x: { - height: 50, width: 50, x: 50, y: 12, + [ + select(getWorkspace), + { + viewportPosition: { height: 100, width: 100 }, }, - }], + ], + [ + select(getElasticLayout), + { + x: { + height: 50, + width: 50, + x: 50, + y: 12, + }, + }, + ], ]) .put({ payload: { @@ -375,7 +408,10 @@ describe('window-level sagas', () => { .provide([ [select(getWindowConfig, { windowId }), { switchCanvasOnSearch: true }], [select(getSelectedContentSearchAnnotationIds, { companionWindowId, windowId }), []], - [select(getSortedSearchAnnotationsForCompanionWindow, { companionWindowId, windowId }), [{ id: 'a' }, { id: 'b' }]], + [ + select(getSortedSearchAnnotationsForCompanionWindow, { companionWindowId, windowId }), + [{ id: 'a' }, { id: 'b' }], + ], ]) .put({ annotationId: 'a', @@ -399,7 +435,8 @@ describe('window-level sagas', () => { [select(getWindowConfig, { windowId }), { switchCanvasOnSearch: true }], [select(getSelectedContentSearchAnnotationIds, { companionWindowId, windowId }), ['y']], ]) - .run().then(({ allEffects }) => allEffects.length === 0); + .run() + .then(({ allEffects }) => allEffects.length === 0); }); it('does nothing if canvas switching for searches is disabled', () => { @@ -412,10 +449,9 @@ describe('window-level sagas', () => { }; return expectSaga(setCanvasOfFirstSearchResult, action) - .provide([ - [select(getWindowConfig, { windowId }), { switchCanvasOnSearch: false }], - ]) - .run().then(({ allEffects }) => allEffects.length === 0); + .provide([[select(getWindowConfig, { windowId }), { switchCanvasOnSearch: false }]]) + .run() + .then(({ allEffects }) => allEffects.length === 0); }); }); @@ -453,7 +489,8 @@ describe('window-level sagas', () => { [select(getVisibleCanvasIds, { windowId }), ['z']], [select(getCanvasForAnnotation, { annotationId, windowId }), { id: 'z' }], ]) - .run().then(({ allEffects }) => allEffects.length === 0); + .run() + .then(({ allEffects }) => allEffects.length === 0); }); it('does nothing if the annotation is not on one of our canvases', () => { @@ -470,7 +507,8 @@ describe('window-level sagas', () => { [select(getVisibleCanvasIds, { windowId }), ['z']], [select(getCanvasForAnnotation, { annotationId, windowId }), null], ]) - .run().then(({ allEffects }) => allEffects.length === 0); + .run() + .then(({ allEffects }) => allEffects.length === 0); }); }); @@ -508,7 +546,10 @@ describe('window-level sagas', () => { return expectSaga(fetchInfoResponses, action) .provide([ [select(getCanvases, { windowId: 'foo' }), manifest.getSequences()[0].getCanvases()], - [select(selectInfoResponses), { 'https://stacks.stanford.edu/image/iiif/hg676jb4964%2F0380_796-44': {} }], + [ + select(selectInfoResponses), + { 'https://stacks.stanford.edu/image/iiif/hg676jb4964%2F0380_796-44': {} }, + ], ]) .not.put.like({ action: { @@ -525,9 +566,7 @@ describe('window-level sagas', () => { const manifest = Utils.parseManifest(collectionFixture); return expectSaga(determineAndShowCollectionDialog, 'manifest.json', 'x') - .provide([ - [select(getManifestoInstance, { manifestId: 'manifest.json' }), manifest], - ]) + .provide([[select(getManifestoInstance, { manifestId: 'manifest.json' }), manifest]]) .put.like({ action: { dialogCollectionPath: [], @@ -543,9 +582,7 @@ describe('window-level sagas', () => { const manifest = Utils.parseManifest(fixture); return expectSaga(determineAndShowCollectionDialog, 'manifest.json', 'x') - .provide([ - [select(getManifestoInstance, { manifestId: 'manifest.json' }), manifest], - ]) + .provide([[select(getManifestoInstance, { manifestId: 'manifest.json' }), manifest]]) .not.put.like({ action: { dialogCollectionPath: [], diff --git a/__tests__/src/selectors/annotations.test.js b/__tests__/src/selectors/annotations.test.js index f077cd4a1..79cf8ccf0 100644 --- a/__tests__/src/selectors/annotations.test.js +++ b/__tests__/src/selectors/annotations.test.js @@ -6,10 +6,7 @@ import { describe('getAnnotationResourcesByMotivationForCanvas', () => { it('returns an array of annotation resources on a given canvas (filtered by the passed in array of motiviations)', () => { - const expected = [ - ['oa:commenting'], - ['sc:something-else', 'oa:commenting'], - ]; + const expected = [['oa:commenting'], ['sc:something-else', 'oa:commenting']]; const state = { annotations: { @@ -42,10 +39,7 @@ describe('getAnnotationResourcesByMotivationForCanvas', () => { '@type': 'sc:Manifest', sequences: [ { - canvases: [ - { '@id': 'cid1' }, - { '@id': 'cid2' }, - ], + canvases: [{ '@id': 'cid1' }, { '@id': 'cid2' }], }, ], }, @@ -59,17 +53,18 @@ describe('getAnnotationResourcesByMotivationForCanvas', () => { }; expect( - getAnnotationResourcesByMotivationForCanvas(state, { canvasId: 'cid2', motivations: ['something', 'oa:commenting'], windowId: 'abc123' }).map(r => r.motivations), + getAnnotationResourcesByMotivationForCanvas(state, { + canvasId: 'cid2', + motivations: ['something', 'oa:commenting'], + windowId: 'abc123', + }).map((r) => r.motivations), ).toEqual(expected); }); }); describe('getAnnotationResourcesByMotivation', () => { it('returns an array of annotation resources (filtered by the passed in array of motiviations)', () => { - const expected = [ - ['oa:commenting'], - ['sc:something-else', 'oa:commenting'], - ]; + const expected = [['oa:commenting'], ['sc:something-else', 'oa:commenting']]; const state = { annotations: { @@ -90,8 +85,7 @@ describe('getAnnotationResourcesByMotivation', () => { mid: { json: { '@context': 'http://iiif.io/api/presentation/2/context.json', - '@id': - 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', + '@id': 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', '@type': 'sc:Manifest', sequences: [ { @@ -114,7 +108,10 @@ describe('getAnnotationResourcesByMotivation', () => { }; expect( - getAnnotationResourcesByMotivation(state, { motivations: ['something', 'oa:commenting'], windowId: 'abc123' }).map(r => r.motivations), + getAnnotationResourcesByMotivation(state, { + motivations: ['something', 'oa:commenting'], + windowId: 'abc123', + }).map((r) => r.motivations), ).toEqual(expected); }); }); @@ -125,8 +122,7 @@ it('getSelectedAnnotationId returns the selected annotation ID from state', () = mid: { json: { '@context': 'http://iiif.io/api/presentation/2/context.json', - '@id': - 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', + '@id': 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', '@type': 'sc:Manifest', sequences: [ { @@ -150,9 +146,7 @@ it('getSelectedAnnotationId returns the selected annotation ID from state', () = }, }; - expect(getSelectedAnnotationId(state, { windowId: 'wid' })).toEqual( - 'aid1', - ); + expect(getSelectedAnnotationId(state, { windowId: 'wid' })).toEqual('aid1'); }); it('returns all annotation resources when no motivations are passed and config.filteredMotivations is empty', () => { @@ -204,6 +198,6 @@ it('returns all annotation resources when no motivations are passed and config.f // Returns all three resources expect(result).toHaveLength(3); - const resourceIds = result.map(r => r.resource['@id']); + const resourceIds = result.map((r) => r.resource['@id']); expect(resourceIds).toEqual(['annoId1', 'annoId2', 'annoId3']); }); diff --git a/__tests__/src/selectors/auth.test.js b/__tests__/src/selectors/auth.test.js index 2071e9931..71765fcfb 100644 --- a/__tests__/src/selectors/auth.test.js +++ b/__tests__/src/selectors/auth.test.js @@ -1,10 +1,7 @@ import manifestFixture001 from '../../fixtures/version-2/001.json'; import manifestFixture019 from '../../fixtures/version-2/019.json'; import settings from '../../../src/config/settings'; -import { - getAccessTokens, - selectCurrentAuthServices, -} from '../../../src/state/selectors/auth'; +import { getAccessTokens, selectCurrentAuthServices } from '../../../src/state/selectors/auth'; describe('getAccessTokens', () => { const state = { @@ -74,21 +71,22 @@ describe('selectCurrentAuthServices', () => { }, x: { manifestId: 'b', - visibleCanvases: [ - 'http://iiif.io/api/presentation/2.0/example/fixtures/canvas/24/c1.json', - ], + visibleCanvases: ['http://iiif.io/api/presentation/2.0/example/fixtures/canvas/24/c1.json'], }, y: { manifestId: 'b', - visibleCanvases: [ - 'https://purl.stanford.edu/fr426cg9537/iiif/canvas/fr426cg9537_1', - ], + visibleCanvases: ['https://purl.stanford.edu/fr426cg9537/iiif/canvas/fr426cg9537_1'], }, }, }; it('returns undefined if there is no current canvas', () => { - expect(selectCurrentAuthServices({ config: { auth: settings.auth }, manifests: {} }, { windowId: 'noCanvas' })[0]).toBeUndefined(); + expect( + selectCurrentAuthServices( + { config: { auth: settings.auth }, manifests: {} }, + { windowId: 'noCanvas' }, + )[0], + ).toBeUndefined(); }); it('returns the next auth service to try', () => { @@ -106,7 +104,9 @@ describe('selectCurrentAuthServices', () => { login: { isFetching: false, ok: false }, }; expect(selectCurrentAuthServices({ ...state, auth }, { windowId: 'w' })[0].id).toEqual('login'); - expect(selectCurrentAuthServices({ ...state, auth }, { windowId: 'x' })[0].id).toEqual('external'); + expect(selectCurrentAuthServices({ ...state, auth }, { windowId: 'x' })[0].id).toEqual( + 'external', + ); expect(selectCurrentAuthServices({ ...state, auth }, { windowId: 'y' })[0]).toBeUndefined(); }); @@ -159,12 +159,16 @@ describe('selectCurrentAuthServices', () => { it('returns external first', () => { auth = {}; - expect(selectCurrentAuthServices({ ...orderedState, auth }, { windowId: 'w' })[0].id).toEqual('external'); + expect(selectCurrentAuthServices({ ...orderedState, auth }, { windowId: 'w' })[0].id).toEqual( + 'external', + ); }); it('returns kiosk next', () => { auth = { external: { isFetching: false, ok: false } }; - expect(selectCurrentAuthServices({ ...orderedState, auth }, { windowId: 'w' })[0].id).toEqual('kiosk'); + expect(selectCurrentAuthServices({ ...orderedState, auth }, { windowId: 'w' })[0].id).toEqual( + 'kiosk', + ); }); it('returns clickthrough next', () => { @@ -172,7 +176,9 @@ describe('selectCurrentAuthServices', () => { external: { isFetching: false, ok: false }, kiosk: { isFetching: false, ok: false }, }; - expect(selectCurrentAuthServices({ ...orderedState, auth }, { windowId: 'w' })[0].id).toEqual('clickthrough'); + expect(selectCurrentAuthServices({ ...orderedState, auth }, { windowId: 'w' })[0].id).toEqual( + 'clickthrough', + ); }); it('returns logins last', () => { @@ -181,7 +187,9 @@ describe('selectCurrentAuthServices', () => { external: { isFetching: false, ok: false }, kiosk: { isFetching: false, ok: false }, }; - expect(selectCurrentAuthServices({ ...orderedState, auth }, { windowId: 'w' })[0].id).toEqual('login'); + expect(selectCurrentAuthServices({ ...orderedState, auth }, { windowId: 'w' })[0].id).toEqual( + 'login', + ); }); it('returns services within a given type using the order from the manifest', () => { @@ -191,7 +199,9 @@ describe('selectCurrentAuthServices', () => { kiosk: { isFetching: false, ok: false }, login: { isFetching: false, ok: false }, }; - expect(selectCurrentAuthServices({ ...orderedState, auth }, { windowId: 'w' })[0].id).toEqual('login2'); + expect(selectCurrentAuthServices({ ...orderedState, auth }, { windowId: 'w' })[0].id).toEqual( + 'login2', + ); }); }); }); diff --git a/__tests__/src/selectors/canvases.test.js b/__tests__/src/selectors/canvases.test.js index 88b1778ac..a887991a0 100644 --- a/__tests__/src/selectors/canvases.test.js +++ b/__tests__/src/selectors/canvases.test.js @@ -116,7 +116,7 @@ describe('getVisibleCanvases', () => { const selectedCanvases = getVisibleCanvases(state, { windowId: 'a' }); expect(selectedCanvases.length).toEqual(2); - expect(selectedCanvases.map(canvas => canvas.id)).toEqual([ + expect(selectedCanvases.map((canvas) => canvas.id)).toEqual([ 'https://purl.stanford.edu/fr426cg9537/iiif/canvas/fr426cg9537_1', 'https://purl.stanford.edu/rz176rt6531/iiif/canvas/rz176rt6531_1', ]); @@ -155,7 +155,7 @@ describe('getNextCanvasGrouping', () => { it('should return the next canvas groupings', () => { const selectedCanvases = getNextCanvasGrouping(state, { windowId: 'a' }); - expect(selectedCanvases.map(canvas => canvas.id)).toEqual([ + expect(selectedCanvases.map((canvas) => canvas.id)).toEqual([ 'https://purl.stanford.edu/fr426cg9537/iiif/canvas/fr426cg9537_1', 'https://purl.stanford.edu/rz176rt6531/iiif/canvas/rz176rt6531_1', ]); @@ -192,7 +192,7 @@ describe('getPreviousCanvasGrouping', () => { it('should return the next canvas groupings', () => { const selectedCanvases = getPreviousCanvasGrouping(state, { windowId: 'a' }); - expect(selectedCanvases.map(canvas => canvas.id)).toEqual([ + expect(selectedCanvases.map((canvas) => canvas.id)).toEqual([ 'http://iiif.io/api/presentation/2.0/example/fixtures/canvas/24/c1.json', ]); }); @@ -206,10 +206,13 @@ describe('getCanvas', () => { it('returns the canvas by id', () => { const state = { manifests: { a: { json: manifestFixture001 } } }; const received = getCanvas(state, { - canvasId: 'https://iiif.bodleian.ox.ac.uk/iiif/canvas/9cca8fdd-4a61-4429-8ac1-f648764b4d6d.json', + canvasId: + 'https://iiif.bodleian.ox.ac.uk/iiif/canvas/9cca8fdd-4a61-4429-8ac1-f648764b4d6d.json', manifestId: 'a', }); - expect(received.id).toBe('https://iiif.bodleian.ox.ac.uk/iiif/canvas/9cca8fdd-4a61-4429-8ac1-f648764b4d6d.json'); + expect(received.id).toBe( + 'https://iiif.bodleian.ox.ac.uk/iiif/canvas/9cca8fdd-4a61-4429-8ac1-f648764b4d6d.json', + ); }); }); @@ -217,25 +220,28 @@ describe('getCanvasLabel', () => { it('should return label of the canvas', () => { const state = { manifests: { a: { json: manifestFixture001 } } }; const received = getCanvasLabel(state, { - canvasId: 'https://iiif.bodleian.ox.ac.uk/iiif/canvas/9cca8fdd-4a61-4429-8ac1-f648764b4d6d.json', + canvasId: + 'https://iiif.bodleian.ox.ac.uk/iiif/canvas/9cca8fdd-4a61-4429-8ac1-f648764b4d6d.json', manifestId: 'a', }); expect(received).toBe('Whole Page'); }); it('should return undefined if the canvas is undefined', () => { - const state = { manifests: { } }; - expect(getCanvasLabel(state, { - canvasId: 'https://iiif.bodleian.ox.ac.uk/iiif/canvas/9cca8fdd-4a61-4429-8ac1-f648764b4d6d.json', - manifestId: 'b', - })).toBeUndefined(); + const state = { manifests: {} }; + expect( + getCanvasLabel(state, { + canvasId: + 'https://iiif.bodleian.ox.ac.uk/iiif/canvas/9cca8fdd-4a61-4429-8ac1-f648764b4d6d.json', + manifestId: 'b', + }), + ).toBeUndefined(); }); it('should return the canvas index as (+1) as string if no label given', () => { const manifest = { '@context': 'http://iiif.io/api/presentation/2/context.json', - '@id': - 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', + '@id': 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', '@type': 'sc:Manifest', sequences: [ { @@ -276,7 +282,13 @@ describe('selectInfoResponse', () => { }, }; - expect(selectInfoResponse(state, { canvasId: 'https://iiif.bodleian.ox.ac.uk/iiif/canvas/9cca8fdd-4a61-4429-8ac1-f648764b4d6d.json', manifestId: 'a' }).json).toBe(resource); + expect( + selectInfoResponse(state, { + canvasId: + 'https://iiif.bodleian.ox.ac.uk/iiif/canvas/9cca8fdd-4a61-4429-8ac1-f648764b4d6d.json', + manifestId: 'a', + }).json, + ).toBe(resource); }); it('returns nothing if there are no canvas resources', () => { @@ -286,8 +298,7 @@ describe('selectInfoResponse', () => { a: { json: { '@context': 'http://iiif.io/api/presentation/2/context.json', - '@id': - 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', + '@id': 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', '@type': 'sc:Manifest', sequences: [ { @@ -303,7 +314,9 @@ describe('selectInfoResponse', () => { }, }; - expect(selectInfoResponse(state, { canvasId: 'some-canvas-without-resources', manifestId: 'a' })).toBe(undefined); + expect( + selectInfoResponse(state, { canvasId: 'some-canvas-without-resources', manifestId: 'a' }), + ).toBe(undefined); }); it('returns nothing if there are no canvas services', () => { @@ -313,8 +326,7 @@ describe('selectInfoResponse', () => { a: { json: { '@context': 'http://iiif.io/api/presentation/2/context.json', - '@id': - 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', + '@id': 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', '@type': 'sc:Manifest', sequences: [ { @@ -323,8 +335,7 @@ describe('selectInfoResponse', () => { '@id': 'some-canvas-without-services', images: [ { - resource: { - }, + resource: {}, }, ], }, @@ -336,7 +347,9 @@ describe('selectInfoResponse', () => { }, }; - expect(selectInfoResponse(state, { canvasId: 'some-canvas-without-services', manifestId: 'a' })).toBe(undefined); + expect( + selectInfoResponse(state, { canvasId: 'some-canvas-without-services', manifestId: 'a' }), + ).toBe(undefined); }); }); @@ -358,7 +371,9 @@ describe('getVisibleCanvasNonTiledResources', () => { }, }, }; - expect(getVisibleCanvasNonTiledResources(state, { windowId: 'a' })[0].id).toBe('http://iiif.io/api/presentation/2.0/example/fixtures/resources/page1-full.png'); + expect(getVisibleCanvasNonTiledResources(state, { windowId: 'a' })[0].id).toBe( + 'http://iiif.io/api/presentation/2.0/example/fixtures/resources/page1-full.png', + ); }); it('works for v3 Presentation API', () => { const state = { @@ -377,7 +392,9 @@ describe('getVisibleCanvasNonTiledResources', () => { }, }, }; - expect(getVisibleCanvasNonTiledResources(state, { windowId: 'a' })[0].id).toBe('http://iiif.io/api/presentation/2.1/example/fixtures/resources/page1-full.png'); + expect(getVisibleCanvasNonTiledResources(state, { windowId: 'a' })[0].id).toBe( + 'http://iiif.io/api/presentation/2.1/example/fixtures/resources/page1-full.png', + ); }); describe('getVisibleCanvasVideoResources', () => { @@ -392,13 +409,13 @@ describe('getVisibleCanvasNonTiledResources', () => { windows: { a: { manifestId: 'https://iiif.io/api/cookbook/recipe/0015-start/manifest.json', - visibleCanvases: [ - 'https://iiif.io/api/cookbook/recipe/0015-start/canvas/segment1', - ], + 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'); + expect(getVisibleCanvasVideoResources(state, { windowId: 'a' })[0].id).toBe( + 'https://fixtures.iiif.io/video/indiana/30-minute-clock/medium/30-minute-clock.mp4', + ); }); }); @@ -414,32 +431,36 @@ describe('getVisibleCanvasNonTiledResources', () => { windows: { a: { manifestId: 'https://iiif.io/api/cookbook/recipe/0015-start/manifest.json', - visibleCanvases: [ - 'https://iiif.io/api/cookbook/recipe/0015-start/canvas/segment1', - ], + visibleCanvases: ['https://iiif.io/api/cookbook/recipe/0015-start/canvas/segment1'], }, }, }; - expect(getVisibleCanvasCaptions(state, { windowId: 'a' })[0].id).toBe('https://example.com/file.vtt'); + expect(getVisibleCanvasCaptions(state, { windowId: 'a' })[0].id).toBe( + 'https://example.com/file.vtt', + ); }); it('returns v3 canvases resources', () => { const state = { manifests: { - 'https://preview.iiif.io/cookbook/0219-using-caption-file/recipe/0219-using-caption-file/manifest.json': { - id: 'https://preview.iiif.io/cookbook/0219-using-caption-file/recipe/0219-using-caption-file/manifest.json', - json: videoWithAnnoCaptions, - }, + 'https://preview.iiif.io/cookbook/0219-using-caption-file/recipe/0219-using-caption-file/manifest.json': + { + id: 'https://preview.iiif.io/cookbook/0219-using-caption-file/recipe/0219-using-caption-file/manifest.json', + json: videoWithAnnoCaptions, + }, }, windows: { b: { - manifestId: 'https://preview.iiif.io/cookbook/0219-using-caption-file/recipe/0219-using-caption-file/manifest.json', + manifestId: + 'https://preview.iiif.io/cookbook/0219-using-caption-file/recipe/0219-using-caption-file/manifest.json', visibleCanvases: [ 'https://preview.iiif.io/cookbook/0219-using-caption-file/recipe/0219-using-caption-file/canvas', ], }, }, }; - expect(getVisibleCanvasCaptions(state, { windowId: 'b' })[0].id).toBe('https://fixtures.iiif.io/video/indiana/lunchroom_manners/lunchroom_manners.vtt'); + expect(getVisibleCanvasCaptions(state, { windowId: 'b' })[0].id).toBe( + 'https://fixtures.iiif.io/video/indiana/lunchroom_manners/lunchroom_manners.vtt', + ); }); }); @@ -455,13 +476,13 @@ describe('getVisibleCanvasNonTiledResources', () => { 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', - ], + 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'); + expect(getVisibleCanvasAudioResources(state, { windowId: 'a' })[0].id).toBe( + 'https://fixtures.iiif.io/audio/indiana/mahler-symphony-3/CD1/medium/128Kbps.mp4', + ); }); }); @@ -477,13 +498,13 @@ describe('getVisibleCanvasNonTiledResources', () => { windows: { a: { manifestId: 'https://iiif.io/api/cookbook/recipe/0001-text-pdf/manifest.json', - visibleCanvases: [ - 'https://iiif.io/api/cookbook/recipe/0001-text-pdf/canvas', - ], + visibleCanvases: ['https://iiif.io/api/cookbook/recipe/0001-text-pdf/canvas'], }, }, }; - expect(getVisibleCanvasTextResources(state, { windowId: 'a' })[0].id).toBe('https://fixtures.iiif.io/other/UCLA/kabuki_ezukushi_rtl.pdf'); + expect(getVisibleCanvasTextResources(state, { windowId: 'a' })[0].id).toBe( + 'https://fixtures.iiif.io/other/UCLA/kabuki_ezukushi_rtl.pdf', + ); }); }); }); diff --git a/__tests__/src/selectors/companionWindows.test.js b/__tests__/src/selectors/companionWindows.test.js index d02ff913c..76821201c 100644 --- a/__tests__/src/selectors/companionWindows.test.js +++ b/__tests__/src/selectors/companionWindows.test.js @@ -191,8 +191,6 @@ describe('getCompanionWindowsForContent', () => { const props = { content: 'search', windowId: 'a' }; - expect(getCompanionWindowsForContent(state, props).map(cw => cw.id)).toEqual([ - 'abc', 'def', - ]); + expect(getCompanionWindowsForContent(state, props).map((cw) => cw.id)).toEqual(['abc', 'def']); }); }); diff --git a/__tests__/src/selectors/config.test.js b/__tests__/src/selectors/config.test.js index 4ad2db26c..2c33f6573 100644 --- a/__tests__/src/selectors/config.test.js +++ b/__tests__/src/selectors/config.test.js @@ -27,9 +27,12 @@ describe('getExportableState', () => { it('filters out parts of stems', () => { const f = { - a: 1, b: 2, c: 3, d: 4, + a: 1, + b: 2, + c: 3, + d: 4, }; - const state = { config: { export: { f: { filter: ([k, v]) => (v % 2) === 0 } } }, f }; + const state = { config: { export: { f: { filter: ([k, v]) => v % 2 === 0 } } }, f }; expect(getExportableState(state)).toEqual({ f: { b: 2, d: 4 } }); }); }); @@ -130,7 +133,7 @@ describe('getThemeDirection', () => { expect(getThemeDirection(state)).toBe('rtl'); }); it('returns ltr as default', () => { - const state = { config: { theme: { } } }; + const state = { config: { theme: {} } }; expect(getThemeDirection(state)).toBe('ltr'); }); }); diff --git a/__tests__/src/selectors/index.test.js b/__tests__/src/selectors/index.test.js index 8ea4545e6..4ab86a921 100644 --- a/__tests__/src/selectors/index.test.js +++ b/__tests__/src/selectors/index.test.js @@ -6,10 +6,7 @@ import { describe('getAnnotationResourcesByMotivation', () => { it('returns an array of annotation resources (filtered by the passed in array of motiviations)', () => { - const expected = [ - ['oa:commenting'], - ['sc:something-else', 'oa:commenting'], - ]; + const expected = [['oa:commenting'], ['sc:something-else', 'oa:commenting']]; const state = { annotations: { @@ -30,8 +27,7 @@ describe('getAnnotationResourcesByMotivation', () => { mid: { json: { '@context': 'http://iiif.io/api/presentation/2/context.json', - '@id': - 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', + '@id': 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', '@type': 'sc:Manifest', sequences: [ { @@ -54,7 +50,10 @@ describe('getAnnotationResourcesByMotivation', () => { }; expect( - getAnnotationResourcesByMotivation(state, { motivations: ['something', 'oa:commenting'], windowId: 'abc123' }).map(r => r.motivations), + getAnnotationResourcesByMotivation(state, { + motivations: ['something', 'oa:commenting'], + windowId: 'abc123', + }).map((r) => r.motivations), ).toEqual(expected); }); }); @@ -94,8 +93,7 @@ it('getSelectedAnnotationId returns an array of selected annotation IDs from sta mid: { json: { '@context': 'http://iiif.io/api/presentation/2/context.json', - '@id': - 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', + '@id': 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', '@type': 'sc:Manifest', sequences: [ { @@ -118,7 +116,5 @@ it('getSelectedAnnotationId returns an array of selected annotation IDs from sta }, }; - expect(getSelectedAnnotationId(state, { windowId: 'wid' })).toEqual( - 'aid1', - ); + expect(getSelectedAnnotationId(state, { windowId: 'wid' })).toEqual('aid1'); }); diff --git a/__tests__/src/selectors/layers.test.js b/__tests__/src/selectors/layers.test.js index 12b5cf8a4..eb0107e2b 100644 --- a/__tests__/src/selectors/layers.test.js +++ b/__tests__/src/selectors/layers.test.js @@ -18,9 +18,14 @@ describe('getCanvasLayers', () => { }; it('returns the image resources for a canvas', () => { - const actual = getCanvasLayers(state, { canvasId: 'https://prtd.app/hamilton/canvas/p1.json', manifestId: 'x' }); + const actual = getCanvasLayers(state, { + canvasId: 'https://prtd.app/hamilton/canvas/p1.json', + manifestId: 'x', + }); expect(actual.length).toEqual(23); - expect(actual[0].id).toEqual('https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PSC/full/862,1024/0/default.jpg'); + expect(actual[0].id).toEqual( + 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PSC/full/862,1024/0/default.jpg', + ); }); }); @@ -46,8 +51,7 @@ describe('getSortedLayers', () => { beforeEach(() => { state = { - layers: { - }, + layers: {}, manifests: { hamilton: { id: 'hamilton', @@ -63,25 +67,38 @@ describe('getSortedLayers', () => { }); it('returns the image resources in the manifest order when there is no configuration', () => { - const actual = getSortedLayers(state, { canvasId: 'https://prtd.app/hamilton/canvas/p1.json', windowId: 'x' }); - const imageIds = actual.map(i => i.id); - expect(imageIds[0]).toEqual('https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PSC/full/862,1024/0/default.jpg'); - expect(imageIds[22]).toEqual('https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PCA_RGB-1-3-5_gradi/full/739,521/0/default.jpg'); + const actual = getSortedLayers(state, { + canvasId: 'https://prtd.app/hamilton/canvas/p1.json', + windowId: 'x', + }); + const imageIds = actual.map((i) => i.id); + expect(imageIds[0]).toEqual( + 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PSC/full/862,1024/0/default.jpg', + ); + expect(imageIds[22]).toEqual( + 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PCA_RGB-1-3-5_gradi/full/739,521/0/default.jpg', + ); }); it('uses the layers configuration to sort the image resources', () => { state.layers = { x: { 'https://prtd.app/hamilton/canvas/p1.json': { - 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PCA_RGB-1-3-5_gradi/full/739,521/0/default.jpg': { - index: 0, - }, + 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PCA_RGB-1-3-5_gradi/full/739,521/0/default.jpg': + { + index: 0, + }, }, }, }; - const actual = getSortedLayers(state, { canvasId: 'https://prtd.app/hamilton/canvas/p1.json', windowId: 'x' }); - const imageIds = actual.map(i => i.id); - expect(imageIds[0]).toEqual('https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PCA_RGB-1-3-5_gradi/full/739,521/0/default.jpg'); + const actual = getSortedLayers(state, { + canvasId: 'https://prtd.app/hamilton/canvas/p1.json', + windowId: 'x', + }); + const imageIds = actual.map((i) => i.id); + expect(imageIds[0]).toEqual( + 'https://prtd.app/image/iiif/2/hamilton%2fHL_524_1r_00_PCA_RGB-1-3-5_gradi/full/739,521/0/default.jpg', + ); }); }); diff --git a/__tests__/src/selectors/manifests.test.js b/__tests__/src/selectors/manifests.test.js index bf14e2d0a..c453109f2 100644 --- a/__tests__/src/selectors/manifests.test.js +++ b/__tests__/src/selectors/manifests.test.js @@ -60,13 +60,18 @@ describe('getManifestoInstance', () => { it('creates a manifesto instance', () => { const state = { manifests: { x: { json: manifestFixture019 } } }; const received = getManifestoInstance(state, { manifestId: 'x' }); - expect(received.id).toEqual('http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json'); + expect(received.id).toEqual( + 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', + ); }); }); describe('getManifestLogo()', () => { it('should return manifest logo id', () => { - const received = getManifestLogo({ manifests: { x: { json: manifestFixture001 } } }, { manifestId: 'x' }); + const received = getManifestLogo( + { manifests: { x: { json: manifestFixture001 } } }, + { manifestId: 'x' }, + ); expect(received).toEqual(manifestFixture001.logo['@id']); }); @@ -80,14 +85,15 @@ describe('getManifestThumbnail()', () => { it('should return manifest-level thumbnail', () => { const state = { manifests: { x: { json: manifestFixture001 } } }; const received = getManifestThumbnail(state, { manifestId: 'x' }); - expect(received).toEqual('https://iiif.bodleian.ox.ac.uk/iiif/image/9cca8fdd-4a61-4429-8ac1-f648764b4d6d/full/,120/0/default.jpg'); + expect(received).toEqual( + 'https://iiif.bodleian.ox.ac.uk/iiif/image/9cca8fdd-4a61-4429-8ac1-f648764b4d6d/full/,120/0/default.jpg', + ); }); it('returns the first canvas thumbnail id', () => { const manifest = { '@context': 'http://iiif.io/api/presentation/2/context.json', - '@id': - 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', + '@id': 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', '@type': 'sc:Manifest', sequences: [ { @@ -108,7 +114,9 @@ describe('getManifestThumbnail()', () => { it('returns a thumbnail sized image url from the first canvas', () => { const state = { manifests: { x: { json: manifestFixture019 } } }; const received = getManifestThumbnail(state, { manifestId: 'x' }); - expect(received).toEqual('https://stacks.stanford.edu/image/iiif/hg676jb4964%2F0380_796-44/full/!120,120/0/default.jpg'); + expect(received).toEqual( + 'https://stacks.stanford.edu/image/iiif/hg676jb4964%2F0380_796-44/full/!120,120/0/default.jpg', + ); }); it('should return null if manifest has no thumbnail', () => { @@ -322,10 +330,12 @@ describe('getDestructuredMetadata', () => { it('should return the first value of label/value attributes for each object in the array ', () => { const iiifResource = Utils.parseManifest(manifestFixture002); const received = getDestructuredMetadata(iiifResource); - const expected = [{ - label: 'date', - values: ['some date'], - }]; + const expected = [ + { + label: 'date', + values: ['some date'], + }, + ]; expect(received).toEqual(expected); }); @@ -342,10 +352,12 @@ describe('getManifestMetadata', () => { it('should return the first value of label/value attributes for each object in the array ', () => { const state = { manifests: { x: { json: manifestFixture002 } } }; const received = getManifestMetadata(state, { manifestId: 'x' }); - const expected = [{ - label: 'date', - values: ['some date'], - }]; + const expected = [ + { + label: 'date', + values: ['some date'], + }, + ]; expect(received).toEqual(expected); }); @@ -370,8 +382,7 @@ describe('getMetadataLocales', () => { it('gets the locales preseent in the IIIF v2 manifest metadata', () => { const manifest = { '@context': 'http://iiif.io/api/presentation/2/context.json', - '@id': - 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', + '@id': 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', '@type': 'sc:Manifest', metadata: [ { @@ -384,8 +395,16 @@ describe('getMetadataLocales', () => { { label: 'Digitization Project', value: [ - { '@language': 'en-value', '@value': 'Manuscripts from German-Speaking Lands - A Polonsky Foundation Digitization Project - A collaboration between the Bodleian Libraries and the Herzog August Bibliothek.' }, - { '@language': 'de-value', '@value': 'Handschriften aus dem deutschen Sprachraum. Ein Digitalisierungsprojekt der Polonsky Stiftung. Eine Zusammenarbeit zwischen der Universit\u00e4t Oxford und der Herzog August Bibliothek Wolfenb\u00fcttel' }, + { + '@language': 'en-value', + '@value': + 'Manuscripts from German-Speaking Lands - A Polonsky Foundation Digitization Project - A collaboration between the Bodleian Libraries and the Herzog August Bibliothek.', + }, + { + '@language': 'de-value', + '@value': + 'Handschriften aus dem deutschen Sprachraum. Ein Digitalisierungsprojekt der Polonsky Stiftung. Eine Zusammenarbeit zwischen der Universit\u00e4t Oxford und der Herzog August Bibliothek Wolfenb\u00fcttel', + }, ], }, { @@ -405,45 +424,27 @@ describe('getMetadataLocales', () => { '@context': 'http://iiif.io/api/presentation/3/context.json', id: 'https://iiif.io/api/cookbook/recipe/0006-text-language/manifest.json', label: { - en: [ - "Whistler's Mother", - ], - fr: [ - 'La Mère de Whistler', - ], + en: ["Whistler's Mother"], + fr: ['La Mère de Whistler'], }, metadata: [ { label: { - en: [ - 'Creator', - ], - fr: [ - 'Auteur', - ], + en: ['Creator'], + fr: ['Auteur'], }, value: { - none: [ - 'Whistler, James Abbott McNeill', - ], + none: ['Whistler, James Abbott McNeill'], }, }, { label: { - en: [ - 'Subject', - ], - fr: [ - 'Sujet', - ], + en: ['Subject'], + fr: ['Sujet'], }, value: { - en: [ - 'McNeill Anna Matilda, mother of Whistler (1804-1881)', - ], - fr: [ - 'McNeill Anna Matilda, mère de Whistler (1804-1881)', - ], + en: ['McNeill Anna Matilda, mother of Whistler (1804-1881)'], + fr: ['McNeill Anna Matilda, mère de Whistler (1804-1881)'], }, }, ], @@ -459,7 +460,9 @@ describe('getRequiredStatement', () => { it('gets the attribution data for a IIIF v2 manifest', () => { const state = { manifests: { x: { json: manifestFixture001 } } }; const received = getRequiredStatement(state, { manifestId: 'x' }); - expect(received).toEqual([{ label: null, values: ['http://creativecommons.org/licenses/by-nc-sa/3.0/.'] }]); + expect(received).toEqual([ + { label: null, values: ['http://creativecommons.org/licenses/by-nc-sa/3.0/.'] }, + ]); }); it('suppresses empty attribution data', () => { @@ -479,8 +482,7 @@ describe('getRights', () => { it('gets the license data for a IIIF v2 manifest', () => { const manifest = { '@context': 'http://iiif.io/api/presentation/2/context.json', - '@id': - 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', + '@id': 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', '@type': 'sc:Manifest', license: 'http://example.com', }; @@ -491,8 +493,7 @@ describe('getRights', () => { it('gets the rights data for a IIIF v3 manifest', () => { const manifest = { '@context': 'http://iiif.io/api/presentation/2/context.json', - '@id': - 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', + '@id': 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', '@type': 'sc:Manifest', license: 'http://example.com', }; @@ -505,14 +506,18 @@ describe('getRights', () => { describe('getManifestSearchService', () => { it('gets from the manifest', () => { const state = { manifests: { x: { json: manifestFixtureFg165hz3589 } } }; - expect(getManifestSearchService(state, { manifestId: 'x' }).id).toEqual('https://contentsearch.stanford.edu/fg165hz3589/search'); + expect(getManifestSearchService(state, { manifestId: 'x' }).id).toEqual( + 'https://contentsearch.stanford.edu/fg165hz3589/search', + ); }); it('supports v1 of the search spec', () => { const v1 = structuredClone(manifestFixtureFg165hz3589); v1.service[0].profile = 'http://iiif.io/api/search/1/search'; const state = { manifests: { x: { json: v1 } } }; - expect(getManifestSearchService(state, { manifestId: 'x' }).id).toEqual('https://contentsearch.stanford.edu/fg165hz3589/search'); + expect(getManifestSearchService(state, { manifestId: 'x' }).id).toEqual( + 'https://contentsearch.stanford.edu/fg165hz3589/search', + ); }); it('is null if no search service is specified', () => { @@ -524,7 +529,9 @@ describe('getManifestSearchService', () => { describe('getManifestAutocompleteService', () => { it('gets from the manifest', () => { const state = { manifests: { x: { json: manifestFixtureFg165hz3589 } } }; - expect(getManifestAutocompleteService(state, { manifestId: 'x' }).id).toEqual('https://contentsearch.stanford.edu/fg165hz3589/autocomplete'); + expect(getManifestAutocompleteService(state, { manifestId: 'x' }).id).toEqual( + 'https://contentsearch.stanford.edu/fg165hz3589/autocomplete', + ); }); it('supports v1 of the search spec', () => { @@ -532,7 +539,9 @@ describe('getManifestAutocompleteService', () => { v1.service[0].profile = 'http://iiif.io/api/search/1/search'; v1.service[0].service.profile = 'http://iiif.io/api/search/1/autocomplete'; const state = { manifests: { x: { json: v1 } } }; - expect(getManifestAutocompleteService(state, { manifestId: 'x' }).id).toEqual('https://contentsearch.stanford.edu/fg165hz3589/autocomplete'); + expect(getManifestAutocompleteService(state, { manifestId: 'x' }).id).toEqual( + 'https://contentsearch.stanford.edu/fg165hz3589/autocomplete', + ); }); it('is null if no search service is specified', () => { diff --git a/__tests__/src/selectors/ranges.test.js b/__tests__/src/selectors/ranges.test.js index 8aed328a9..781099cfc 100644 --- a/__tests__/src/selectors/ranges.test.js +++ b/__tests__/src/selectors/ranges.test.js @@ -32,20 +32,24 @@ const state = { }, }; -const expandedNodesState = set(['companionWindows', 'cw123', 'tocNodes'], { - '0-0': { - expanded: false, - }, - '0-1': { - expanded: true, - }, - '0-1-1': { - expanded: true, - }, - '0-1-2': { - expanded: false, +const expandedNodesState = set( + ['companionWindows', 'cw123', 'tocNodes'], + { + '0-0': { + expanded: false, + }, + '0-1': { + expanded: true, + }, + '0-1-1': { + expanded: true, + }, + '0-1-2': { + expanded: false, + }, }, -}, state); + state, +); describe('getVisibleNodeIds', () => { const prezi3BookState = set(['manifests', 'mID', 'json'], presentation3Json, state); @@ -53,140 +57,199 @@ describe('getVisibleNodeIds', () => { it('contains node ids for all ranges which contain currently visible canvases, and for their parents', () => { const visibleNodeIds = getVisibleNodeIds(state, { windowId: 'w1' }); - expect(visibleNodeIds).toEqual(expect.arrayContaining([ - '0-1', - '0-1-1', - '0-1-1-0', - '0-1-1-1', - ])); + expect(visibleNodeIds).toEqual(expect.arrayContaining(['0-1', '0-1-1', '0-1-1-0', '0-1-1-1'])); expect(visibleNodeIds.length).toBe(4); - const prezi3StateForCanvas2 = set(['windows', 'w1', 'visibleCanvases'], ['http://foo.test/1/canvas/c2'], prezi3State); + const prezi3StateForCanvas2 = set( + ['windows', 'w1', 'visibleCanvases'], + ['http://foo.test/1/canvas/c2'], + prezi3State, + ); const prezi3visibleNodeIds = getVisibleNodeIds(prezi3StateForCanvas2, { windowId: 'w1' }); - expect(prezi3visibleNodeIds).toEqual(expect.arrayContaining([ - '0-0', - '0-0-0', - ])); + expect(prezi3visibleNodeIds).toEqual(expect.arrayContaining(['0-0', '0-0-0'])); expect(prezi3visibleNodeIds.length).toBe(2); }); it('contains node ids for ranges with currently visible canvas fragments', () => { - const prezi2XYWHFragmentBookState = set(['windows', 'w1', 'visibleCanvases'], ['http://foo.test/1/canvas/c3'], state); - const prezi2XYWHFragmentState = set(['windows', 'w1', 'view'], 'single', prezi2XYWHFragmentBookState); + const prezi2XYWHFragmentBookState = set( + ['windows', 'w1', 'visibleCanvases'], + ['http://foo.test/1/canvas/c3'], + state, + ); + const prezi2XYWHFragmentState = set( + ['windows', 'w1', 'view'], + 'single', + prezi2XYWHFragmentBookState, + ); const visibleNodeIdsForPrezi2 = getVisibleNodeIds(prezi2XYWHFragmentState, { windowId: 'w1' }); - expect(visibleNodeIdsForPrezi2).toEqual(expect.arrayContaining([ - '0-0', - '0-0-1', - ])); + expect(visibleNodeIdsForPrezi2).toEqual(expect.arrayContaining(['0-0', '0-0-1'])); expect(visibleNodeIdsForPrezi2.length).toBe(2); - const prezi3XYWHFragmentState = set(['windows', 'w1', 'visibleCanvases'], ['http://foo.test/1/canvas/c3'], prezi3State); - const visibleNodeIdsForXYWHFragment = getVisibleNodeIds(prezi3XYWHFragmentState, { windowId: 'w1' }); - expect(visibleNodeIdsForXYWHFragment).toEqual(expect.arrayContaining([ - '0-0', - '0-0-0', - ])); + const prezi3XYWHFragmentState = set( + ['windows', 'w1', 'visibleCanvases'], + ['http://foo.test/1/canvas/c3'], + prezi3State, + ); + const visibleNodeIdsForXYWHFragment = getVisibleNodeIds(prezi3XYWHFragmentState, { + windowId: 'w1', + }); + expect(visibleNodeIdsForXYWHFragment).toEqual(expect.arrayContaining(['0-0', '0-0-0'])); expect(visibleNodeIdsForXYWHFragment.length).toBe(2); - const prezi3TemporalFragmentState = set(['windows', 'w1', 'visibleCanvases'], ['http://foo.test/1/canvas/c4'], prezi3State); - const visibleNodeIdsForTemporalFragment = getVisibleNodeIds(prezi3TemporalFragmentState, { windowId: 'w1' }); - expect(visibleNodeIdsForTemporalFragment).toEqual(expect.arrayContaining([ - '0-0', - '0-0-0', - ])); + const prezi3TemporalFragmentState = set( + ['windows', 'w1', 'visibleCanvases'], + ['http://foo.test/1/canvas/c4'], + prezi3State, + ); + const visibleNodeIdsForTemporalFragment = getVisibleNodeIds(prezi3TemporalFragmentState, { + windowId: 'w1', + }); + expect(visibleNodeIdsForTemporalFragment).toEqual(expect.arrayContaining(['0-0', '0-0-0'])); expect(visibleNodeIdsForTemporalFragment.length).toBe(2); }); // This test fails as there is no support for SpecificResource in manifesto yet it.skip('contains node ids for ranges that contain a SpecificResource based on a current canvas', () => { - const specificResourceState = set(['windows', 'w1', 'visibleCanvases'], ['http://foo.test/1/canvas/c5'], prezi3State); + const specificResourceState = set( + ['windows', 'w1', 'visibleCanvases'], + ['http://foo.test/1/canvas/c5'], + prezi3State, + ); const visibleNodeIds = getVisibleNodeIds(specificResourceState, { windowId: 'w1' }); - expect(visibleNodeIds).toEqual(expect.arrayContaining([ - '0-0', - '0-0-0', - ])); + expect(visibleNodeIds).toEqual(expect.arrayContaining(['0-0', '0-0-0'])); expect(visibleNodeIds.length).toBe(2); }); }); describe('getManuallyExpandedNodeIds', () => { it('returns empty array if there are no manually opened or closed nodes', () => { - expect(getManuallyExpandedNodeIds(state, { companionWindowId: 'cw123', windowId: 'w1' }, true)).toEqual([]); - expect(getManuallyExpandedNodeIds(state, { companionWindowId: 'cw123', windowId: 'w1' }, false)).toEqual([]); + expect( + getManuallyExpandedNodeIds(state, { companionWindowId: 'cw123', windowId: 'w1' }, true), + ).toEqual([]); + expect( + getManuallyExpandedNodeIds(state, { companionWindowId: 'cw123', windowId: 'w1' }, false), + ).toEqual([]); }); it('returns manually opened and closed node ids correctly', () => { - expect(getManuallyExpandedNodeIds(expandedNodesState, { companionWindowId: 'cw123' }, true)).toEqual(['0-1', '0-1-1']); - expect(getManuallyExpandedNodeIds(expandedNodesState, { companionWindowId: 'cw123' }, false)).toEqual(['0-0', '0-1-2']); + expect( + getManuallyExpandedNodeIds(expandedNodesState, { companionWindowId: 'cw123' }, true), + ).toEqual(['0-1', '0-1-1']); + expect( + getManuallyExpandedNodeIds(expandedNodesState, { companionWindowId: 'cw123' }, false), + ).toEqual(['0-0', '0-1-2']); }); }); describe('getExpandedNodeIds', () => { it('returns manually expanded node ids and visible, non collapsed branch node ids', () => { - const canvas8BookViewState = set(['windows', 'w1', 'visibleCanvases'], ['http://foo.test/1/canvas/c8', 'http://foo.test/1/canvas/c9'], expandedNodesState); - const canvas8BookViewVisibleNodeIds = getExpandedNodeIds(canvas8BookViewState, { companionWindowId: 'cw123', windowId: 'w1' }); - expect(canvas8BookViewVisibleNodeIds).toEqual(expect.arrayContaining([ - '0-1', - '0-1-1', - '0-2', - '0-2-1', - '0-2-2', - ])); + const canvas8BookViewState = set( + ['windows', 'w1', 'visibleCanvases'], + ['http://foo.test/1/canvas/c8', 'http://foo.test/1/canvas/c9'], + expandedNodesState, + ); + const canvas8BookViewVisibleNodeIds = getExpandedNodeIds(canvas8BookViewState, { + companionWindowId: 'cw123', + windowId: 'w1', + }); + expect(canvas8BookViewVisibleNodeIds).toEqual( + expect.arrayContaining(['0-1', '0-1-1', '0-2', '0-2-1', '0-2-2']), + ); expect(canvas8BookViewVisibleNodeIds.length).toBe(5); - const canvas8SingleViewState = set(['windows', 'w1', 'visibleCanvases'], ['http://foo.test/1/canvas/c8'], canvas8BookViewState); - const canvas8SingleViewVisibleNodeIds = getExpandedNodeIds(canvas8SingleViewState, { companionWindowId: 'cw123', windowId: 'w1' }); - expect(canvas8SingleViewVisibleNodeIds).toEqual(expect.arrayContaining([ - '0-1', - '0-1-1', - ])); + const canvas8SingleViewState = set( + ['windows', 'w1', 'visibleCanvases'], + ['http://foo.test/1/canvas/c8'], + canvas8BookViewState, + ); + const canvas8SingleViewVisibleNodeIds = getExpandedNodeIds(canvas8SingleViewState, { + companionWindowId: 'cw123', + windowId: 'w1', + }); + expect(canvas8SingleViewVisibleNodeIds).toEqual(expect.arrayContaining(['0-1', '0-1-1'])); expect(canvas8SingleViewVisibleNodeIds.length).toBe(2); }); it('returns a combination of manually opened and current canvas containing node ids', () => { - const canvas9State = set(['windows', 'w1', 'visibleCanvases'], ['http://foo.test/1/canvas/c9'], expandedNodesState); - const expandedNodeIds = getExpandedNodeIds(canvas9State, { companionWindowId: 'cw123', windowId: 'w1' }); - expect(expandedNodeIds).toEqual(expect.arrayContaining([ - '0-1', - '0-1-1', - '0-2', - '0-2-1', - '0-2-2', - ])); + const canvas9State = set( + ['windows', 'w1', 'visibleCanvases'], + ['http://foo.test/1/canvas/c9'], + expandedNodesState, + ); + const expandedNodeIds = getExpandedNodeIds(canvas9State, { + companionWindowId: 'cw123', + windowId: 'w1', + }); + expect(expandedNodeIds).toEqual( + expect.arrayContaining(['0-1', '0-1-1', '0-2', '0-2-1', '0-2-2']), + ); expect(expandedNodeIds.length).toBe(5); }); it('does not contain ids of nodes whos descendants do not contain currently visible canvases', () => { - const canvas13State = set(['windows', 'w1', 'visibleCanvases'], ['http://foo.test/1/canvas/c13'], state); - const expandedNodeIds = getExpandedNodeIds(canvas13State, { companionWindowId: 'cw123', windowId: 'w1' }); + const canvas13State = set( + ['windows', 'w1', 'visibleCanvases'], + ['http://foo.test/1/canvas/c13'], + state, + ); + const expandedNodeIds = getExpandedNodeIds(canvas13State, { + companionWindowId: 'cw123', + windowId: 'w1', + }); expect(expandedNodeIds.length).toBe(0); }); }); describe('getNodeIdToScrollTo', () => { it('returns first leaf node with visible canvas', () => { - expect(getNodeIdToScrollTo(state, { companionWindowId: 'cw123', windowId: 'w1' })).toBe('0-1-1-0'); + expect(getNodeIdToScrollTo(state, { companionWindowId: 'cw123', windowId: 'w1' })).toBe( + '0-1-1-0', + ); }); it('returns branch node with visible canvas if it is the deepest in the tree to contain a canvas', () => { - const canvas10State = set(['windows', 'w1', 'visibleCanvases'], ['http://foo.test/1/canvas/c10'], expandedNodesState); - expect(getNodeIdToScrollTo(canvas10State, { companionWindowId: 'cw123', windowId: 'w1' })).toBe('0-2-1'); + const canvas10State = set( + ['windows', 'w1', 'visibleCanvases'], + ['http://foo.test/1/canvas/c10'], + expandedNodesState, + ); + expect(getNodeIdToScrollTo(canvas10State, { companionWindowId: 'cw123', windowId: 'w1' })).toBe( + '0-2-1', + ); }); it('returns the deepest non hidden branch node if leaf node or its parent node are collapsed', () => { - const closedParentState1 = set(['companionWindows', 'cw123', 'tocNodes'], { '0-1-1': { expanded: false } }, state); - expect(getNodeIdToScrollTo(closedParentState1, { companionWindowId: 'cw123', windowId: 'w1' })).toBe('0-1-1'); - const closedParentState2 = set(['companionWindows', 'cw123', 'tocNodes'], { - '0-1': { expanded: false }, - '0-1-1': { expanded: false }, - }, state); - expect(getNodeIdToScrollTo(closedParentState2, { companionWindowId: 'cw123', windowId: 'w1' })).toBe('0-1'); + const closedParentState1 = set( + ['companionWindows', 'cw123', 'tocNodes'], + { '0-1-1': { expanded: false } }, + state, + ); + expect( + getNodeIdToScrollTo(closedParentState1, { companionWindowId: 'cw123', windowId: 'w1' }), + ).toBe('0-1-1'); + const closedParentState2 = set( + ['companionWindows', 'cw123', 'tocNodes'], + { + '0-1': { expanded: false }, + '0-1-1': { expanded: false }, + }, + state, + ); + expect( + getNodeIdToScrollTo(closedParentState2, { companionWindowId: 'cw123', windowId: 'w1' }), + ).toBe('0-1'); }); it('returns no node id if current canvas is not contained in any range', () => { const singleViewState = set(['windows', 'w1', 'view'], 'single', expandedNodesState); - const rangeFreeCanvasState = set(['windows', 'w1', 'visibleCanvases'], ['http://foo.test/1/canvas/c12'], singleViewState); - expect(getNodeIdToScrollTo(rangeFreeCanvasState, { companionWindowId: 'cw123', windowId: 'w1' })).toBe(null); + const rangeFreeCanvasState = set( + ['windows', 'w1', 'visibleCanvases'], + ['http://foo.test/1/canvas/c12'], + singleViewState, + ); + expect( + getNodeIdToScrollTo(rangeFreeCanvasState, { companionWindowId: 'cw123', windowId: 'w1' }), + ).toBe(null); }); }); diff --git a/__tests__/src/selectors/searches.test.js b/__tests__/src/selectors/searches.test.js index a34086090..70029076c 100644 --- a/__tests__/src/selectors/searches.test.js +++ b/__tests__/src/selectors/searches.test.js @@ -32,12 +32,8 @@ describe('getSearchQuery', () => { }, }, }; - expect( - getSearchQuery(state, { companionWindowId, windowId: 'a' }), - ).toEqual('xyz'); - expect( - getSearchQuery(state, { companionWindowId, windowId: 'b' }), - ).toEqual(undefined); + expect(getSearchQuery(state, { companionWindowId, windowId: 'a' })).toEqual('xyz'); + expect(getSearchQuery(state, { companionWindowId, windowId: 'b' })).toEqual(undefined); }); }); @@ -66,12 +62,8 @@ describe('getSearchIsFetching', () => { }, }, }; - expect( - getSearchIsFetching(state, { companionWindowId, windowId: 'a' }), - ).toEqual(true); - expect( - getSearchIsFetching(state, { companionWindowId, windowId: 'b' }), - ).toEqual(false); + expect(getSearchIsFetching(state, { companionWindowId, windowId: 'a' })).toEqual(true); + expect(getSearchIsFetching(state, { companionWindowId, windowId: 'b' })).toEqual(false); }); }); @@ -99,12 +91,8 @@ describe('getNextSearchId', () => { }, }, }; - expect( - getNextSearchId(state, { companionWindowId, windowId: 'a' }), - ).toEqual('search?page=3'); - expect( - getSearchQuery(state, { companionWindowId, windowId: 'b' }), - ).toEqual(undefined); + expect(getNextSearchId(state, { companionWindowId, windowId: 'a' })).toEqual('search?page=3'); + expect(getSearchQuery(state, { companionWindowId, windowId: 'b' })).toEqual(undefined); }); }); @@ -169,9 +157,9 @@ describe('getSortedSearchHitsForCompanionWindow', () => { expect( getSortedSearchHitsForCompanionWindow(state, { companionWindowId, windowId: 'b' }), ).toEqual([]); - expect( - getSortedSearchHitsForCompanionWindow({}, { companionWindowId, windowId: 'a' }), - ).toEqual([]); + expect(getSortedSearchHitsForCompanionWindow({}, { companionWindowId, windowId: 'a' })).toEqual( + [], + ); }); }); @@ -199,7 +187,9 @@ describe('getSortedSearchAnnotationsForCompanionWindow', () => { }; expect( - getSortedSearchAnnotationsForCompanionWindow(state, { companionWindowId, windowId: 'a' }).map(r => r.id), + getSortedSearchAnnotationsForCompanionWindow(state, { companionWindowId, windowId: 'a' }).map( + (r) => r.id, + ), ).toEqual([ 'http://example.com/iiif/canvas1', 'http://example.com/iiif/canvas2', @@ -237,24 +227,15 @@ describe('getSearchAnnotationsForWindow', () => { }, }, }; - expect( - getSearchAnnotationsForWindow(state, { companionWindowId, windowId: 'a' }), - ).toEqual([{ - id: 'yolo', - resources: [ - { resource: { '@id': 'annoId2' } }, - { resource: { '@id': 'annoId3' } }, - ], - }]); - expect( - getSearchAnnotationsForWindow(state, { companionWindowId, windowId: 'b' }), - ).toEqual([]); - expect( - getSearchAnnotationsForWindow({}, { companionWindowId, windowId: 'a' }), - ).toEqual([]); - expect( - getSearchAnnotationsForWindow({}, { windowId: 'a' }), - ).toEqual([]); + expect(getSearchAnnotationsForWindow(state, { companionWindowId, windowId: 'a' })).toEqual([ + { + id: 'yolo', + resources: [{ resource: { '@id': 'annoId2' } }, { resource: { '@id': 'annoId3' } }], + }, + ]); + expect(getSearchAnnotationsForWindow(state, { companionWindowId, windowId: 'b' })).toEqual([]); + expect(getSearchAnnotationsForWindow({}, { companionWindowId, windowId: 'a' })).toEqual([]); + expect(getSearchAnnotationsForWindow({}, { windowId: 'a' })).toEqual([]); }); }); @@ -277,9 +258,7 @@ describe('getSelectedContentSearchAnnotationIds', () => { getSelectedContentSearchAnnotationIds(state, { companionWindowId: 'bar', windowId: 'foo' }), ).toEqual(['baz']); - expect( - getSelectedContentSearchAnnotationIds(state, { windowId: 'baz' }), - ).toEqual([]); + expect(getSelectedContentSearchAnnotationIds(state, { windowId: 'baz' })).toEqual([]); }); }); @@ -305,7 +284,11 @@ describe('getResourceAnnotationForSearchHit', () => { }; expect( - getResourceAnnotationForSearchHit(state, { annotationUri: annoId, companionWindowId, windowId: 'a' }).resource['@id'], + getResourceAnnotationForSearchHit(state, { + annotationUri: annoId, + companionWindowId, + windowId: 'a', + }).resource['@id'], ).toEqual(annoId); }); }); @@ -325,10 +308,12 @@ describe('getResourceAnnotationLabel', () => { 'search?page=1': { json: { '@id': 'yolo', - resources: [{ - '@id': annoId, - label: { '@language': 'en', '@value': 'The Annotation Label' }, - }], + resources: [ + { + '@id': annoId, + label: { '@language': 'en', '@value': 'The Annotation Label' }, + }, + ], }, }, }, @@ -338,7 +323,11 @@ describe('getResourceAnnotationLabel', () => { }; expect( - getResourceAnnotationLabel(state, { annotationUri: annoId, companionWindowId, windowId: 'a' }), + getResourceAnnotationLabel(state, { + annotationUri: annoId, + companionWindowId, + windowId: 'a', + }), ).toEqual(['The Annotation Label']); }); @@ -361,7 +350,11 @@ describe('getResourceAnnotationLabel', () => { }; expect( - getResourceAnnotationLabel(state, { annotationUri: annoId, companionWindowId, windowId: 'a' }), + getResourceAnnotationLabel(state, { + annotationUri: annoId, + companionWindowId, + windowId: 'a', + }), ).toEqual([]); }); }); diff --git a/__tests__/src/selectors/sequences.test.js b/__tests__/src/selectors/sequences.test.js index ee3f5aae0..9d295eb76 100644 --- a/__tests__/src/selectors/sequences.test.js +++ b/__tests__/src/selectors/sequences.test.js @@ -19,7 +19,7 @@ describe('getSequences', () => { const state = { manifests: { x: { json: manifestFixtureGau } } }; const sequences = getSequences(state, { manifestId: 'x' }); expect(sequences.length).toEqual(2); - expect(sequences.map(s => s.id)).toEqual([ + expect(sequences.map((s) => s.id)).toEqual([ 'https://www.e-codices.unifr.ch/metadata/iiif/gau-Fragment/sequence/Sequence-1740.json', 'https://www.e-codices.unifr.ch/metadata/iiif/gau-Fragment/sequence/Sequence-1741.json', ]); @@ -38,7 +38,9 @@ describe('getSequences', () => { const state = { manifests: { x: { json: manifest } } }; const sequences = getSequences(state, { manifestId: 'x' }); expect(sequences.length).toEqual(1); - expect(sequences.map(s => s.id)).toEqual(['https://iiif.bodleian.ox.ac.uk/iiif/sequence/9cca8fdd-4a61-4429-8ac1-f648764b4d6d_default.json']); + expect(sequences.map((s) => s.id)).toEqual([ + 'https://iiif.bodleian.ox.ac.uk/iiif/sequence/9cca8fdd-4a61-4429-8ac1-f648764b4d6d_default.json', + ]); }); }); describe('with a v3 manifest', () => { @@ -54,7 +56,7 @@ describe('getSequences', () => { const state = { manifests: { x: { json: manifest } } }; const sequences = getSequences(state, { manifestId: 'x' }); expect(sequences.length).toEqual(3); - expect(sequences.map(s => s.id)).toEqual([undefined, 'a', 'b']); + expect(sequences.map((s) => s.id)).toEqual([undefined, 'a', 'b']); }); }); }); @@ -70,7 +72,13 @@ describe('getSequence', () => { it('picks the sequence selected by the window', () => { const state = { manifests: { x: { json: manifestFixtureGau } }, - windows: { a: { manifestId: 'x', sequenceId: 'https://www.e-codices.unifr.ch/metadata/iiif/gau-Fragment/sequence/Sequence-1741.json' } }, + windows: { + a: { + manifestId: 'x', + sequenceId: + 'https://www.e-codices.unifr.ch/metadata/iiif/gau-Fragment/sequence/Sequence-1741.json', + }, + }, }; const sequence = getSequence(state, { windowId: 'a' }); expect(sequence.id).toEqual( @@ -79,7 +87,11 @@ describe('getSequence', () => { }); it('picks the sequences with an explicit sequenceId', () => { const state = { manifests: { x: { json: manifestFixtureGau } } }; - const sequence = getSequence(state, { manifestId: 'x', sequenceId: 'https://www.e-codices.unifr.ch/metadata/iiif/gau-Fragment/sequence/Sequence-1741.json' }); + const sequence = getSequence(state, { + manifestId: 'x', + sequenceId: + 'https://www.e-codices.unifr.ch/metadata/iiif/gau-Fragment/sequence/Sequence-1741.json', + }); expect(sequence.id).toEqual( 'https://www.e-codices.unifr.ch/metadata/iiif/gau-Fragment/sequence/Sequence-1741.json', ); @@ -93,7 +105,10 @@ describe('getCanvasIndex', () => { y: { json: { ...manifestFixture015 } }, }, windows: { - a: { canvasId: 'http://iiif.io/api/presentation/2.0/example/fixtures/canvas/15/c2.json', manifestId: 'y' }, + a: { + canvasId: 'http://iiif.io/api/presentation/2.0/example/fixtures/canvas/15/c2.json', + manifestId: 'y', + }, }, }; diff --git a/__tests__/src/selectors/thumbnails.test.js b/__tests__/src/selectors/thumbnails.test.js index 3231f777e..b7b22e1a4 100644 --- a/__tests__/src/selectors/thumbnails.test.js +++ b/__tests__/src/selectors/thumbnails.test.js @@ -1,12 +1,14 @@ import { Utils } from 'manifesto.js'; import settings from '../../../src/config/settings'; import { ThumbnailFactory } from '../../../src/lib/ThumbnailFactory'; -import { - getThumbnailFactory, -} from '../../../src/state/selectors/thumbnails'; +import { getThumbnailFactory } from '../../../src/state/selectors/thumbnails'; /** return the slice of config relevant to MiradorCanvas */ -const miradorConfigSlice = () => ({ auth: settings.auth, canvas: settings.canvas, image: settings.image }); +const miradorConfigSlice = () => ({ + auth: settings.auth, + canvas: settings.canvas, + image: settings.image, +}); describe('getThumbnailFactory', () => { const state = { config: miradorConfigSlice() }; diff --git a/__tests__/src/selectors/viewer.test.js b/__tests__/src/selectors/viewer.test.js index ece25446b..a0427cb56 100644 --- a/__tests__/src/selectors/viewer.test.js +++ b/__tests__/src/selectors/viewer.test.js @@ -1,6 +1,4 @@ -import { - getCurrentCanvasWorld, -} from '../../../src/state/selectors/viewer'; +import { getCurrentCanvasWorld } from '../../../src/state/selectors/viewer'; describe('getCurrentCanvasWorld', () => { it('returns a CanvasWorld', () => { @@ -23,9 +21,7 @@ describe('getCurrentCanvasWorld', () => { windows: { [windowId]: { manifestId: 'a', - visibleCanvases: [ - 'a1', 'a2', - ], + visibleCanvases: ['a1', 'a2'], }, }, }; diff --git a/__tests__/src/selectors/workspace.test.js b/__tests__/src/selectors/workspace.test.js index f4f78c592..59e5de12e 100644 --- a/__tests__/src/selectors/workspace.test.js +++ b/__tests__/src/selectors/workspace.test.js @@ -1,8 +1,4 @@ -import { - getFullScreenEnabled, - getWorkspaceType, - isFocused, -} from '../../../src/state/selectors'; +import { getFullScreenEnabled, getWorkspaceType, isFocused } from '../../../src/state/selectors'; describe('getFullScreenEnabled', () => { it('returns the workspace configuration for full screen', () => { diff --git a/__tests__/utils/safe-queries.js b/__tests__/utils/safe-queries.js index 7dca9b242..dca9bc70c 100644 --- a/__tests__/utils/safe-queries.js +++ b/__tests__/utils/safe-queries.js @@ -29,9 +29,10 @@ export async function failIfErrorDialogPresent({ waitForRole, roleOptions } = {} * Helper to extract the error message from the dialog */ function getErrorDialogMessage() { - const errorDialog = document.querySelector('h2#error-dialog-title'); // eslint-disable-line testing-library/no-node-access + // eslint-disable-next-line testing-library/no-node-access + const errorDialog = document.querySelector('h2#error-dialog-title'); return errorDialog - ? errorDialog.closest('[role="dialog"]')?.querySelector('p')?.textContent ?? 'Unknown error' + ? (errorDialog.closest('[role="dialog"]')?.querySelector('p')?.textContent ?? 'Unknown error') : null; } diff --git a/__tests__/utils/test-utils.js b/__tests__/utils/test-utils.js index dacd6d8a8..604806473 100644 --- a/__tests__/utils/test-utils.js +++ b/__tests__/utils/test-utils.js @@ -38,9 +38,7 @@ function renderWithProviders( return ( - - {children} - + {children} ); @@ -56,7 +54,8 @@ function renderWithProviders( return { store, ...rendered, - rerender: (newUi, options) => render(newUi, { container: rendered.container, wrapper: Wrapper, ...options }), + rerender: (newUi, options) => + render(newUi, { container: rendered.container, wrapper: Wrapper, ...options }), }; } @@ -68,7 +67,11 @@ const setupMiradorViewer = async (config, plugins) => {
{viewer.render()} @@ -83,7 +86,8 @@ const setupMiradorViewer = async (config, plugins) => { export const setupIntegrationTestViewer = (config, plugins) => { beforeEach(async (context) => { const miradorInstance = await setupMiradorViewer(config, plugins); - context.miradorInstance = miradorInstance; // eslint-disable-line no-param-reassign + // eslint-disable-next-line no-param-reassign + context.miradorInstance = miradorInstance; // Wait for the viewer to render expect(await screen.findByTestId('mirador')).toBeInTheDocument(); diff --git a/eslint.config.js b/eslint.config.js index c155a8610..9c2aaaadd 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -66,7 +66,7 @@ export default [ 'consistent-return': 'error', 'default-case': ['error', { commentPattern: '^no default$' }], 'dot-notation': ['error', { allowKeywords: true }], - 'eqeqeq': ['warn', 'smart'], + eqeqeq: ['warn', 'smart'], 'import/extensions': ['error', 'ignorePackages', { js: 'never', jsx: 'never' }], 'import/first': 'error', 'import/newline-after-import': ['error', { count: 1 }], @@ -88,7 +88,7 @@ export default [ 'no-lonely-if': 'error', 'no-nested-ternary': 'warn', 'no-new-func': 'error', - 'no-param-reassign': ['error', { props: true}], + 'no-param-reassign': ['error', { props: true }], 'no-restricted-globals': [ 'error', { name: 'isFinite', message: 'Use Number.isFinite instead' }, @@ -105,10 +105,16 @@ export default [ 'no-useless-return': 'error', 'no-var': 'error', 'prefer-const': 'error', - 'prefer-destructuring': ['warn', { VariableDeclarator: { array: false, object: true }, AssignmentExpression: { array: false, object: false } }], + 'prefer-destructuring': [ + 'warn', + { + VariableDeclarator: { array: false, object: true }, + AssignmentExpression: { array: false, object: false }, + }, + ], 'prefer-rest-params': 'error', 'prefer-template': 'warn', - 'radix': 'error', + radix: 'error', 'react-hooks/exhaustive-deps': 'error', 'react/function-component-definition': 'off', 'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx'] }], @@ -126,7 +132,10 @@ export default [ 'testing-library/no-await-sync-queries': 'error', 'testing-library/no-debugging-utils': 'warn', 'testing-library/no-dom-import': 'off', - 'testing-library/no-render-in-lifecycle': ['error', { allowTestingFrameworkSetupHook: 'beforeEach' }], + 'testing-library/no-render-in-lifecycle': [ + 'error', + { allowTestingFrameworkSetupHook: 'beforeEach' }, + ], 'testing-library/render-result-naming-convention': 'off', }, diff --git a/scripts/i18n-lint.js b/scripts/i18n-lint.js index b30981de8..ea5aade16 100644 --- a/scripts/i18n-lint.js +++ b/scripts/i18n-lint.js @@ -13,7 +13,10 @@ const errors = {}; * Return a new copy of the array lowercased and sorted */ function lowerCaseSortedArray(arr) { - return arr.slice().map(v => v.toLowerCase()).sort(); + return arr + .slice() + .map((v) => v.toLowerCase()) + .sort(); } /** @@ -49,22 +52,22 @@ Object.keys(normalizedFiles).forEach((fileName) => { if (unsorted.length) { errors[fileName] = errors[fileName] || []; errors[fileName].push('Keys are not sorted properly'); - errors[fileName].push( - `\tSorting starts to be incorrect around: ${unsorted[0]}`, - ); + errors[fileName].push(`\tSorting starts to be incorrect around: ${unsorted[0]}`); } if (missing.length) { errors[fileName] = errors[fileName] || []; errors[fileName].push('Some keys from the default locale file are missing'); - errors[fileName].push( - `\tMissing keys: ${missing.join(', ')}`, - ); + errors[fileName].push(`\tMissing keys: ${missing.join(', ')}`); } }); Object.keys(errors).forEach((errorFileName) => { - log(chalk.red(`${chalk.inverse.bold(errorFileName)} has ${chalk.underline.bold('internationalization')} errors`)); + log( + chalk.red( + `${chalk.inverse.bold(errorFileName)} has ${chalk.underline.bold('internationalization')} errors`, + ), + ); errors[errorFileName].forEach((error) => { log(`\t${chalk.yellow(error)}`); }); diff --git a/setupTest.js b/setupTest.js index da533e441..fe8fe529f 100644 --- a/setupTest.js +++ b/setupTest.js @@ -22,9 +22,7 @@ beforeEach((context) => { }); /** */ -class Path2D { - -} +class Path2D {} global.Path2D = Path2D; diff --git a/src/components/AccessTokenSender.jsx b/src/components/AccessTokenSender.jsx index ade30b8c1..94080c0c9 100644 --- a/src/components/AccessTokenSender.jsx +++ b/src/components/AccessTokenSender.jsx @@ -6,9 +6,12 @@ import { IIIFIFrameCommunication } from './IIIFIFrameCommunication'; * Opens a new window for click */ export function AccessTokenSender({ handleAccessTokenMessage, url = undefined }) { - const onReceiveAccessTokenMessage = useCallback((e) => { - if (e.data && e.data.messageId && e.data.messageId === url) handleAccessTokenMessage(e.data); - }, [handleAccessTokenMessage, url]); + const onReceiveAccessTokenMessage = useCallback( + (e) => { + if (e.data && e.data.messageId && e.data.messageId === url) handleAccessTokenMessage(e.data); + }, + [handleAccessTokenMessage, url], + ); if (!url) return null; diff --git a/src/components/AnnotationSettings.jsx b/src/components/AnnotationSettings.jsx index 8604a2f17..3c3dfb992 100644 --- a/src/components/AnnotationSettings.jsx +++ b/src/components/AnnotationSettings.jsx @@ -7,10 +7,8 @@ import MiradorMenuButton from '../containers/MiradorMenuButton'; /** * AnnotationSettings is a component to handle various annotation * display settings in the Annotation companion window -*/ -export function AnnotationSettings({ - displayAll, displayAllDisabled, toggleAnnotationDisplay, -}) { + */ +export function AnnotationSettings({ displayAll, displayAllDisabled, toggleAnnotationDisplay }) { const { t } = useTranslation(); return ( - { displayAll ? : } + {displayAll ? : } ); } @@ -28,5 +26,6 @@ AnnotationSettings.propTypes = { displayAll: PropTypes.bool.isRequired, displayAllDisabled: PropTypes.bool.isRequired, toggleAnnotationDisplay: PropTypes.func.isRequired, - windowId: PropTypes.string.isRequired, // eslint-disable-line react/no-unused-prop-types + // eslint-disable-next-line react/no-unused-prop-types + windowId: PropTypes.string.isRequired, }; diff --git a/src/components/AnnotationsOverlay.jsx b/src/components/AnnotationsOverlay.jsx index 152ddce6a..f97361e68 100644 --- a/src/components/AnnotationsOverlay.jsx +++ b/src/components/AnnotationsOverlay.jsx @@ -1,6 +1,4 @@ -import { - useRef, useEffect, useCallback, useMemo, -} from 'react'; +import { useRef, useEffect, useCallback, useMemo } from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; import { useDebouncedCallback } from 'use-debounce'; @@ -20,15 +18,14 @@ function isAnnotationAtPoint(canvasWorld, osdCanvasOverlay, resource, canvas, po if (resource.svgSelector) { const context = osdCanvasOverlay.context2d; const { svgPaths } = new CanvasAnnotationDisplay({ resource }); - return [...svgPaths].some(path => ( - context.isPointInPath(new Path2D(path.attributes.d.nodeValue), relativeX, relativeY) - )); + return [...svgPaths].some((path) => + context.isPointInPath(new Path2D(path.attributes.d.nodeValue), relativeX, relativeY), + ); } if (resource.fragmentSelector) { const [x, y, w, h] = resource.fragmentSelector; - return x <= relativeX && relativeX <= (x + w) - && y <= relativeY && relativeY <= (y + h); + return x <= relativeX && relativeX <= x + w && y <= relativeY && relativeY <= y + h; } return false; } @@ -38,51 +35,77 @@ function isAnnotationAtPoint(canvasWorld, osdCanvasOverlay, resource, canvas, po * and rendering OSD. */ export function AnnotationsOverlay({ - annotations = [], canvasWorld, deselectAnnotation = () => {}, drawAnnotations = true, drawSearchAnnotations = true, - highlightAllAnnotations = false, hoverAnnotation = () => {}, hoveredAnnotationIds = [], - palette = {}, searchAnnotations = [], selectAnnotation = () => {}, selectedAnnotationId = null, - viewer = null, windowId, + annotations = [], + canvasWorld, + deselectAnnotation = () => {}, + drawAnnotations = true, + drawSearchAnnotations = true, + highlightAllAnnotations = false, + hoverAnnotation = () => {}, + hoveredAnnotationIds = [], + palette = {}, + searchAnnotations = [], + selectAnnotation = () => {}, + selectedAnnotationId = null, + viewer = null, + windowId, }) { const ref = useRef(); - const osdCanvasOverlay = useMemo(() => new OpenSeadragonCanvasOverlay(viewer, ref), [ref, viewer]); + const osdCanvasOverlay = useMemo( + () => new OpenSeadragonCanvasOverlay(viewer, ref), + [ref, viewer], + ); - const toggleAnnotation = useCallback((id) => { - if (selectedAnnotationId === id) { - deselectAnnotation(windowId, id); - } else { - selectAnnotation(windowId, id); - } - }, [selectedAnnotationId, deselectAnnotation, selectAnnotation, windowId]); + const toggleAnnotation = useCallback( + (id) => { + if (selectedAnnotationId === id) { + deselectAnnotation(windowId, id); + } else { + selectAnnotation(windowId, id); + } + }, + [selectedAnnotationId, deselectAnnotation, selectAnnotation, windowId], + ); /** * annotationsToContext - converts anontations to a canvas context */ - const annotationsToContext = useCallback((renderedAnnotations, currentPalette) => { - const context = osdCanvasOverlay.context2d; - const zoomRatio = viewer.viewport.getZoom(true) / viewer.viewport.getMaxZoom(); - renderedAnnotations.forEach((annotation) => { - annotation.resources.forEach((resource) => { - if (!canvasWorld.canvasIds.includes(resource.targetId)) return; - const offset = canvasWorld.offsetByCanvas(resource.targetId); - const canvasAnnotationDisplay = new CanvasAnnotationDisplay({ - hovered: hoveredAnnotationIds.includes(resource.id), - offset, - palette: { - ...currentPalette, - default: { - ...currentPalette.default, - ...(!highlightAllAnnotations && currentPalette.hidden), + const annotationsToContext = useCallback( + (renderedAnnotations, currentPalette) => { + const context = osdCanvasOverlay.context2d; + const zoomRatio = viewer.viewport.getZoom(true) / viewer.viewport.getMaxZoom(); + renderedAnnotations.forEach((annotation) => { + annotation.resources.forEach((resource) => { + if (!canvasWorld.canvasIds.includes(resource.targetId)) return; + const offset = canvasWorld.offsetByCanvas(resource.targetId); + const canvasAnnotationDisplay = new CanvasAnnotationDisplay({ + hovered: hoveredAnnotationIds.includes(resource.id), + offset, + palette: { + ...currentPalette, + default: { + ...currentPalette.default, + ...(!highlightAllAnnotations && currentPalette.hidden), + }, }, - }, - resource, - selected: selectedAnnotationId === resource.id, - zoomRatio, + resource, + selected: selectedAnnotationId === resource.id, + zoomRatio, + }); + canvasAnnotationDisplay.toContext(context); }); - canvasAnnotationDisplay.toContext(context); }); - }); - }, [osdCanvasOverlay, viewer, canvasWorld, highlightAllAnnotations, hoveredAnnotationIds, selectedAnnotationId]); + }, + [ + osdCanvasOverlay, + viewer, + canvasWorld, + highlightAllAnnotations, + hoveredAnnotationIds, + selectedAnnotationId, + ], + ); const renderAnnotations = useCallback(() => { if (drawSearchAnnotations) { @@ -92,7 +115,14 @@ export function AnnotationsOverlay({ if (drawAnnotations) { annotationsToContext(annotations, palette.annotations); } - }, [annotations, annotationsToContext, drawAnnotations, drawSearchAnnotations, palette, searchAnnotations]); + }, [ + annotations, + annotationsToContext, + drawAnnotations, + drawSearchAnnotations, + palette, + searchAnnotations, + ]); const updateCanvas = useCallback(() => { if (!osdCanvasOverlay) return; @@ -102,96 +132,131 @@ export function AnnotationsOverlay({ osdCanvasOverlay.canvasUpdate(renderAnnotations); }, [osdCanvasOverlay, renderAnnotations]); - const annotationsAtPoint = useCallback((canvas, point) => { - const lists = [...annotations, ...searchAnnotations]; - const annos = flatten(lists.map(l => l.resources)).filter((resource) => { - if (canvas.id !== resource.targetId) return false; + const annotationsAtPoint = useCallback( + (canvas, point) => { + const lists = [...annotations, ...searchAnnotations]; + const annos = flatten(lists.map((l) => l.resources)).filter((resource) => { + if (canvas.id !== resource.targetId) return false; - return isAnnotationAtPoint(canvasWorld, osdCanvasOverlay, resource, canvas, point); - }); - - return annos; - }, [annotations, canvasWorld, osdCanvasOverlay, searchAnnotations]); - - const onCanvasClick = useCallback((event) => { - const { position: webPosition, eventSource: { viewport } } = event; - const point = viewport.pointFromPixel(webPosition); - - const canvas = canvasWorld.canvasAtPoint(point); - if (!canvas) return; - const [ - _canvasX, _canvasY, canvasWidth, canvasHeight, - ] = canvasWorld.canvasToWorldCoordinates(canvas.id); + return isAnnotationAtPoint(canvasWorld, osdCanvasOverlay, resource, canvas, point); + }); - // get all the annotations that contain the click - const annos = annotationsAtPoint(canvas, point); + return annos; + }, + [annotations, canvasWorld, osdCanvasOverlay, searchAnnotations], + ); - if (annos.length > 0) { - event.preventDefaultAction = true; // eslint-disable-line no-param-reassign - } + const onCanvasClick = useCallback( + (event) => { + const { + position: webPosition, + eventSource: { viewport }, + } = event; + const point = viewport.pointFromPixel(webPosition); + + const canvas = canvasWorld.canvasAtPoint(point); + if (!canvas) return; + const [_canvasX, _canvasY, canvasWidth, canvasHeight] = canvasWorld.canvasToWorldCoordinates( + canvas.id, + ); + + // get all the annotations that contain the click + const annos = annotationsAtPoint(canvas, point); + + if (annos.length > 0) { + // eslint-disable-next-line no-param-reassign + event.preventDefaultAction = true; + } - if (annos.length === 1) { - toggleAnnotation(annos[0].id); - } else if (annos.length > 0) { - /** - * Try to find the "right" annotation to select after a click. - * - * This is perhaps a naive method, but seems to deal with rectangles and SVG shapes: - * - * - figure out how many points around a circle are inside the annotation shape - * - if there's a shape with the fewest interior points, it's probably the one - * with the closest boundary? - * - if there's a tie, make the circle bigger and try again. - */ - const annosWithClickScore = (radius) => { - const degreesToRadians = Math.PI / 180; - - return (anno) => { - let score = 0; - for (let degrees = 0; degrees < 360; degrees += 1) { - const x = Math.cos(degrees * degreesToRadians) * radius + point.x; - const y = Math.sin(degrees * degreesToRadians) * radius + point.y; - - if (isAnnotationAtPoint(canvasWorld, osdCanvasOverlay, anno, canvas, { x, y })) score += 1; - } - - return { anno, score }; + if (annos.length === 1) { + toggleAnnotation(annos[0].id); + } else if (annos.length > 0) { + /** + * Try to find the "right" annotation to select after a click. + * + * This is perhaps a naive method, but seems to deal with rectangles and SVG shapes: + * + * - figure out how many points around a circle are inside the annotation shape + * - if there's a shape with the fewest interior points, it's probably the one + * with the closest boundary? + * - if there's a tie, make the circle bigger and try again. + */ + const annosWithClickScore = (radius) => { + const degreesToRadians = Math.PI / 180; + + return (anno) => { + let score = 0; + for (let degrees = 0; degrees < 360; degrees += 1) { + const x = Math.cos(degrees * degreesToRadians) * radius + point.x; + const y = Math.sin(degrees * degreesToRadians) * radius + point.y; + + if (isAnnotationAtPoint(canvasWorld, osdCanvasOverlay, anno, canvas, { x, y })) + score += 1; + } + + return { anno, score }; + }; }; - }; - let annosWithScore = []; - let radius = 1; - annosWithScore = sortBy(annos.map(annosWithClickScore(radius)), 'score'); - - while (radius < Math.max(canvasWidth, canvasHeight) - && annosWithScore[0].score === annosWithScore[1].score) { - radius *= 2; + let annosWithScore = []; + let radius = 1; annosWithScore = sortBy(annos.map(annosWithClickScore(radius)), 'score'); - } - - toggleAnnotation(annosWithScore[0].anno.id); - } - }, [annotationsAtPoint, canvasWorld, osdCanvasOverlay, toggleAnnotation]); - const onCanvasMouseMove = useDebouncedCallback(useCallback((event) => { - if (annotations.length === 0 && searchAnnotations.length === 0) return; - - const { position: webPosition } = event; - const point = viewer.viewport.pointFromPixel(webPosition); - - const canvas = canvasWorld.canvasAtPoint(point); - if (!canvas) { - hoverAnnotation(windowId, []); - return; - } + while ( + radius < Math.max(canvasWidth, canvasHeight) && + annosWithScore[0].score === annosWithScore[1].score + ) { + radius *= 2; + annosWithScore = sortBy(annos.map(annosWithClickScore(radius)), 'score'); + } - const annos = annotationsAtPoint(canvas, point); + toggleAnnotation(annosWithScore[0].anno.id); + } + }, + [annotationsAtPoint, canvasWorld, osdCanvasOverlay, toggleAnnotation], + ); - if (xor(hoveredAnnotationIds, annos.map(a => a.id)).length > 0) { - hoverAnnotation(windowId, annos.map(a => a.id)); - } - }, [annotations, annotationsAtPoint, canvasWorld, hoverAnnotation, - hoveredAnnotationIds, searchAnnotations, viewer, windowId]), 10); + const onCanvasMouseMove = useDebouncedCallback( + useCallback( + (event) => { + if (annotations.length === 0 && searchAnnotations.length === 0) return; + + const { position: webPosition } = event; + const point = viewer.viewport.pointFromPixel(webPosition); + + const canvas = canvasWorld.canvasAtPoint(point); + if (!canvas) { + hoverAnnotation(windowId, []); + return; + } + + const annos = annotationsAtPoint(canvas, point); + + if ( + xor( + hoveredAnnotationIds, + annos.map((a) => a.id), + ).length > 0 + ) { + hoverAnnotation( + windowId, + annos.map((a) => a.id), + ); + } + }, + [ + annotations, + annotationsAtPoint, + canvasWorld, + hoverAnnotation, + hoveredAnnotationIds, + searchAnnotations, + viewer, + windowId, + ], + ), + 10, + ); const onCanvasExit = useCallback(() => { // a move event may be queued up by the debouncer @@ -221,8 +286,16 @@ export function AnnotationsOverlay({ useEffect(() => { if (viewer) viewer.forceRedraw(); - }, [annotations, drawAnnotations, drawSearchAnnotations, highlightAllAnnotations, - hoveredAnnotationIds, searchAnnotations, selectedAnnotationId, viewer]); + }, [ + annotations, + drawAnnotations, + drawSearchAnnotations, + highlightAllAnnotations, + hoveredAnnotationIds, + searchAnnotations, + selectedAnnotationId, + viewer, + ]); useEffect(() => { if (!ref.current) return; @@ -237,16 +310,18 @@ export function AnnotationsOverlay({ if (!viewer) return null; return ReactDOM.createPortal( - ( -
- -
- ), +
+ +
, viewer.canvas, ); } diff --git a/src/components/App.jsx b/src/components/App.jsx index 0942feff9..591f404b5 100644 --- a/src/components/App.jsx +++ b/src/components/App.jsx @@ -1,6 +1,4 @@ -import { - createRef, lazy, Suspense, -} from 'react'; +import { createRef, lazy, Suspense } from 'react'; import PropTypes from 'prop-types'; import PluginProvider from '../extend/PluginProvider'; import AppProviders from '../containers/AppProviders'; @@ -19,9 +17,7 @@ export function App({ dndManager = undefined, plugins = [] }) { - } - > + }> diff --git a/src/components/AppProviders.jsx b/src/components/AppProviders.jsx index eb2e390fe..98d06c811 100644 --- a/src/components/AppProviders.jsx +++ b/src/components/AppProviders.jsx @@ -2,9 +2,7 @@ import { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import { FullScreen, useFullScreenHandle } from 'react-full-screen'; import { I18nextProvider } from 'react-i18next'; -import { - ThemeProvider, StyledEngineProvider, createTheme, -} from '@mui/material/styles'; +import { ThemeProvider, StyledEngineProvider, createTheme } from '@mui/material/styles'; import { DndContext, DndProvider } from 'react-dnd'; import { MultiBackend } from 'react-dnd-multi-backend'; import { HTML5toTouch } from 'rdndmb-html5-to-touch'; @@ -33,20 +31,12 @@ const MaybeDndProvider = ({ dndManager = undefined, children }) => { ); } - return ( - - {children} - - ); + return {children}; }; MaybeDndProvider.propTypes = { children: PropTypes.node.isRequired, - dndManager: PropTypes.oneOf([ - undefined, - false, - PropTypes.object, - ]), + dndManager: PropTypes.oneOf([undefined, false, PropTypes.object]), }; /** @@ -57,9 +47,7 @@ const FullScreenShim = ({ children }) => { return ( - - {children} - + {children} ); }; @@ -84,7 +72,7 @@ const StoreAwareI18nextProvider = ({ children, language, translations }) => { }); }, [i18n, translations]); - return ({children}); + return {children}; }; StoreAwareI18nextProvider.propTypes = { @@ -115,7 +103,8 @@ const cacheDefault = createCache({ export function AppProviders({ children = null, language, - theme, translations, + theme, + translations, dndManager = undefined, }) { return ( @@ -124,11 +113,9 @@ export function AppProviders({ - + - - {children} - + {children} diff --git a/src/components/AttributionPanel.jsx b/src/components/AttributionPanel.jsx index d15288a99..2c8ce7970 100644 --- a/src/components/AttributionPanel.jsx +++ b/src/components/AttributionPanel.jsx @@ -31,7 +31,8 @@ export function AttributionPanel({ }) { const { t } = useTranslation(); - const pluginProps = arguments[0]; // eslint-disable-line prefer-rest-params + // eslint-disable-next-line prefer-rest-params + const pluginProps = arguments[0]; return ( - { requiredStatement && ( - + {requiredStatement && ( + + )} + {rights && rights.length > 0 && ( +
+ + {t('rights')} + + {rights.map((v) => ( + + + {v} + + + ))} +
)} - { - rights && rights.length > 0 && ( -
- {t('rights')} - { rights.map(v => ( - - - {v} - - - )) } -
- ) - }
- { manifestLogo && ( - - - } - /> - + {manifestLogo && ( + + } + /> + )} @@ -81,10 +80,12 @@ export function AttributionPanel({ AttributionPanel.propTypes = { id: PropTypes.string.isRequired, manifestLogo: PropTypes.string, - requiredStatement: PropTypes.arrayOf(PropTypes.shape({ - label: PropTypes.string, - value: PropTypes.string, - })), + requiredStatement: PropTypes.arrayOf( + PropTypes.shape({ + label: PropTypes.string, + value: PropTypes.string, + }), + ), rights: PropTypes.arrayOf(PropTypes.string), windowId: PropTypes.string.isRequired, }; diff --git a/src/components/AudioViewer.jsx b/src/components/AudioViewer.jsx index 63edd3a47..9835fd3ce 100644 --- a/src/components/AudioViewer.jsx +++ b/src/components/AudioViewer.jsx @@ -24,7 +24,11 @@ export function AudioViewer({ audioOptions = {}, audioResources = [], captions = ))} {captions.map((caption) => ( - + ))} diff --git a/src/components/Branding.jsx b/src/components/Branding.jsx index 5fe596734..549e83375 100644 --- a/src/components/Branding.jsx +++ b/src/components/Branding.jsx @@ -12,10 +12,12 @@ export function Branding({ variant = 'default', ...ContainerProps }) { const { t } = useTranslation(); return ( - { variant === 'wide' && ( -
- {t('mirador')} -
+ {variant === 'wide' && ( +
+ + {t('mirador')} + +
)} - +
diff --git a/src/components/CanvasAnnotations.jsx b/src/components/CanvasAnnotations.jsx index 3009ba4ff..4c3a83171 100644 --- a/src/components/CanvasAnnotations.jsx +++ b/src/components/CanvasAnnotations.jsx @@ -11,24 +11,40 @@ import { ScrollTo } from './ScrollTo'; /** * CanvasAnnotations ~ -*/ + */ export function CanvasAnnotations({ - annotations = [], index, label, selectedAnnotationId = undefined, totalSize, - listContainerComponent = 'li', htmlSanitizationRuleSet = 'iiif', hoveredAnnotationIds = [], - containerRef = undefined, deselectAnnotation, selectAnnotation, windowId, hoverAnnotation, + annotations = [], + index, + label, + selectedAnnotationId = undefined, + totalSize, + listContainerComponent = 'li', + htmlSanitizationRuleSet = 'iiif', + hoveredAnnotationIds = [], + containerRef = undefined, + deselectAnnotation, + selectAnnotation, + windowId, + hoverAnnotation, }) { const { t } = useTranslation(); - const handleClick = useCallback((_event, annotation) => { - if (selectedAnnotationId === annotation.id) { - deselectAnnotation(windowId, annotation.id); - } else { - selectAnnotation(windowId, annotation.id); - } - }, [windowId, deselectAnnotation, selectAnnotation, selectedAnnotationId]); + const handleClick = useCallback( + (_event, annotation) => { + if (selectedAnnotationId === annotation.id) { + deselectAnnotation(windowId, annotation.id); + } else { + selectAnnotation(windowId, annotation.id); + } + }, + [windowId, deselectAnnotation, selectAnnotation, selectedAnnotationId], + ); - const handleAnnotationHover = useCallback((annotation) => { - hoverAnnotation(windowId, [annotation.id]); - }, [hoverAnnotation, windowId]); + const handleAnnotationHover = useCallback( + (annotation) => { + hoverAnnotation(windowId, [annotation.id]); + }, + [hoverAnnotation, windowId], + ); const handleAnnotationBlur = useCallback(() => { hoverAnnotation(windowId, []); @@ -71,13 +87,21 @@ export function CanvasAnnotations({ - } - secondary={ - annotation.tags.map((tag) => ( - - )) + } + secondary={annotation.tags.map((tag) => ( + + ))} /> diff --git a/src/components/CanvasInfo.jsx b/src/components/CanvasInfo.jsx index 8cc9fbbde..0a1b7408d 100644 --- a/src/components/CanvasInfo.jsx +++ b/src/components/CanvasInfo.jsx @@ -20,22 +20,13 @@ export function CanvasInfo({ const { t } = useTranslation(); const id = useId(); const titleId = useId(); - const pluginProps = arguments[0]; // eslint-disable-line prefer-rest-params + // eslint-disable-next-line prefer-rest-params + const pluginProps = arguments[0]; return ( - + {canvasLabel && ( - + {canvasLabel} )} diff --git a/src/components/CanvasLayers.jsx b/src/components/CanvasLayers.jsx index 19d45098e..b58039eaf 100644 --- a/src/components/CanvasLayers.jsx +++ b/src/components/CanvasLayers.jsx @@ -44,7 +44,13 @@ const reorder = (list, startIndex, endIndex) => { /** @private */ function Layer({ - resource, layerMetadata = {}, index, handleOpacityChange, setLayerVisibility, moveToBackground, moveToFront, + resource, + layerMetadata = {}, + index, + handleOpacityChange, + setLayerVisibility, + moveToBackground, + moveToFront, }) { const { t } = useTranslation(); const { width, height } = { height: undefined, width: 40 }; @@ -58,12 +64,7 @@ function Layer({ return (
- +
- { setLayerVisibility(resource.id, !layer.visibility); }}> - { layer.visibility ? : } + { + setLayerVisibility(resource.id, !layer.visibility); + }} + > + {layer.visibility ? : } - { layer.index !== 0 && ( - { moveToBackground(resource.id); }}> + {layer.index !== 0 && ( + { + moveToBackground(resource.id); + }} + > )} - { layer.index !== layerMetadata && ( - { moveToFront(resource.id); }}> + {layer.index !== layerMetadata && ( + { + moveToFront(resource.id); + }} + > )} @@ -91,7 +111,11 @@ function Layer({
- + handleOpacityChange(resource.id, e.target.value)} - endAdornment={%} + onChange={(e) => handleOpacityChange(resource.id, e.target.value)} + endAdornment={ + + % + + } inputProps={{ 'aria-label': t('layer_opacity'), }} @@ -135,10 +163,12 @@ function Layer({ Layer.propTypes = { handleOpacityChange: PropTypes.func.isRequired, index: PropTypes.number.isRequired, - layerMetadata: PropTypes.objectOf(PropTypes.shape({ - opacity: PropTypes.number, - visibility: PropTypes.bool, - })), + layerMetadata: PropTypes.objectOf( + PropTypes.shape({ + opacity: PropTypes.number, + visibility: PropTypes.bool, + }), + ), moveToBackground: PropTypes.func.isRequired, moveToFront: PropTypes.func.isRequired, resource: PropTypes.object.isRequired, @@ -146,9 +176,7 @@ Layer.propTypes = { }; /** @private */ -function DraggableLayer({ - children, resource, index, -}) { +function DraggableLayer({ children, resource, index }) { const { t } = useTranslation(); return ( @@ -184,7 +212,7 @@ function DraggableLayer({ - { children } + {children} )} @@ -199,74 +227,107 @@ DraggableLayer.propTypes = { /** */ export function CanvasLayers({ - canvasId, index, label, layers, layerMetadata = {}, totalSize, updateLayers, windowId, + canvasId, + index, + label, + layers, + layerMetadata = {}, + totalSize, + updateLayers, + windowId, }) { const { t } = useTranslation(); const droppableId = useId(); - const handleOpacityChange = useCallback((layerId, value) => { - const payload = { - [layerId]: { opacity: value / 100.0 }, - }; + const handleOpacityChange = useCallback( + (layerId, value) => { + const payload = { + [layerId]: { opacity: value / 100.0 }, + }; - updateLayers(windowId, canvasId, payload); - }, [canvasId, updateLayers, windowId]); + updateLayers(windowId, canvasId, payload); + }, + [canvasId, updateLayers, windowId], + ); /** */ - const onDragEnd = useCallback((result) => { - if (!result.destination) return; - if (result.destination.droppableId !== droppableId) return; - if (result.source.droppableId !== droppableId) return; + const onDragEnd = useCallback( + (result) => { + if (!result.destination) return; + if (result.destination.droppableId !== droppableId) return; + if (result.source.droppableId !== droppableId) return; - const sortedLayers = reorder( - layers.map(l => l.id), - result.source.index, - result.destination.index, - ); + const sortedLayers = reorder( + layers.map((l) => l.id), + result.source.index, + result.destination.index, + ); - const payload = layers.reduce((acc, layer) => { - acc[layer.id] = { index: sortedLayers.indexOf(layer.id) }; // eslint-disable-line no-param-reassign - return acc; - }, {}); + const payload = layers.reduce((acc, layer) => { + // eslint-disable-next-line no-param-reassign + acc[layer.id] = { index: sortedLayers.indexOf(layer.id) }; + return acc; + }, {}); - updateLayers(windowId, canvasId, payload); - }, [canvasId, droppableId, layers, updateLayers, windowId]); + updateLayers(windowId, canvasId, payload); + }, + [canvasId, droppableId, layers, updateLayers, windowId], + ); /** */ - const setLayerVisibility = useCallback((layerId, value) => { - const payload = { - [layerId]: { visibility: value }, - }; + const setLayerVisibility = useCallback( + (layerId, value) => { + const payload = { + [layerId]: { visibility: value }, + }; - updateLayers(windowId, canvasId, payload); - }, [canvasId, updateLayers, windowId]); + updateLayers(windowId, canvasId, payload); + }, + [canvasId, updateLayers, windowId], + ); /** */ - const moveToBackground = useCallback((layerId) => { - const sortedLayers = reorder(layers.map(l => l.id), layers.findIndex(l => l.id === layerId), 0); + const moveToBackground = useCallback( + (layerId) => { + const sortedLayers = reorder( + layers.map((l) => l.id), + layers.findIndex((l) => l.id === layerId), + 0, + ); - const payload = layers.reduce((acc, layer) => { - acc[layer.id] = { index: sortedLayers.indexOf(layer.id) }; // eslint-disable-line no-param-reassign - return acc; - }, {}); + const payload = layers.reduce((acc, layer) => { + // eslint-disable-next-line no-param-reassign + acc[layer.id] = { index: sortedLayers.indexOf(layer.id) }; + return acc; + }, {}); - updateLayers(windowId, canvasId, payload); - }, [canvasId, layers, updateLayers, windowId]); + updateLayers(windowId, canvasId, payload); + }, + [canvasId, layers, updateLayers, windowId], + ); - const moveToFront = useCallback((layerId) => { - const sortedLayers = reorder(layers.map(l => l.id), layers.findIndex(l => l.id === layerId), layers.length - 1); + const moveToFront = useCallback( + (layerId) => { + const sortedLayers = reorder( + layers.map((l) => l.id), + layers.findIndex((l) => l.id === layerId), + layers.length - 1, + ); - const payload = layers.reduce((acc, layer) => { - acc[layer.id] = { index: sortedLayers.indexOf(layer.id) }; // eslint-disable-line no-param-reassign - return acc; - }, {}); + const payload = layers.reduce((acc, layer) => { + // eslint-disable-next-line no-param-reassign + acc[layer.id] = { index: sortedLayers.indexOf(layer.id) }; + return acc; + }, {}); - updateLayers(windowId, canvasId, payload); - }, [canvasId, layers, updateLayers, windowId]); + updateLayers(windowId, canvasId, payload); + }, + [canvasId, layers, updateLayers, windowId], + ); return ( <> - { totalSize > 1 && ( + {totalSize > 1 && ( - { - layers && layers.map((r, i) => ( + {layers && + layers.map((r, i) => ( - )) - } + ))} {provided.placeholder} )} @@ -316,11 +376,12 @@ CanvasLayers.propTypes = { canvasId: PropTypes.string.isRequired, index: PropTypes.number.isRequired, label: PropTypes.string.isRequired, - layerMetadata: PropTypes.objectOf(PropTypes.shape({ - opacity: PropTypes.number, - })), - layers: PropTypes.arrayOf(PropTypes.shape({ - })).isRequired, + layerMetadata: PropTypes.objectOf( + PropTypes.shape({ + opacity: PropTypes.number, + }), + ), + layers: PropTypes.arrayOf(PropTypes.shape({})).isRequired, totalSize: PropTypes.number.isRequired, updateLayers: PropTypes.func.isRequired, windowId: PropTypes.string.isRequired, diff --git a/src/components/ChangeThemeDialog.jsx b/src/components/ChangeThemeDialog.jsx index 10e90f26c..25b02a5e7 100644 --- a/src/components/ChangeThemeDialog.jsx +++ b/src/components/ChangeThemeDialog.jsx @@ -21,19 +21,25 @@ const ThemeIcon = styled(PaletteIcon, { name: 'ThemeIcon', slot: 'icon' })(({ th * a simple dialog providing the possibility to switch the theme */ export function ChangeThemeDialog({ - container = null, handleClose, open = false, selectedTheme, setSelectedTheme, themeIds = [], + container = null, + handleClose, + open = false, + selectedTheme, + setSelectedTheme, + themeIds = [], }) { const { t } = useTranslation(); - const handleThemeChange = useCallback((theme) => { - setSelectedTheme(theme); - handleClose(); - }, [handleClose, setSelectedTheme]); + const handleThemeChange = useCallback( + (theme) => { + setSelectedTheme(theme); + handleClose(); + }, + [handleClose, setSelectedTheme], + ); return ( - - {t('changeTheme')} - + {t('changeTheme')} {themeIds.map((value) => ( diff --git a/src/components/CollapsibleSection.jsx b/src/components/CollapsibleSection.jsx index cc64d350b..483dbbcf1 100644 --- a/src/components/CollapsibleSection.jsx +++ b/src/components/CollapsibleSection.jsx @@ -9,27 +9,38 @@ import { useTranslation } from 'react-i18next'; /** * CollapsableSection ~ -*/ -export function CollapsibleSection({ - children, id, label, -}) { + */ +export function CollapsibleSection({ children, id, label }) { const { t } = useTranslation(); const [open, setOpen] = useState(true); - const handleChange = useCallback((_event, isExpanded) => { - setOpen(isExpanded); - }, [setOpen]); + const handleChange = useCallback( + (_event, isExpanded) => { + setOpen(isExpanded); + }, + [setOpen], + ); return ( - - }> - - {label} - + + } + > + {label} - - {children} - + {children} ); } diff --git a/src/components/CollectionDialog.jsx b/src/components/CollectionDialog.jsx index 022ccb182..5d7c9e0e3 100644 --- a/src/components/CollectionDialog.jsx +++ b/src/components/CollectionDialog.jsx @@ -41,12 +41,7 @@ const StyledCollectionFilter = styled('div')(() => ({ /** */ const Placeholder = ({ onClose, container }) => ( - + @@ -65,7 +60,8 @@ Placeholder.propTypes = { /** * a dialog providing the possibility to select the collection */ -export function CollectionDialog({ // eslint-disable-line complexity +// eslint-disable-next-line complexity +export function CollectionDialog({ addWindow, collection = null, dialogCollectionPath = [], @@ -107,7 +103,9 @@ export function CollectionDialog({ // eslint-disable-line complexity const selectManifest = (m) => { if (windowId) { updateWindow(windowId, { - canvasId: null, collectionPath: [...dialogCollectionPath, manifestId], manifestId: m.id, + canvasId: null, + collectionPath: [...dialogCollectionPath, manifestId], + manifestId: m.id, }); } else { addWindow({ collectionPath: [...dialogCollectionPath, manifestId], manifestId: m.id }); @@ -127,111 +125,115 @@ export function CollectionDialog({ // eslint-disable-line complexity if (!ready) return ; - const rights = manifest && (asArray(manifest.getProperty('rights') || manifest.getProperty('license'))); + const rights = + manifest && asArray(manifest.getProperty('rights') || manifest.getProperty('license')); - const requiredStatement = manifest - && asArray(manifest.getRequiredStatement()).filter(l => l && l.getValue()).map(labelValuePair => ({ - label: null, - values: labelValuePair.getValues(), - })); + const requiredStatement = + manifest && + asArray(manifest.getRequiredStatement()) + .filter((l) => l && l.getValue()) + .map((labelValuePair) => ({ + label: null, + values: labelValuePair.getValues(), + })); const collections = manifest.getCollections(); const currentFilter = filter || (collections.length > 0 ? 'collections' : 'manifests'); return ( - + - { t(isMultipart ? 'multipartCollection' : 'collection') } + {t(isMultipart ? 'multipartCollection' : 'collection')} - { collection && ( - )} - - { requiredStatement && ( - + + {requiredStatement && ( + + )} + {rights && rights.length > 0 && ( + <> + + {t('rights')} + + {rights.map((v) => ( + + + {v} + + + ))} + )} - { - rights && rights.length > 0 && ( - <> - {t('rights')} - { rights.map(v => ( - - - {v} - - - )) } - - ) - } {manifest.getTotalCollections() > 0 && ( - setFilter('collections')} label={t('totalCollections', { count: manifest.getTotalCollections() })} /> + setFilter('collections')} + label={t('totalCollections', { count: manifest.getTotalCollections() })} + /> )} {manifest.getTotalManifests() > 0 && ( - setFilter('manifests')} label={t('totalManifests', { count: manifest.getTotalManifests() })} /> + setFilter('manifests')} + label={t('totalManifests', { count: manifest.getTotalManifests() })} + /> )} - { currentFilter === 'collections' && ( + {currentFilter === 'collections' && ( - { - collections.map(c => ( - { selectCollection(c); }} - variant="multiline" - > - - - )) - } + {collections.map((c) => ( + { + selectCollection(c); + }} + variant="multiline" + > + + + ))} )} - { currentFilter === 'manifests' && ( + {currentFilter === 'manifests' && ( - { - manifest.getManifests().map(m => ( - { selectManifest(m); }} - variant="multiline" - > - - - )) - } + {manifest.getManifests().map((m) => ( + { + selectManifest(m); + }} + variant="multiline" + > + + + ))} )} - + ); diff --git a/src/components/CollectionInfo.jsx b/src/components/CollectionInfo.jsx index 1e4c6550d..2d2522360 100644 --- a/src/components/CollectionInfo.jsx +++ b/src/components/CollectionInfo.jsx @@ -10,7 +10,10 @@ import CollapsibleSection from '../containers/CollapsibleSection'; * CollectionInfo */ export function CollectionInfo({ - collectionLabel = null, collectionPath = [], showCollectionDialog, windowId = null, + collectionLabel = null, + collectionPath = [], + showCollectionDialog, + windowId = null, }) { const { t } = useTranslation(); const id = useId(); @@ -28,25 +31,14 @@ export function CollectionInfo({ if (collectionPath.length === 0) return null; return ( - + {collectionLabel && ( - + {collectionLabel} )} - diff --git a/src/components/CompanionArea.jsx b/src/components/CompanionArea.jsx index ba21834df..000c608f9 100644 --- a/src/components/CompanionArea.jsx +++ b/src/components/CompanionArea.jsx @@ -26,9 +26,11 @@ const Container = styled('div', { name: 'CompanionArea', slot: 'container' })(({ flexDirection: 'column', width: '100%', }), - ...((ownerState?.position === 'left' && (ownerState?.companionWindowIds && ownerState.companionWindowIds.length > 0)) && { - minWidth: '235px', - }), + ...(ownerState?.position === 'left' && + ownerState?.companionWindowIds && + ownerState.companionWindowIds.length > 0 && { + minWidth: '235px', + }), })); const StyledToggle = styled('div', { name: 'CompanionArea', slot: 'toggle' })(({ theme }) => ({ @@ -51,13 +53,20 @@ const StyledToggle = styled('div', { name: 'CompanionArea', slot: 'toggle' })(({ /** */ export function CompanionArea({ - classes = {}, className = undefined, direction, - companionWindowIds, companionAreaOpen, setCompanionAreaOpen = () => {}, - position, sideBarOpen = false, windowId, + classes = {}, + className = undefined, + direction, + companionWindowIds, + companionAreaOpen, + setCompanionAreaOpen = () => {}, + position, + sideBarOpen = false, + windowId, }) { const { t } = useTranslation(); /** */ - const areaLayoutClass = (position === 'bottom' || position === 'far-bottom') ? classes.horizontal : null; + const areaLayoutClass = + position === 'bottom' || position === 'far-bottom' ? classes.horizontal : null; /** */ const collapseIcon = (() => { @@ -88,33 +97,36 @@ export function CompanionArea({ })(); const rootClasses = classNames(areaLayoutClass, ns(`companion-area-${position}`), className); - const ownerState = arguments[0]; // eslint-disable-line prefer-rest-params + // eslint-disable-next-line prefer-rest-params + const ownerState = arguments[0]; return ( - + {companionWindowIds.map((id) => ( ))} - {setCompanionAreaOpen && position === 'left' && sideBarOpen && companionWindowIds.length > 0 && ( - - { setCompanionAreaOpen(windowId, !companionAreaOpen); }} - TooltipProps={{ placement: 'right' }} - > - {collapseIcon} - - - )} + {setCompanionAreaOpen && + position === 'left' && + sideBarOpen && + companionWindowIds.length > 0 && ( + + { + setCompanionAreaOpen(windowId, !companionAreaOpen); + }} + TooltipProps={{ placement: 'right' }} + > + {collapseIcon} + + + )} ); } diff --git a/src/components/CompanionWindow.jsx b/src/components/CompanionWindow.jsx index bacdcbe9c..7dab48020 100644 --- a/src/components/CompanionWindow.jsx +++ b/src/components/CompanionWindow.jsx @@ -24,21 +24,42 @@ const StyledTitle = styled(Typography, { name: 'CompanionWindow', slot: 'title' const StyledTitleControls = styled('div', { name: 'CompanionWindow', slot: 'controls' })({}); const Contents = styled(Paper, { name: 'CompanionWindow', slot: 'contents' })({}); const StyledRnd = styled(Rnd, { name: 'CompanionWindow', slot: 'resize' })({}); -const StyledPositionButton = styled(MiradorMenuButton, { name: 'CompanionWindow', slot: 'positionButton' })({}); -const StyledCloseButton = styled(MiradorMenuButton, { name: 'CompanionWindow', slot: 'closeButton' })({}); +const StyledPositionButton = styled(MiradorMenuButton, { + name: 'CompanionWindow', + slot: 'positionButton', +})({}); +const StyledCloseButton = styled(MiradorMenuButton, { + name: 'CompanionWindow', + slot: 'closeButton', +})({}); /** * CompanionWindow */ -export const CompanionWindow = forwardRef((props, innerRef) => { // eslint-disable-line complexity +// eslint-disable-next-line complexity +export const CompanionWindow = forwardRef((props, innerRef) => { const { - ariaLabel = undefined, classes = {}, direction, id, paperClassName = '', onCloseClick = () => {}, updateCompanionWindow = undefined, isDisplayed = false, - position = null, title = null, children = undefined, titleControls = null, - defaultSidebarPanelWidth = 235, defaultSidebarPanelHeight = 201, + ariaLabel = undefined, + classes = {}, + direction, + id, + paperClassName = '', + onCloseClick = () => {}, + updateCompanionWindow = undefined, + isDisplayed = false, + position = null, + title = null, + children = undefined, + titleControls = null, + defaultSidebarPanelWidth = 235, + defaultSidebarPanelHeight = 201, } = props; const [sizeRef, size] = useElementSize(); const { t } = useTranslation(); - const locale = useSelector(state => getCompanionWindowLocale(state, { companionWindowId: id }), [id]); + const locale = useSelector( + (state) => getCompanionWindowLocale(state, { companionWindowId: id }), + [id], + ); /** */ const openInNewStyle = direction === 'rtl' ? { transform: 'scale(-1, 1)' } : {}; @@ -82,18 +103,15 @@ export const CompanionWindow = forwardRef((props, innerRef) => { // eslint-disab return base; })(); - const isBottom = (position === 'bottom' || position === 'far-bottom'); + const isBottom = position === 'bottom' || position === 'far-bottom'; const childrenWithAdditionalProps = Children.map(children, (child) => { if (!child) return null; - return cloneElement( - child, - { - parentactions: { - closeCompanionWindow: onCloseClick, - }, + return cloneElement(child, { + parentactions: { + closeCompanionWindow: onCloseClick, }, - ); + }); }); return ( @@ -104,7 +122,11 @@ export const CompanionWindow = forwardRef((props, innerRef) => { // eslint-disab display: isDisplayed ? null : 'none', order: position === 'left' ? -1 : null, }} - className={[ns(`companion-window-${position}`), paperClassName, position === 'bottom' ? classes.horizontal : classes.vertical].join(' ')} + className={[ + ns(`companion-window-${position}`), + paperClassName, + position === 'bottom' ? classes.horizontal : classes.vertical, + ].join(' ')} square component="aside" aria-label={ariaLabel || title} @@ -122,68 +144,67 @@ export const CompanionWindow = forwardRef((props, innerRef) => { // eslint-disab minHeight={50} minWidth={position === 'left' ? 235 : 100} > - {title} - { - position === 'left' - ? updateCompanionWindow - && ( - { updateCompanionWindow({ position: 'right' }); }} - > - - - ) - : ( - <> - { - updateCompanionWindow && ( - { updateCompanionWindow({ position: position === 'bottom' ? 'right' : 'bottom' }); }} - > - - - ) + {position === 'left' ? ( + updateCompanionWindow && ( + { + updateCompanionWindow({ position: 'right' }); + }} + > + + + ) + ) : ( + <> + {updateCompanionWindow && ( + - - - - ) - } - { - titleControls && ( - { + updateCompanionWindow({ + position: position === 'bottom' ? 'right' : 'bottom', + }); + }} + > + + + )} + - {titleControls} - - ) - } + + + + )} + {titleControls && ( + + {titleControls} + + )} - + {childrenWithAdditionalProps} @@ -205,10 +226,7 @@ CompanionWindow.propTypes = { paperClassName: PropTypes.string, position: PropTypes.string, size: PropTypes.shape({ width: PropTypes.number }), - title: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.node, - ]), + title: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), titleControls: PropTypes.node, updateCompanionWindow: PropTypes.func, }; diff --git a/src/components/CompanionWindowFactory.jsx b/src/components/CompanionWindowFactory.jsx index b3511dabd..2b0ae3204 100644 --- a/src/components/CompanionWindowFactory.jsx +++ b/src/components/CompanionWindowFactory.jsx @@ -9,19 +9,16 @@ import ErrorContent from '../containers/ErrorContent'; /** * Render a companion window using the appropriate component for the content */ -export function CompanionWindowFactory({ - content = null, id, windowId, -}) { +export function CompanionWindowFactory({ content = null, id, windowId }) { const { t } = useTranslation(); - const ErroredCompanionWindow = useCallback(({ error }) => ( - - - - ), [windowId, t, id]); + const ErroredCompanionWindow = useCallback( + ({ error }) => ( + + + + ), + [windowId, t, id], + ); const DynamicCompanionWindowType = CompanionWindowRegistry[content]; diff --git a/src/components/CompanionWindowSection.jsx b/src/components/CompanionWindowSection.jsx index 312164e85..318ca7310 100644 --- a/src/components/CompanionWindowSection.jsx +++ b/src/components/CompanionWindowSection.jsx @@ -1,6 +1,9 @@ import { styled } from '@mui/material/styles'; -export const CompanionWindowSection = styled('div', { name: 'CompanionWindowSection', slot: 'root' })(({ theme }) => ({ +export const CompanionWindowSection = styled('div', { + name: 'CompanionWindowSection', + slot: 'root', +})(({ theme }) => ({ paddingBlockEnd: theme.spacing(1), paddingBlockStart: theme.spacing(2), paddingInlineEnd: theme.spacing(1), diff --git a/src/components/CustomPanel.jsx b/src/components/CustomPanel.jsx index 62378958a..5963e817c 100644 --- a/src/components/CustomPanel.jsx +++ b/src/components/CustomPanel.jsx @@ -5,16 +5,10 @@ import CompanionWindow from '../containers/CompanionWindow'; /** * a custom panel that can be used for anything */ -export function CustomPanel({ - id, children = null, title, windowId, -}) { +export function CustomPanel({ id, children = null, title, windowId }) { const { t } = useTranslation(); return ( - + {children} ); diff --git a/src/components/ErrorContent.jsx b/src/components/ErrorContent.jsx index 01125ab58..a783e0b3e 100644 --- a/src/components/ErrorContent.jsx +++ b/src/components/ErrorContent.jsx @@ -25,14 +25,16 @@ const InlineAccordion = styled(Accordion, { name: 'ErrorContent', slot: 'accordi }); /** */ -export function ErrorContent({ - error, metadata = null, showJsError = true, ...rest -}) { +export function ErrorContent({ error, metadata = null, showJsError = true, ...rest }) { const { t } = useTranslation(); if (!showJsError) return null; const pluginProps = { - error, metadata, showJsError, t, ...rest, + error, + metadata, + showJsError, + t, + ...rest, }; return ( @@ -40,7 +42,10 @@ export function ErrorContent({ {t('errorDialogTitle')} {showJsError && ( - }> + } + > {t('jsError', { message: error.message, name: error.name })} diff --git a/src/components/ErrorDialog.jsx b/src/components/ErrorDialog.jsx index 33c34bd2f..f4bcffc43 100644 --- a/src/components/ErrorDialog.jsx +++ b/src/components/ErrorDialog.jsx @@ -22,9 +22,7 @@ export function ErrorDialog({ error = null, removeError = () => {} }) { onClose={() => removeError(error.id)} open={hasError} > - - {t('errorDialogTitle')} - + {t('errorDialogTitle')} {`${error.message}`} diff --git a/src/components/FullScreenButton.jsx b/src/components/FullScreenButton.jsx index 3794820f2..9f35b15b4 100644 --- a/src/components/FullScreenButton.jsx +++ b/src/components/FullScreenButton.jsx @@ -24,11 +24,27 @@ export function FullScreenButton({ className = undefined }) { if (!canFullscreenDiv) return null; if (handle && handle.active) { - return ; + return ( + + + + ); } if (handle) { - return ; + return ( + + + + ); } return null; diff --git a/src/components/GalleryView.jsx b/src/components/GalleryView.jsx index c2ba4898c..8ed9e1c89 100644 --- a/src/components/GalleryView.jsx +++ b/src/components/GalleryView.jsx @@ -28,15 +28,9 @@ export function GalleryView({ canvases, viewingDirection = '', windowId }) { elevation={0} id={`${windowId}-gallery`} > - { - canvases.map(canvas => ( - - )) - } + {canvases.map((canvas) => ( + + ))} ); } diff --git a/src/components/GalleryViewThumbnail.jsx b/src/components/GalleryViewThumbnail.jsx index af4fb5928..ea8d2dc2b 100644 --- a/src/components/GalleryViewThumbnail.jsx +++ b/src/components/GalleryViewThumbnail.jsx @@ -18,9 +18,10 @@ const Root = styled('div', { name: 'GalleryView', slot: 'thumbnail' })(({ ownerS ...(ownerState.selected && { borderColor: theme.palette.primary.main, }), - ...(!ownerState.selected && ownerState.searchAnnotationsCount > 0 && { - borderColor: theme.palette.action.selected, - }), + ...(!ownerState.selected && + ownerState.searchAnnotationsCount > 0 && { + borderColor: theme.palette.action.selected, + }), cursor: 'pointer', display: 'inline-block', margin: theme.spacing(1, 0.5), @@ -32,14 +33,16 @@ const Root = styled('div', { name: 'GalleryView', slot: 'thumbnail' })(({ ownerS width: 'min-content', })); -const StyledChipsContainer = styled('div', { name: 'GalleryView', slot: 'chipArea' })(({ theme }) => ({ - display: 'flex', - flexDirection: 'column', - gap: theme.spacing(0.25), - position: 'absolute', - right: 0, - top: 0, -})); +const StyledChipsContainer = styled('div', { name: 'GalleryView', slot: 'chipArea' })( + ({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(0.25), + position: 'absolute', + right: 0, + top: 0, + }), +); const AnnotationChip = styled(Chip, { name: 'GalleryView', slot: 'chip' })(({ theme }) => ({ backgroundColor: theme.palette.annotations.chipBackground, @@ -52,7 +55,12 @@ const AnnotationChip = styled(Chip, { name: 'GalleryView', slot: 'chip' })(({ th * OSD and Navigation */ export function GalleryViewThumbnail({ - canvas, selected = false, setCanvas, focusOnCanvas, annotationsCount = undefined, requestCanvasAnnotations = () => {}, + canvas, + selected = false, + setCanvas, + focusOnCanvas, + annotationsCount = undefined, + requestCanvasAnnotations = () => {}, searchAnnotationsCount = 0, config = { height: 100, width: null }, }) { @@ -86,12 +94,11 @@ export function GalleryViewThumbnail({ space: 32, }; - const enterOrSpace = ( - event.key === keys.enter - || event.which === chars.enter - || event.key === keys.space - || event.which === chars.space - ); + const enterOrSpace = + event.key === keys.enter || + event.which === chars.enter || + event.key === keys.space || + event.which === chars.space; if (enterOrSpace) { focusOnCanvas(); @@ -103,17 +110,23 @@ export function GalleryViewThumbnail({ /** */ const handleIntersection = (_inView, { isIntersecting }) => { if ( - !isIntersecting - || annotationsCount === undefined - || annotationsCount > 0 - || requestedAnnotations) return; + !isIntersecting || + annotationsCount === undefined || + annotationsCount > 0 || + requestedAnnotations + ) + return; setRequestedAnnotations(true); requestCanvasAnnotations(); }; const ownerState = { - annotationsCount, canvas, config, searchAnnotationsCount, selected, + annotationsCount, + canvas, + config, + searchAnnotationsCount, + selected, }; return ( diff --git a/src/components/IIIFAuthentication.jsx b/src/components/IIIFAuthentication.jsx index 826d7025d..ab27e649d 100644 --- a/src/components/IIIFAuthentication.jsx +++ b/src/components/IIIFAuthentication.jsx @@ -8,12 +8,25 @@ import WindowAuthenticationBar from '../containers/WindowAuthenticationBar'; * Opens a new window for click */ export function IIIFAuthentication({ - accessTokenServiceId = undefined, authServiceId = undefined, confirm = undefined, description = undefined, - failureDescription = undefined, failureHeader = undefined, features = 'centerscreen', - handleAuthInteraction, header = undefined, isInteractive = true, label = undefined, - logoutConfirm = undefined, logoutServiceId = undefined, openWindow = window.open, - resetAuthenticationState, resolveAccessTokenRequest, resolveAuthenticationRequest, - status = null, windowId, + accessTokenServiceId = undefined, + authServiceId = undefined, + confirm = undefined, + description = undefined, + failureDescription = undefined, + failureHeader = undefined, + features = 'centerscreen', + handleAuthInteraction, + header = undefined, + isInteractive = true, + label = undefined, + logoutConfirm = undefined, + logoutServiceId = undefined, + openWindow = window.open, + resetAuthenticationState, + resolveAccessTokenRequest, + resolveAuthenticationRequest, + status = null, + windowId, }) { const { t } = useTranslation(); @@ -65,7 +78,12 @@ export function IIIFAuthentication({ const renderLoggingInCookie = () => ( <> {renderLogin()} - resolveAuthenticationRequest(authServiceId, accessTokenServiceId)} /> + resolveAuthenticationRequest(authServiceId, accessTokenServiceId)} + /> ); diff --git a/src/components/IIIFDropTarget.jsx b/src/components/IIIFDropTarget.jsx index 18a60eb5b..061d3f692 100644 --- a/src/components/IIIFDropTarget.jsx +++ b/src/components/IIIFDropTarget.jsx @@ -48,20 +48,21 @@ export const handleDrop = (item, monitor, props) => { } if (item.files) { - const manifestFiles = item.files.filter(f => f.type === 'application/json'); - const manifestPromises = manifestFiles.map(file => ( - new Promise((resolve, reject) => { - const reader = new FileReader(); - reader.addEventListener('load', () => { - const manifestJson = reader.result; - const manifestId = uuid(); - - if (manifestJson) onDrop({ manifestId, manifestJson }, props, monitor); - resolve(); - }); - reader.readAsText(file); - }) - )); + const manifestFiles = item.files.filter((f) => f.type === 'application/json'); + const manifestPromises = manifestFiles.map( + (file) => + new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.addEventListener('load', () => { + const manifestJson = reader.result; + const manifestId = uuid(); + + if (manifestJson) onDrop({ manifestId, manifestJson }, props, monitor); + resolve(); + }); + reader.readAsText(file); + }), + ); const imageFiles = item.files.filter(({ type }) => type.startsWith('image/')); @@ -69,33 +70,33 @@ export const handleDrop = (item, monitor, props) => { if (imageFiles.length > 0) { const id = uuid(); - const imageData = imageFiles.map(file => readImageMetadata(file)); + const imageData = imageFiles.map((file) => readImageMetadata(file)); imagePromise = Promise.all(imageData).then((images) => { const manifestJson = { '@context': 'http://iiif.io/api/presentation/3/context.json', id, - items: images.map(({ - name, type, width, height, url, - }, index) => ({ + items: images.map(({ name, type, width, height, url }, index) => ({ height, id: `${id}/canvas/${index}`, items: [ { id: `${id}/canvas/${index}/1`, - items: [{ - body: { - format: type, - id: url, - type: 'Image', + items: [ + { + body: { + format: type, + id: url, + type: 'Image', + }, + height, + id: `${id}/canvas/${index}/1/image`, + motivation: 'painting', + target: `${id}/canvas/${index}/1`, + type: 'Annotation', + width, }, - height, - id: `${id}/canvas/${index}/1/image`, - motivation: 'painting', - target: `${id}/canvas/${index}/1`, - type: 'Annotation', - width, - }], + ], type: 'AnnotationPage', }, ], @@ -123,7 +124,7 @@ export const IIIFDropTarget = (props) => { const { children, onDrop } = props; const [{ canDrop, isOver }, drop] = useDrop({ accept: [NativeTypes.URL, NativeTypes.FILE, NativeTypes.HTML], - collect: monitor => ({ + collect: (monitor) => ({ canDrop: monitor.canDrop(), isOver: monitor.isOver(), }), @@ -141,8 +142,7 @@ export const IIIFDropTarget = (props) => { const hackForSafari = (e) => { if (!window.safari || !onDrop || !e.dataTransfer) return; - if (e.dataTransfer.types.includes('Files') - && e.dataTransfer.types.includes('text/uri-list')) { + if (e.dataTransfer.types.includes('Files') && e.dataTransfer.types.includes('text/uri-list')) { const url = e.dataTransfer.getData('text/uri-list'); if (!url) return; diff --git a/src/components/IIIFIFrameCommunication.jsx b/src/components/IIIFIFrameCommunication.jsx index 9a5a224f5..164180e3c 100644 --- a/src/components/IIIFIFrameCommunication.jsx +++ b/src/components/IIIFIFrameCommunication.jsx @@ -26,14 +26,9 @@ export function IIIFIFrameCommunication({ handleReceiveMessage = undefined, ...p }, [handleReceiveMessage]); return ( - // iframe "title" attribute is passed in via props for accessibility - /* eslint-disable jsx-a11y/iframe-has-title */ - ( -