From 37719809ca1372f3c9918571829fcb9a55f1f12b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Saracca?= Date: Fri, 31 Oct 2025 14:45:06 -0300 Subject: [PATCH 01/62] fix: wording while deleting draft dataset --- public/locales/en/dataset.json | 4 ++-- .../edit-dataset-menu/DeleteDraftDatasetButton.spec.tsx | 4 ++-- .../edit-dataset-menu/EditDatasetMenu.spec.tsx | 4 ++-- tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/public/locales/en/dataset.json b/public/locales/en/dataset.json index 8353e0254..056d00de5 100644 --- a/public/locales/en/dataset.json +++ b/public/locales/en/dataset.json @@ -68,7 +68,7 @@ }, "deleteDatasetModal": { "title": "Delete Dataset", - "message": "Are you sure you want to delete this dataset? This action cannot be undone.", + "message": "Are you sure you want to delete this draft version? Files will be reverted to the most recently published version. You cannot undelete this draft.", "defaultDatasetDeleteError": "An error occurred while deleting the dataset." } }, @@ -137,7 +137,7 @@ "heading": "Unpublished Dataset Private URL", "alertText": "This unpublished dataset is being privately shared." }, - "datasetDeletedSuccess": "The dataset has been deleted." + "datasetDeletedSuccess": "The dataset draft has been deleted." }, "termsTab": { "editTermsButton": "Edit Term Requirements", diff --git a/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/DeleteDraftDatasetButton.spec.tsx b/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/DeleteDraftDatasetButton.spec.tsx index fbd4799d8..f80a74b4c 100644 --- a/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/DeleteDraftDatasetButton.spec.tsx +++ b/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/DeleteDraftDatasetButton.spec.tsx @@ -83,7 +83,7 @@ describe('DeleteDraftDatasetButton', () => { cy.findByRole('button', { name: 'Delete Dataset' }).click() cy.findByRole('dialog').should('exist') - cy.findByText(/Are you sure you want to delete this dataset?/i).should('exist') + cy.findByText(/Are you sure you want to delete this draft version?/i).should('exist') }) it('closes confirmation modal when cancel is clicked', () => { @@ -118,7 +118,7 @@ describe('DeleteDraftDatasetButton', () => { cy.findByRole('dialog').should('exist') cy.findByRole('button', { name: 'Delete' }).click() cy.findByRole('dialog').should('not.exist') - cy.findByText(/The dataset has been deleted./).should('exist') + cy.findByText(/The dataset draft has been deleted./).should('exist') }) it('should not delete dataset if delete button clicked and repository fails', () => { diff --git a/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/EditDatasetMenu.spec.tsx b/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/EditDatasetMenu.spec.tsx index 1523c6616..a78f3cdc9 100644 --- a/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/EditDatasetMenu.spec.tsx +++ b/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/EditDatasetMenu.spec.tsx @@ -203,9 +203,9 @@ describe('EditDatasetMenu', () => { ) cy.findByRole('button', { name: 'Edit Dataset' }).click() cy.findByRole('button', { name: /Delete/ }).click() - cy.findByText(/Are you sure you want to delete this dataset?/i).should('exist') + cy.findByText(/Are you sure you want to delete this draft version?/i).should('exist') cy.findByRole('button', { name: 'Delete' }).click() - cy.findByText(/The dataset has been deleted./).should('exist') + cy.findByText(/The dataset draft has been deleted./).should('exist') const searchParams = new URLSearchParams({ [QueryParamKey.PERSISTENT_ID]: dataset.persistentId, diff --git a/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx b/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx index 2a127df07..4f28146df 100644 --- a/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx +++ b/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx @@ -304,9 +304,9 @@ describe('Dataset', () => { cy.findByRole('button', { name: 'Edit Dataset' }).should('exist').click() cy.findByRole('button', { name: 'Delete Dataset' }).should('exist').click() - cy.findByText(/Are you sure you want to delete this dataset?/i).should('exist') + cy.findByText(/Are you sure you want to delete this draft version?/i).should('exist') cy.findByRole('button', { name: 'Delete' }).should('exist').click() - cy.findByText(/The dataset has been deleted./i).should('exist') + cy.findByText(/The dataset draft has been deleted./i).should('exist') }) }) }) From 69708058478b092920dfe35f9afc3ef4782a8c0e Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Wed, 21 Jan 2026 15:19:47 -0500 Subject: [PATCH 02/62] add environment var to hide SPA OIDC client in the JSF frontend --- dev-env/docker-compose-dev.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-env/docker-compose-dev.yml b/dev-env/docker-compose-dev.yml index 2969b9bc0..7db94a04c 100644 --- a/dev-env/docker-compose-dev.yml +++ b/dev-env/docker-compose-dev.yml @@ -49,6 +49,7 @@ services: DATAVERSE_FEATURE_API_BEARER_AUTH_PROVIDE_MISSING_CLAIMS: 1 DATAVERSE_FEATURE_API_BEARER_AUTH_USE_BUILTIN_USER_ON_ID_MATCH: 1 DATAVERSE_AUTH_OIDC_ENABLED: 1 + DATAVERSE_AUTH_OIDC_HIDDEN_JSF: 1 DATAVERSE_AUTH_OIDC_CLIENT_ID: test DATAVERSE_AUTH_OIDC_CLIENT_SECRET: 94XHrfNRwXsjqTqApRrwWmhDLDHpIYV8 DATAVERSE_AUTH_OIDC_AUTH_SERVER_URL: http://keycloak.mydomain.com:9080/realms/test From f4ec328fc8fb9e4b19aa5574550bc10bb42866cb Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Wed, 21 Jan 2026 15:31:58 -0500 Subject: [PATCH 03/62] update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1e42a04c..625e63b98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ This changelog follows the principles of [Keep a Changelog](https://keepachangel - Link Collection and Link Dataset features. - With the addition of the new runtime configuration approach, we now support dynamic configuration for languages. If more than one language is configured, the Language Switcher will be shown in the header to allow users to change the language. - Added Notifications tab in Account Page +- Added an environment variable to docker-compose-dev.yml to hide the OIDC client used in the SPA from the JSF frontend: DATAVERSE_AUTH_OIDC_HIDDEN_JSF: 1 ### Changed From 92465ebb3f6643b3ea9ac7bc17b08ed452944eec Mon Sep 17 00:00:00 2001 From: Cheng Shi Date: Fri, 30 Jan 2026 18:10:18 -0500 Subject: [PATCH 04/62] fix: delete draft or delete dataset text --- public/locales/en/dataset.json | 6 +++-- public/locales/es/dataset.json | 6 +++-- .../ConfirmDeleteDraftDatasetModal.tsx | 13 ++++++++--- .../DeleteDraftDatasetButton.tsx | 12 ++++++++-- .../ConfirmDeleteDatasetModal.stories.tsx | 11 +++++----- .../DeleteDraftDatasetButton.spec.tsx | 22 ++++++++++++++++++- 6 files changed, 55 insertions(+), 15 deletions(-) diff --git a/public/locales/en/dataset.json b/public/locales/en/dataset.json index dab43771c..d23399b5b 100644 --- a/public/locales/en/dataset.json +++ b/public/locales/en/dataset.json @@ -68,7 +68,8 @@ }, "deleteDatasetModal": { "title": "Delete Dataset", - "message": "Are you sure you want to delete this draft version? Files will be reverted to the most recently published version. You cannot undelete this draft.", + "messageDraft": "Are you sure you want to delete this draft version? You cannot undelete this draft.", + "messageDataset": "Are you sure you want to delete this dataset? You cannot undelete this dataset.", "defaultDatasetDeleteError": "An error occurred while deleting the dataset." } }, @@ -137,7 +138,8 @@ "heading": "Unpublished Dataset Private URL", "alertText": "This unpublished dataset is being privately shared." }, - "datasetDeletedSuccess": "The dataset draft has been deleted." + "datasetDeletedSuccessDraft": "The dataset draft has been deleted.", + "datasetDeletedSuccessDataset": "The dataset has been deleted." }, "termsTab": { "editTermsButton": "Edit Term Requirements", diff --git a/public/locales/es/dataset.json b/public/locales/es/dataset.json index 30ad2dc4e..e07990aa3 100644 --- a/public/locales/es/dataset.json +++ b/public/locales/es/dataset.json @@ -68,7 +68,8 @@ }, "deleteDatasetModal": { "title": "Eliminar dataset", - "message": "¿Seguro que quieres eliminar este dataset? Esta acción no se puede deshacer.", + "messageDraft": "¿Seguro que quieres eliminar esta versión borrador? No podrás recuperar este borrador.", + "messageDataset": "¿Seguro que quieres eliminar este dataset? Esta acción no se puede deshacer.", "defaultDatasetDeleteError": "Ocurrió un error al eliminar el dataset." } }, @@ -137,7 +138,8 @@ "heading": "URL privada de dataset no publicado", "alertText": "Este dataset no publicado se está compartiendo de forma privada." }, - "datasetDeletedSuccess": "El dataset ha sido eliminado." + "datasetDeletedSuccessDraft": "El borrador del dataset ha sido eliminado.", + "datasetDeletedSuccessDataset": "El dataset ha sido eliminado." }, "termsTab": { "editTermsButton": "Editar requisitos de términos", diff --git a/src/sections/dataset/dataset-action-buttons/edit-dataset-menu/delete-draft-dataset/ConfirmDeleteDraftDatasetModal.tsx b/src/sections/dataset/dataset-action-buttons/edit-dataset-menu/delete-draft-dataset/ConfirmDeleteDraftDatasetModal.tsx index 2fea8f73f..255b9d307 100644 --- a/src/sections/dataset/dataset-action-buttons/edit-dataset-menu/delete-draft-dataset/ConfirmDeleteDraftDatasetModal.tsx +++ b/src/sections/dataset/dataset-action-buttons/edit-dataset-menu/delete-draft-dataset/ConfirmDeleteDraftDatasetModal.tsx @@ -9,6 +9,7 @@ interface ConfirmDeleteDraftDatasetModalProps { handleDelete: () => void isDeletingDataset: boolean errorDeletingDataset: string | null + hasReleasedVersion: boolean } export const ConfirmDeleteDraftDatasetModal = ({ @@ -16,11 +17,17 @@ export const ConfirmDeleteDraftDatasetModal = ({ handleClose, handleDelete, isDeletingDataset, - errorDeletingDataset + errorDeletingDataset, + hasReleasedVersion }: ConfirmDeleteDraftDatasetModalProps) => { const { t: tShared } = useTranslation('shared') const { t } = useTranslation('dataset') - const modalTitle = t('datasetActionButtons.editDataset.deleteDatasetModal.title') + const modalTitle = hasReleasedVersion + ? t('datasetActionButtons.editDataset.delete.draft') + : t('datasetActionButtons.editDataset.delete.released') + const modalMessage = hasReleasedVersion + ? t('datasetActionButtons.editDataset.deleteDatasetModal.messageDraft') + : t('datasetActionButtons.editDataset.deleteDatasetModal.messageDataset') return ( {' '} - {t('datasetActionButtons.editDataset.deleteDatasetModal.message')} + {modalMessage} {errorDeletingDataset && ( diff --git a/src/sections/dataset/dataset-action-buttons/edit-dataset-menu/delete-draft-dataset/DeleteDraftDatasetButton.tsx b/src/sections/dataset/dataset-action-buttons/edit-dataset-menu/delete-draft-dataset/DeleteDraftDatasetButton.tsx index 78600a0d5..22b1d873e 100644 --- a/src/sections/dataset/dataset-action-buttons/edit-dataset-menu/delete-draft-dataset/DeleteDraftDatasetButton.tsx +++ b/src/sections/dataset/dataset-action-buttons/edit-dataset-menu/delete-draft-dataset/DeleteDraftDatasetButton.tsx @@ -22,6 +22,7 @@ export function DeleteDraftDatasetButton({ const [showConfirmationModal, setShowConfirmationModal] = useState(false) const navigate = useNavigate() const { t } = useTranslation('dataset') + const hasReleasedVersion = dataset.version.someDatasetVersionHasBeenReleased const handleOpenModal = () => setShowConfirmationModal(true) const handleCloseModal = () => setShowConfirmationModal(false) @@ -45,7 +46,13 @@ export function DeleteDraftDatasetButton({ navigate(`${Route.DATASETS}?${searchParams.toString()}`) } - toast.success(t('alerts.datasetDeletedSuccess')) + toast.success( + t( + hasReleasedVersion + ? 'alerts.datasetDeletedSuccessDraft' + : 'alerts.datasetDeletedSuccessDataset' + ) + ) } if ( @@ -59,7 +66,7 @@ export function DeleteDraftDatasetButton({ <> - {dataset.version.someDatasetVersionHasBeenReleased + {hasReleasedVersion ? t('datasetActionButtons.editDataset.delete.draft') : t('datasetActionButtons.editDataset.delete.released')} @@ -69,6 +76,7 @@ export function DeleteDraftDatasetButton({ handleDelete={() => handleDeleteDraftDataset(dataset.persistentId)} isDeletingDataset={isDeletingDataset} errorDeletingDataset={errorDeletingDataset} + hasReleasedVersion={hasReleasedVersion} /> ) diff --git a/src/stories/dataset/delete-draft-dataset/ConfirmDeleteDatasetModal.stories.tsx b/src/stories/dataset/delete-draft-dataset/ConfirmDeleteDatasetModal.stories.tsx index 83dd56916..430740f6f 100644 --- a/src/stories/dataset/delete-draft-dataset/ConfirmDeleteDatasetModal.stories.tsx +++ b/src/stories/dataset/delete-draft-dataset/ConfirmDeleteDatasetModal.stories.tsx @@ -18,7 +18,8 @@ export const Default: Story = { handleClose={() => {}} handleDelete={() => {}} isDeletingDataset={false} - errorDeletingDataset={null}> + errorDeletingDataset={null} + hasReleasedVersion={true}> ) } export const DeleteInProgress: Story = { @@ -28,7 +29,8 @@ export const DeleteInProgress: Story = { isDeletingDataset={true} handleClose={() => {}} handleDelete={() => {}} - errorDeletingDataset={null}> + errorDeletingDataset={null} + hasReleasedVersion={true}> ) } export const WithError: Story = { @@ -38,8 +40,7 @@ export const WithError: Story = { isDeletingDataset={true} handleClose={() => {}} handleDelete={() => {}} - errorDeletingDataset={ - Error('Error deleting dataset').message - }> + errorDeletingDataset={Error('Error deleting dataset').message} + hasReleasedVersion={true}> ) } diff --git a/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/DeleteDraftDatasetButton.spec.tsx b/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/DeleteDraftDatasetButton.spec.tsx index f80a74b4c..c93af4efa 100644 --- a/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/DeleteDraftDatasetButton.spec.tsx +++ b/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/DeleteDraftDatasetButton.spec.tsx @@ -83,7 +83,7 @@ describe('DeleteDraftDatasetButton', () => { cy.findByRole('button', { name: 'Delete Dataset' }).click() cy.findByRole('dialog').should('exist') - cy.findByText(/Are you sure you want to delete this draft version?/i).should('exist') + cy.findByText(/Are you sure you want to delete this dataset\?/i).should('exist') }) it('closes confirmation modal when cancel is clicked', () => { @@ -118,6 +118,26 @@ describe('DeleteDraftDatasetButton', () => { cy.findByRole('dialog').should('exist') cy.findByRole('button', { name: 'Delete' }).click() cy.findByRole('dialog').should('not.exist') + cy.findByText(/The dataset has been deleted./).should('exist') + }) + + it('shows draft-specific messaging and toast when a released dataset draft is deleted', () => { + repository.deleteDatasetDraft = cy.stub().resolves() + cy.customMount( + + ) + + cy.findByRole('button', { name: 'Delete Draft Version' }).click() + cy.findByRole('dialog').should('exist') + cy.findByText(/Are you sure you want to delete this draft version\?/i).should('exist') + cy.findByRole('button', { name: 'Delete' }).click() cy.findByText(/The dataset draft has been deleted./).should('exist') }) From 61d2fc318c9eaef478d9d9eb39a70c222fd16ad8 Mon Sep 17 00:00:00 2001 From: Cheng Shi Date: Fri, 30 Jan 2026 18:15:13 -0500 Subject: [PATCH 05/62] fix: lint error --- .../delete-draft-dataset/ConfirmDeleteDraftDatasetModal.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sections/dataset/dataset-action-buttons/edit-dataset-menu/delete-draft-dataset/ConfirmDeleteDraftDatasetModal.tsx b/src/sections/dataset/dataset-action-buttons/edit-dataset-menu/delete-draft-dataset/ConfirmDeleteDraftDatasetModal.tsx index 255b9d307..4c8b5335b 100644 --- a/src/sections/dataset/dataset-action-buttons/edit-dataset-menu/delete-draft-dataset/ConfirmDeleteDraftDatasetModal.tsx +++ b/src/sections/dataset/dataset-action-buttons/edit-dataset-menu/delete-draft-dataset/ConfirmDeleteDraftDatasetModal.tsx @@ -42,8 +42,7 @@ export const ConfirmDeleteDraftDatasetModal = ({ - {' '} - {modalMessage} + {modalMessage} {errorDeletingDataset && ( From c8fd95f10c219280f6fa21c7cfa4c236e64f2276 Mon Sep 17 00:00:00 2001 From: Cheng Shi Date: Fri, 30 Jan 2026 19:50:16 -0500 Subject: [PATCH 06/62] fix: test error --- .../edit-dataset-menu/EditDatasetMenu.spec.tsx | 4 ++-- tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/EditDatasetMenu.spec.tsx b/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/EditDatasetMenu.spec.tsx index a78f3cdc9..0737f5c17 100644 --- a/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/EditDatasetMenu.spec.tsx +++ b/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/EditDatasetMenu.spec.tsx @@ -203,9 +203,9 @@ describe('EditDatasetMenu', () => { ) cy.findByRole('button', { name: 'Edit Dataset' }).click() cy.findByRole('button', { name: /Delete/ }).click() - cy.findByText(/Are you sure you want to delete this draft version?/i).should('exist') + cy.findByText(/Are you sure you want to delete this dataset\?/i).should('exist') cy.findByRole('button', { name: 'Delete' }).click() - cy.findByText(/The dataset draft has been deleted./).should('exist') + cy.findByText(/The dataset has been deleted./).should('exist') const searchParams = new URLSearchParams({ [QueryParamKey.PERSISTENT_ID]: dataset.persistentId, diff --git a/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx b/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx index 4f28146df..a3e22dbc9 100644 --- a/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx +++ b/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx @@ -304,9 +304,9 @@ describe('Dataset', () => { cy.findByRole('button', { name: 'Edit Dataset' }).should('exist').click() cy.findByRole('button', { name: 'Delete Dataset' }).should('exist').click() - cy.findByText(/Are you sure you want to delete this draft version?/i).should('exist') + cy.findByText(/Are you sure you want to delete this dataset\?/i).should('exist') cy.findByRole('button', { name: 'Delete' }).should('exist').click() - cy.findByText(/The dataset draft has been deleted./i).should('exist') + cy.findByText(/The dataset has been deleted./i).should('exist') }) }) }) From b7d74cc4fcf86f72c621ee3afe38917f7313239f Mon Sep 17 00:00:00 2001 From: Cheng Shi <91049239+ChengShi-1@users.noreply.github.com> Date: Fri, 6 Feb 2026 14:13:57 -0500 Subject: [PATCH 07/62] Update public/locales/en/dataset.json Co-authored-by: Ellen Kraffmiller --- public/locales/en/dataset.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/locales/en/dataset.json b/public/locales/en/dataset.json index d23399b5b..ec0a5f4d0 100644 --- a/public/locales/en/dataset.json +++ b/public/locales/en/dataset.json @@ -68,7 +68,7 @@ }, "deleteDatasetModal": { "title": "Delete Dataset", - "messageDraft": "Are you sure you want to delete this draft version? You cannot undelete this draft.", + "messageDraft": "Are you sure you want to delete this draft version? Files will be reverted to the most recently published version. You cannot undelete this draft.", "messageDataset": "Are you sure you want to delete this dataset? You cannot undelete this dataset.", "defaultDatasetDeleteError": "An error occurred while deleting the dataset." } From 577e79c4b90714f59fe4241aa1df85cece4debb9 Mon Sep 17 00:00:00 2001 From: Cheng Shi Date: Fri, 6 Feb 2026 16:27:11 -0500 Subject: [PATCH 08/62] feat: upload limit intergation --- package-lock.json | 8 +- package.json | 2 +- public/locales/en/shared.json | 3 + public/locales/es/shared.json | 3 + .../domain/models/DatasetUploadLimits.ts | 4 + .../domain/useCases/getDatasetUploadLimits.ts | 8 ++ .../file-upload-input/FileUploadInput.tsx | 25 +++++++ .../file-upload-input/useUploadLimit.ts | 65 +++++++++++++++++ .../FileUploadInputUploadLimits.spec.tsx | 73 +++++++++++++++++++ .../file-uploader/useUploadLimit.spec.tsx | 43 +++++++++++ 10 files changed, 229 insertions(+), 5 deletions(-) create mode 100644 src/dataset/domain/models/DatasetUploadLimits.ts create mode 100644 src/dataset/domain/useCases/getDatasetUploadLimits.ts create mode 100644 src/sections/shared/file-uploader/file-upload-input/useUploadLimit.ts create mode 100644 tests/component/sections/shared/file-uploader/FileUploadInputUploadLimits.spec.tsx create mode 100644 tests/component/sections/shared/file-uploader/useUploadLimit.spec.tsx diff --git a/package-lock.json b/package-lock.json index cf249ad1d..f63cd72ab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@dnd-kit/sortable": "8.0.0", "@dnd-kit/utilities": "3.2.2", "@faker-js/faker": "7.6.0", - "@iqss/dataverse-client-javascript": "2.0.0-alpha.85", + "@iqss/dataverse-client-javascript": "v2.1.0-pr421.6d795bb", "@iqss/dataverse-design-system": "*", "@istanbuljs/nyc-config-typescript": "1.0.2", "@tanstack/react-table": "8.9.2", @@ -1954,9 +1954,9 @@ }, "node_modules/@iqss/dataverse-client-javascript": { "name": "@IQSS/dataverse-client-javascript", - "version": "2.0.0-alpha.85", - "resolved": "https://npm.pkg.github.com/download/@IQSS/dataverse-client-javascript/2.0.0-alpha.85/9f7d8be5c1fbe022c11fcc6d956bbf1cc4821776", - "integrity": "sha512-2aEA0MdkhFjugxImJ3a334jlVbwmNMDVsFXnwPutbbkqn89UMXClMxADkqlmLQ3/4dOMtOrdVDitxYsYmYZ6RQ==", + "version": "2.1.0-pr421.6d795bb", + "resolved": "https://npm.pkg.github.com/download/@IQSS/dataverse-client-javascript/2.1.0-pr421.6d795bb/f4fcb31c1f3f1fe4fd84c3f81bdab8d00555d83a", + "integrity": "sha512-EGWgECeBuemUswYnxgJiZtVw+XVYC/V6R/mC4qtvFMsFwqBmvX84JBqgoEVUnLLJ1PHPd+oYEbmUgJt0Vqc0hg==", "license": "MIT", "dependencies": { "@types/node": "^18.15.11", diff --git a/package.json b/package.json index 3b8b27edf..4a647ea32 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "@dnd-kit/sortable": "8.0.0", "@dnd-kit/utilities": "3.2.2", "@faker-js/faker": "7.6.0", - "@iqss/dataverse-client-javascript": "2.0.0-alpha.85", + "@iqss/dataverse-client-javascript": "v2.1.0-pr421.6d795bb", "@iqss/dataverse-design-system": "*", "@istanbuljs/nyc-config-typescript": "1.0.2", "@tanstack/react-table": "8.9.2", diff --git a/public/locales/en/shared.json b/public/locales/en/shared.json index d4dbc4e26..e00b67b0b 100644 --- a/public/locales/en/shared.json +++ b/public/locales/en/shared.json @@ -220,6 +220,9 @@ "selectFileMultiple": "Select files to add", "dragDropSingle": "Drag and drop file here.", "dragDropMultiple": "Drag and drop files and/or directories here.", + "uploadWidgetHelp": "Select files or drag and drop into the upload widget. Maximum of {{maxFilesPerUpload}} files per upload.", + "uploadWidgetMaxFilesHelp": "Maximum of {{maxFilesAvailableToUpload}} files available to upload.", + "uploadWidgetStorageQuotaHelp": "Storage quota: {{storageQuotaRemaining}} remaining.", "cancelUpload": "Cancel upload", "uploadFailed": "There was an error uploading this file.", "loadingConfiguration": "Loading configuration", diff --git a/public/locales/es/shared.json b/public/locales/es/shared.json index a3010a550..d22e10dcd 100644 --- a/public/locales/es/shared.json +++ b/public/locales/es/shared.json @@ -220,6 +220,9 @@ "selectFileMultiple": "Seleccionar ficheros para agregar", "dragDropSingle": "Arrastra y suelta el fichero aquí.", "dragDropMultiple": "Arrastra y suelta ficheros y/o directorios aquí.", + "uploadWidgetHelp": "Selecciona ficheros o arrástralos y suéltalos en el widget de carga. Máximo de {{maxFilesPerUpload}} ficheros por carga.", + "uploadWidgetMaxFilesHelp": "Máximo de {{maxFilesAvailableToUpload}} ficheros disponibles para cargar.", + "uploadWidgetStorageQuotaHelp": "Cuota de almacenamiento: {{storageQuotaRemaining}} restantes.", "cancelUpload": "Cancelar carga", "uploadFailed": "Ocurrió un error al cargar este fichero.", "loadingConfiguration": "Cargando configuración", diff --git a/src/dataset/domain/models/DatasetUploadLimits.ts b/src/dataset/domain/models/DatasetUploadLimits.ts new file mode 100644 index 000000000..6dbf22205 --- /dev/null +++ b/src/dataset/domain/models/DatasetUploadLimits.ts @@ -0,0 +1,4 @@ +export interface DatasetUploadLimits { + numberOfFilesRemaining?: number + storageQuotaRemaining?: number +} diff --git a/src/dataset/domain/useCases/getDatasetUploadLimits.ts b/src/dataset/domain/useCases/getDatasetUploadLimits.ts new file mode 100644 index 000000000..e28bbebe4 --- /dev/null +++ b/src/dataset/domain/useCases/getDatasetUploadLimits.ts @@ -0,0 +1,8 @@ +import { getDatasetUploadLimits as jsGetDatasetUploadLimits } from '@iqss/dataverse-client-javascript' +import { DatasetUploadLimits } from '../models/DatasetUploadLimits' + +export async function getDatasetUploadLimits( + datasetId: string | number +): Promise { + return jsGetDatasetUploadLimits.execute(datasetId) +} diff --git a/src/sections/shared/file-uploader/file-upload-input/FileUploadInput.tsx b/src/sections/shared/file-uploader/file-upload-input/FileUploadInput.tsx index e24995e0c..b1bf0c072 100644 --- a/src/sections/shared/file-uploader/file-upload-input/FileUploadInput.tsx +++ b/src/sections/shared/file-uploader/file-upload-input/FileUploadInput.tsx @@ -14,6 +14,7 @@ import { OperationType } from '../FileUploader' import { FileUploaderHelper } from '../FileUploaderHelper' import { SwalModal } from '../../swal-modal/SwalModal' import styles from './FileUploadInput.module.scss' +import { useUploadLimit } from './useUploadLimit' type FileUploadInputProps = { fileRepository: FileRepository @@ -23,6 +24,8 @@ type FileUploadInputProps = { const limit = 6 const semaphore = new Semaphore(limit) +const maxFilesPerUpload = 1000 + const FileUploadInput = ({ fileRepository, datasetPersistentId }: FileUploadInputProps) => { const { fileUploaderState, @@ -44,6 +47,7 @@ const FileUploadInput = ({ fileRepository, datasetPersistentId }: FileUploadInpu const inputRef = useRef(null) const [isDragging, setIsDragging] = useState(false) + const { uploadLimit } = useUploadLimit(datasetPersistentId) const totalFiles = Object.keys(fileUploaderState.files).length @@ -267,6 +271,27 @@ const FileUploadInput = ({ fileRepository, datasetPersistentId }: FileUploadInpu {t('fileUploader.accordionTitle')} +

+ {t('fileUploader.uploadWidgetHelp', { + maxFilesPerUpload: maxFilesPerUpload.toLocaleString() + })} + {uploadLimit.maxFilesAvailableToUploadFormatted && ( + <> + {' '} + {t('fileUploader.uploadWidgetMaxFilesHelp', { + maxFilesAvailableToUpload: uploadLimit.maxFilesAvailableToUploadFormatted + })} + + )} + {uploadLimit.storageQuotaRemainingFormatted && ( + <> + {' '} + {t('fileUploader.uploadWidgetStorageQuotaHelp', { + storageQuotaRemaining: uploadLimit.storageQuotaRemainingFormatted + })} + + )} +

diff --git a/src/sections/settings/SettingsProvider.tsx b/src/sections/settings/SettingsProvider.tsx index ce77eeb0a..3f470e09e 100644 --- a/src/sections/settings/SettingsProvider.tsx +++ b/src/sections/settings/SettingsProvider.tsx @@ -4,6 +4,8 @@ import { Setting, SettingName } from '../../settings/domain/models/Setting' import { DataverseInfoRepository } from '@/info/domain/repositories/DataverseInfoRepository' import { getZipDownloadLimit } from '@/info/domain/useCases/getZipDownloadLimit' import { getMaxEmbargoDurationInMonths } from '@/info/domain/useCases/getMaxEmbargoDurationInMonths' +import { getPublishDatasetDisclaimerText } from '@/info/domain/useCases/getPublishDatasetDisclaimerText' +import { getDatasetPublishPopupCustomText } from '@/info/domain/useCases/getDatasetPublishPopupCustomText' import { getHasPublicStore } from '@/info/domain/useCases/getHasPublicStore' import { getExternalStatusesAllowed } from '@/info/domain/useCases/getExternalStatusesAllowed' import { AppLoader } from '../shared/layout/app-loader/AppLoader' @@ -26,7 +28,9 @@ export function SettingsProvider({ getZipDownloadLimit(dataverseInfoRepository), getMaxEmbargoDurationInMonths(dataverseInfoRepository), getHasPublicStore(dataverseInfoRepository), - getExternalStatusesAllowed(dataverseInfoRepository) + getExternalStatusesAllowed(dataverseInfoRepository), + getDatasetPublishPopupCustomText(dataverseInfoRepository), + getPublishDatasetDisclaimerText(dataverseInfoRepository) ]) setSettings(settingsResponse) diff --git a/src/settings/domain/models/Setting.ts b/src/settings/domain/models/Setting.ts index 5492848a8..6ee0ff3af 100644 --- a/src/settings/domain/models/Setting.ts +++ b/src/settings/domain/models/Setting.ts @@ -2,7 +2,9 @@ export enum SettingName { ZIP_DOWNLOAD_LIMIT = 'ZIP_DOWNLOAD_LIMIT', ALLOWED_EXTERNAL_STATUSES = 'ALLOWED_EXTERNAL_STATUSES', HAS_PUBLIC_STORE = 'HAS_PUBLIC_STORE', - MAX_EMBARGO_DURATION_IN_MONTHS = 'MAX_EMBARGO_DURATION_IN_MONTHS' + MAX_EMBARGO_DURATION_IN_MONTHS = 'MAX_EMBARGO_DURATION_IN_MONTHS', + PUBLISH_DATASET_DISCLAIMER_TEXT = 'PUBLISH_DATASET_DISCLAIMER_TEXT', + DATASET_PUBLISH_POPUP_CUSTOM_TEXT = 'DATASET_PUBLISH_POPUP_CUSTOM_TEXT' } export interface Setting { diff --git a/src/stories/WithSettings.tsx b/src/stories/WithSettings.tsx index f025eccbf..059b57b8b 100644 --- a/src/stories/WithSettings.tsx +++ b/src/stories/WithSettings.tsx @@ -25,6 +25,17 @@ export const WithSettings = (Story: StoryFn) => { case SettingName.MAX_EMBARGO_DURATION_IN_MONTHS: return SettingMother.createMaxEmbargoDurationInMonths(-1) as Setting + case SettingName.DATASET_PUBLISH_POPUP_CUSTOM_TEXT: + return SettingMother.createDatasetPublishPopupCustomText( + 'This is custom text for the dataset publish popup.' + ) as Setting + case SettingName.PUBLISH_DATASET_DISCLAIMER_TEXT: + return SettingMother.createPublishDatasetDisclaimerText( + 'This is custom text for the publish dataset disclaimer.' + ) as Setting + + default: + throw new Error(`No mock implementation for setting`) } } diff --git a/src/stories/shared-mock-repositories/info/DataverseInfoMockErrorRepository.ts b/src/stories/shared-mock-repositories/info/DataverseInfoMockErrorRepository.ts index 7ad95ecd3..9ffe94f07 100644 --- a/src/stories/shared-mock-repositories/info/DataverseInfoMockErrorRepository.ts +++ b/src/stories/shared-mock-repositories/info/DataverseInfoMockErrorRepository.ts @@ -61,4 +61,18 @@ export class DataverseInfoMockErrorRepository implements DataverseInfoMockReposi }, FakerHelper.loadingTimout()) }) } + getPublishDatasetDisclaimerText(): Promise> { + return new Promise((_resolve, reject) => { + setTimeout(() => { + reject() + }, FakerHelper.loadingTimout()) + }) + } + getDatasetPublishPopupCustomText(): Promise> { + return new Promise((_resolve, reject) => { + setTimeout(() => { + reject() + }, FakerHelper.loadingTimout()) + }) + } } diff --git a/src/stories/shared-mock-repositories/info/DataverseInfoMockLoadingkRepository.ts b/src/stories/shared-mock-repositories/info/DataverseInfoMockLoadingkRepository.ts index 4e3df43cd..f71384749 100644 --- a/src/stories/shared-mock-repositories/info/DataverseInfoMockLoadingkRepository.ts +++ b/src/stories/shared-mock-repositories/info/DataverseInfoMockLoadingkRepository.ts @@ -33,4 +33,10 @@ export class DataverseInfoMockLoadingRepository implements DataverseInfoMockRepo getAvailableDatasetMetadataExportFormats(): Promise { return new Promise(() => {}) } + getPublishDatasetDisclaimerText(): Promise> { + return new Promise(() => {}) + } + getDatasetPublishPopupCustomText(): Promise> { + return new Promise(() => {}) + } } diff --git a/src/stories/shared-mock-repositories/info/DataverseInfoMockRepository.ts b/src/stories/shared-mock-repositories/info/DataverseInfoMockRepository.ts index 174e31b30..8b5d48b72 100644 --- a/src/stories/shared-mock-repositories/info/DataverseInfoMockRepository.ts +++ b/src/stories/shared-mock-repositories/info/DataverseInfoMockRepository.ts @@ -75,4 +75,18 @@ export class DataverseInfoMockRepository implements DataverseInfoRepository { }, FakerHelper.loadingTimout()) }) } + getPublishDatasetDisclaimerText(): Promise> { + return new Promise((resolve) => { + setTimeout(() => { + resolve(SettingMother.createPublishDatasetDisclaimerText()) + }, FakerHelper.loadingTimout()) + }) + } + getDatasetPublishPopupCustomText(): Promise> { + return new Promise((resolve) => { + setTimeout(() => { + resolve(SettingMother.createDatasetPublishPopupCustomText()) + }, FakerHelper.loadingTimout()) + }) + } } diff --git a/tests/component/settings/domain/models/SettingMother.ts b/tests/component/settings/domain/models/SettingMother.ts index ef8f1924b..626f7cd2b 100644 --- a/tests/component/settings/domain/models/SettingMother.ts +++ b/tests/component/settings/domain/models/SettingMother.ts @@ -36,4 +36,17 @@ export class SettingMother { value: value ? value : faker.datatype.number() } } + static createDatasetPublishPopupCustomText(value?: string): Setting { + return { + name: SettingName.DATASET_PUBLISH_POPUP_CUSTOM_TEXT, + value: value ? value : faker.lorem.sentence() + } + } + + static createPublishDatasetDisclaimerText(value?: string): Setting { + return { + name: SettingName.PUBLISH_DATASET_DISCLAIMER_TEXT, + value: value ? value : faker.lorem.sentence() + } + } } From 444b3c1c18f2d9bae79143cf3c7e97947ea3c04a Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Fri, 13 Feb 2026 10:22:26 -0500 Subject: [PATCH 17/62] refactor tests to remove duplicate code --- .../PublishDatasetModal.spec.tsx | 297 ++++++++---------- 1 file changed, 123 insertions(+), 174 deletions(-) diff --git a/tests/component/sections/dataset/dataset-publish/PublishDatasetModal.spec.tsx b/tests/component/sections/dataset/dataset-publish/PublishDatasetModal.spec.tsx index 6b0a9c59b..b423c2f12 100644 --- a/tests/component/sections/dataset/dataset-publish/PublishDatasetModal.spec.tsx +++ b/tests/component/sections/dataset/dataset-publish/PublishDatasetModal.spec.tsx @@ -6,26 +6,66 @@ import { UpwardHierarchyNodeMother } from '../../../shared/hierarchy/domain/mode import { CustomTermsMother } from '@tests/component/dataset/domain/models/TermsOfUseMother' import { LicenseMother } from '@tests/component/dataset/domain/models/LicenseMother' +// Small helpers to keep tests focused on behavior (not setup boilerplate). +const TEST_PERSISTENT_ID = 'testPersistentId' + +type CreateRepositoryOptions = { + publish?: sinon.SinonStub +} + +const createDatasetRepository = (options: CreateRepositoryOptions = {}) => { + const repository = {} as DatasetRepository + repository.publish = options.publish ?? cy.stub().as('repositoryPublish').resolves() + return repository +} + +const createCollectionRepository = (options: CreateRepositoryOptions = {}) => { + const collectionRepository = {} as CollectionRepository + collectionRepository.publish = + options.publish ?? cy.stub().as('collectionRepositoryPublish').resolves() + return collectionRepository +} + +type MountOptions = { + mountAs?: 'authenticated' | 'superuser' + repository?: DatasetRepository + collectionRepository?: CollectionRepository + parentCollection?: ReturnType + handleClose?: sinon.SinonStub + props?: Partial> +} + +const mountPublishDatasetModal = ({ + mountAs = 'authenticated', + repository = createDatasetRepository(), + collectionRepository = createCollectionRepository(), + parentCollection = UpwardHierarchyNodeMother.createCollection(), + handleClose = cy.stub(), + props = {} +}: MountOptions = {}) => { + const mountFn = mountAs === 'superuser' ? cy.mountSuperuser : cy.mountAuthenticated + + mountFn( + + ) + + return { repository, collectionRepository, parentCollection, handleClose } +} + describe('PublishDatasetModal', () => { it('display modal for never released dataset', () => { - const handleClose = cy.stub() - const repository = {} as DatasetRepository // Mock the repository as needed - repository.publish = cy.stub().as('repositoryPublish').resolves() - const collectionRepository = {} as CollectionRepository - collectionRepository.publish = cy.stub().as('collectionRepositoryPublish').resolves() - const parentCollection = UpwardHierarchyNodeMother.createCollection() - cy.mountAuthenticated( - - ) + mountPublishDatasetModal() + cy.findByText('Publish Dataset').should('exist') cy.findByText( 'Are you sure you want to publish this dataset? Once you do so, it must remain published.' @@ -37,31 +77,18 @@ describe('PublishDatasetModal', () => { cy.findByText('Continue').click() cy.get('@repositoryPublish').should( 'have.been.calledWith', - 'testPersistentId', + TEST_PERSISTENT_ID, VersionUpdateType.MAJOR ) }) it('displays an error message when publishDataset fails', () => { - const handleClose = cy.stub() - const repository = {} as DatasetRepository // Mock the repository as needed const errorMessage = 'Publishing failed' - repository.publish = cy.stub().as('repositoryPublish').rejects(new Error(errorMessage)) - const collectionRepository = {} as CollectionRepository - collectionRepository.publish = cy.stub().as('collectionRepositoryPublish').resolves() - const parentCollection = UpwardHierarchyNodeMother.createCollection() - cy.mountAuthenticated( - - ) + const repository = createDatasetRepository({ + publish: cy.stub().as('repositoryPublish').rejects(new Error(errorMessage)) + }) + + mountPublishDatasetModal({ repository }) // Trigger the Publish action cy.findByText('Continue').click() @@ -69,27 +96,14 @@ describe('PublishDatasetModal', () => { // Check if the error message is displayed cy.contains(errorMessage).should('exist') }) + it('displays an error message when publishCollection fails', () => { - const handleClose = cy.stub() - const repository = {} as DatasetRepository // Mock the repository as needed - const collectionRepository = {} as CollectionRepository - collectionRepository.publish = cy - .stub() - .as('collectionRepositoryPublish') - .rejects(new Error('collection error')) + const collectionRepository = createCollectionRepository({ + publish: cy.stub().as('collectionRepositoryPublish').rejects(new Error('collection error')) + }) const parentCollection = UpwardHierarchyNodeMother.createCollection({ isReleased: false }) - cy.mountAuthenticated( - - ) + + mountPublishDatasetModal({ collectionRepository, parentCollection }) // Trigger the Publish action cy.findByText('Continue').click() @@ -97,27 +111,15 @@ describe('PublishDatasetModal', () => { // Check if the error message is displayed cy.contains('collection error').should('exist') }) + it('renders the PublishDatasetModal for previously released dataset and triggers submitPublish on button click', () => { - const handleClose = cy.stub() - const repository = {} as DatasetRepository // Mock the repository as needed - repository.publish = cy.stub().as('repositoryPublish').resolves() - const collectionRepository = {} as CollectionRepository - collectionRepository.publish = cy.stub().as('collectionRepositoryPublish').resolves() - const parentCollection = UpwardHierarchyNodeMother.createCollection() - cy.mountAuthenticated( - - ) + mountPublishDatasetModal({ + props: { + releasedVersionExists: true, + nextMajorVersion: '2.0', + nextMinorVersion: '1.1' + } + }) // Check if the modal is rendered cy.findByText('Publish Dataset').should('exist') @@ -126,80 +128,45 @@ describe('PublishDatasetModal', () => { cy.findByText('Continue').click() cy.get('@repositoryPublish').should( 'have.been.calledWith', - 'testPersistentId', + TEST_PERSISTENT_ID, VersionUpdateType.MAJOR ) }) it('renders the third radio button when user.superuser is true', () => { - const handleClose = cy.stub() - const repository = {} as DatasetRepository // Mock the repository as needed - repository.publish = cy.stub().as('repositoryPublish').resolves() - const collectionRepository = {} as CollectionRepository - collectionRepository.publish = cy.stub().as('collectionRepositoryPublish').resolves() - const parentCollection = UpwardHierarchyNodeMother.createCollection() - cy.mountSuperuser( - - ) + mountPublishDatasetModal({ + mountAs: 'superuser', + props: { + releasedVersionExists: true, + nextMajorVersion: '2.0', + nextMinorVersion: '1.1' + } + }) + cy.findByText(/Update Current Version/).should('exist') }) it('does not display the third radio button when user.superuser is false', () => { - const handleClose = cy.stub() - const repository = {} as DatasetRepository // Mock the repository as needed - repository.publish = cy.stub().as('repositoryPublish').resolves() - const collectionRepository = {} as CollectionRepository - collectionRepository.publish = cy.stub().as('collectionRepositoryPublish').resolves() - const parentCollection = UpwardHierarchyNodeMother.createCollection() - cy.mountAuthenticated( - - ) + mountPublishDatasetModal({ + props: { + releasedVersionExists: true, + nextMajorVersion: '2.0', + nextMinorVersion: '1.1' + } + }) + cy.findByText(/Update Current Version/).should('not.exist') }) + it('renders the PublishDatasetModal for previously released dataset that requires major version update', () => { - const handleClose = cy.stub() - const repository = {} as DatasetRepository // Mock the repository as needed - repository.publish = cy.stub().as('repositoryPublish').resolves() - const collectionRepository = {} as CollectionRepository - collectionRepository.publish = cy.stub().as('collectionRepositoryPublish').resolves() - const parentCollection = UpwardHierarchyNodeMother.createCollection() - cy.mountAuthenticated( - - ) + mountPublishDatasetModal({ + props: { + releasedVersionExists: true, + nextMajorVersion: '2.0', + requiresMajorVersionUpdate: true, + nextMinorVersion: '1.1' + } + }) // Check if the modal is rendered cy.findByText('Publish Dataset').should('exist') @@ -211,30 +178,21 @@ describe('PublishDatasetModal', () => { cy.findByText('Continue').click() cy.get('@repositoryPublish').should( 'have.been.calledWith', - 'testPersistentId', + TEST_PERSISTENT_ID, VersionUpdateType.MAJOR ) }) it('Displays warning text for unreleased Collection', () => { - const handleClose = cy.stub() - const repository = {} as DatasetRepository // Mock the repository as needed - repository.publish = cy.stub().as('repositoryPublish').resolves() - const collectionRepository = {} as CollectionRepository - collectionRepository.publish = cy.stub().as('collectionRepositoryPublish').resolves() const parentCollection = UpwardHierarchyNodeMother.createCollection({ isReleased: false }) - cy.mountAuthenticated( - - ) + + mountPublishDatasetModal({ + parentCollection, + props: { + releasedVersionExists: false + } + }) + cy.findByText(/This dataset cannot be published until/).should('exist') cy.findByRole('link', { name: parentCollection.name }).should('exist') cy.findByRole('link', { name: parentCollection.name }) @@ -243,25 +201,16 @@ describe('PublishDatasetModal', () => { }) it('Displays custom terms when license is undefined', () => { - const handleClose = cy.stub() - const repository = {} as DatasetRepository // Mock the repository as needed - repository.publish = cy.stub().as('repositoryPublish').resolves() - const collectionRepository = {} as CollectionRepository - collectionRepository.publish = cy.stub().as('collectionRepositoryPublish').resolves() const parentCollection = UpwardHierarchyNodeMother.createCollection({ isReleased: false }) - cy.mountAuthenticated( - - ) + + mountPublishDatasetModal({ + parentCollection, + props: { + license: undefined, + customTerms: CustomTermsMother.create() + } + }) + cy.findByText(/Custom Dataset Terms/).should('exist') }) }) From 2cac7e904cad754d82d04914eded7b4d74b13a6f Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Fri, 13 Feb 2026 11:18:15 -0500 Subject: [PATCH 18/62] add tests for disclaimer text and custom text --- .../PublishDatasetModal.spec.tsx | 77 +++++++++++++++---- 1 file changed, 64 insertions(+), 13 deletions(-) diff --git a/tests/component/sections/dataset/dataset-publish/PublishDatasetModal.spec.tsx b/tests/component/sections/dataset/dataset-publish/PublishDatasetModal.spec.tsx index b423c2f12..0313e000b 100644 --- a/tests/component/sections/dataset/dataset-publish/PublishDatasetModal.spec.tsx +++ b/tests/component/sections/dataset/dataset-publish/PublishDatasetModal.spec.tsx @@ -5,7 +5,10 @@ import { CollectionRepository } from '../../../../../src/collection/domain/repos import { UpwardHierarchyNodeMother } from '../../../shared/hierarchy/domain/models/UpwardHierarchyNodeMother' import { CustomTermsMother } from '@tests/component/dataset/domain/models/TermsOfUseMother' import { LicenseMother } from '@tests/component/dataset/domain/models/LicenseMother' - +import { SettingsProvider } from '../../../../../src/sections/settings/SettingsProvider' +import { SettingMother } from '@tests/component/settings/domain/models/SettingMother' +import { DataverseInfoMockRepository } from '@/stories/shared-mock-repositories/info/DataverseInfoMockRepository' +import { DataverseInfoRepository } from '@/info/domain/repositories/DataverseInfoRepository' // Small helpers to keep tests focused on behavior (not setup boilerplate). const TEST_PERSISTENT_ID = 'testPersistentId' @@ -32,6 +35,7 @@ type MountOptions = { collectionRepository?: CollectionRepository parentCollection?: ReturnType handleClose?: sinon.SinonStub + dataverseInfoRepository?: DataverseInfoRepository props?: Partial> } @@ -40,23 +44,30 @@ const mountPublishDatasetModal = ({ repository = createDatasetRepository(), collectionRepository = createCollectionRepository(), parentCollection = UpwardHierarchyNodeMother.createCollection(), + dataverseInfoRepository, handleClose = cy.stub(), props = {} }: MountOptions = {}) => { const mountFn = mountAs === 'superuser' ? cy.mountSuperuser : cy.mountAuthenticated - + const dataverseInfoWithoutCustomText = new DataverseInfoMockRepository() + dataverseInfoWithoutCustomText.getDatasetPublishPopupCustomText = cy.stub().resolves('') + dataverseInfoWithoutCustomText.getPublishDatasetDisclaimerText = cy.stub().resolves('') + const resolvedDataverseInfoRepository = dataverseInfoRepository ?? dataverseInfoWithoutCustomText + console.log(resolvedDataverseInfoRepository.getPublishDatasetDisclaimerText()) mountFn( - + + + ) return { repository, collectionRepository, parentCollection, handleClose } @@ -213,4 +224,44 @@ describe('PublishDatasetModal', () => { cy.findByText(/Custom Dataset Terms/).should('exist') }) + it('Displays disclaimer text from settings', () => { + const dataverseInfoRepository = new DataverseInfoMockRepository() + const disclaimerText = 'This is custom text for the dataset publish popup.' + + dataverseInfoRepository.getPublishDatasetDisclaimerText = cy + .stub() + .resolves(SettingMother.createPublishDatasetDisclaimerText(disclaimerText)) + + mountPublishDatasetModal({ dataverseInfoRepository }) + + cy.findByText(disclaimerText).should('exist') + }) + it('Displays disables the continue button until the user checks the disclaimer text', () => { + const dataverseInfoRepository = new DataverseInfoMockRepository() + const disclaimerText = 'This is disclaimer text for the dataset publish popup.' + + dataverseInfoRepository.getPublishDatasetDisclaimerText = cy + .stub() + .resolves(SettingMother.createPublishDatasetDisclaimerText(disclaimerText)) + mountPublishDatasetModal({ dataverseInfoRepository }) + + cy.findByText(disclaimerText).should('exist') + cy.findByRole('button', { name: 'Continue' }).should('be.disabled') + cy.findByRole('checkbox', { name: disclaimerText }).click() + cy.findByRole('button', { name: 'Continue' }).should('not.be.disabled') + }) + it('Displays the custom popup text if it is available', () => { + const dataverseInfoRepository = new DataverseInfoMockRepository() + const popupText = 'This is custom text for the popup.' + + dataverseInfoRepository.getDatasetPublishPopupCustomText = cy + .stub() + .resolves(SettingMother.createDatasetPublishPopupCustomText(popupText)) + dataverseInfoRepository.getPublishDatasetDisclaimerText = cy.stub().resolves('') + + mountPublishDatasetModal({ dataverseInfoRepository }) + + cy.findByText(popupText).should('exist') + cy.findByRole('button', { name: 'Continue' }).should('not.be.disabled') + }) }) From 6631f0fbcc63284dd57ab56292809b8d54d5509b Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Fri, 13 Feb 2026 11:21:48 -0500 Subject: [PATCH 19/62] fix comments and remove logs --- .../dataset/dataset-publish/PublishDatasetModal.spec.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/component/sections/dataset/dataset-publish/PublishDatasetModal.spec.tsx b/tests/component/sections/dataset/dataset-publish/PublishDatasetModal.spec.tsx index 0313e000b..2257c4692 100644 --- a/tests/component/sections/dataset/dataset-publish/PublishDatasetModal.spec.tsx +++ b/tests/component/sections/dataset/dataset-publish/PublishDatasetModal.spec.tsx @@ -9,7 +9,7 @@ import { SettingsProvider } from '../../../../../src/sections/settings/SettingsP import { SettingMother } from '@tests/component/settings/domain/models/SettingMother' import { DataverseInfoMockRepository } from '@/stories/shared-mock-repositories/info/DataverseInfoMockRepository' import { DataverseInfoRepository } from '@/info/domain/repositories/DataverseInfoRepository' -// Small helpers to keep tests focused on behavior (not setup boilerplate). + const TEST_PERSISTENT_ID = 'testPersistentId' type CreateRepositoryOptions = { @@ -53,7 +53,7 @@ const mountPublishDatasetModal = ({ dataverseInfoWithoutCustomText.getDatasetPublishPopupCustomText = cy.stub().resolves('') dataverseInfoWithoutCustomText.getPublishDatasetDisclaimerText = cy.stub().resolves('') const resolvedDataverseInfoRepository = dataverseInfoRepository ?? dataverseInfoWithoutCustomText - console.log(resolvedDataverseInfoRepository.getPublishDatasetDisclaimerText()) + mountFn( { cy.findByText(disclaimerText).should('exist') }) - it('Displays disables the continue button until the user checks the disclaimer text', () => { + it('Disables the continue button until the user checks the disclaimer text', () => { const dataverseInfoRepository = new DataverseInfoMockRepository() const disclaimerText = 'This is disclaimer text for the dataset publish popup.' From 0fd3eed70daa02ecbae9311371769136850556b4 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Fri, 13 Feb 2026 13:26:00 -0500 Subject: [PATCH 20/62] add PublishDatasetModal stories --- src/stories/WithSettings.tsx | 1 - .../PublishDatasetModal.stories.tsx | 31 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/stories/WithSettings.tsx b/src/stories/WithSettings.tsx index 059b57b8b..c13051d31 100644 --- a/src/stories/WithSettings.tsx +++ b/src/stories/WithSettings.tsx @@ -33,7 +33,6 @@ export const WithSettings = (Story: StoryFn) => { return SettingMother.createPublishDatasetDisclaimerText( 'This is custom text for the publish dataset disclaimer.' ) as Setting - default: throw new Error(`No mock implementation for setting`) } diff --git a/src/stories/dataset/publish-dataset/PublishDatasetModal.stories.tsx b/src/stories/dataset/publish-dataset/PublishDatasetModal.stories.tsx index eea4ca804..501767a4a 100644 --- a/src/stories/dataset/publish-dataset/PublishDatasetModal.stories.tsx +++ b/src/stories/dataset/publish-dataset/PublishDatasetModal.stories.tsx @@ -8,6 +8,7 @@ import { CollectionMockRepository } from '@/stories/collection/CollectionMockRep import { UpwardHierarchyNodeMother } from '@tests/component/shared/hierarchy/domain/models/UpwardHierarchyNodeMother' import { CustomTermsMother } from '@tests/component/dataset/domain/models/TermsOfUseMother' import { LicenseMother } from '@tests/component/dataset/domain/models/LicenseMother' +import { WithSettings } from '@/stories/WithSettings' const meta: Meta = { title: 'Sections/Dataset Page/PublishDatasetModal', @@ -117,3 +118,33 @@ export const WithCustomTerms: Story = { handleClose={() => {}}> ) } +export const withTextSettings: Story = { + decorators: [WithLoggedInUser, WithSettings], + render: () => ( + {}}> + ) +} +export const withTextSettingsAndCustomTerms: Story = { + decorators: [WithLoggedInUser, WithSettings], + render: () => ( + {}}> + ) +} From b629f79badb9b904c25899228feff23fc568f075 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Fri, 13 Feb 2026 13:33:11 -0500 Subject: [PATCH 21/62] add container for custom popup text --- .../publish-dataset/PublishDatasetModal.module.scss | 13 +++++++++++++ .../dataset/publish-dataset/PublishDatasetModal.tsx | 4 +++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/sections/dataset/publish-dataset/PublishDatasetModal.module.scss b/src/sections/dataset/publish-dataset/PublishDatasetModal.module.scss index 9f6531aa5..698b07991 100644 --- a/src/sections/dataset/publish-dataset/PublishDatasetModal.module.scss +++ b/src/sections/dataset/publish-dataset/PublishDatasetModal.module.scss @@ -13,3 +13,16 @@ color: $dv-danger-color; } } + +.customPopupTextBlock { + border: 1px solid $dv-border-color; + background-color: #f8f9fa; + border-left: 4px solid $dv-primary-color; + padding: 0.75rem 1rem; + border-radius: 0.25rem; +} + +.customPopupText { + margin: 0; + color: $dv-text-color; +} diff --git a/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx b/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx index 54f99d71c..220aa06b1 100644 --- a/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx +++ b/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx @@ -119,7 +119,9 @@ export function PublishDatasetModal({ /> {shouldShowCustomPopupText && ( -

{datasetPublishPopupCustomText}

+
+

{datasetPublishPopupCustomText}

+
)} {releasedVersionExists && !requiresMajorVersionUpdate && ( From 26ded317e1edb82ed1eb348d11872051dc4be877 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Fri, 13 Feb 2026 13:36:41 -0500 Subject: [PATCH 22/62] update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f90edbeb..f0fee4cad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ This changelog follows the principles of [Keep a Changelog](https://keepachangel - Changed the way we were handling DATE type metadata field validation to better match the backend validation and give users better error messages. For example, for an input like “foo AD”, we now show “Production Date is not a valid date. The AD year must be numeric.“. For an input like “99999 AD”, we now show “Production Date is not a valid date. The AD year cant be higher than 9999.“. For an input like “[-9999?], we now show “Production Date is not a valid date. The year in brackets cannot be negative.“, etc. - The SPA now fetches the runtime configuration from `config.js` on each load, allowing configurations without rebuilding the app. We don't use `.env` variables at build time anymore. - Renamed dataset template fetch/create use cases and DTOs to `getTemplatesByCollectionId` and `CreateTemplateDTO` for API alignment, and added new `getTemplate` and `deleteTemplate` use cases for retrieving a single template by ID and deleting templates. +- Added disclaimer text and custom popup text to Publish Dataset modal for better communication of the implications of publishing a dataset. The text can be configured through the runtime configuration. ### Fixed From e00f434699ce070902aaeb9c627c6656e35cba98 Mon Sep 17 00:00:00 2001 From: Cheng Shi Date: Fri, 13 Feb 2026 13:53:52 -0500 Subject: [PATCH 23/62] fix: copilot reviews on usage.tsx --- src/sections/homepage/usage/Usage.tsx | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/sections/homepage/usage/Usage.tsx b/src/sections/homepage/usage/Usage.tsx index cc038ddd5..d4a4f6adb 100644 --- a/src/sections/homepage/usage/Usage.tsx +++ b/src/sections/homepage/usage/Usage.tsx @@ -10,20 +10,13 @@ interface UsageProps { collectionId: string } -interface AppConfig { - branding: { - dataverseName: string - } - homepage: { - supportUrl: string - } -} +const DEFAULT_SUPPORT_URL = 'https://guides.dataverse.org/en/latest/user/index.html' export const Usage = ({ collectionId }: UsageProps) => { const { t } = useTranslation('homepage', { keyPrefix: 'usage' }) - const appConfig = requireAppConfig() as AppConfig - const dataverseName = appConfig.branding.dataverseName ?? 'Dataverse' - const supportUrl = appConfig.homepage.supportUrl + const appConfig = requireAppConfig() + const dataverseName = appConfig.branding?.dataverseName ?? 'Dataverse' + const supportUrl = appConfig.homepage?.supportUrl ?? DEFAULT_SUPPORT_URL return ( From 4b83887b42decda219a5354de00a7528dec2ba31 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Fri, 13 Feb 2026 14:17:48 -0500 Subject: [PATCH 24/62] add stubs to dataverseInfoRepository in component tests --- .../dataset/dataset-files/files-table/FilesTable.spec.tsx | 2 ++ .../zip-download-limit-message/ZipDownloadLimitMessage.spec.tsx | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/component/sections/dataset/dataset-files/files-table/FilesTable.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/FilesTable.spec.tsx index 952f50bc6..380319ea6 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/FilesTable.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/FilesTable.spec.tsx @@ -207,6 +207,8 @@ describe('FilesTable', () => { dataverseInfoRepository.getHasPublicStore = cy.stub().resolves({}) dataverseInfoRepository.getExternalStatusesAllowed = cy.stub().resolves({}) dataverseInfoRepository.getMaxEmbargoDurationInMonths = cy.stub().resolves({}) + dataverseInfoRepository.getPublishDatasetDisclaimerText = cy.stub().resolves({}) + dataverseInfoRepository.getDatasetPublishPopupCustomText = cy.stub().resolves({}) cy.customMount( diff --git a/tests/component/sections/dataset/dataset-files/files-table/zip-download-limit-message/ZipDownloadLimitMessage.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/zip-download-limit-message/ZipDownloadLimitMessage.spec.tsx index 2a6f81425..efb9ad281 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/zip-download-limit-message/ZipDownloadLimitMessage.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/zip-download-limit-message/ZipDownloadLimitMessage.spec.tsx @@ -28,6 +28,8 @@ describe('ZipDownloadLimitMessage', () => { dataverseInfoRepository.getHasPublicStore = cy.stub().resolves({}) dataverseInfoRepository.getExternalStatusesAllowed = cy.stub().resolves({}) dataverseInfoRepository.getMaxEmbargoDurationInMonths = cy.stub().resolves({}) + dataverseInfoRepository.getPublishDatasetDisclaimerText = cy.stub().resolves({}) + dataverseInfoRepository.getDatasetPublishPopupCustomText = cy.stub().resolves({}) }) it('should not render if there is less than 1 file selected', () => { From 0fcc465ae0d1f2c76d55858e37a32f25ebe65ad5 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Fri, 13 Feb 2026 16:55:21 -0500 Subject: [PATCH 25/62] refactor: use DataverseInfoMockEmptyRepository in component tests --- .../publish-dataset/PublishDatasetModal.tsx | 4 +- .../info/DataverseInfoMockEmptyRepository.ts | 86 +++++++++++++++++++ ...lableDatasetMetadataExportFormats.spec.tsx | 3 +- .../EditDatasetPermissionsMenu.spec.tsx | 11 +-- .../ChangeCurationStatusMenu.spec.tsx | 8 +- .../PublishDatasetMenu.spec.tsx | 10 +-- .../dataset-files/DatasetFiles.spec.tsx | 4 +- .../DatasetFilesScrollable.spec.tsx | 4 +- .../files-table/FilesTable.spec.tsx | 10 +-- .../ZipDownloadLimitMessage.spec.tsx | 9 +- .../sections/layout/footer/Footer.spec.tsx | 7 +- 11 files changed, 110 insertions(+), 46 deletions(-) create mode 100644 src/stories/shared-mock-repositories/info/DataverseInfoMockEmptyRepository.ts diff --git a/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx b/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx index 220aa06b1..54f99d71c 100644 --- a/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx +++ b/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx @@ -119,9 +119,7 @@ export function PublishDatasetModal({ /> {shouldShowCustomPopupText && ( -
-

{datasetPublishPopupCustomText}

-
+

{datasetPublishPopupCustomText}

)} {releasedVersionExists && !requiresMajorVersionUpdate && ( diff --git a/src/stories/shared-mock-repositories/info/DataverseInfoMockEmptyRepository.ts b/src/stories/shared-mock-repositories/info/DataverseInfoMockEmptyRepository.ts new file mode 100644 index 000000000..67dfc91e6 --- /dev/null +++ b/src/stories/shared-mock-repositories/info/DataverseInfoMockEmptyRepository.ts @@ -0,0 +1,86 @@ +import { DatasetMetadataExportFormats } from '@/info/domain/models/DatasetMetadataExportFormats' +import { DataverseVersion } from '@/info/domain/models/DataverseVersion' +import { TermsOfUse } from '@/info/domain/models/TermsOfUse' +import { DataverseInfoRepository } from '@/info/domain/repositories/DataverseInfoRepository' +import { Setting, SettingName } from '@/settings/domain/models/Setting' +import { ZipDownloadLimit } from '@/settings/domain/models/ZipDownloadLimit' +import { FileSizeUnit } from '@/files/domain/models/FileMetadata' + +export class DataverseInfoMockEmptyRepository implements DataverseInfoRepository { + private readonly delayMs = 100 + + getVersion(): Promise { + return new Promise((resolve) => { + setTimeout(() => { + resolve({} as DataverseVersion) + }, this.delayMs) + }) + } + + getTermsOfUse(): Promise { + return new Promise((resolve) => { + setTimeout(() => { + resolve('') + }, this.delayMs) + }) + } + + getZipDownloadLimit(): Promise> { + return new Promise((resolve) => { + setTimeout(() => { + resolve({ + name: SettingName.ZIP_DOWNLOAD_LIMIT, + value: new ZipDownloadLimit(0, FileSizeUnit.BYTES) + }) + }, this.delayMs) + }) + } + + getMaxEmbargoDurationInMonths(): Promise> { + return new Promise((resolve) => { + setTimeout(() => { + resolve({ name: SettingName.MAX_EMBARGO_DURATION_IN_MONTHS, value: 0 }) + }, this.delayMs) + }) + } + + getHasPublicStore(): Promise> { + return new Promise((resolve) => { + setTimeout(() => { + resolve({ name: SettingName.HAS_PUBLIC_STORE, value: false }) + }, this.delayMs) + }) + } + + getExternalStatusesAllowed(): Promise> { + return new Promise((resolve) => { + setTimeout(() => { + resolve({ name: SettingName.ALLOWED_EXTERNAL_STATUSES, value: [] }) + }, this.delayMs) + }) + } + + getAvailableDatasetMetadataExportFormats(): Promise { + return new Promise((resolve) => { + setTimeout(() => { + resolve({}) + }, this.delayMs) + }) + } + + getPublishDatasetDisclaimerText(): Promise> { + return new Promise((resolve) => { + setTimeout(() => { + resolve({ name: SettingName.PUBLISH_DATASET_DISCLAIMER_TEXT, value: '' }) + }, this.delayMs) + }) + } + + getDatasetPublishPopupCustomText(): Promise> { + return new Promise((resolve) => { + setTimeout(() => { + resolve({ name: SettingName.DATASET_PUBLISH_POPUP_CUSTOM_TEXT, value: '' }) + }, this.delayMs) + }) + } +} diff --git a/tests/component/info/domain/hooks/useGetAvailableDatasetMetadataExportFormats.spec.tsx b/tests/component/info/domain/hooks/useGetAvailableDatasetMetadataExportFormats.spec.tsx index b2f26e3a0..b935b5cd4 100644 --- a/tests/component/info/domain/hooks/useGetAvailableDatasetMetadataExportFormats.spec.tsx +++ b/tests/component/info/domain/hooks/useGetAvailableDatasetMetadataExportFormats.spec.tsx @@ -3,8 +3,9 @@ import { ReadError } from '@iqss/dataverse-client-javascript' import { DataverseInfoRepository } from '@/info/domain/repositories/DataverseInfoRepository' import { useGetAvailableDatasetMetadataExportFormats } from '@/info/domain/hooks/useGetAvailableDatasetMetadataExportFormats' import { DatasetMetadataExportFormatsMother } from '../models/DatasetMetadataExportFormatsMother' +import { DataverseInfoMockEmptyRepository } from '@/stories/shared-mock-repositories/info/DataverseInfoMockEmptyRepository' -const dataverseInfoRepository: DataverseInfoRepository = {} as DataverseInfoRepository +const dataverseInfoRepository: DataverseInfoRepository = new DataverseInfoMockEmptyRepository() const availableDsMetadataExportFormats = DatasetMetadataExportFormatsMother.create() describe('useGetAvailableDatasetMetadataExportFormats', () => { diff --git a/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/EditDatasetPermissionsMenu.spec.tsx b/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/EditDatasetPermissionsMenu.spec.tsx index dfea23efa..e4f103f1c 100644 --- a/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/EditDatasetPermissionsMenu.spec.tsx +++ b/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/EditDatasetPermissionsMenu.spec.tsx @@ -3,20 +3,15 @@ import { DatasetMother, DatasetPermissionsMother } from '../../../../dataset/domain/models/DatasetMother' -import { DataverseInfoRepository } from '../../../../../../src/info/domain/repositories/DataverseInfoRepository' import { SettingMother } from '../../../../settings/domain/models/SettingMother' import { SettingsProvider } from '../../../../../../src/sections/settings/SettingsProvider' +import { DataverseInfoMockEmptyRepository } from '@/stories/shared-mock-repositories/info/DataverseInfoMockEmptyRepository' -const dataverseInfoRepository = {} as DataverseInfoRepository - +let dataverseInfoRepository: DataverseInfoMockEmptyRepository describe('EditDatasetPermissionsMenu', () => { beforeEach(() => { - dataverseInfoRepository.getHasPublicStore = cy.stub().resolves({}) - dataverseInfoRepository.getExternalStatusesAllowed = cy.stub().resolves({}) - dataverseInfoRepository.getMaxEmbargoDurationInMonths = cy.stub().resolves({}) - dataverseInfoRepository.getZipDownloadLimit = cy.stub().resolves({}) + dataverseInfoRepository = new DataverseInfoMockEmptyRepository() }) - it('renders the EditDatasetPermissionsMenu if the user has manage dataset permissions', () => { const dataset = DatasetMother.create({ permissions: DatasetPermissionsMother.createWithManageDatasetPermissionsAllowed(), diff --git a/tests/component/sections/dataset/dataset-action-buttons/publish-dataset-menu/ChangeCurationStatusMenu.spec.tsx b/tests/component/sections/dataset/dataset-action-buttons/publish-dataset-menu/ChangeCurationStatusMenu.spec.tsx index a96399010..e8fe78ca3 100644 --- a/tests/component/sections/dataset/dataset-action-buttons/publish-dataset-menu/ChangeCurationStatusMenu.spec.tsx +++ b/tests/component/sections/dataset/dataset-action-buttons/publish-dataset-menu/ChangeCurationStatusMenu.spec.tsx @@ -4,15 +4,13 @@ import { SettingMother } from '../../../../settings/domain/models/SettingMother' import { SettingsProvider } from '../../../../../../src/sections/settings/SettingsProvider' import { DataverseInfoRepository } from '@/info/domain/repositories/DataverseInfoRepository' import { NotImplementedModalProvider } from '../../../../../../src/sections/not-implemented/NotImplementedModalProvider' +import { DataverseInfoMockEmptyRepository } from '@/stories/shared-mock-repositories/info/DataverseInfoMockEmptyRepository' -const dataverseInfoRepository = {} as DataverseInfoRepository +let dataverseInfoRepository: DataverseInfoRepository describe('ChangeCurationStatusMenu', () => { beforeEach(() => { - dataverseInfoRepository.getHasPublicStore = cy.stub().resolves({}) - dataverseInfoRepository.getExternalStatusesAllowed = cy.stub().resolves({}) - dataverseInfoRepository.getMaxEmbargoDurationInMonths = cy.stub().resolves({}) - dataverseInfoRepository.getZipDownloadLimit = cy.stub().resolves({}) + dataverseInfoRepository = new DataverseInfoMockEmptyRepository() }) it('renders the ChangeCurationStatusMenu if external statuses are allowed and the user has update dataset permissions', () => { diff --git a/tests/component/sections/dataset/dataset-action-buttons/publish-dataset-menu/PublishDatasetMenu.spec.tsx b/tests/component/sections/dataset/dataset-action-buttons/publish-dataset-menu/PublishDatasetMenu.spec.tsx index c09e26e19..b51366b36 100644 --- a/tests/component/sections/dataset/dataset-action-buttons/publish-dataset-menu/PublishDatasetMenu.spec.tsx +++ b/tests/component/sections/dataset/dataset-action-buttons/publish-dataset-menu/PublishDatasetMenu.spec.tsx @@ -5,21 +5,19 @@ import { DatasetPermissionsMother, DatasetVersionMother } from '../../../../dataset/domain/models/DatasetMother' -import { DataverseInfoRepository } from '@/info/domain/repositories/DataverseInfoRepository' import { CollectionRepository } from '@/collection/domain/repositories/CollectionRepository' import { DatasetRepository } from '@/dataset/domain/repositories/DatasetRepository' import { SettingMother } from '../../../../settings/domain/models/SettingMother' import { SettingsProvider } from '../../../../../../src/sections/settings/SettingsProvider' +import { DataverseInfoMockEmptyRepository } from '@/stories/shared-mock-repositories/info/DataverseInfoMockEmptyRepository' +import { DataverseInfoRepository } from '@/info/domain/repositories/DataverseInfoRepository' const collectionRepository = {} as CollectionRepository const datasetRepository = {} as DatasetRepository -const dataverseInfoRepository = {} as DataverseInfoRepository +let dataverseInfoRepository: DataverseInfoRepository describe('PublishDatasetMenu', () => { beforeEach(() => { - dataverseInfoRepository.getHasPublicStore = cy.stub().resolves({}) - dataverseInfoRepository.getExternalStatusesAllowed = cy.stub().resolves({}) - dataverseInfoRepository.getMaxEmbargoDurationInMonths = cy.stub().resolves({}) - dataverseInfoRepository.getZipDownloadLimit = cy.stub().resolves({}) + dataverseInfoRepository = new DataverseInfoMockEmptyRepository() }) it('renders the PublishDatasetMenu if is dataset latest version and it is a draft and publishing is allowed', () => { diff --git a/tests/component/sections/dataset/dataset-files/DatasetFiles.spec.tsx b/tests/component/sections/dataset/dataset-files/DatasetFiles.spec.tsx index c14980054..84b514cab 100644 --- a/tests/component/sections/dataset/dataset-files/DatasetFiles.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/DatasetFiles.spec.tsx @@ -21,8 +21,8 @@ import { SettingsProvider } from '../../../../../src/sections/settings/SettingsP import { FilePaginationInfo } from '../../../../../src/files/domain/models/FilePaginationInfo' import { FilePreviewMother } from '../../../files/domain/models/FilePreviewMother' import { FilePreview } from '../../../../../src/files/domain/models/FilePreview' -import { DataverseInfoRepository } from '@/info/domain/repositories/DataverseInfoRepository' import { DatasetRepository } from '@/dataset/domain/repositories/DatasetRepository' +import { DataverseInfoMockEmptyRepository } from '@/stories/shared-mock-repositories/info/DataverseInfoMockEmptyRepository' const testFiles: FilePreview[] = FilePreviewMother.createMany(10) const datasetPersistentId = 'test-dataset-persistent-id' @@ -51,7 +51,7 @@ const testFilesCountInfo = FilesCountInfoMother.create({ ] }) const paginationInfo: FilePaginationInfo = new FilePaginationInfo(1, 10, 200) -const dataverseInfoRepository = {} as DataverseInfoRepository +const dataverseInfoRepository = new DataverseInfoMockEmptyRepository() describe('DatasetFiles', () => { beforeEach(() => { diff --git a/tests/component/sections/dataset/dataset-files/DatasetFilesScrollable.spec.tsx b/tests/component/sections/dataset/dataset-files/DatasetFilesScrollable.spec.tsx index 3bae068ff..2565483c2 100644 --- a/tests/component/sections/dataset/dataset-files/DatasetFilesScrollable.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/DatasetFilesScrollable.spec.tsx @@ -22,8 +22,8 @@ import { FilePreviewMother } from '../../../files/domain/models/FilePreviewMothe import { DatasetFilesScrollable } from '../../../../../src/sections/dataset/dataset-files/DatasetFilesScrollable' import { FilesWithCount } from '../../../../../src/files/domain/models/FilesWithCount' import { getCellStyle } from '../../../../../src/sections/dataset/dataset-files/files-table/FilesTableScrollable' -import { DataverseInfoRepository } from '@/info/domain/repositories/DataverseInfoRepository' import { DatasetMockRepository } from '../../../../../src/stories/dataset/DatasetMockRepository' +import { DataverseInfoMockEmptyRepository } from '@/stories/shared-mock-repositories/info/DataverseInfoMockEmptyRepository' const TOTAL_FILES_COUNT = 200 const ONLY_4_FILES_COUNT = 4 @@ -65,7 +65,7 @@ const testFilesCountInfo = FilesCountInfoMother.create({ { tag: new FileTag('code'), count: 10 } ] }) -const dataverseInfoRepository = {} as DataverseInfoRepository +const dataverseInfoRepository = new DataverseInfoMockEmptyRepository() describe('DatasetFilesScrollable', () => { beforeEach(() => { diff --git a/tests/component/sections/dataset/dataset-files/files-table/FilesTable.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/FilesTable.spec.tsx index 380319ea6..7aa894063 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/FilesTable.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/FilesTable.spec.tsx @@ -12,8 +12,8 @@ import { FileCriteria } from '../../../../../../src/files/domain/models/FileCrit import { FilePaginationInfo } from '../../../../../../src/files/domain/models/FilePaginationInfo' import { FilePreviewMother } from '../../../../files/domain/models/FilePreviewMother' import { FileRepository } from '@/files/domain/repositories/FileRepository' -import { DataverseInfoRepository } from '@/info/domain/repositories/DataverseInfoRepository' import { DatasetRepository } from '@/dataset/domain/repositories/DatasetRepository' +import { DataverseInfoMockEmptyRepository } from '@/stories/shared-mock-repositories/info/DataverseInfoMockEmptyRepository' const fileRepository: FileRepository = {} as FileRepository const datasetRepository: DatasetRepository = {} as DatasetRepository @@ -199,16 +199,10 @@ describe('FilesTable', () => { }) ] - const dataverseInfoRepository = {} as DataverseInfoRepository - + const dataverseInfoRepository = new DataverseInfoMockEmptyRepository() dataverseInfoRepository.getZipDownloadLimit = cy .stub() .resolves(SettingMother.createZipDownloadLimit(new ZipDownloadLimit(500, FileSizeUnit.BYTES))) - dataverseInfoRepository.getHasPublicStore = cy.stub().resolves({}) - dataverseInfoRepository.getExternalStatusesAllowed = cy.stub().resolves({}) - dataverseInfoRepository.getMaxEmbargoDurationInMonths = cy.stub().resolves({}) - dataverseInfoRepository.getPublishDatasetDisclaimerText = cy.stub().resolves({}) - dataverseInfoRepository.getDatasetPublishPopupCustomText = cy.stub().resolves({}) cy.customMount( diff --git a/tests/component/sections/dataset/dataset-files/files-table/zip-download-limit-message/ZipDownloadLimitMessage.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/zip-download-limit-message/ZipDownloadLimitMessage.spec.tsx index efb9ad281..a0d4af7bb 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/zip-download-limit-message/ZipDownloadLimitMessage.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/zip-download-limit-message/ZipDownloadLimitMessage.spec.tsx @@ -5,7 +5,7 @@ import { SettingMother } from '../../../../../settings/domain/models/SettingMoth import { ZipDownloadLimit } from '../../../../../../../src/settings/domain/models/ZipDownloadLimit' import { SettingsProvider } from '@/sections/settings/SettingsProvider' import { FilePreviewMother } from '../../../../../files/domain/models/FilePreviewMother' -import { DataverseInfoRepository } from '@/info/domain/repositories/DataverseInfoRepository' +import { DataverseInfoMockEmptyRepository } from '@/stories/shared-mock-repositories/info/DataverseInfoMockEmptyRepository' const fileSelection = { 0: FilePreviewMother.create({ @@ -18,18 +18,13 @@ const fileSelection = { const zipDownloadLimit = new ZipDownloadLimit(500, FileSizeUnit.BYTES) const filesTotalDownloadSize = 3072 // 3.0 KB -const dataverseInfoRepository = {} as DataverseInfoRepository +const dataverseInfoRepository = new DataverseInfoMockEmptyRepository() describe('ZipDownloadLimitMessage', () => { beforeEach(() => { dataverseInfoRepository.getZipDownloadLimit = cy .stub() .resolves(SettingMother.createZipDownloadLimit(zipDownloadLimit)) - dataverseInfoRepository.getHasPublicStore = cy.stub().resolves({}) - dataverseInfoRepository.getExternalStatusesAllowed = cy.stub().resolves({}) - dataverseInfoRepository.getMaxEmbargoDurationInMonths = cy.stub().resolves({}) - dataverseInfoRepository.getPublishDatasetDisclaimerText = cy.stub().resolves({}) - dataverseInfoRepository.getDatasetPublishPopupCustomText = cy.stub().resolves({}) }) it('should not render if there is less than 1 file selected', () => { diff --git a/tests/component/sections/layout/footer/Footer.spec.tsx b/tests/component/sections/layout/footer/Footer.spec.tsx index f43d5a080..6c0090f5d 100644 --- a/tests/component/sections/layout/footer/Footer.spec.tsx +++ b/tests/component/sections/layout/footer/Footer.spec.tsx @@ -1,8 +1,8 @@ import { createSandbox, SinonSandbox } from 'sinon' import { DataverseVersionMother } from '../../../info/domain/models/DataverseVersionMother' -import { DataverseInfoRepository } from '../../../../../src/info/domain/repositories/DataverseInfoRepository' import { FooterMother } from './FooterMother' import { Footer } from '../../../../../src/sections/layout/footer/Footer' +import { DataverseInfoMockEmptyRepository } from '@/stories/shared-mock-repositories/info/DataverseInfoMockEmptyRepository' describe('Footer component', () => { const sandbox: SinonSandbox = createSandbox() @@ -19,9 +19,8 @@ describe('Footer component', () => { }) it('should call dataverseInfoRepository.getVersion on mount', () => { - const dataverseInfoRepository: DataverseInfoRepository = { - getVersion: cy.stub().resolves(testVersion) - } + const dataverseInfoRepository = new DataverseInfoMockEmptyRepository() + dataverseInfoRepository.getVersion = cy.stub().resolves(testVersion) cy.customMount(