From 1e1d2738258c3f2b4aacf1fd1be80c16bc11c583 Mon Sep 17 00:00:00 2001 From: MellyGray Date: Mon, 27 Nov 2023 16:04:37 +0100 Subject: [PATCH 1/6] feat(IntegrationFileDownload): add use case --- .../DropdownButtonItem.tsx | 9 +++++++- .../domain/repositories/FileRepository.ts | 1 + src/files/domain/useCases/getFile.ts | 10 ++++++++ .../FileJSDataverseRepository.ts | 16 +++++++++++++ src/sections/dataset/DatasetFactory.tsx | 21 +++++++++-------- .../FileNonTabularDownloadOptions.tsx | 4 ++++ .../FileDownloadHelperContext.ts | 11 +++++++++ .../FileDownloadHelperProvider.tsx | 23 +++++++++++++++++++ .../file-download-helper/useFileDownload.tsx | 19 +++++++++++++++ .../files/FileMockLoadingRepository.ts | 9 ++++++++ src/stories/files/FileMockNoDataRepository.ts | 9 ++++++++ .../files/FileMockNoFiltersRepository.ts | 10 ++++++++ src/stories/files/FileMockRepository.ts | 10 ++++++++ .../files/domain/models/FileMother.ts | 7 ++++++ .../FileNonTabularDownloadOptions.spec.tsx | 16 +++++++++++++ 15 files changed, 165 insertions(+), 10 deletions(-) create mode 100644 src/files/domain/useCases/getFile.ts create mode 100644 src/sections/file/file-download-helper/FileDownloadHelperContext.ts create mode 100644 src/sections/file/file-download-helper/FileDownloadHelperProvider.tsx create mode 100644 src/sections/file/file-download-helper/useFileDownload.tsx diff --git a/packages/design-system/src/lib/components/dropdown-button/dropdown-button-item/DropdownButtonItem.tsx b/packages/design-system/src/lib/components/dropdown-button/dropdown-button-item/DropdownButtonItem.tsx index f820d33dd..61425e7ef 100644 --- a/packages/design-system/src/lib/components/dropdown-button/dropdown-button-item/DropdownButtonItem.tsx +++ b/packages/design-system/src/lib/components/dropdown-button/dropdown-button-item/DropdownButtonItem.tsx @@ -5,6 +5,7 @@ interface DropdownItemProps extends React.HTMLAttributes { href?: string eventKey?: string disabled?: boolean + download?: string children: ReactNode } @@ -12,11 +13,17 @@ export function DropdownButtonItem({ href, eventKey, disabled, + download, children, ...props }: DropdownItemProps) { return ( - + {children} ) diff --git a/src/files/domain/repositories/FileRepository.ts b/src/files/domain/repositories/FileRepository.ts index 976fd5a66..458be1b4b 100644 --- a/src/files/domain/repositories/FileRepository.ts +++ b/src/files/domain/repositories/FileRepository.ts @@ -23,4 +23,5 @@ export interface FileRepository { criteria?: FileCriteria ) => Promise getUserPermissionsById: (id: number) => Promise + getById: (id: number) => Promise } diff --git a/src/files/domain/useCases/getFile.ts b/src/files/domain/useCases/getFile.ts new file mode 100644 index 000000000..c63857399 --- /dev/null +++ b/src/files/domain/useCases/getFile.ts @@ -0,0 +1,10 @@ +import { FileRepository } from '../repositories/FileRepository' + +export async function getFile( + fileRepository: FileRepository, + id: number +): Promise { + return fileRepository.getById(id).catch((error: Error) => { + throw new Error(error.message) + }) +} diff --git a/src/files/infrastructure/FileJSDataverseRepository.ts b/src/files/infrastructure/FileJSDataverseRepository.ts index e16c3c004..3cf43c92a 100644 --- a/src/files/infrastructure/FileJSDataverseRepository.ts +++ b/src/files/infrastructure/FileJSDataverseRepository.ts @@ -147,4 +147,20 @@ export class FileJSDataverseRepository implements FileRepository { throw new Error(error.message) }) } + + getById(id: number): Promise { + return fetch(`${FileJSDataverseRepository.DATAVERSE_BACKEND_URL}/api/access/datafile/${id}`) + .then((response) => { + if (!response.ok) { + throw new Error('Network response was not ok') + } + return response.blob() + }) + .then((blob) => { + return URL.createObjectURL(blob) + }) + .catch(() => { + return undefined + }) + } } diff --git a/src/sections/dataset/DatasetFactory.tsx b/src/sections/dataset/DatasetFactory.tsx index 1ac3e1e15..e303cc1c0 100644 --- a/src/sections/dataset/DatasetFactory.tsx +++ b/src/sections/dataset/DatasetFactory.tsx @@ -11,6 +11,7 @@ import { SettingJSDataverseRepository } from '../../settings/infrastructure/Sett import { FilePermissionsProvider } from '../file/file-permissions/FilePermissionsProvider' import { SettingsProvider } from '../settings/SettingsProvider' import { DatasetProvider } from './DatasetProvider' +import { FileDownloadHelperProvider } from '../file/file-download-helper/FileDownloadHelperProvider' const datasetRepository = new DatasetJSDataverseRepository() const fileRepository = new FileJSDataverseRepository() @@ -20,15 +21,17 @@ const settingRepository = new SettingJSDataverseRepository() export class DatasetFactory { static create(): ReactElement { return ( - - - - - - - - - + + + + + + + + + + + ) } } diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.tsx b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.tsx index e7306abb0..12a624318 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.tsx @@ -3,6 +3,7 @@ import FileTypeToFriendlyTypeMap from '../../../../../../../../files/domain/mode import { DropdownButtonItem } from '@iqss/dataverse-design-system' import { useDataset } from '../../../../../../DatasetContext' import { useTranslation } from 'react-i18next' +import { useFileDownload } from '../../../../../../../file/file-download-helper/useFileDownload' interface FileNonTabularDownloadOptionsProps { file: File @@ -11,6 +12,7 @@ interface FileNonTabularDownloadOptionsProps { export function FileNonTabularDownloadOptions({ file }: FileNonTabularDownloadOptionsProps) { const { t } = useTranslation('files') const { dataset } = useDataset() + const { originalFile } = useFileDownload(file.id) const originalFileFormatIsKnown = file.type.toDisplayFormat() !== FileTypeToFriendlyTypeMap.unknown @@ -20,6 +22,8 @@ export function FileNonTabularDownloadOptions({ file }: FileNonTabularDownloadOp return ( Promise +} + +export const FileDownloadHelperContext = createContext({ + download: () => Promise.reject('Not implemented') +}) + +export const useFileDownloadHelper = () => useContext(FileDownloadHelperContext) diff --git a/src/sections/file/file-download-helper/FileDownloadHelperProvider.tsx b/src/sections/file/file-download-helper/FileDownloadHelperProvider.tsx new file mode 100644 index 000000000..a2006db8a --- /dev/null +++ b/src/sections/file/file-download-helper/FileDownloadHelperProvider.tsx @@ -0,0 +1,23 @@ +import { FileRepository } from '../../../files/domain/repositories/FileRepository' +import { PropsWithChildren } from 'react' +import { getFile } from '../../../files/domain/useCases/getFile' +import { FileDownloadHelperContext } from './FileDownloadHelperContext' + +interface FileDownloadProviderProps { + repository: FileRepository +} + +export function FileDownloadHelperProvider({ + repository, + children +}: PropsWithChildren) { + const download = (id: number): Promise => { + return getFile(repository, id) + } + + return ( + + {children} + + ) +} diff --git a/src/sections/file/file-download-helper/useFileDownload.tsx b/src/sections/file/file-download-helper/useFileDownload.tsx new file mode 100644 index 000000000..22cb7d418 --- /dev/null +++ b/src/sections/file/file-download-helper/useFileDownload.tsx @@ -0,0 +1,19 @@ +import { useEffect, useState } from 'react' +import { useFileDownloadHelper } from './FileDownloadHelperContext' + +export function useFileDownload(id: number) { + const { download } = useFileDownloadHelper() + const [originalFile, setOriginalFile] = useState() + + useEffect(() => { + download(id) + .then((downloadedFile) => { + setOriginalFile(downloadedFile) + }) + .catch((error) => { + console.error('There was an error downloading the file', error) + }) + }, [id]) + + return { originalFile } +} diff --git a/src/stories/files/FileMockLoadingRepository.ts b/src/stories/files/FileMockLoadingRepository.ts index eff4bd897..b2d04fcd5 100644 --- a/src/stories/files/FileMockLoadingRepository.ts +++ b/src/stories/files/FileMockLoadingRepository.ts @@ -57,4 +57,13 @@ export class FileMockLoadingRepository implements FileRepository { }, 1000) }) } + + // eslint-disable-next-line unused-imports/no-unused-vars + getById(id: number): Promise { + return new Promise((resolve) => { + setTimeout(() => { + resolve(undefined) + }, 1000) + }) + } } diff --git a/src/stories/files/FileMockNoDataRepository.ts b/src/stories/files/FileMockNoDataRepository.ts index ba7c10a3b..4f18a3327 100644 --- a/src/stories/files/FileMockNoDataRepository.ts +++ b/src/stories/files/FileMockNoDataRepository.ts @@ -57,4 +57,13 @@ export class FileMockNoDataRepository implements FileRepository { }, 1000) }) } + + // eslint-disable-next-line unused-imports/no-unused-vars + getById(id: number): Promise { + return new Promise((resolve) => { + setTimeout(() => { + resolve(undefined) + }, 1000) + }) + } } diff --git a/src/stories/files/FileMockNoFiltersRepository.ts b/src/stories/files/FileMockNoFiltersRepository.ts index eec689eaa..5f0935022 100644 --- a/src/stories/files/FileMockNoFiltersRepository.ts +++ b/src/stories/files/FileMockNoFiltersRepository.ts @@ -7,6 +7,7 @@ import { FileUserPermissions } from '../../files/domain/models/FileUserPermissio import { FileUserPermissionsMother } from '../../../tests/component/files/domain/models/FileUserPermissionsMother' import { DatasetVersion } from '../../dataset/domain/models/Dataset' import { FileCriteria } from '../../files/domain/models/FileCriteria' +import { FileMother } from '../../../tests/component/files/domain/models/FileMother' export class FileMockNoFiltersRepository implements FileRepository { getAllByDatasetPersistentId( @@ -59,4 +60,13 @@ export class FileMockNoFiltersRepository implements FileRepository { }, 1000) }) } + + // eslint-disable-next-line unused-imports/no-unused-vars + getById(id: number): Promise { + return new Promise((resolve) => { + setTimeout(() => { + resolve(FileMother.createToDownload()) + }, 1000) + }) + } } diff --git a/src/stories/files/FileMockRepository.ts b/src/stories/files/FileMockRepository.ts index 63e1499fa..419b55d7e 100644 --- a/src/stories/files/FileMockRepository.ts +++ b/src/stories/files/FileMockRepository.ts @@ -8,6 +8,7 @@ import { FileUserPermissionsMother } from '../../../tests/component/files/domain import { FileUserPermissions } from '../../files/domain/models/FileUserPermissions' import { DatasetVersion } from '../../dataset/domain/models/Dataset' import { FileCriteria } from '../../files/domain/models/FileCriteria' +import { FileMother } from '../../../tests/component/files/domain/models/FileMother' export class FileMockRepository implements FileRepository { // eslint-disable-next-line unused-imports/no-unused-vars @@ -59,4 +60,13 @@ export class FileMockRepository implements FileRepository { }, 1000) }) } + + // eslint-disable-next-line unused-imports/no-unused-vars + getById(id: number): Promise { + return new Promise((resolve) => { + setTimeout(() => { + resolve(FileMother.createToDownload()) + }, 1000) + }) + } } diff --git a/tests/component/files/domain/models/FileMother.ts b/tests/component/files/domain/models/FileMother.ts index 99dc36332..239d1dcaf 100644 --- a/tests/component/files/domain/models/FileMother.ts +++ b/tests/component/files/domain/models/FileMother.ts @@ -148,6 +148,13 @@ export class FileMother { ) } + static createToDownload(): string { + const blob = new Blob(['Name,Age,Location\nJohn,25,New York\nJane,30,San Francisco'], { + type: 'text/csv' + }) + return URL.createObjectURL(blob) + } + static createMany(quantity: number, props?: Partial): File[] { return Array.from({ length: quantity }).map(() => this.create(props)) } diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx index da32a5321..feb22f9f0 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx @@ -10,6 +10,8 @@ import { DatasetLockMother, DatasetMother } from '../../../../../../../../dataset/domain/models/DatasetMother' +import { FileDownloadHelperProvider } from '../../../../../../../../../../src/sections/file/file-download-helper/FileDownloadHelperProvider' +import { FileRepository } from '../../../../../../../../../../src/files/domain/repositories/FileRepository' const fileNonTabular = FileMother.create({ tabularData: undefined, @@ -74,4 +76,18 @@ describe('FileNonTabularDownloadOptions', () => { cy.findByRole('button', { name: 'Plain Text' }).should('have.class', 'disabled') }) + + it('calls the file repository to get the original file', () => { + const fileRepository: FileRepository = {} as FileRepository + const fileToDownload = FileMother.createToDownload() + fileRepository.getById = cy.stub().resolves(fileToDownload) + + cy.customMount( + + + + ) + + cy.wrap(fileRepository.getById).should('be.calledOnceWith', fileNonTabular.id) + }) }) From 2de6a49ac2a27a0b849f25eeb022264936d844d3 Mon Sep 17 00:00:00 2001 From: MellyGray Date: Mon, 27 Nov 2023 16:39:16 +0100 Subject: [PATCH 2/6] feat(IntegrationFileDownload): add e2e test --- .../domain/repositories/FileRepository.ts | 2 +- src/files/domain/useCases/getFile.ts | 2 +- .../FileJSDataverseRepository.ts | 2 +- .../files/FileMockLoadingRepository.ts | 2 +- src/stories/files/FileMockNoDataRepository.ts | 2 +- .../files/FileMockNoFiltersRepository.ts | 2 +- src/stories/files/FileMockRepository.ts | 2 +- .../FileNonTabularDownloadOptions.spec.tsx | 4 +-- .../e2e/sections/dataset/Dataset.spec.tsx | 23 ++++++++++++++ .../files/FileJSDataverseRepository.spec.ts | 31 ++++++++++++++++++- 10 files changed, 62 insertions(+), 10 deletions(-) diff --git a/src/files/domain/repositories/FileRepository.ts b/src/files/domain/repositories/FileRepository.ts index 458be1b4b..b913a5bb7 100644 --- a/src/files/domain/repositories/FileRepository.ts +++ b/src/files/domain/repositories/FileRepository.ts @@ -23,5 +23,5 @@ export interface FileRepository { criteria?: FileCriteria ) => Promise getUserPermissionsById: (id: number) => Promise - getById: (id: number) => Promise + getOriginalFileById: (id: number) => Promise } diff --git a/src/files/domain/useCases/getFile.ts b/src/files/domain/useCases/getFile.ts index c63857399..96f5f01c7 100644 --- a/src/files/domain/useCases/getFile.ts +++ b/src/files/domain/useCases/getFile.ts @@ -4,7 +4,7 @@ export async function getFile( fileRepository: FileRepository, id: number ): Promise { - return fileRepository.getById(id).catch((error: Error) => { + return fileRepository.getOriginalFileById(id).catch((error: Error) => { throw new Error(error.message) }) } diff --git a/src/files/infrastructure/FileJSDataverseRepository.ts b/src/files/infrastructure/FileJSDataverseRepository.ts index 3cf43c92a..fe1328b1d 100644 --- a/src/files/infrastructure/FileJSDataverseRepository.ts +++ b/src/files/infrastructure/FileJSDataverseRepository.ts @@ -148,7 +148,7 @@ export class FileJSDataverseRepository implements FileRepository { }) } - getById(id: number): Promise { + getOriginalFileById(id: number): Promise { return fetch(`${FileJSDataverseRepository.DATAVERSE_BACKEND_URL}/api/access/datafile/${id}`) .then((response) => { if (!response.ok) { diff --git a/src/stories/files/FileMockLoadingRepository.ts b/src/stories/files/FileMockLoadingRepository.ts index b2d04fcd5..318631d86 100644 --- a/src/stories/files/FileMockLoadingRepository.ts +++ b/src/stories/files/FileMockLoadingRepository.ts @@ -59,7 +59,7 @@ export class FileMockLoadingRepository implements FileRepository { } // eslint-disable-next-line unused-imports/no-unused-vars - getById(id: number): Promise { + getOriginalFileById(id: number): Promise { return new Promise((resolve) => { setTimeout(() => { resolve(undefined) diff --git a/src/stories/files/FileMockNoDataRepository.ts b/src/stories/files/FileMockNoDataRepository.ts index 4f18a3327..2b8ff7b41 100644 --- a/src/stories/files/FileMockNoDataRepository.ts +++ b/src/stories/files/FileMockNoDataRepository.ts @@ -59,7 +59,7 @@ export class FileMockNoDataRepository implements FileRepository { } // eslint-disable-next-line unused-imports/no-unused-vars - getById(id: number): Promise { + getOriginalFileById(id: number): Promise { return new Promise((resolve) => { setTimeout(() => { resolve(undefined) diff --git a/src/stories/files/FileMockNoFiltersRepository.ts b/src/stories/files/FileMockNoFiltersRepository.ts index 5f0935022..aab3eb69b 100644 --- a/src/stories/files/FileMockNoFiltersRepository.ts +++ b/src/stories/files/FileMockNoFiltersRepository.ts @@ -62,7 +62,7 @@ export class FileMockNoFiltersRepository implements FileRepository { } // eslint-disable-next-line unused-imports/no-unused-vars - getById(id: number): Promise { + getOriginalFileById(id: number): Promise { return new Promise((resolve) => { setTimeout(() => { resolve(FileMother.createToDownload()) diff --git a/src/stories/files/FileMockRepository.ts b/src/stories/files/FileMockRepository.ts index 419b55d7e..79d27aaed 100644 --- a/src/stories/files/FileMockRepository.ts +++ b/src/stories/files/FileMockRepository.ts @@ -62,7 +62,7 @@ export class FileMockRepository implements FileRepository { } // eslint-disable-next-line unused-imports/no-unused-vars - getById(id: number): Promise { + getOriginalFileById(id: number): Promise { return new Promise((resolve) => { setTimeout(() => { resolve(FileMother.createToDownload()) diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx index feb22f9f0..1c3babc91 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx @@ -80,7 +80,7 @@ describe('FileNonTabularDownloadOptions', () => { it('calls the file repository to get the original file', () => { const fileRepository: FileRepository = {} as FileRepository const fileToDownload = FileMother.createToDownload() - fileRepository.getById = cy.stub().resolves(fileToDownload) + fileRepository.getOriginalFileById = cy.stub().resolves(fileToDownload) cy.customMount( @@ -88,6 +88,6 @@ describe('FileNonTabularDownloadOptions', () => { ) - cy.wrap(fileRepository.getById).should('be.calledOnceWith', fileNonTabular.id) + cy.wrap(fileRepository.getOriginalFileById).should('be.calledOnceWith', fileNonTabular.id) }) }) diff --git a/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx b/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx index 3bc6a7c50..945094452 100644 --- a/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx +++ b/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx @@ -418,4 +418,27 @@ describe('Dataset', () => { }) }) }) + + it('downloads a file', () => { + cy.wrap( + DatasetHelper.createWithFiles(FileHelper.createMany(1)).then((dataset) => + DatasetHelper.publish(dataset.persistentId) + ) + ) + .its('persistentId') + .then((persistentId: string) => { + cy.wait(1500) // Wait for the dataset to be published + cy.visit(`/spa/datasets?persistentId=${persistentId}`) + cy.wait(1500) // Wait for the page to load + + cy.findByText('Files').should('exist') + + cy.findByRole('button', { name: 'Access File' }).should('exist').click() + cy.findByText('Plain Text').should('exist').click() + + cy.visit(`/spa/datasets?persistentId=${persistentId}`) + + cy.findByText('1 Downloads').should('exist') + }) + }) }) diff --git a/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts b/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts index d08c7bbd4..9133904e0 100644 --- a/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts +++ b/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts @@ -264,7 +264,6 @@ describe('File JSDataverse Repository', () => { await fileRepository .getAllByDatasetPersistentId(dataset.persistentId, dataset.version) .then((files) => { - console.log(files) expect(files[0].thumbnail).to.not.be.undefined }) }) @@ -736,4 +735,34 @@ describe('File JSDataverse Repository', () => { }) }) }) + + describe('getOriginalFileById', () => { + it('gets the original file by id', async () => { + const file = FileHelper.create('csv', { + description: 'Some description', + categories: ['category'], + tabIngest: 'true' + }) + const dataset = await DatasetHelper.createWithFiles([file]).then((datasetResponse) => + datasetRepository.getByPersistentId(datasetResponse.persistentId) + ) + if (!dataset) throw new Error('Dataset not found') + + await TestsUtils.wait(2500) // wait for the files to be ingested + + const files = await fileRepository.getAllByDatasetPersistentId( + dataset.persistentId, + dataset.version + ) + + await fileRepository + .getOriginalFileById(files[0].id) + .then((originalFile) => { + expect(originalFile).to.not.be.undefined + }) + .catch((error) => { + throw error + }) + }) + }) }) From 178bd71362acfbd0b8791e5513b3e0af8cdcfdd7 Mon Sep 17 00:00:00 2001 From: MellyGray Date: Tue, 28 Nov 2023 13:44:09 +0100 Subject: [PATCH 3/6] feat(IntegrationFileDownload): connect use case with dataverse API --- src/files/domain/models/File.ts | 5 +- .../domain/repositories/FileRepository.ts | 1 - src/files/domain/useCases/getFile.ts | 10 -- .../FileJSDataverseRepository.ts | 16 --- .../infrastructure/mappers/JSFileMapper.ts | 13 ++- src/sections/dataset/DatasetFactory.tsx | 21 ++-- .../FileNonTabularDownloadOptions.tsx | 4 +- .../FileDownloadHelperContext.ts | 11 -- .../FileDownloadHelperProvider.tsx | 23 ---- .../file-download-helper/useFileDownload.tsx | 19 ---- .../DatasetCitation.stories.tsx | 1 - .../files/FileMockLoadingRepository.ts | 9 -- src/stories/files/FileMockNoDataRepository.ts | 9 -- .../files/FileMockNoFiltersRepository.ts | 10 -- src/stories/files/FileMockRepository.ts | 10 -- .../files/domain/models/FileMother.ts | 8 +- .../FileDownloadOptions.spec.tsx | 2 +- .../FileNonTabularDownloadOptions.spec.tsx | 30 ++---- .../files/FileJSDataverseRepository.spec.ts | 101 +++++++----------- 19 files changed, 74 insertions(+), 229 deletions(-) delete mode 100644 src/files/domain/useCases/getFile.ts delete mode 100644 src/sections/file/file-download-helper/FileDownloadHelperContext.ts delete mode 100644 src/sections/file/file-download-helper/FileDownloadHelperProvider.tsx delete mode 100644 src/sections/file/file-download-helper/useFileDownload.tsx diff --git a/src/files/domain/models/File.ts b/src/files/domain/models/File.ts index b6f685c75..c83274844 100644 --- a/src/files/domain/models/File.ts +++ b/src/files/domain/models/File.ts @@ -158,12 +158,13 @@ export class File { readonly labels: FileLabel[], public readonly isDeleted: boolean, public readonly ingest: FileIngest, - readonly checksum?: FileChecksum, + public readonly originalFileDownloadUrl: string, public thumbnail?: string, readonly directory?: string, readonly embargo?: FileEmbargo, readonly tabularData?: FileTabularData, - readonly description?: string + readonly description?: string, + readonly checksum?: FileChecksum ) {} getLink(): string { diff --git a/src/files/domain/repositories/FileRepository.ts b/src/files/domain/repositories/FileRepository.ts index b913a5bb7..976fd5a66 100644 --- a/src/files/domain/repositories/FileRepository.ts +++ b/src/files/domain/repositories/FileRepository.ts @@ -23,5 +23,4 @@ export interface FileRepository { criteria?: FileCriteria ) => Promise getUserPermissionsById: (id: number) => Promise - getOriginalFileById: (id: number) => Promise } diff --git a/src/files/domain/useCases/getFile.ts b/src/files/domain/useCases/getFile.ts deleted file mode 100644 index 96f5f01c7..000000000 --- a/src/files/domain/useCases/getFile.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { FileRepository } from '../repositories/FileRepository' - -export async function getFile( - fileRepository: FileRepository, - id: number -): Promise { - return fileRepository.getOriginalFileById(id).catch((error: Error) => { - throw new Error(error.message) - }) -} diff --git a/src/files/infrastructure/FileJSDataverseRepository.ts b/src/files/infrastructure/FileJSDataverseRepository.ts index fe1328b1d..e16c3c004 100644 --- a/src/files/infrastructure/FileJSDataverseRepository.ts +++ b/src/files/infrastructure/FileJSDataverseRepository.ts @@ -147,20 +147,4 @@ export class FileJSDataverseRepository implements FileRepository { throw new Error(error.message) }) } - - getOriginalFileById(id: number): Promise { - return fetch(`${FileJSDataverseRepository.DATAVERSE_BACKEND_URL}/api/access/datafile/${id}`) - .then((response) => { - if (!response.ok) { - throw new Error('Network response was not ok') - } - return response.blob() - }) - .then((blob) => { - return URL.createObjectURL(blob) - }) - .catch(() => { - return undefined - }) - } } diff --git a/src/files/infrastructure/mappers/JSFileMapper.ts b/src/files/infrastructure/mappers/JSFileMapper.ts index 3956b6d25..4dc167a41 100644 --- a/src/files/infrastructure/mappers/JSFileMapper.ts +++ b/src/files/infrastructure/mappers/JSFileMapper.ts @@ -46,14 +46,15 @@ export class JSFileMapper { this.toFileDate(jsFile.creationDate, jsFile.publicationDate, jsFile.embargo), this.toFileDownloads(), this.toFileLabels(jsFile.categories, jsFile.tabularTags), - false, // TODO - Implement this when it is added to js-dataverse - { status: FileIngestStatus.NONE }, // TODO - Implement this when it is added to js-dataverse - this.toFileChecksum(jsFile.checksum), + false, + { status: FileIngestStatus.NONE }, + this.toFileOriginalFileDownloadUrl(jsFile.id), this.toFileThumbnail(), this.toFileDirectory(jsFile.directoryLabel), this.toFileEmbargo(jsFile.embargo), this.toFileTabularData(), - this.toFileDescription(jsFile.description) + this.toFileDescription(jsFile.description), + this.toFileChecksum(jsFile.checksum) ) } @@ -159,6 +160,10 @@ export class JSFileMapper { return undefined } + static toFileOriginalFileDownloadUrl(id: number): string { + return `/api/access/datafile/${id}` + } + static toFileThumbnail(): undefined { return undefined // This is always undefined because the thumbnails come from a different endpoint } diff --git a/src/sections/dataset/DatasetFactory.tsx b/src/sections/dataset/DatasetFactory.tsx index e303cc1c0..1ac3e1e15 100644 --- a/src/sections/dataset/DatasetFactory.tsx +++ b/src/sections/dataset/DatasetFactory.tsx @@ -11,7 +11,6 @@ import { SettingJSDataverseRepository } from '../../settings/infrastructure/Sett import { FilePermissionsProvider } from '../file/file-permissions/FilePermissionsProvider' import { SettingsProvider } from '../settings/SettingsProvider' import { DatasetProvider } from './DatasetProvider' -import { FileDownloadHelperProvider } from '../file/file-download-helper/FileDownloadHelperProvider' const datasetRepository = new DatasetJSDataverseRepository() const fileRepository = new FileJSDataverseRepository() @@ -21,17 +20,15 @@ const settingRepository = new SettingJSDataverseRepository() export class DatasetFactory { static create(): ReactElement { return ( - - - - - - - - - - - + + + + + + + + + ) } } diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.tsx b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.tsx index 12a624318..e26049dab 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.tsx @@ -3,7 +3,6 @@ import FileTypeToFriendlyTypeMap from '../../../../../../../../files/domain/mode import { DropdownButtonItem } from '@iqss/dataverse-design-system' import { useDataset } from '../../../../../../DatasetContext' import { useTranslation } from 'react-i18next' -import { useFileDownload } from '../../../../../../../file/file-download-helper/useFileDownload' interface FileNonTabularDownloadOptionsProps { file: File @@ -12,7 +11,6 @@ interface FileNonTabularDownloadOptionsProps { export function FileNonTabularDownloadOptions({ file }: FileNonTabularDownloadOptionsProps) { const { t } = useTranslation('files') const { dataset } = useDataset() - const { originalFile } = useFileDownload(file.id) const originalFileFormatIsKnown = file.type.toDisplayFormat() !== FileTypeToFriendlyTypeMap.unknown @@ -22,7 +20,7 @@ export function FileNonTabularDownloadOptions({ file }: FileNonTabularDownloadOp return ( Promise -} - -export const FileDownloadHelperContext = createContext({ - download: () => Promise.reject('Not implemented') -}) - -export const useFileDownloadHelper = () => useContext(FileDownloadHelperContext) diff --git a/src/sections/file/file-download-helper/FileDownloadHelperProvider.tsx b/src/sections/file/file-download-helper/FileDownloadHelperProvider.tsx deleted file mode 100644 index a2006db8a..000000000 --- a/src/sections/file/file-download-helper/FileDownloadHelperProvider.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { FileRepository } from '../../../files/domain/repositories/FileRepository' -import { PropsWithChildren } from 'react' -import { getFile } from '../../../files/domain/useCases/getFile' -import { FileDownloadHelperContext } from './FileDownloadHelperContext' - -interface FileDownloadProviderProps { - repository: FileRepository -} - -export function FileDownloadHelperProvider({ - repository, - children -}: PropsWithChildren) { - const download = (id: number): Promise => { - return getFile(repository, id) - } - - return ( - - {children} - - ) -} diff --git a/src/sections/file/file-download-helper/useFileDownload.tsx b/src/sections/file/file-download-helper/useFileDownload.tsx deleted file mode 100644 index 22cb7d418..000000000 --- a/src/sections/file/file-download-helper/useFileDownload.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { useEffect, useState } from 'react' -import { useFileDownloadHelper } from './FileDownloadHelperContext' - -export function useFileDownload(id: number) { - const { download } = useFileDownloadHelper() - const [originalFile, setOriginalFile] = useState() - - useEffect(() => { - download(id) - .then((downloadedFile) => { - setOriginalFile(downloadedFile) - }) - .catch((error) => { - console.error('There was an error downloading the file', error) - }) - }, [id]) - - return { originalFile } -} diff --git a/src/stories/dataset/dataset-citation/DatasetCitation.stories.tsx b/src/stories/dataset/dataset-citation/DatasetCitation.stories.tsx index dc89d2f59..cd7d511d4 100644 --- a/src/stories/dataset/dataset-citation/DatasetCitation.stories.tsx +++ b/src/stories/dataset/dataset-citation/DatasetCitation.stories.tsx @@ -34,7 +34,6 @@ export const Default: Story = { export const WithThumbnail: Story = { render: () => { const dataset = DatasetMother.createRealistic({ thumbnail: faker.image.imageUrl() }) - console.log(dataset) return (


diff --git a/src/stories/files/FileMockLoadingRepository.ts b/src/stories/files/FileMockLoadingRepository.ts index 318631d86..eff4bd897 100644 --- a/src/stories/files/FileMockLoadingRepository.ts +++ b/src/stories/files/FileMockLoadingRepository.ts @@ -57,13 +57,4 @@ export class FileMockLoadingRepository implements FileRepository { }, 1000) }) } - - // eslint-disable-next-line unused-imports/no-unused-vars - getOriginalFileById(id: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(undefined) - }, 1000) - }) - } } diff --git a/src/stories/files/FileMockNoDataRepository.ts b/src/stories/files/FileMockNoDataRepository.ts index 2b8ff7b41..ba7c10a3b 100644 --- a/src/stories/files/FileMockNoDataRepository.ts +++ b/src/stories/files/FileMockNoDataRepository.ts @@ -57,13 +57,4 @@ export class FileMockNoDataRepository implements FileRepository { }, 1000) }) } - - // eslint-disable-next-line unused-imports/no-unused-vars - getOriginalFileById(id: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(undefined) - }, 1000) - }) - } } diff --git a/src/stories/files/FileMockNoFiltersRepository.ts b/src/stories/files/FileMockNoFiltersRepository.ts index aab3eb69b..eec689eaa 100644 --- a/src/stories/files/FileMockNoFiltersRepository.ts +++ b/src/stories/files/FileMockNoFiltersRepository.ts @@ -7,7 +7,6 @@ import { FileUserPermissions } from '../../files/domain/models/FileUserPermissio import { FileUserPermissionsMother } from '../../../tests/component/files/domain/models/FileUserPermissionsMother' import { DatasetVersion } from '../../dataset/domain/models/Dataset' import { FileCriteria } from '../../files/domain/models/FileCriteria' -import { FileMother } from '../../../tests/component/files/domain/models/FileMother' export class FileMockNoFiltersRepository implements FileRepository { getAllByDatasetPersistentId( @@ -60,13 +59,4 @@ export class FileMockNoFiltersRepository implements FileRepository { }, 1000) }) } - - // eslint-disable-next-line unused-imports/no-unused-vars - getOriginalFileById(id: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(FileMother.createToDownload()) - }, 1000) - }) - } } diff --git a/src/stories/files/FileMockRepository.ts b/src/stories/files/FileMockRepository.ts index 79d27aaed..63e1499fa 100644 --- a/src/stories/files/FileMockRepository.ts +++ b/src/stories/files/FileMockRepository.ts @@ -8,7 +8,6 @@ import { FileUserPermissionsMother } from '../../../tests/component/files/domain import { FileUserPermissions } from '../../files/domain/models/FileUserPermissions' import { DatasetVersion } from '../../dataset/domain/models/Dataset' import { FileCriteria } from '../../files/domain/models/FileCriteria' -import { FileMother } from '../../../tests/component/files/domain/models/FileMother' export class FileMockRepository implements FileRepository { // eslint-disable-next-line unused-imports/no-unused-vars @@ -60,13 +59,4 @@ export class FileMockRepository implements FileRepository { }, 1000) }) } - - // eslint-disable-next-line unused-imports/no-unused-vars - getOriginalFileById(id: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(FileMother.createToDownload()) - }, 1000) - }) - } } diff --git a/tests/component/files/domain/models/FileMother.ts b/tests/component/files/domain/models/FileMother.ts index 239d1dcaf..0b9b523ad 100644 --- a/tests/component/files/domain/models/FileMother.ts +++ b/tests/component/files/domain/models/FileMother.ts @@ -124,6 +124,7 @@ export class FileMother { description: valueOrUndefined(faker.lorem.paragraph()), isDeleted: faker.datatype.boolean(), ingest: { status: FileIngestStatus.NONE }, + originalFileDownloadUrl: this.createOriginalFileDownloadUrl(), ...props } @@ -139,16 +140,17 @@ export class FileMother { fileMockedData.labels, fileMockedData.isDeleted, fileMockedData.ingest, - fileMockedData.checksum, + fileMockedData.originalFileDownloadUrl, fileMockedData.thumbnail, fileMockedData.directory, fileMockedData.embargo, fileMockedData.tabularData, - fileMockedData.description + fileMockedData.description, + fileMockedData.checksum ) } - static createToDownload(): string { + static createOriginalFileDownloadUrl(): string { const blob = new Blob(['Name,Age,Location\nJohn,25,New York\nJane,30,San Francisco'], { type: 'text/csv' }) diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions.spec.tsx index 0c8d299cb..c8cc64737 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions.spec.tsx @@ -17,7 +17,7 @@ describe('FileDownloadOptions', () => { it('renders the download options for a non-tabular file', () => { cy.customMount() - cy.findByRole('button', { name: 'Plain Text' }).should('exist') + cy.findByRole('link', { name: 'Plain Text' }).should('exist') }) it('renders the download options for a tabular file', () => { diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx index 1c3babc91..2fad88bc1 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx @@ -10,8 +10,6 @@ import { DatasetLockMother, DatasetMother } from '../../../../../../../../dataset/domain/models/DatasetMother' -import { FileDownloadHelperProvider } from '../../../../../../../../../../src/sections/file/file-download-helper/FileDownloadHelperProvider' -import { FileRepository } from '../../../../../../../../../../src/files/domain/repositories/FileRepository' const fileNonTabular = FileMother.create({ tabularData: undefined, @@ -25,25 +23,27 @@ describe('FileNonTabularDownloadOptions', () => { }) cy.customMount() - cy.findByRole('button', { name: 'Original File Format' }) + cy.findByRole('link', { name: 'Original File Format' }) .should('exist') .should('not.have.class', 'disabled') + .should('have.attr', 'href', fileNonTabularUnknown.originalFileDownloadUrl) }) it('renders the download options for a non-tabular file', () => { cy.customMount() - cy.findByRole('button', { name: 'Plain Text' }) + cy.findByRole('link', { name: 'Plain Text' }) .should('exist') .should('not.have.class', 'disabled') + .should('have.attr', 'href', fileNonTabular.originalFileDownloadUrl) }) it('does not render the download options for a tabular file', () => { const fileTabular = FileMother.createWithTabularData() cy.customMount() - cy.findByRole('button', { name: 'Original File Format' }).should('not.exist') - cy.findByRole('button', { name: 'Tab-Delimited' }).should('not.exist') + cy.findByRole('link', { name: 'Original File Format' }).should('not.exist') + cy.findByRole('link', { name: 'Tab-Delimited' }).should('not.exist') }) it('renders the options as disabled when the file ingest is in progress', () => { @@ -56,7 +56,7 @@ describe('FileNonTabularDownloadOptions', () => { }) cy.customMount() - cy.findByRole('button', { name: 'Plain Text' }).should('have.class', 'disabled') + cy.findByRole('link', { name: 'Plain Text' }).should('have.class', 'disabled') }) it('renders the options as disabled when the dataset is locked from file download', () => { @@ -74,20 +74,6 @@ describe('FileNonTabularDownloadOptions', () => { ) - cy.findByRole('button', { name: 'Plain Text' }).should('have.class', 'disabled') - }) - - it('calls the file repository to get the original file', () => { - const fileRepository: FileRepository = {} as FileRepository - const fileToDownload = FileMother.createToDownload() - fileRepository.getOriginalFileById = cy.stub().resolves(fileToDownload) - - cy.customMount( - - - - ) - - cy.wrap(fileRepository.getOriginalFileById).should('be.calledOnceWith', fileNonTabular.id) + cy.findByRole('link', { name: 'Plain Text' }).should('have.class', 'disabled') }) }) diff --git a/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts b/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts index 9133904e0..47bf0b851 100644 --- a/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts +++ b/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts @@ -36,36 +36,39 @@ const fileRepository = new FileJSDataverseRepository() const datasetRepository = new DatasetJSDataverseRepository() const dateNow = new Date() dateNow.setHours(2, 0, 0, 0) -const expectedFile = new File( - 1, - { number: 1, publishingStatus: FilePublishingStatus.DRAFT }, - 'blob', - { - restricted: false, - latestVersionRestricted: false, - canBeRequested: false, - requested: false - }, - new FileType('text/plain'), - new FileSize(25, FileSizeUnit.BYTES), - { - type: FileDateType.DEPOSITED, - date: dateNow - }, - 0, - [], - false, - { status: FileIngestStatus.NONE }, - { - algorithm: 'MD5', - value: '0187a54071542738aa47939e8218e5f2' - }, - undefined, - undefined, - undefined, - undefined, - 'This is an example file' -) +const fileData = (id: number) => { + return new File( + id, + { number: 1, publishingStatus: FilePublishingStatus.DRAFT }, + 'blob', + { + restricted: false, + latestVersionRestricted: false, + canBeRequested: false, + requested: false + }, + new FileType('text/plain'), + new FileSize(25, FileSizeUnit.BYTES), + { + type: FileDateType.DEPOSITED, + date: dateNow + }, + 0, + [], + false, + { status: FileIngestStatus.NONE }, + `/api/access/datafile/${id}`, + undefined, + undefined, + undefined, + undefined, + 'This is an example file', + { + algorithm: 'MD5', + value: '0187a54071542738aa47939e8218e5f2' + } + ) +} describe('File JSDataverse Repository', () => { before(() => { @@ -87,6 +90,7 @@ describe('File JSDataverse Repository', () => { .then((files) => { files.forEach((file, index) => { const expectedFileNames = ['blob', 'blob-1', 'blob-2'] + const expectedFile = fileData(file.id) expect(file.name).to.deep.equal(expectedFileNames[index]) expect(file.version).to.deep.equal(expectedFile.version) expect(file.access).to.deep.equal(expectedFile.access) @@ -100,6 +104,7 @@ describe('File JSDataverse Repository', () => { expect(file.embargo).to.deep.equal(expectedFile.embargo) expect(file.tabularData).to.deep.equal(expectedFile.tabularData) expect(file.description).to.deep.equal(expectedFile.description) + expect(file.originalFileDownloadUrl).to.deep.equal(expectedFile.originalFileDownloadUrl) }) }) }) @@ -145,13 +150,13 @@ describe('File JSDataverse Repository', () => { ) ) .then((files) => { - const expectedPublishedFile = expectedFile + const expectedPublishedFile = fileData(files[0].id) expectedPublishedFile.version.publishingStatus = FilePublishingStatus.RELEASED expectedPublishedFile.date.type = FileDateType.PUBLISHED files.forEach((file) => { expect(file.version).to.deep.equal(expectedPublishedFile.version) - cy.compareDate(file.date.date, expectedFile.date.date) + cy.compareDate(file.date.date, fileData(file.id).date.date) }) }) }) @@ -184,7 +189,7 @@ describe('File JSDataverse Repository', () => { ) ) .then((files) => { - const expectedDeaccessionedFile = expectedFile + const expectedDeaccessionedFile = fileData(files[0].id) expectedDeaccessionedFile.version.publishingStatus = FilePublishingStatus.DEACCESSIONED files.forEach((file) => { @@ -735,34 +740,4 @@ describe('File JSDataverse Repository', () => { }) }) }) - - describe('getOriginalFileById', () => { - it('gets the original file by id', async () => { - const file = FileHelper.create('csv', { - description: 'Some description', - categories: ['category'], - tabIngest: 'true' - }) - const dataset = await DatasetHelper.createWithFiles([file]).then((datasetResponse) => - datasetRepository.getByPersistentId(datasetResponse.persistentId) - ) - if (!dataset) throw new Error('Dataset not found') - - await TestsUtils.wait(2500) // wait for the files to be ingested - - const files = await fileRepository.getAllByDatasetPersistentId( - dataset.persistentId, - dataset.version - ) - - await fileRepository - .getOriginalFileById(files[0].id) - .then((originalFile) => { - expect(originalFile).to.not.be.undefined - }) - .catch((error) => { - throw error - }) - }) - }) }) From 09cd2a3e1da1abe300fa5b2b57bc0b714481fd13 Mon Sep 17 00:00:00 2001 From: MellyGray Date: Tue, 28 Nov 2023 16:36:18 +0100 Subject: [PATCH 4/6] fix(FileDownloadOptions): don't show the options if user do not have permissions --- .../access-file-menu/FileDownloadOptions.tsx | 7 +++ .../FileDownloadOptions.spec.tsx | 46 +++++++++++++++++-- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions.tsx b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions.tsx index 61f0e8400..a1b98acf9 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions.tsx @@ -4,6 +4,7 @@ import { File } from '../../../../../../../../files/domain/models/File' import { FileTabularDownloadOptions } from './FileTabularDownloadOptions' import { FileNonTabularDownloadOptions } from './FileNonTabularDownloadOptions' import { useTranslation } from 'react-i18next' +import { useFileDownloadPermission } from '../../../../../../../file/file-permissions/useFileDownloadPermission' interface FileDownloadOptionsProps { file: File @@ -11,6 +12,12 @@ interface FileDownloadOptionsProps { export function FileDownloadOptions({ file }: FileDownloadOptionsProps) { const { t } = useTranslation('files') + const { sessionUserHasFileDownloadPermission } = useFileDownloadPermission(file) + + if (!sessionUserHasFileDownloadPermission) { + return <> + } + return ( <> diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions.spec.tsx index c8cc64737..db4ce1522 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions.spec.tsx @@ -1,27 +1,67 @@ import { FileDownloadOptions } from '../../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions' import { FileMother } from '../../../../../../../../files/domain/models/FileMother' import { FileType } from '../../../../../../../../../../src/files/domain/models/File' +import { FileUserPermissionsMother } from '../../../../../../../../files/domain/models/FileUserPermissionsMother' +import { FilePermissionsProvider } from '../../../../../../../../../../src/sections/file/file-permissions/FilePermissionsProvider' +import { FileRepository } from '../../../../../../../../../../src/files/domain/repositories/FileRepository' const fileNonTabular = FileMother.create({ tabularData: undefined, type: new FileType('text/plain') }) const fileTabular = FileMother.createWithTabularData() +const fileRepository = {} as FileRepository describe('FileDownloadOptions', () => { + beforeEach(() => { + fileRepository.getUserPermissionsById = cy.stub().resolves( + FileUserPermissionsMother.create({ + canDownloadFile: true + }) + ) + }) + it('renders the download options header', () => { - cy.customMount() + cy.customMount( + + + + ) cy.findByRole('heading', { name: 'Download Options' }).should('exist') }) + it('does not render the download options if the user does not have permissions', () => { + fileRepository.getUserPermissionsById = cy.stub().resolves( + FileUserPermissionsMother.create({ + canDownloadFile: false + }) + ) + + cy.customMount( + + + + ) + + cy.findByRole('heading', { name: 'Download Options' }).should('not.exist') + }) + it('renders the download options for a non-tabular file', () => { - cy.customMount() + cy.customMount( + + {' '} + + ) cy.findByRole('link', { name: 'Plain Text' }).should('exist') }) it('renders the download options for a tabular file', () => { - cy.customMount() + cy.customMount( + + + + ) cy.findByRole('button', { name: 'Comma Separated Values (Original File Format)' }).should( 'exist' From d458245ce82a63c67fc1165f18087545f7fcc253 Mon Sep 17 00:00:00 2001 From: MellyGray Date: Tue, 28 Nov 2023 17:51:33 +0100 Subject: [PATCH 5/6] feat(IntegrationFileDownload): add tabular files download --- src/files/domain/models/File.ts | 8 +++- .../infrastructure/mappers/JSFileMapper.ts | 9 +++- .../FileNonTabularDownloadOptions.tsx | 3 +- .../FileTabularDownloadOptions.tsx | 10 ++-- .../files/domain/models/FileMother.ts | 10 ++-- .../access-file-menu/AccessFileMenu.spec.tsx | 16 ++++++- .../FileDownloadOptions.spec.tsx | 4 +- .../FileNonTabularDownloadOptions.spec.tsx | 4 +- .../FileTabularDownloadOptions.spec.tsx | 47 ++++++++++--------- .../e2e/sections/dataset/Dataset.spec.tsx | 13 ++++- .../files/FileJSDataverseRepository.spec.ts | 8 +++- 11 files changed, 87 insertions(+), 45 deletions(-) diff --git a/src/files/domain/models/File.ts b/src/files/domain/models/File.ts index c83274844..1be76bc8f 100644 --- a/src/files/domain/models/File.ts +++ b/src/files/domain/models/File.ts @@ -145,6 +145,12 @@ export interface FileIngest { reportMessage?: string } +export interface FileDownloadUrls { + original: string + tabular?: string + rData?: string +} + export class File { constructor( readonly id: number, @@ -158,7 +164,7 @@ export class File { readonly labels: FileLabel[], public readonly isDeleted: boolean, public readonly ingest: FileIngest, - public readonly originalFileDownloadUrl: string, + public readonly downloadUrls: FileDownloadUrls, public thumbnail?: string, readonly directory?: string, readonly embargo?: FileEmbargo, diff --git a/src/files/infrastructure/mappers/JSFileMapper.ts b/src/files/infrastructure/mappers/JSFileMapper.ts index 4dc167a41..cba999277 100644 --- a/src/files/infrastructure/mappers/JSFileMapper.ts +++ b/src/files/infrastructure/mappers/JSFileMapper.ts @@ -4,6 +4,7 @@ import { FileChecksum, FileDate, FileDateType, + FileDownloadUrls, FileEmbargo, FileIngestStatus, FileLabel, @@ -160,8 +161,12 @@ export class JSFileMapper { return undefined } - static toFileOriginalFileDownloadUrl(id: number): string { - return `/api/access/datafile/${id}` + static toFileOriginalFileDownloadUrl(id: number): FileDownloadUrls { + return { + original: `/api/access/datafile/${id}?format=original`, + tabular: `/api/access/datafile/${id}`, + rData: `/api/access/datafile/${id}?format=RData` + } } static toFileThumbnail(): undefined { diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.tsx b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.tsx index e26049dab..eb64a832d 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.tsx @@ -20,8 +20,7 @@ export function FileNonTabularDownloadOptions({ file }: FileNonTabularDownloadOp return ( {originalFileFormatIsKnown && ( - {`${file.type.original} (${t( - 'actions.accessFileMenu.downloadOptions.options.original' - )})`} + {`${ + file.type.original + } (${t('actions.accessFileMenu.downloadOptions.options.original')})`} )} - + {t('actions.accessFileMenu.downloadOptions.options.tabular')} {file.type.original !== 'R Data' && ( - + {t('actions.accessFileMenu.downloadOptions.options.RData')} )} diff --git a/tests/component/files/domain/models/FileMother.ts b/tests/component/files/domain/models/FileMother.ts index 0b9b523ad..c06948a17 100644 --- a/tests/component/files/domain/models/FileMother.ts +++ b/tests/component/files/domain/models/FileMother.ts @@ -124,7 +124,11 @@ export class FileMother { description: valueOrUndefined(faker.lorem.paragraph()), isDeleted: faker.datatype.boolean(), ingest: { status: FileIngestStatus.NONE }, - originalFileDownloadUrl: this.createOriginalFileDownloadUrl(), + downloadUrls: { + original: this.createDownloadUrl(), + tabular: this.createDownloadUrl(), + rData: this.createDownloadUrl() + }, ...props } @@ -140,7 +144,7 @@ export class FileMother { fileMockedData.labels, fileMockedData.isDeleted, fileMockedData.ingest, - fileMockedData.originalFileDownloadUrl, + fileMockedData.downloadUrls, fileMockedData.thumbnail, fileMockedData.directory, fileMockedData.embargo, @@ -150,7 +154,7 @@ export class FileMother { ) } - static createOriginalFileDownloadUrl(): string { + static createDownloadUrl(): string { const blob = new Blob(['Name,Age,Location\nJohn,25,New York\nJane,30,San Francisco'], { type: 'text/csv' }) diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessFileMenu.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessFileMenu.spec.tsx index b25c43a4e..39887fd78 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessFileMenu.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessFileMenu.spec.tsx @@ -1,9 +1,21 @@ import { AccessFileMenu } from '../../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessFileMenu' import { FileMother } from '../../../../../../../../files/domain/models/FileMother' import { Suspense } from 'react' +import { FilePermissionsProvider } from '../../../../../../../../../../src/sections/file/file-permissions/FilePermissionsProvider' +import { FileRepository } from '../../../../../../../../../../src/files/domain/repositories/FileRepository' +import { FileUserPermissionsMother } from '../../../../../../../../files/domain/models/FileUserPermissionsMother' const file = FileMother.create() + +const fileRepository = {} as FileRepository describe('AccessFileMenu', () => { + beforeEach(() => { + fileRepository.getUserPermissionsById = cy.stub().resolves( + FileUserPermissionsMother.create({ + canDownloadFile: true + }) + ) + }) it('renders the access file menu', () => { cy.customMount() @@ -55,7 +67,9 @@ describe('AccessFileMenu', () => { it('renders the download options header', () => { cy.customMount( - + + + ) diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions.spec.tsx index db4ce1522..f4c6c9b44 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions.spec.tsx @@ -63,8 +63,6 @@ describe('FileDownloadOptions', () => { ) - cy.findByRole('button', { name: 'Comma Separated Values (Original File Format)' }).should( - 'exist' - ) + cy.findByRole('link', { name: 'Comma Separated Values (Original File Format)' }).should('exist') }) }) diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx index 2fad88bc1..d2207f468 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx @@ -26,7 +26,7 @@ describe('FileNonTabularDownloadOptions', () => { cy.findByRole('link', { name: 'Original File Format' }) .should('exist') .should('not.have.class', 'disabled') - .should('have.attr', 'href', fileNonTabularUnknown.originalFileDownloadUrl) + .should('have.attr', 'href', fileNonTabularUnknown.downloadUrls.original) }) it('renders the download options for a non-tabular file', () => { @@ -35,7 +35,7 @@ describe('FileNonTabularDownloadOptions', () => { cy.findByRole('link', { name: 'Plain Text' }) .should('exist') .should('not.have.class', 'disabled') - .should('have.attr', 'href', fileNonTabular.originalFileDownloadUrl) + .should('have.attr', 'href', fileNonTabular.downloadUrls.original) }) it('does not render the download options for a tabular file', () => { diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileTabularDownloadOptions.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileTabularDownloadOptions.spec.tsx index d54605ab2..e89603eca 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileTabularDownloadOptions.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileTabularDownloadOptions.spec.tsx @@ -1,4 +1,3 @@ -import { FileDownloadOptions } from '../../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions' import { FileMother } from '../../../../../../../../files/domain/models/FileMother' import { FileIngestStatus, @@ -24,31 +23,35 @@ describe('FileTabularDownloadOptions', () => { it('renders the download options for a tabular file', () => { cy.customMount() - cy.findByRole('button', { name: 'Comma Separated Values (Original File Format)' }).should( - 'exist' - ) - cy.findByRole('button', { name: 'Tab-Delimited' }) + cy.findByRole('link', { name: 'Comma Separated Values (Original File Format)' }) + .should('exist') + .should('have.attr', 'href', fileTabular.downloadUrls.original) + cy.findByRole('link', { name: 'Tab-Delimited' }) + .should('exist') + .should('have.attr', 'href', fileTabular.downloadUrls.tabular) + .should('not.have.class', 'disabled') + cy.findByRole('link', { name: 'R Data' }) .should('exist') .should('not.have.class', 'disabled') - cy.findByRole('button', { name: 'R Data' }).should('exist').should('not.have.class', 'disabled') + .should('have.attr', 'href', fileTabular.downloadUrls.rData) }) it('renders the download options for a tabular file of unknown original type', () => { - cy.customMount() + cy.customMount() - cy.findByRole('button', { name: /(Original File Format)/ }).should('not.exist') - cy.findByRole('button', { name: 'Tab-Delimited' }) + cy.findByRole('link', { name: /(Original File Format)/ }).should('not.exist') + cy.findByRole('link', { name: 'Tab-Delimited' }) .should('exist') .should('not.have.class', 'disabled') - cy.findByRole('button', { name: 'R Data' }).should('exist').should('not.have.class', 'disabled') + cy.findByRole('link', { name: 'R Data' }).should('exist').should('not.have.class', 'disabled') }) it('does not render the download options for a non-tabular file', () => { cy.customMount() - cy.findByRole('button', { name: /(Original File Format)/ }).should('not.exist') - cy.findByRole('button', { name: 'Tab-Delimited' }).should('not.exist') - cy.findByRole('button', { name: 'R Data' }).should('not.exist') + cy.findByRole('link', { name: /(Original File Format)/ }).should('not.exist') + cy.findByRole('link', { name: 'Tab-Delimited' }).should('not.exist') + cy.findByRole('link', { name: 'R Data' }).should('not.exist') }) it('renders the options as disabled when the file ingest is in progress', () => { @@ -59,13 +62,13 @@ describe('FileTabularDownloadOptions', () => { }) cy.customMount() - cy.findByRole('button', { name: 'Comma Separated Values (Original File Format)' }) + cy.findByRole('link', { name: 'Comma Separated Values (Original File Format)' }) .should('exist') .should('have.class', 'disabled') - cy.findByRole('button', { name: 'Tab-Delimited' }) + cy.findByRole('link', { name: 'Tab-Delimited' }) .should('exist') .should('have.class', 'disabled') - cy.findByRole('button', { name: 'R Data' }).should('exist').should('have.class', 'disabled') + cy.findByRole('link', { name: 'R Data' }).should('exist').should('have.class', 'disabled') }) it('renders the options as disabled when the dataset is locked from file download', () => { @@ -83,13 +86,13 @@ describe('FileTabularDownloadOptions', () => { ) - cy.findByRole('button', { name: 'Comma Separated Values (Original File Format)' }) + cy.findByRole('link', { name: 'Comma Separated Values (Original File Format)' }) .should('exist') .should('have.class', 'disabled') - cy.findByRole('button', { name: 'Tab-Delimited' }) + cy.findByRole('link', { name: 'Tab-Delimited' }) .should('exist') .should('have.class', 'disabled') - cy.findByRole('button', { name: 'R Data' }).should('exist').should('have.class', 'disabled') + cy.findByRole('link', { name: 'R Data' }).should('exist').should('have.class', 'disabled') }) it('does not render the RData option if the file type is already R Data', () => { @@ -98,12 +101,12 @@ describe('FileTabularDownloadOptions', () => { }) cy.customMount() - cy.findByRole('button', { name: 'R Data (Original File Format)' }) + cy.findByRole('link', { name: 'R Data (Original File Format)' }) .should('exist') .should('not.have.class', 'disabled') - cy.findByRole('button', { name: 'Tab-Delimited' }) + cy.findByRole('link', { name: 'Tab-Delimited' }) .should('exist') .should('not.have.class', 'disabled') - cy.findByRole('button', { name: 'R Data' }).should('not.exist') + cy.findByRole('link', { name: 'R Data' }).should('not.exist') }) }) diff --git a/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx b/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx index 945094452..96ef1d87b 100644 --- a/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx +++ b/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx @@ -434,9 +434,18 @@ describe('Dataset', () => { cy.findByText('Files').should('exist') cy.findByRole('button', { name: 'Access File' }).should('exist').click() - cy.findByText('Plain Text').should('exist').click() - cy.visit(`/spa/datasets?persistentId=${persistentId}`) + // Workaround for issue where Cypress gets stuck on the download + cy.window() + .document() + .then(function (doc) { + doc.addEventListener('click', () => { + setTimeout(function () { + doc.location.reload() + }, 5000) + }) + cy.findByText('Plain Text').should('exist').click() + }) cy.findByText('1 Downloads').should('exist') }) diff --git a/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts b/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts index 47bf0b851..e2513adf0 100644 --- a/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts +++ b/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts @@ -57,7 +57,11 @@ const fileData = (id: number) => { [], false, { status: FileIngestStatus.NONE }, - `/api/access/datafile/${id}`, + { + original: `/api/access/datafile/${id}?format=original`, + tabular: `/api/access/datafile/${id}`, + rData: `/api/access/datafile/${id}?format=RData` + }, undefined, undefined, undefined, @@ -104,7 +108,7 @@ describe('File JSDataverse Repository', () => { expect(file.embargo).to.deep.equal(expectedFile.embargo) expect(file.tabularData).to.deep.equal(expectedFile.tabularData) expect(file.description).to.deep.equal(expectedFile.description) - expect(file.originalFileDownloadUrl).to.deep.equal(expectedFile.originalFileDownloadUrl) + expect(file.downloadUrls).to.deep.equal(expectedFile.downloadUrls) }) }) }) From 6610d27c10777bb948255ec4ea637b883ac5ab96 Mon Sep 17 00:00:00 2001 From: MellyGray Date: Mon, 11 Dec 2023 12:43:50 +0100 Subject: [PATCH 6/6] fix: unit tests mocks --- .../access-file-menu/AccessFileMenu.stories.tsx | 2 +- .../file-info/file-info-cell/FileInfoCell.stories.tsx | 2 +- tests/component/files/domain/models/FileMother.ts | 10 +++++++++- .../access-file-menu/AccessFileMenu.spec.tsx | 9 ++++----- .../access-file-menu/FileDownloadOptions.spec.tsx | 8 ++------ .../FileNonTabularDownloadOptions.spec.tsx | 2 +- .../FileTabularDownloadOptions.spec.tsx | 8 ++++---- .../file-info-cell/file-info-data/FileType.spec.tsx | 2 +- 8 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/stories/dataset/dataset-files/files-table/file-actions/file-action-buttons/access-file-menu/AccessFileMenu.stories.tsx b/src/stories/dataset/dataset-files/files-table/file-actions/file-action-buttons/access-file-menu/AccessFileMenu.stories.tsx index a3a80a32d..b016c7722 100644 --- a/src/stories/dataset/dataset-files/files-table/file-actions/file-action-buttons/access-file-menu/AccessFileMenu.stories.tsx +++ b/src/stories/dataset/dataset-files/files-table/file-actions/file-action-buttons/access-file-menu/AccessFileMenu.stories.tsx @@ -25,7 +25,7 @@ export const NonTabularFiles: Story = { } export const TabularFiles: Story = { - render: () => + render: () => } export const Restricted: Story = { diff --git a/src/stories/dataset/dataset-files/files-table/file-info/file-info-cell/FileInfoCell.stories.tsx b/src/stories/dataset/dataset-files/files-table/file-info/file-info-cell/FileInfoCell.stories.tsx index 6f4d8c401..7cd2f550d 100644 --- a/src/stories/dataset/dataset-files/files-table/file-info/file-info-cell/FileInfoCell.stories.tsx +++ b/src/stories/dataset/dataset-files/files-table/file-info/file-info-cell/FileInfoCell.stories.tsx @@ -29,7 +29,7 @@ export const WithEmbargo: Story = { } export const WithTabularData: Story = { - render: () => + render: () => } export const WithDescription: Story = { diff --git a/tests/component/files/domain/models/FileMother.ts b/tests/component/files/domain/models/FileMother.ts index c06948a17..880cbb459 100644 --- a/tests/component/files/domain/models/FileMother.ts +++ b/tests/component/files/domain/models/FileMother.ts @@ -225,7 +225,7 @@ export class FileMother { }) } - static createWithTabularData(props?: Partial): File { + static createTabular(props?: Partial): File { return this.createDefault({ type: new FileType('text/tab-separated-values', 'Comma Separated Values'), tabularData: { @@ -237,6 +237,14 @@ export class FileMother { }) } + static createNonTabular(props?: Partial): File { + return this.createDefault({ + type: new FileType('text/plain'), + tabularData: undefined, + ...props + }) + } + static createWithDescription(): File { return this.createDefault({ description: faker.lorem.paragraph() diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessFileMenu.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessFileMenu.spec.tsx index 39887fd78..460cfab8d 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessFileMenu.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessFileMenu.spec.tsx @@ -65,12 +65,11 @@ describe('AccessFileMenu', () => { }) it('renders the download options header', () => { + const filePublic = FileMother.createWithPublicAccess() cy.customMount( - - - - - + + + ) cy.findByRole('button', { name: 'Access File' }).click() diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions.spec.tsx index f4c6c9b44..912c63a18 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions.spec.tsx @@ -1,15 +1,11 @@ import { FileDownloadOptions } from '../../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions' import { FileMother } from '../../../../../../../../files/domain/models/FileMother' -import { FileType } from '../../../../../../../../../../src/files/domain/models/File' import { FileUserPermissionsMother } from '../../../../../../../../files/domain/models/FileUserPermissionsMother' import { FilePermissionsProvider } from '../../../../../../../../../../src/sections/file/file-permissions/FilePermissionsProvider' import { FileRepository } from '../../../../../../../../../../src/files/domain/repositories/FileRepository' -const fileNonTabular = FileMother.create({ - tabularData: undefined, - type: new FileType('text/plain') -}) -const fileTabular = FileMother.createWithTabularData() +const fileNonTabular = FileMother.createNonTabular() +const fileTabular = FileMother.createTabular() const fileRepository = {} as FileRepository describe('FileDownloadOptions', () => { beforeEach(() => { diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx index d2207f468..2d9cf8c17 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx @@ -39,7 +39,7 @@ describe('FileNonTabularDownloadOptions', () => { }) it('does not render the download options for a tabular file', () => { - const fileTabular = FileMother.createWithTabularData() + const fileTabular = FileMother.createTabular() cy.customMount() cy.findByRole('link', { name: 'Original File Format' }).should('not.exist') diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileTabularDownloadOptions.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileTabularDownloadOptions.spec.tsx index e89603eca..8dad61fb6 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileTabularDownloadOptions.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileTabularDownloadOptions.spec.tsx @@ -15,8 +15,8 @@ const fileNonTabular = FileMother.create({ tabularData: undefined, type: new FileType('text/plain') }) -const fileTabular = FileMother.createWithTabularData() -const fileTabularUnknown = FileMother.createWithTabularData({ +const fileTabular = FileMother.createTabular() +const fileTabularUnknown = FileMother.createTabular({ type: new FileType('text/tab-separated-values', 'Unknown') }) describe('FileTabularDownloadOptions', () => { @@ -55,7 +55,7 @@ describe('FileTabularDownloadOptions', () => { }) it('renders the options as disabled when the file ingest is in progress', () => { - const fileTabularInProgress = FileMother.createWithTabularData({ + const fileTabularInProgress = FileMother.createTabular({ ingest: { status: FileIngestStatus.IN_PROGRESS } @@ -96,7 +96,7 @@ describe('FileTabularDownloadOptions', () => { }) it('does not render the RData option if the file type is already R Data', () => { - const fileTabularRData = FileMother.createWithTabularData({ + const fileTabularRData = FileMother.createTabular({ type: new FileType('text/tab-separated-values', 'R Data') }) cy.customMount() diff --git a/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileType.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileType.spec.tsx index db176f339..e68ae02c7 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileType.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileType.spec.tsx @@ -28,7 +28,7 @@ describe('FileType', () => { }) it('renders the type correctly when is a tabular file', () => { - const file = FileMother.createWithTabularData({ + const file = FileMother.createTabular({ size: new FileSize(123.03932894722, FileSizeUnit.BYTES) })