diff --git a/README.md b/README.md index c6e758b18..a91b5db61 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ ## Demo videos - 2023-08-01: [View mode of the dataset page](https://groups.google.com/g/dataverse-community/c/cxZ3Bal_-uo/m/h3kh3iVNCwAJ) +- 2023-12-13: [Files table on the dataset page](https://groups.google.com/g/dataverse-community/c/w_rEMddESYc/m/6F7QC1p-AgAJ) ## Getting Started diff --git a/public/locales/en/dataset.json b/public/locales/en/dataset.json index e08244985..b9a083d83 100644 --- a/public/locales/en/dataset.json +++ b/public/locales/en/dataset.json @@ -54,9 +54,12 @@ }, "accessDataset": { "title": "Access Dataset", - "downloadZip": "Download ZIP", - "downloadOriginalZip": "Original Format ZIP", - "downloadArchiveZip": "Archive Format (.tab) ZIP" + "downloadOptions": { + "header": "Download Options", + "zip": "Download ZIP", + "originalZip": "Original Format ZIP", + "archivalZip": "Archival Format (.tab) ZIP" + } }, "uploadFiles": "Upload Files" }, diff --git a/src/dataset/domain/models/Dataset.ts b/src/dataset/domain/models/Dataset.ts index a85bed30f..96c56d448 100644 --- a/src/dataset/domain/models/Dataset.ts +++ b/src/dataset/domain/models/Dataset.ts @@ -366,9 +366,9 @@ export class Dataset { public readonly hasOneTabularFileAtLeast: boolean, public readonly isValid: boolean, public readonly downloadUrls: DatasetDownloadUrls, + public readonly fileDownloadSizes: FileDownloadSize[], public readonly thumbnail?: string, public readonly privateUrl?: PrivateUrl, - public readonly fileDownloadSizes?: FileDownloadSize[], public readonly requestedVersion?: string // will be set if the user requested a version that did not exist ) {} @@ -446,9 +446,9 @@ export class Dataset { public readonly hasOneTabularFileAtLeast: boolean, public readonly isValid: boolean, public readonly downloadUrls: DatasetDownloadUrls, + public readonly fileDownloadSizes: FileDownloadSize[], public readonly thumbnail?: string, public readonly privateUrl?: PrivateUrl, - public readonly fileDownloadSizes?: FileDownloadSize[], public readonly requestedVersion?: string // will be set if the user requested a version that did not exist ) { this.withAlerts() @@ -509,9 +509,9 @@ export class Dataset { this.hasOneTabularFileAtLeast, this.isValid, this.downloadUrls, + this.fileDownloadSizes, this.thumbnail, this.privateUrl, - this.fileDownloadSizes, this.requestedVersion ) } diff --git a/src/dataset/infrastructure/mappers/JSDatasetMapper.ts b/src/dataset/infrastructure/mappers/JSDatasetMapper.ts index 60adc8be0..bd7d8dbdb 100644 --- a/src/dataset/infrastructure/mappers/JSDatasetMapper.ts +++ b/src/dataset/infrastructure/mappers/JSDatasetMapper.ts @@ -1,28 +1,33 @@ import { Dataset as JSDataset, + DatasetLock as JSDatasetLock, DatasetMetadataBlock as JSDatasetMetadataBlock, DatasetMetadataBlocks as JSDatasetMetadataBlocks, DatasetMetadataFields as JSDatasetMetadataFields, - DatasetVersionInfo as JSDatasetVersionInfo, DatasetUserPermissions as JSDatasetPermissions, - DatasetLock as JSDatasetLock + DatasetVersionInfo as JSDatasetVersionInfo } from '@iqss/dataverse-client-javascript' import { DatasetVersionState as JSDatasetVersionState } from '@iqss/dataverse-client-javascript/dist/datasets/domain/models/Dataset' import { Dataset, - DatasetPublishingStatus, + DatasetDownloadUrls, + DatasetLock, + DatasetLockReason, DatasetMetadataBlock, DatasetMetadataBlocks, DatasetMetadataFields, + DatasetPermissions, + DatasetPublishingStatus, DatasetVersion, MetadataBlockName, PrivateUrl, - DatasetDownloadUrls, - DatasetPermissions, - DatasetLock, - DatasetLockReason, DatasetVersionNumber } from '../../domain/models/Dataset' +import { + FileDownloadMode, + FileDownloadSize, + FileSizeUnit +} from '../../../files/domain/models/FilePreview' export class JSDatasetMapper { static toDataset( @@ -31,6 +36,8 @@ export class JSDatasetMapper { jsDatasetSummaryFieldsNames: string[], jsDatasetPermissions: JSDatasetPermissions, jsDatasetLocks: JSDatasetLock[], + jsDatasetFilesTotalOriginalDownloadSize: number, + jsDatasetFilesTotalArchivalDownloadSize: number, requestedVersion?: string, privateUrl?: PrivateUrl ): Dataset { @@ -57,9 +64,12 @@ export class JSDatasetMapper { true, // TODO Connect with dataset hasOneTabularFileAtLeast true, // TODO Connect with dataset isValid JSDatasetMapper.toDownloadUrls(jsDataset.persistentId, version), + JSDatasetMapper.toFileDownloadSizes( + jsDatasetFilesTotalOriginalDownloadSize, + jsDatasetFilesTotalArchivalDownloadSize + ), undefined, // TODO: get dataset thumbnail from Dataverse https://github.com/IQSS/dataverse-frontend/issues/203 privateUrl, - [], // TODO: Connect with file download use case, requestedVersion ).build() } @@ -217,6 +227,7 @@ export class JSDatasetMapper { archival: `/api/access/dataset/:persistentId/versions/${version.number.toString()}?persistentId=${jsDatasetPersistentId}` } } + static toSomeDatasetVersionHasBeenReleased(jsDatasetVersionInfo: JSDatasetVersionInfo): boolean { return ( jsDatasetVersionInfo.releaseTime !== undefined && @@ -242,4 +253,22 @@ export class JSDatasetMapper { } }) } + + static toFileDownloadSizes( + jsDatasetFilesTotalOriginalDownloadSize: number, + jsDatasetFilesTotalArchivalDownloadSize: number + ): FileDownloadSize[] { + return [ + new FileDownloadSize( + jsDatasetFilesTotalOriginalDownloadSize, + FileSizeUnit.BYTES, + FileDownloadMode.ORIGINAL + ), + new FileDownloadSize( + jsDatasetFilesTotalArchivalDownloadSize, + FileSizeUnit.BYTES, + FileDownloadMode.ARCHIVAL + ) + ] + } } diff --git a/src/dataset/infrastructure/repositories/DatasetJSDataverseRepository.ts b/src/dataset/infrastructure/repositories/DatasetJSDataverseRepository.ts index 02f05124b..c3773641b 100644 --- a/src/dataset/infrastructure/repositories/DatasetJSDataverseRepository.ts +++ b/src/dataset/infrastructure/repositories/DatasetJSDataverseRepository.ts @@ -11,12 +11,13 @@ import { getDatasetUserPermissions, ReadError, getDatasetLocks, - DatasetLock as JSDatasetLock + DatasetLock as JSDatasetLock, + getDatasetFilesTotalDownloadSize, + FileDownloadSizeMode } from '@iqss/dataverse-client-javascript' import { JSDatasetMapper } from '../mappers/JSDatasetMapper' const includeDeaccessioned = true - export class DatasetJSDataverseRepository implements DatasetRepository { getByPersistentId( persistentId: string, @@ -31,23 +32,41 @@ export class DatasetJSDataverseRepository implements DatasetRepository { getDatasetSummaryFieldNames.execute(), getDatasetCitation.execute(jsDataset.id, this.versionToVersionId(version)), getDatasetUserPermissions.execute(jsDataset.id), - getDatasetLocks.execute(jsDataset.id) + getDatasetLocks.execute(jsDataset.id), + getDatasetFilesTotalDownloadSize.execute( + persistentId, + this.versionToVersionId(version), + FileDownloadSizeMode.ORIGINAL, + undefined, + includeDeaccessioned + ), + getDatasetFilesTotalDownloadSize.execute( + persistentId, + this.versionToVersionId(version), + FileDownloadSizeMode.ARCHIVAL, + undefined, + includeDeaccessioned + ) ]) ) .then( - ([jsDataset, summaryFieldsNames, citation, jsDatasetPermissions, jsDatasetLocks]: [ - JSDataset, - string[], - string, - JSDatasetPermissions, - JSDatasetLock[] - ]) => + ([ + jsDataset, + summaryFieldsNames, + citation, + jsDatasetPermissions, + jsDatasetLocks, + jsDatasetFilesTotalOriginalDownloadSize, + jsDatasetFilesTotalArchivalDownloadSize + ]: [JSDataset, string[], string, JSDatasetPermissions, JSDatasetLock[], number, number]) => JSDatasetMapper.toDataset( jsDataset, citation, summaryFieldsNames, jsDatasetPermissions, jsDatasetLocks, + jsDatasetFilesTotalOriginalDownloadSize, + jsDatasetFilesTotalArchivalDownloadSize, requestedVersion ) ) @@ -76,10 +95,12 @@ export class DatasetJSDataverseRepository implements DatasetRepository { canManageDatasetPermissions: true, canDeleteDatasetDraft: true, canViewUnpublishedDataset: true - }, - [] + }, // TODO Connect with JS dataset permissions for privateUrl when it is available in js-dataverse + [], // TODO Connect with JS dataset locks for privateUrl when it is available in js-dataverse + 0, // TODO Connect with JS dataset filesTotalDownloadSize for privateUrl when it is available in js-dataverse + 0 // TODO Connect with JS dataset filesTotalDownloadSize for privateUrl when it is available in js-dataverse ) - ) // TODO Connect with JS dataset permissions and getDatasetLocks.execute(privateUrlToken) when it is available in js-dataverse + ) .catch((error: ReadError) => { throw new Error(error.message) }) diff --git a/src/files/domain/models/FilePreview.ts b/src/files/domain/models/FilePreview.ts index 293fc15f0..1cdd9bd2d 100644 --- a/src/files/domain/models/FilePreview.ts +++ b/src/files/domain/models/FilePreview.ts @@ -20,7 +20,7 @@ export class FileSize { } constructor(readonly value: number, readonly unit: FileSizeUnit) { - ;[this.value, this.unit] = this.convertToLargestUnit(value, unit) + ;[this.value, this.unit] = FileSize.convertToLargestUnit(value, unit) } toString(): string { @@ -33,7 +33,7 @@ export class FileSize { return this.value * FileSize.multiplier[this.unit] } - private convertToLargestUnit(value: number, unit: FileSizeUnit): [number, FileSizeUnit] { + static convertToLargestUnit(value: number, unit: FileSizeUnit): [number, FileSizeUnit] { let convertedValue = value let convertedUnit = unit @@ -45,7 +45,7 @@ export class FileSize { return [convertedValue, convertedUnit] } - private getNextUnit(unit: FileSizeUnit): FileSizeUnit { + static getNextUnit(unit: FileSizeUnit): FileSizeUnit { switch (unit) { case FileSizeUnit.BYTES: return FileSizeUnit.KILOBYTES @@ -63,6 +63,11 @@ export class FileSize { } } +export enum FileDownloadMode { + ORIGINAL = 'original', + ARCHIVAL = 'archival' +} + export class FileDownloadSize extends FileSize { constructor( readonly value: number, @@ -70,6 +75,7 @@ export class FileDownloadSize extends FileSize { readonly mode: FileDownloadMode ) { super(value, unit) + ;[this.value, this.unit] = FileDownloadSize.convertToLargestUnit(value, unit) } } @@ -121,11 +127,6 @@ export interface FileTabularData { unf?: string } -export enum FileDownloadMode { - ARCHIVAL = 'archival', - ORIGINAL = 'original' -} - export enum FileLabelType { CATEGORY = 'category', TAG = 'tag' diff --git a/src/sections/dataset/dataset-action-buttons/DatasetActionButtons.tsx b/src/sections/dataset/dataset-action-buttons/DatasetActionButtons.tsx index 1c5a41116..96260a4a9 100644 --- a/src/sections/dataset/dataset-action-buttons/DatasetActionButtons.tsx +++ b/src/sections/dataset/dataset-action-buttons/DatasetActionButtons.tsx @@ -21,6 +21,7 @@ export function DatasetActionButtons({ dataset }: DatasetActionButtonsProps) { permissions={dataset.permissions} hasOneTabularFileAtLeast={dataset.hasOneTabularFileAtLeast} fileDownloadSizes={dataset.fileDownloadSizes} + downloadUrls={dataset.downloadUrls} /> diff --git a/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx b/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx index 2cb49247e..a58ad9125 100644 --- a/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx +++ b/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx @@ -1,4 +1,5 @@ import { + DatasetDownloadUrls, DatasetPermissions, DatasetPublishingStatus, DatasetVersion @@ -12,15 +13,19 @@ interface AccessDatasetMenuProps { version: DatasetVersion permissions: DatasetPermissions hasOneTabularFileAtLeast: boolean - fileDownloadSizes?: FileDownloadSize[] + fileDownloadSizes: FileDownloadSize[] + downloadUrls: DatasetDownloadUrls } export function AccessDatasetMenu({ version, permissions, hasOneTabularFileAtLeast, - fileDownloadSizes + fileDownloadSizes, + downloadUrls }: AccessDatasetMenuProps) { + const { t } = useTranslation('dataset') + if ( !permissions.canDownloadFiles || (version.publishingStatus === DatasetPublishingStatus.DEACCESSIONED && @@ -29,41 +34,6 @@ export function AccessDatasetMenu({ return <> } - function getFormattedFileSize(mode: FileDownloadMode): string { - const foundSize = fileDownloadSizes && fileDownloadSizes.find((size) => size.mode === mode) - return foundSize ? foundSize.toString() : '' - } - - const handleDownload = (type: FileDownloadMode) => { - //TODO: implement download feature - console.log('downloading file ' + type) - } - - interface DatasetDownloadOptionsProps { - datasetContainsTabularFiles: boolean - } - - const DatasetDownloadOptions = ({ datasetContainsTabularFiles }: DatasetDownloadOptionsProps) => { - return datasetContainsTabularFiles ? ( - <> - handleDownload(FileDownloadMode.ORIGINAL)}> - {t('datasetActionButtons.accessDataset.downloadOriginalZip')} ( - {getFormattedFileSize(FileDownloadMode.ORIGINAL)}) - - handleDownload(FileDownloadMode.ARCHIVAL)}> - {t('datasetActionButtons.accessDataset.downloadArchiveZip')} ( - {getFormattedFileSize(FileDownloadMode.ARCHIVAL)}) - - - ) : ( - handleDownload(FileDownloadMode.ORIGINAL)}> - {t('datasetActionButtons.accessDataset.downloadZip')} ( - {getFormattedFileSize(FileDownloadMode.ORIGINAL)}) - - ) - } - - const { t } = useTranslation('dataset') return ( - Download Options + {t('datasetActionButtons.accessDataset.downloadOptions.header')} - + ) } +interface DatasetDownloadOptionsProps { + hasOneTabularFileAtLeast: boolean + fileDownloadSizes: FileDownloadSize[] + downloadUrls: DatasetDownloadUrls +} + +const DatasetDownloadOptions = ({ + hasOneTabularFileAtLeast, + fileDownloadSizes, + downloadUrls +}: DatasetDownloadOptionsProps) => { + const { t } = useTranslation('dataset') + function getFormattedFileSize(mode: FileDownloadMode): string { + const foundSize = fileDownloadSizes.find((size) => size.mode === mode) + return foundSize ? foundSize.toString() : '' + } + + return hasOneTabularFileAtLeast ? ( + <> + + {t('datasetActionButtons.accessDataset.downloadOptions.originalZip')} ( + {getFormattedFileSize(FileDownloadMode.ORIGINAL)}) + + + {t('datasetActionButtons.accessDataset.downloadOptions.archivalZip')} ( + {getFormattedFileSize(FileDownloadMode.ARCHIVAL)}) + + + ) : ( + + {t('datasetActionButtons.accessDataset.downloadOptions.zip')} ( + {getFormattedFileSize(FileDownloadMode.ORIGINAL)}) + + ) +} + // TODO: add download feature https://github.com/IQSS/dataverse-frontend/issues/63 // TODO: add explore feature // TODO: add compute feature diff --git a/src/stories/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.stories.tsx b/src/stories/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.stories.tsx index 402e9753e..52bfda20c 100644 --- a/src/stories/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.stories.tsx +++ b/src/stories/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.stories.tsx @@ -2,6 +2,7 @@ import { Meta, StoryObj } from '@storybook/react' import { WithI18next } from '../../../WithI18next' import { WithSettings } from '../../../WithSettings' import { + DatasetDownloadUrlsMother, DatasetFileDownloadSizeMother, DatasetPermissionsMother, DatasetVersionMother @@ -28,6 +29,7 @@ export const WithDownloadNotAllowed: Story = { version={DatasetVersionMother.createReleased()} permissions={DatasetPermissionsMother.createWithFilesDownloadNotAllowed()} fileDownloadSizes={[DatasetFileDownloadSizeMother.createOriginal()]} + downloadUrls={DatasetDownloadUrlsMother.create()} /> ) } @@ -38,6 +40,7 @@ export const WithoutTabularFiles: Story = { version={DatasetVersionMother.createReleased()} permissions={DatasetPermissionsMother.createWithAllAllowed()} fileDownloadSizes={[DatasetFileDownloadSizeMother.createOriginal()]} + downloadUrls={DatasetDownloadUrlsMother.create()} /> ) } @@ -51,6 +54,7 @@ export const WithTabularFiles: Story = { DatasetFileDownloadSizeMother.createArchival(), DatasetFileDownloadSizeMother.createOriginal() ]} + downloadUrls={DatasetDownloadUrlsMother.create()} /> ) } diff --git a/tests/component/dataset/domain/models/DatasetMother.ts b/tests/component/dataset/domain/models/DatasetMother.ts index 1ff9a88c8..76a69dcab 100644 --- a/tests/component/dataset/domain/models/DatasetMother.ts +++ b/tests/component/dataset/domain/models/DatasetMother.ts @@ -2,6 +2,7 @@ import { faker } from '@faker-js/faker' import { ANONYMIZED_FIELD_VALUE, Dataset, + DatasetDownloadUrls, DatasetLabelSemanticMeaning, DatasetLabelValue, DatasetLock, @@ -252,12 +253,29 @@ export class DatasetFileDownloadSizeMother { ) } - static createArchival(): FileDownloadSize { - return this.create({ mode: FileDownloadMode.ARCHIVAL }) + static createArchival(props?: Partial): FileDownloadSize { + return this.create({ mode: FileDownloadMode.ARCHIVAL, ...props }) } - static createOriginal(): FileDownloadSize { - return this.create({ mode: FileDownloadMode.ORIGINAL }) + static createOriginal(props?: Partial): FileDownloadSize { + return this.create({ mode: FileDownloadMode.ORIGINAL, ...props }) + } +} + +export class DatasetDownloadUrlsMother { + static create(props?: Partial): DatasetDownloadUrls { + return { + original: this.createDownloadUrl(), + archival: this.createDownloadUrl(), + ...props + } + } + + static createDownloadUrl(): string { + const blob = new Blob(['Name,Age,Location\nJohn,25,New York\nJane,30,San Francisco'], { + type: 'text/csv' + }) + return URL.createObjectURL(blob) } } @@ -360,13 +378,10 @@ export class DatasetMother { hasValidTermsOfAccess: faker.datatype.boolean(), hasOneTabularFileAtLeast: faker.datatype.boolean(), isValid: faker.datatype.boolean(), - downloadUrls: { - original: this.createDownloadUrl(), - archival: this.createDownloadUrl() - }, + downloadUrls: DatasetDownloadUrlsMother.create(), thumbnail: undefined, privateUrl: undefined, - fileDownloadSizes: undefined, + fileDownloadSizes: [], requestedVersion: undefined, ...props } @@ -383,20 +398,13 @@ export class DatasetMother { dataset.hasOneTabularFileAtLeast, dataset.isValid, dataset.downloadUrls, + dataset.fileDownloadSizes, dataset.thumbnail, dataset.privateUrl, - dataset.fileDownloadSizes, dataset.requestedVersion ).build() } - static createDownloadUrl(): string { - const blob = new Blob(['Name,Age,Location\nJohn,25,New York\nJane,30,San Francisco'], { - type: 'text/csv' - }) - return URL.createObjectURL(blob) - } - static createAnonymized(): Dataset { return this.create({ version: DatasetVersionMother.createAnonymized(), diff --git a/tests/component/dataset/infrastructure/mappers/JSDatasetMapper.spec.ts b/tests/component/dataset/infrastructure/mappers/JSDatasetMapper.spec.ts index b95faad86..6a0da652e 100644 --- a/tests/component/dataset/infrastructure/mappers/JSDatasetMapper.spec.ts +++ b/tests/component/dataset/infrastructure/mappers/JSDatasetMapper.spec.ts @@ -11,6 +11,11 @@ import { DatasetMetadataBlock } from '@iqss/dataverse-client-javascript/dist/datasets/domain/models/Dataset' import { DatasetLockReason } from '../../../../../src/dataset/domain/models/Dataset' +import { + FileDownloadMode, + FileDownloadSize, + FileSizeUnit +} from '../../../../../src/files/domain/models/FilePreview' chai.use(chaiAsPromised) const expect = chai.expect @@ -70,6 +75,8 @@ const jsDatasetLocks: JSDatasetLock[] = [ datasetPersistentId: 'doi:10.5072/FK2/B4B2MJ' } ] +const jsDatasetFilesTotalOriginalDownloadSize = 5 +const jsDatasetFilesTotalArchivalDownloadSize = 7 const expectedDataset = { persistentId: 'doi:10.5072/FK2/B4B2MJ', version: { @@ -150,11 +157,14 @@ const expectedDataset = { isValid: true, thumbnail: undefined, privateUrl: undefined, + fileDownloadSizes: [ + new FileDownloadSize(5, FileSizeUnit.BYTES, FileDownloadMode.ORIGINAL), + new FileDownloadSize(7, FileSizeUnit.BYTES, FileDownloadMode.ARCHIVAL) + ], downloadUrls: { original: `/api/access/dataset/:persistentId/versions/0.0?persistentId=doi:10.5072/FK2/B4B2MJ&format=original`, archival: `/api/access/dataset/:persistentId/versions/0.0?persistentId=doi:10.5072/FK2/B4B2MJ` - }, - fileDownloadSizes: [] + } } const expectedDatasetAlternateVersion = { persistentId: 'doi:10.5072/FK2/B4B2MJ', @@ -182,7 +192,10 @@ const expectedDatasetAlternateVersion = { hasOneTabularFileAtLeast: true, isValid: true, privateUrl: undefined, - fileDownloadSizes: [], + fileDownloadSizes: [ + new FileDownloadSize(5, FileSizeUnit.BYTES, FileDownloadMode.ORIGINAL), + new FileDownloadSize(7, FileSizeUnit.BYTES, FileDownloadMode.ARCHIVAL) + ], alerts: [ { variant: 'warning', @@ -260,7 +273,9 @@ describe('JS Dataset Mapper', () => { citation, datasetSummaryFields, jsDatasetPermissions, - jsDatasetLocks + jsDatasetLocks, + jsDatasetFilesTotalOriginalDownloadSize, + jsDatasetFilesTotalArchivalDownloadSize ) expect(expectedDataset).to.deep.equal(mapped) }) @@ -271,6 +286,8 @@ describe('JS Dataset Mapper', () => { datasetSummaryFields, jsDatasetPermissions, jsDatasetLocks, + jsDatasetFilesTotalOriginalDownloadSize, + jsDatasetFilesTotalArchivalDownloadSize, '4.0' ) @@ -312,7 +329,9 @@ describe('JS Dataset Mapper', () => { citation, datasetSummaryFields, jsDatasetPermissions, - jsDatasetLocks + jsDatasetLocks, + jsDatasetFilesTotalOriginalDownloadSize, + jsDatasetFilesTotalArchivalDownloadSize ) ) }) @@ -352,7 +371,9 @@ describe('JS Dataset Mapper', () => { citation, datasetSummaryFields, jsDatasetPermissions, - jsDatasetLocks + jsDatasetLocks, + jsDatasetFilesTotalOriginalDownloadSize, + jsDatasetFilesTotalArchivalDownloadSize ) ) }) @@ -391,7 +412,9 @@ describe('JS Dataset Mapper', () => { citation, datasetSummaryFields, jsDatasetPermissions, - jsDatasetLocks + jsDatasetLocks, + jsDatasetFilesTotalOriginalDownloadSize, + jsDatasetFilesTotalArchivalDownloadSize ) ) }) diff --git a/tests/component/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.spec.tsx b/tests/component/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.spec.tsx index 9a3ff1e0d..53926122f 100644 --- a/tests/component/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.spec.tsx +++ b/tests/component/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.spec.tsx @@ -1,59 +1,14 @@ import { AccessDatasetMenu } from '../../../../../../src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu' import { + DatasetDownloadUrlsMother, DatasetFileDownloadSizeMother, DatasetPermissionsMother, DatasetVersionMother } from '../../../../dataset/domain/models/DatasetMother' +import { FileSizeUnit } from '../../../../../../src/files/domain/models/FilePreview' +const downloadUrls = DatasetDownloadUrlsMother.create() describe('AccessDatasetMenu', () => { - it('returns the correct file size string', () => { - const version = DatasetVersionMother.createReleased() - const permissions = DatasetPermissionsMother.createWithFilesDownloadAllowed() - const originalFileDownloadSize = DatasetFileDownloadSizeMother.createOriginal() - const archivalDownloadSize = DatasetFileDownloadSizeMother.createArchival() - const fileDownloadSizes = [originalFileDownloadSize, archivalDownloadSize] - cy.customMount( - - ) - cy.findByRole('button', { name: 'Access Dataset' }).should('exist') - cy.findByRole('button', { name: 'Access Dataset' }).click() - - cy.contains(originalFileDownloadSize.value.toString()).should('be.visible') - cy.contains(archivalDownloadSize.value.toString()).should('be.visible') - cy.contains(originalFileDownloadSize.unit.toString()).should('be.visible') - cy.contains(archivalDownloadSize.unit.toString()).should('be.visible') - }) - - it('logs the correct message when handleDownload is called', () => { - const version = DatasetVersionMother.createReleased() - const permissions = DatasetPermissionsMother.createWithFilesDownloadAllowed() - const fileDownloadSizes = [ - DatasetFileDownloadSizeMother.createOriginal(), - DatasetFileDownloadSizeMother.createArchival() - ] - cy.customMount( - - ) - const consoleLogStub = cy.stub(console, 'log').as('consoleLog') - cy.findByRole('button', { name: 'Access Dataset' }).should('exist') - cy.findByRole('button', { name: 'Access Dataset' }).click() - cy.contains('Original Format ZIP').click() - cy.get('@consoleLog').should('have.been.calledWith', 'downloading file original') - cy.findByRole('button', { name: 'Access Dataset' }).click() - cy.contains('Archive Format').click() - cy.get('@consoleLog').should('have.been.calledWith', 'downloading file archival') - }) - it('renders the AccessDatasetMenu if the user has download files permissions and the dataset is not deaccessioned', () => { const version = DatasetVersionMother.createReleased() const permissions = DatasetPermissionsMother.createWithFilesDownloadAllowed() @@ -67,6 +22,7 @@ describe('AccessDatasetMenu', () => { hasOneTabularFileAtLeast={true} version={version} permissions={permissions} + downloadUrls={downloadUrls} /> ) @@ -89,6 +45,7 @@ describe('AccessDatasetMenu', () => { hasOneTabularFileAtLeast={true} version={version} permissions={permissions} + downloadUrls={downloadUrls} /> ) cy.findByRole('button', { name: 'Access Dataset' }).should('exist') @@ -107,6 +64,7 @@ describe('AccessDatasetMenu', () => { hasOneTabularFileAtLeast={true} version={version} permissions={permissions} + downloadUrls={downloadUrls} /> ) cy.findByRole('button', { name: 'Access Dataset' }).should('not.exist') @@ -125,32 +83,43 @@ describe('AccessDatasetMenu', () => { hasOneTabularFileAtLeast={true} version={version} permissions={permissions} + downloadUrls={downloadUrls} /> ) cy.findByRole('button', { name: 'Access Dataset' }).should('not.exist') }) + it('displays one dropdown option if there are no tabular files', () => { const version = DatasetVersionMother.createReleased() const permissions = DatasetPermissionsMother.createWithFilesDownloadAllowed() - const fileDownloadSizes = [DatasetFileDownloadSizeMother.createOriginal()] + const fileDownloadSizes = [ + DatasetFileDownloadSizeMother.createOriginal({ value: 2000, unit: FileSizeUnit.BYTES }) + ] cy.customMount( ) cy.findByRole('button', { name: 'Access Dataset' }).should('exist') cy.findByRole('button', { name: 'Access Dataset' }).click() - cy.findByText(/Download ZIP \(\d+(\.\d+)? (B|KB|MB|GB|TB|PB)\)/).should('exist') + cy.findByText('Download ZIP (2 KB)') + .should('exist') + .should('have.attr', 'href', downloadUrls.original) }) + it('displays two dropdown options if there is at least one', () => { const version = DatasetVersionMother.createReleased() const permissions = DatasetPermissionsMother.createWithFilesDownloadAllowed() const fileDownloadSizes = [ - DatasetFileDownloadSizeMother.createOriginal(), - DatasetFileDownloadSizeMother.createArchival() + DatasetFileDownloadSizeMother.createOriginal({ value: 2000, unit: FileSizeUnit.BYTES }), + DatasetFileDownloadSizeMother.createArchival({ + value: 43483094340394, + unit: FileSizeUnit.BYTES + }) ] cy.customMount( { hasOneTabularFileAtLeast={true} version={version} permissions={permissions} + downloadUrls={downloadUrls} /> ) cy.findByRole('button', { name: 'Access Dataset' }).should('exist') cy.findByRole('button', { name: 'Access Dataset' }).click() - cy.findByText(/Original Format ZIP \(\d+(\.\d+)? (B|KB|MB|GB|TB|PB)\)/).should('exist') - cy.findByText(/Archive Format \(\.tab\) ZIP \(\d+(\.\d+)? (B|KB|MB|GB|TB|PB)\)/).should('exist') + cy.findByText('Original Format ZIP (2 KB)') + .should('exist') + .should('have.attr', 'href', downloadUrls.original) + cy.findByText('Archival Format (.tab) ZIP (39.5 TB)') + .should('exist') + .should('have.attr', 'href', downloadUrls.archival) }) }) diff --git a/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx b/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx index c7bc50488..d79142ed1 100644 --- a/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx +++ b/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx @@ -511,6 +511,40 @@ describe('Dataset', () => { }) describe('Downloading files', () => { + it('downloads the dataset', () => { + cy.wrap( + DatasetHelper.createWithFiles(FileHelper.createMany(2)).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 Dataset' }).should('exist').click({ force: true }) + + // 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.findByRole('link', { name: /Original Format ZIP/ }) + .should('exist') + .click({ force: true }) + }) + + cy.findAllByText('1 Downloads').should('exist') + }) + }) + it('downloads a file', () => { cy.wrap( DatasetHelper.createWithFiles(FileHelper.createMany(1)).then((dataset) => diff --git a/tests/e2e-integration/integration/datasets/DatasetJSDataverseRepository.spec.ts b/tests/e2e-integration/integration/datasets/DatasetJSDataverseRepository.spec.ts index bdb0e1df9..be2e91bce 100644 --- a/tests/e2e-integration/integration/datasets/DatasetJSDataverseRepository.spec.ts +++ b/tests/e2e-integration/integration/datasets/DatasetJSDataverseRepository.spec.ts @@ -10,6 +10,11 @@ import { DatasetVersion } from '../../../../src/dataset/domain/models/Dataset' import { DatasetHelper } from '../../shared/datasets/DatasetHelper' +import { + FileDownloadMode, + FileDownloadSize, + FileSizeUnit +} from '../../../../src/files/domain/models/FilePreview' chai.use(chaiAsPromised) const expect = chai.expect @@ -99,7 +104,15 @@ const datasetData = (persistentId: string, versionId: number) => { canManageFilesPermissions: true, canDeleteDataset: true }, - locks: [] + locks: [], + downloadUrls: { + original: `/api/access/dataset/:persistentId/versions/:draft?persistentId=${persistentId}&format=original`, + archival: `/api/access/dataset/:persistentId/versions/:draft?persistentId=${persistentId}` + }, + fileDownloadSizes: [ + new FileDownloadSize(0, FileSizeUnit.BYTES, FileDownloadMode.ORIGINAL), + new FileDownloadSize(0, FileSizeUnit.BYTES, FileDownloadMode.ARCHIVAL) + ] } } @@ -125,6 +138,8 @@ describe('Dataset JSDataverse Repository', () => { expect(dataset.metadataBlocks[0].fields.citationDate).not.to.exist expect(dataset.permissions).to.deep.equal(datasetExpected.permissions) expect(dataset.locks).to.deep.equal(datasetExpected.locks) + expect(dataset.downloadUrls).to.deep.equal(datasetExpected.downloadUrls) + expect(dataset.fileDownloadSizes).to.deep.equal(datasetExpected.fileDownloadSizes) }) })