diff --git a/dev-env/.env.example b/dev-env/.env.example index 972aa9026..0064a6676 100644 --- a/dev-env/.env.example +++ b/dev-env/.env.example @@ -1,6 +1,6 @@ POSTGRES_VERSION=13 DATAVERSE_DB_USER=dataverse -SOLR_VERSION=9.3.0 +SOLR_VERSION=9.8.0 REGISTRY=docker.io S3_ACCESS_KEY= S3_SECRET_KEY= diff --git a/public/locales/en/file.json b/public/locales/en/file.json index 21f5d473b..0dc9ddf50 100644 --- a/public/locales/en/file.json +++ b/public/locales/en/file.json @@ -53,6 +53,7 @@ "options": { "metadata": "Metadata", "restrict": "Restrict", + "unrestrict": "Unrestrict", "replace": "Replace", "delete": "Delete" } @@ -65,5 +66,20 @@ "delete": "Delete" }, "fileDeletedSuccess": "The file has been deleted.", - "defaultFileDeleteError": "Something went wrong deleting the file. Try again later." + "defaultFileDeleteError": "Something went wrong deleting the file. Try again later.", + "restriction": { + "fileRestrictdSuccess": "The file has been restricted.", + "fileUnrestrictedSuccess": "The file has been unrestricted.", + "restrictAccess": "Restrict Access", + "restrictionInfoP1": "Restricting limits access to published files. People who want to use the restricted files can request access by default. ", + "restrictionInfoP2": "If you disable request access, you must add information about access to the Terms of Access field.", + "restrictionInfoP3": "Learn about restricting files and dataset access in the ", + "userGuide": "User Guide", + "termsOfAccess": "Terms of Access for Restricted Files", + "enableAccessRequest": "Enable access request", + "saveChanges": "Save Changes", + "cancelChanges": "Cancel Changes", + "messagePublishedDataset": "Files will not be changed from previously published versions of the dataset.", + "message": "The file will be unrestricted." + } } diff --git a/src/dataset/domain/models/Dataset.ts b/src/dataset/domain/models/Dataset.ts index 9afc3c4fa..24e8f749b 100644 --- a/src/dataset/domain/models/Dataset.ts +++ b/src/dataset/domain/models/Dataset.ts @@ -246,12 +246,12 @@ export class DatasetVersion { public readonly isLatest: boolean, public readonly isInReview: boolean, public readonly latestVersionPublishingStatus: DatasetPublishingStatus, - public readonly someDatasetVersionHasBeenReleased: boolean + public readonly someDatasetVersionHasBeenReleased: boolean, + public readonly termsOfAccess?: TermsOfAccess ) {} static Builder = class { public readonly labels: DatasetLabel[] = [] - constructor( public readonly id: number, public readonly title: string, @@ -261,7 +261,8 @@ export class DatasetVersion { public readonly isLatest: boolean, public readonly isInReview: boolean, public readonly latestVersionPublishingStatus: DatasetPublishingStatus, - public readonly someDatasetVersionHasBeenReleased: boolean + public readonly someDatasetVersionHasBeenReleased: boolean, + public readonly termsOfAccess?: TermsOfAccess ) { this.createLabels() } @@ -327,7 +328,8 @@ export class DatasetVersion { this.isLatest, this.isInReview, this.latestVersionPublishingStatus, - this.someDatasetVersionHasBeenReleased + this.someDatasetVersionHasBeenReleased, + this.termsOfAccess ) } } diff --git a/src/dataset/infrastructure/mappers/JSDatasetVersionMapper.ts b/src/dataset/infrastructure/mappers/JSDatasetVersionMapper.ts index de799b603..0b780b519 100644 --- a/src/dataset/infrastructure/mappers/JSDatasetVersionMapper.ts +++ b/src/dataset/infrastructure/mappers/JSDatasetVersionMapper.ts @@ -5,15 +5,18 @@ import { import { DatasetPublishingStatus, DatasetVersion, - DatasetVersionNumber + DatasetVersionNumber, + TermsOfAccess } from '../../domain/models/Dataset' + export class JSDatasetVersionMapper { static toVersion( jDatasetVersionId: number, jsDatasetVersionInfo: JSDatasetVersionInfo, jsDatasetTitle: string, jsDatasetCitation: string, - jsDatasetPublicationDate?: string + jsDatasetPublicationDate?: string, + jsDatasettermsOfAccess?: TermsOfAccess ): DatasetVersion { return new DatasetVersion.Builder( jDatasetVersionId, @@ -24,7 +27,8 @@ export class JSDatasetVersionMapper { true, // TODO Connect with dataset version isLatest false, // TODO Connect with dataset version isInReview this.toStatus(jsDatasetVersionInfo.state), - this.toSomeDatasetVersionHasBeenReleased(jsDatasetVersionInfo, jsDatasetPublicationDate) + this.toSomeDatasetVersionHasBeenReleased(jsDatasetVersionInfo, jsDatasetPublicationDate), + jsDatasettermsOfAccess ) } diff --git a/src/files/domain/repositories/FileRepository.ts b/src/files/domain/repositories/FileRepository.ts index ee0ed95e9..b16b4fbd9 100644 --- a/src/files/domain/repositories/FileRepository.ts +++ b/src/files/domain/repositories/FileRepository.ts @@ -44,4 +44,5 @@ export interface FileRepository { ) => Promise addUploadedFiles: (datasetId: number | string, files: UploadedFileDTO[]) => Promise delete: (fileId: number | string) => Promise + restrict: (fileId: number | string, restrict: boolean) => Promise } diff --git a/src/files/domain/useCases/restrictFile.ts b/src/files/domain/useCases/restrictFile.ts new file mode 100644 index 000000000..52116f7d4 --- /dev/null +++ b/src/files/domain/useCases/restrictFile.ts @@ -0,0 +1,9 @@ +import { FileRepository } from '../repositories/FileRepository' + +export function restrictFile( + fileRepository: FileRepository, + fileId: number | string, + restrict: boolean +): Promise { + return fileRepository.restrict(fileId, restrict) +} diff --git a/src/files/infrastructure/FileJSDataverseRepository.ts b/src/files/infrastructure/FileJSDataverseRepository.ts index 61bad36a5..d80f17c0e 100644 --- a/src/files/infrastructure/FileJSDataverseRepository.ts +++ b/src/files/infrastructure/FileJSDataverseRepository.ts @@ -17,7 +17,8 @@ import { addUploadedFilesToDataset, UploadedFileDTO, ReadError, - deleteFile + deleteFile, + restrictFile } from '@iqss/dataverse-client-javascript' import { FileCriteria } from '../domain/models/FileCriteria' import { DomainFileMapper } from './mappers/DomainFileMapper' @@ -308,4 +309,8 @@ export class FileJSDataverseRepository implements FileRepository { delete(fileId: number | string): Promise { return deleteFile.execute(fileId) } + + restrict(fileId: number | string, restrict: boolean): Promise { + return restrictFile.execute(fileId, restrict) + } } diff --git a/src/files/infrastructure/mappers/JSFileMapper.ts b/src/files/infrastructure/mappers/JSFileMapper.ts index fdf060235..58464aeb7 100644 --- a/src/files/infrastructure/mappers/JSFileMapper.ts +++ b/src/files/infrastructure/mappers/JSFileMapper.ts @@ -54,7 +54,9 @@ export class JSFileMapper { jsDataset.versionId, jsDataset.versionInfo, JSDatasetMapper.toDatasetTitle(jsDataset.metadataBlocks), - datasetCitation + datasetCitation, + jsDataset.publicationDate, + jsDataset.termsOfUse?.termsOfAccess ) return { id: this.toFileId(jsFile.id), diff --git a/src/sections/file/File.tsx b/src/sections/file/File.tsx index c7db06747..4aae12b32 100644 --- a/src/sections/file/File.tsx +++ b/src/sections/file/File.tsx @@ -88,10 +88,13 @@ export function File({ repository, id, datasetVersionNumber }: FileProps) { )} diff --git a/src/sections/file/file-action-buttons/edit-file-menu/EditFileMenu.tsx b/src/sections/file/file-action-buttons/edit-file-menu/EditFileMenu.tsx index 005e171b9..59c82db22 100644 --- a/src/sections/file/file-action-buttons/edit-file-menu/EditFileMenu.tsx +++ b/src/sections/file/file-action-buttons/edit-file-menu/EditFileMenu.tsx @@ -2,19 +2,27 @@ import { useTranslation } from 'react-i18next' import { DropdownButton } from '@iqss/dataverse-design-system' import { FileRepository } from '@/files/domain/repositories/FileRepository' import { DeleteFileButton } from './delete-file-button/DeleteFileButton' +import { RestrictFileButton } from './restrict-file-button/RestrictFileButton' interface EditFileMenuProps { fileId: number fileRepository: FileRepository + isRestricted: boolean datasetInfo: EditFileMenuDatasetInfo } export interface EditFileMenuDatasetInfo { persistentId: string releasedVersionExists: boolean + termsOfAccessForRestrictedFiles?: string } -export const EditFileMenu = ({ fileId, fileRepository, datasetInfo }: EditFileMenuProps) => { +export const EditFileMenu = ({ + fileId, + fileRepository, + datasetInfo, + isRestricted +}: EditFileMenuProps) => { const { t } = useTranslation('file') return ( @@ -25,9 +33,13 @@ export const EditFileMenu = ({ fileId, fileRepository, datasetInfo }: EditFileMe variant="secondary"> {/* 👇 These buttons are commented out but I keep them because they are the next thing to be developed.*/} {/* {t('actionButtons.editFileMenu.options.metadata')} - {t('actionButtons.editFileMenu.options.restrict')} {t('actionButtons.editFileMenu.options.replace')} */} - + ) diff --git a/src/sections/file/file-action-buttons/edit-file-menu/restrict-file-button/RestrictFileButton.tsx b/src/sections/file/file-action-buttons/edit-file-menu/restrict-file-button/RestrictFileButton.tsx new file mode 100644 index 000000000..bc67a1ec4 --- /dev/null +++ b/src/sections/file/file-action-buttons/edit-file-menu/restrict-file-button/RestrictFileButton.tsx @@ -0,0 +1,69 @@ +import { useState } from 'react' +import { useTranslation } from 'react-i18next' +import { useNavigate } from 'react-router-dom' +import { toast } from 'react-toastify' +import { DropdownButtonItem } from '@iqss/dataverse-design-system' +import { FileRepository } from '@/files/domain/repositories/FileRepository' +import { QueryParamKey, Route } from '@/sections/Route.enum' +import { DatasetNonNumericVersionSearchParam } from '@/dataset/domain/models/Dataset' +import { ConfirmRestrictFileModal } from './confirm-restrict-file-modal/ConfirmRestrictFileModal' +import { EditFileMenuDatasetInfo } from '../EditFileMenu' +import { useRestrictFile } from './useRestrictFile' + +interface RestrictFileButtonProps { + fileId: number + isRestricted: boolean + fileRepository: FileRepository + datasetInfo: EditFileMenuDatasetInfo +} + +export const RestrictFileButton = ({ + fileId, + isRestricted, + fileRepository, + datasetInfo +}: RestrictFileButtonProps) => { + const [showConfirmationModal, setShowConfirmationModal] = useState(false) + const navigate = useNavigate() + const { t } = useTranslation('file') + + const { handleRestrictFile, isRestrictingFile, errorRestrictingFile } = useRestrictFile({ + isRestricted, + fileRepository, + onSuccessfulRestrict: closeModalAndNavigateToDataset + }) + const handleOpenModal = () => setShowConfirmationModal(true) + const handleCloseModal = () => setShowConfirmationModal(false) + + function closeModalAndNavigateToDataset() { + setShowConfirmationModal(false) + + const searchParams = new URLSearchParams() + searchParams.set(QueryParamKey.PERSISTENT_ID, datasetInfo.persistentId) + searchParams.set(QueryParamKey.VERSION, DatasetNonNumericVersionSearchParam.DRAFT) + isRestricted + ? toast.success(t('restriction.fileUnrestrictedSuccess')) + : toast.success(t('restriction.fileRestrictdSuccess')) + navigate(`${Route.DATASETS}?${searchParams.toString()}`) + } + + return ( + <> + + {isRestricted + ? t('actionButtons.editFileMenu.options.unrestrict') + : t('actionButtons.editFileMenu.options.restrict')} + + handleRestrictFile(fileId)} + datasetReleasedVersionExists={datasetInfo.releasedVersionExists} + termsOfAccessForRestrictedFiles={datasetInfo.termsOfAccessForRestrictedFiles} + isRestrictingFile={isRestrictingFile} + errorRestrictingFile={errorRestrictingFile} + isRestricted={isRestricted} + /> + + ) +} diff --git a/src/sections/file/file-action-buttons/edit-file-menu/restrict-file-button/confirm-restrict-file-modal/ConfirmRestrictFileModal.module.scss b/src/sections/file/file-action-buttons/edit-file-menu/restrict-file-button/confirm-restrict-file-modal/ConfirmRestrictFileModal.module.scss new file mode 100644 index 000000000..9f3f3c2f5 --- /dev/null +++ b/src/sections/file/file-action-buttons/edit-file-menu/restrict-file-button/confirm-restrict-file-modal/ConfirmRestrictFileModal.module.scss @@ -0,0 +1,24 @@ +@import 'node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/colors.module'; + +.message { + color: $dv-warning-color; + + &.error { + color: $dv-danger-color; + } + + svg { + min-width: fit-content; + } +} + +.restriction_form { + padding-top: 0.5em; + padding-bottom: 0.5em; +} + +.restriction_info { + padding-top: 0.5em; + padding-bottom: 0.5em; + color: $dv-subtext-color; +} diff --git a/src/sections/file/file-action-buttons/edit-file-menu/restrict-file-button/confirm-restrict-file-modal/ConfirmRestrictFileModal.tsx b/src/sections/file/file-action-buttons/edit-file-menu/restrict-file-button/confirm-restrict-file-modal/ConfirmRestrictFileModal.tsx new file mode 100644 index 000000000..70b7b0d4d --- /dev/null +++ b/src/sections/file/file-action-buttons/edit-file-menu/restrict-file-button/confirm-restrict-file-modal/ConfirmRestrictFileModal.tsx @@ -0,0 +1,128 @@ +import { useTranslation } from 'react-i18next' +import { Link } from 'react-router-dom' +import { Button, Modal, Spinner, Stack, Col, Form } from '@iqss/dataverse-design-system' +// import { ExclamationCircleFill, ExclamationTriangle } from 'react-bootstrap-icons' +import styles from './ConfirmRestrictFileModal.module.scss' +import { FormEvent, useState } from 'react' +import { ExclamationTriangle } from 'react-bootstrap-icons' + +interface ConfirmRestrictFileModalProps { + show: boolean + handleClose: () => void + handleRestrict: () => void + datasetReleasedVersionExists: boolean + isRestrictingFile: boolean + errorRestrictingFile: string | null + termsOfAccessForRestrictedFiles?: string + isRestricted: boolean +} + +export const ConfirmRestrictFileModal = ({ + show, + handleClose, + handleRestrict, + datasetReleasedVersionExists, + termsOfAccessForRestrictedFiles, + isRestrictingFile, + errorRestrictingFile, + isRestricted +}: ConfirmRestrictFileModalProps) => { + const { t: tShared } = useTranslation('shared') + const { t } = useTranslation('file') + const [requestAccess, setRequestAccess] = useState(true) // TODO need connect to API + const [terms, setTerms] = useState(termsOfAccessForRestrictedFiles) // TODO need connect to API + + return ( + {} : handleClose} centered size="lg"> + + {t('restriction.restrictAccess')} + + + {!isRestricted && ( +
+
+

+ {t('restriction.restrictionInfoP1')} {t('restriction.restrictionInfoP2')} +

+

+ {t('restriction.restrictionInfoP3')} + + {t('restriction.userGuide')} + +

+
+
+ + + {t('restriction.restrictAccess')} + + + ) => + setRequestAccess(event.currentTarget.checked) + } + /> + + + + + {t('restriction.termsOfAccess')} + + + ) => + setTerms(event.currentTarget.value) + } + /> + + +
+
+ )} + {isRestricted && ( + + + {t('restriction.message')} + + + )} + {datasetReleasedVersionExists && ( + + {t('restriction.messagePublishedDataset')} + + )} + {errorRestrictingFile && ( + + {errorRestrictingFile} + + )} +
+ + + + + +
+ ) +} diff --git a/src/sections/file/file-action-buttons/edit-file-menu/restrict-file-button/useRestrictFile.tsx b/src/sections/file/file-action-buttons/edit-file-menu/restrict-file-button/useRestrictFile.tsx new file mode 100644 index 000000000..9eb532887 --- /dev/null +++ b/src/sections/file/file-action-buttons/edit-file-menu/restrict-file-button/useRestrictFile.tsx @@ -0,0 +1,56 @@ +import { useState } from 'react' +import { useTranslation } from 'react-i18next' +import { WriteError } from '@iqss/dataverse-client-javascript' +import { FileRepository } from '@/files/domain/repositories/FileRepository' +import { restrictFile } from '@/files/domain/useCases/restrictFile' +import { JSDataverseWriteErrorHandler } from '@/shared/helpers/JSDataverseWriteErrorHandler' + +interface UseRestrictFile { + fileRepository: FileRepository + isRestricted: boolean + onSuccessfulRestrict: () => void +} + +interface UseRestrictFileReturn { + isRestrictingFile: boolean + errorRestrictingFile: string | null + handleRestrictFile: (fileId: number) => Promise + isRestricted: boolean +} + +export const useRestrictFile = ({ + isRestricted, + fileRepository, + onSuccessfulRestrict +}: UseRestrictFile): UseRestrictFileReturn => { + const { t } = useTranslation('file') + const [isRestrictingFile, setisRestrictingFile] = useState(false) + const [errorRestrictingFile, seterrorRestrictingFile] = useState(null) + + const handleRestrictFile = async (fileId: number) => { + setisRestrictingFile(true) + + try { + await restrictFile(fileRepository, fileId, !isRestricted) + onSuccessfulRestrict() + } catch (err: WriteError | unknown) { + if (err instanceof WriteError) { + const error = new JSDataverseWriteErrorHandler(err) + const formattedError = + error.getReasonWithoutStatusCode() ?? /* istanbul ignore next */ error.getErrorMessage() + seterrorRestrictingFile(formattedError) + } else { + seterrorRestrictingFile(t('defaultFileRestrictError')) + } + } finally { + setisRestrictingFile(false) + } + } + + return { + isRestrictingFile, + errorRestrictingFile, + handleRestrictFile, + isRestricted + } +} diff --git a/src/stories/file/FileMockLoadingRepository.ts b/src/stories/file/FileMockLoadingRepository.ts index fc2f4af82..2b2f7a24d 100644 --- a/src/stories/file/FileMockLoadingRepository.ts +++ b/src/stories/file/FileMockLoadingRepository.ts @@ -56,4 +56,12 @@ export class FileMockLoadingRepository extends FileMockRepository implements Fil }, FakerHelper.loadingTimout()) }) } + + restrict(_fileId: number | string, _restrict: boolean): Promise { + return new Promise(() => { + setTimeout(() => { + // Do nothing + }, FakerHelper.loadingTimout()) + }) + } } diff --git a/src/stories/file/FileMockRepository.ts b/src/stories/file/FileMockRepository.ts index e2bb10cc5..7e0eb1cec 100644 --- a/src/stories/file/FileMockRepository.ts +++ b/src/stories/file/FileMockRepository.ts @@ -122,4 +122,12 @@ export class FileMockRepository implements FileRepository { }, FakerHelper.loadingTimout()) }) } + + restrict(_fileId: number | string, _restrict: boolean): Promise { + return new Promise((resolve) => { + setTimeout(() => { + resolve() + }, FakerHelper.loadingTimout()) + }) + } } diff --git a/src/stories/file/file-action-buttons/edit-file-dropdown/ConfirmRestrictFileModal.stories.tsx b/src/stories/file/file-action-buttons/edit-file-dropdown/ConfirmRestrictFileModal.stories.tsx new file mode 100644 index 000000000..6a50fae5b --- /dev/null +++ b/src/stories/file/file-action-buttons/edit-file-dropdown/ConfirmRestrictFileModal.stories.tsx @@ -0,0 +1,73 @@ +import { Meta, StoryObj } from '@storybook/react' +import { WithI18next } from '../../../WithI18next' +import { WithSettings } from '../../../WithSettings' +import { ConfirmRestrictFileModal } from '@/sections/file/file-action-buttons/edit-file-menu/restrict-file-button/confirm-restrict-file-modal/ConfirmRestrictFileModal' + +const meta: Meta = { + title: 'Sections/File Page/Action Buttons/EditFileMenu/ConfirmRestrictFileModal', + component: ConfirmRestrictFileModal, + decorators: [WithI18next, WithSettings] +} + +export default meta +type Story = StoryObj + +export const WithDatasetNotReleased: Story = { + render: () => ( + {}} + handleRestrict={() => {}} + termsOfAccessForRestrictedFiles="terms of access for restricted files" + isRestricted={false} + /> + ) +} + +export const WithReleasedDataset: Story = { + render: () => ( + {}} + handleRestrict={() => {}} + termsOfAccessForRestrictedFiles="terms of access for restricted files" + isRestricted={false} + /> + ) +} + +export const WithError: Story = { + render: () => ( + {}} + handleRestrict={() => {}} + termsOfAccessForRestrictedFiles="terms of access for restricted files" + isRestricted={false} + /> + ) +} + +export const RestrictingFileInProgress: Story = { + render: () => ( + {}} + handleRestrict={() => {}} + termsOfAccessForRestrictedFiles="terms of access for restricted files" + isRestricted={false} + /> + ) +} diff --git a/src/stories/file/file-action-buttons/edit-file-dropdown/ConfirmUnrestrictFileModal.stories.tsx b/src/stories/file/file-action-buttons/edit-file-dropdown/ConfirmUnrestrictFileModal.stories.tsx new file mode 100644 index 000000000..b30321356 --- /dev/null +++ b/src/stories/file/file-action-buttons/edit-file-dropdown/ConfirmUnrestrictFileModal.stories.tsx @@ -0,0 +1,73 @@ +import { Meta, StoryObj } from '@storybook/react' +import { WithI18next } from '../../../WithI18next' +import { WithSettings } from '../../../WithSettings' +import { ConfirmRestrictFileModal } from '@/sections/file/file-action-buttons/edit-file-menu/restrict-file-button/confirm-restrict-file-modal/ConfirmRestrictFileModal' + +const meta: Meta = { + title: 'Sections/File Page/Action Buttons/EditFileMenu/ConfirmUnrestrictFileModal', + component: ConfirmRestrictFileModal, + decorators: [WithI18next, WithSettings] +} + +export default meta +type Story = StoryObj + +export const WithDatasetNotReleased: Story = { + render: () => ( + {}} + handleRestrict={() => {}} + termsOfAccessForRestrictedFiles="terms of access for restricted files" + isRestricted={true} + /> + ) +} + +export const WithReleasedDataset: Story = { + render: () => ( + {}} + handleRestrict={() => {}} + termsOfAccessForRestrictedFiles="terms of access for restricted files" + isRestricted={true} + /> + ) +} + +export const WithError: Story = { + render: () => ( + {}} + handleRestrict={() => {}} + termsOfAccessForRestrictedFiles="terms of access for restricted files" + isRestricted={true} + /> + ) +} + +export const RestrictingFileInProgress: Story = { + render: () => ( + {}} + handleRestrict={() => {}} + termsOfAccessForRestrictedFiles="terms of access for restricted files" + isRestricted={true} + /> + ) +} diff --git a/src/stories/file/file-action-buttons/edit-file-dropdown/EditFileDropdown.stories.tsx b/src/stories/file/file-action-buttons/edit-file-dropdown/EditFileDropdown.stories.tsx index 3e60c1733..38ea62bd5 100644 --- a/src/stories/file/file-action-buttons/edit-file-dropdown/EditFileDropdown.stories.tsx +++ b/src/stories/file/file-action-buttons/edit-file-dropdown/EditFileDropdown.stories.tsx @@ -21,6 +21,7 @@ export const Default: Story = { { ) @@ -27,6 +29,7 @@ describe('EditFileMenu', () => { { { { { { cy.findByText('Something went wrong deleting the file. Try again later.').should('exist') }) }) + + describe('Restrict button', () => { + it('opens and close the restrict file modal', () => { + cy.customMount( + + ) + + cy.findByRole('button', { name: 'Edit File' }).click() + cy.findByRole('button', { name: 'Restrict' }).click() + cy.findByRole('dialog').should('exist') + cy.findByRole('checkbox').should('exist') + cy.findAllByText(/terms of access for restricted files/i).should('exist') + + cy.findByRole('button', { name: /Cancel/i }).click() + + cy.findByRole('dialog').should('not.exist') + }) + + it('should show terms Of Access For Restricted Files in restrict file modal', () => { + cy.customMount( + + ) + + cy.findByRole('button', { name: 'Edit File' }).click() + cy.findByRole('button', { name: 'Restrict' }).click() + cy.findByRole('dialog').should('exist') + cy.findByRole('checkbox').should('exist') + cy.findAllByText(/terms of access for restricted files/i).should('exist') + cy.findByText(/test terms of access/i).should('exist') + + cy.findByRole('button', { name: /Cancel/i }).click() + + cy.findByRole('dialog').should('not.exist') + }) + + it('file dataset has a released version, shows custom message also', () => { + cy.customMount( + + ) + + cy.findByRole('button', { name: 'Edit File' }).click() + cy.findByRole('button', { name: 'Restrict' }).click() + cy.findByRole('dialog').should('exist') + + cy.findByText( + /Files will not be changed from previously published versions of the dataset./ + ).should('exist') + }) + + it('should disable Save button if no terms of acccess and disenable access request', () => { + cy.customMount( + + ) + + cy.findByRole('button', { name: 'Edit File' }).click() + cy.findByRole('button', { name: 'Restrict' }).click() + cy.findByRole('dialog').should('exist') + cy.findByRole('checkbox').uncheck() + cy.findByRole('button', { name: 'Save Changes' }).should('be.disabled') + + cy.findByRole('button', { name: /Cancel/i }).click() + + cy.findByRole('dialog').should('not.exist') + }) + + it('closes the modal and shows toast success message when restrict file succeeds', () => { + cy.customMount( + + ) + + cy.findByRole('button', { name: 'Edit File' }).click() + cy.findByRole('button', { name: 'Restrict' }).click() + cy.findByRole('dialog').should('exist') + + cy.findByRole('button', { name: /Save Changes/i }).click() + + cy.findByRole('status').should('exist') + + cy.findByRole('dialog').should('not.exist') + cy.findByText(/The file has been restricted./) + .should('exist') + .should('be.visible') + }) + }) + + describe('Unrestrict button', () => { + it('opens and close the unrestrict file modal', () => { + cy.customMount( + + ) + + cy.findByRole('button', { name: 'Edit File' }).click() + cy.findByRole('button', { name: 'Unrestrict' }).click() + cy.findByRole('dialog').should('exist') + cy.findByText(/The file will be unrestricted./i).should('exist') + + cy.findByRole('button', { name: /Cancel/i }).click() + + cy.findByRole('dialog').should('not.exist') + }) + + it('file dataset has a released version, shows custom message also', () => { + cy.customMount( + + ) + + cy.findByRole('button', { name: 'Edit File' }).click() + cy.findByRole('button', { name: 'Unrestrict' }).click() + cy.findByRole('dialog').should('exist') + cy.findByText( + /Files will not be changed from previously published versions of the dataset./ + ).should('exist') + }) + + it('closes the modal and shows toast success message when unrestrict file succeeds', () => { + cy.customMount( + + ) + + cy.findByRole('button', { name: 'Edit File' }).click() + cy.findByRole('button', { name: 'Unrestrict' }).click() + cy.findByRole('dialog').should('exist') + + cy.findByRole('button', { name: /Save Changes/i }).click() + + cy.findByRole('status').should('exist') + + cy.findByRole('dialog').should('not.exist') + cy.findByText(/The file has been unrestricted./) + .should('exist') + .should('be.visible') + }) + }) })