diff --git a/public/locales/en/file.json b/public/locales/en/file.json index 95a92ccb5..86231a113 100644 --- a/public/locales/en/file.json +++ b/public/locales/en/file.json @@ -45,5 +45,8 @@ "directory": "File Path", "description": "Description" } + }, + "actionButtons": { + "title": "File Action Buttons" } } diff --git a/src/dataset/domain/models/Dataset.ts b/src/dataset/domain/models/Dataset.ts index b0f465d6b..2db611fc2 100644 --- a/src/dataset/domain/models/Dataset.ts +++ b/src/dataset/domain/models/Dataset.ts @@ -1,5 +1,5 @@ import { Alert, AlertMessageKey } from '../../../alert/domain/models/Alert' -import { FileDownloadSize } from '../../../files/domain/models/FilePreview' +import { FileDownloadSize } from '../../../files/domain/models/FileMetadata' export enum DatasetLabelSemanticMeaning { DATASET = 'dataset', diff --git a/src/dataset/infrastructure/mappers/JSDatasetMapper.ts b/src/dataset/infrastructure/mappers/JSDatasetMapper.ts index 817ec6ff1..4bc4c2a84 100644 --- a/src/dataset/infrastructure/mappers/JSDatasetMapper.ts +++ b/src/dataset/infrastructure/mappers/JSDatasetMapper.ts @@ -23,7 +23,7 @@ import { FileDownloadMode, FileDownloadSize, FileSizeUnit -} from '../../../files/domain/models/FilePreview' +} from '../../../files/domain/models/FileMetadata' import { JSDatasetVersionMapper } from './JSDatasetVersionMapper' export class JSDatasetMapper { diff --git a/src/files/domain/models/File.ts b/src/files/domain/models/File.ts index 23e27ef23..08135ffed 100644 --- a/src/files/domain/models/File.ts +++ b/src/files/domain/models/File.ts @@ -1,37 +1,18 @@ import { DatasetVersion } from '../../../dataset/domain/models/Dataset' -import { - FileChecksum, - FileDownloadUrls, - FileEmbargo, - FileLabel, - FileSize, - FileTabularData, - FileType, - FileVersion -} from './FilePreview' - -export interface FilePermissions { - canDownloadFile: boolean -} +import { FileMetadata } from './FileMetadata' +import { FileVersion } from './FileVersion' +import { FileAccess } from './FileAccess' +import { FileUserPermissions } from './FileUserPermissions' +import { FileIngest } from './FileIngest' export interface File { - name: string + id: number version: FileVersion + name: string + access: FileAccess datasetVersion: DatasetVersion - type: FileType - size: FileSize citation: string - restricted: boolean - permissions: FilePermissions - labels: FileLabel[] - downloadUrls: FileDownloadUrls - depositDate: Date - publicationDate?: Date - persistentId?: string - thumbnail?: string - directory?: string - tabularData?: FileTabularData - description?: string - checksum?: FileChecksum - embargo?: FileEmbargo + permissions: FileUserPermissions + metadata: FileMetadata + ingest: FileIngest } diff --git a/src/files/domain/models/FileAccess.ts b/src/files/domain/models/FileAccess.ts new file mode 100644 index 000000000..2055fed7d --- /dev/null +++ b/src/files/domain/models/FileAccess.ts @@ -0,0 +1,6 @@ +export interface FileAccess { + restricted: boolean + latestVersionRestricted: boolean + canBeRequested: boolean + requested: boolean +} diff --git a/src/files/domain/models/FileCriteria.ts b/src/files/domain/models/FileCriteria.ts index 11d45fbdc..efd37af89 100644 --- a/src/files/domain/models/FileCriteria.ts +++ b/src/files/domain/models/FileCriteria.ts @@ -1,4 +1,4 @@ -import { FileType } from './FilePreview' +import { FileType } from './FileMetadata' export class FileCriteria { constructor( diff --git a/src/files/domain/models/FileIngest.ts b/src/files/domain/models/FileIngest.ts new file mode 100644 index 000000000..802ae5ec8 --- /dev/null +++ b/src/files/domain/models/FileIngest.ts @@ -0,0 +1,14 @@ +export enum FileIngestStatus { + NONE = 'none', + IN_PROGRESS = 'inProgress', + SCHEDULED = 'scheduled', + ERROR = 'error' +} + +export class FileIngest { + constructor(readonly status: FileIngestStatus, readonly message?: string) {} + + get isInProgress(): boolean { + return this.status === FileIngestStatus.IN_PROGRESS + } +} diff --git a/src/files/domain/models/FileMetadata.ts b/src/files/domain/models/FileMetadata.ts new file mode 100644 index 000000000..dadf7856d --- /dev/null +++ b/src/files/domain/models/FileMetadata.ts @@ -0,0 +1,174 @@ +import FileTypeToFriendlyTypeMap from './FileTypeToFriendlyTypeMap' + +export enum FileSizeUnit { + BYTES = 'B', + KILOBYTES = 'KB', + MEGABYTES = 'MB', + GIGABYTES = 'GB', + TERABYTES = 'TB', + PETABYTES = 'PB' +} + +export class FileSize { + static readonly multiplier = { + [FileSizeUnit.BYTES]: 1, + [FileSizeUnit.KILOBYTES]: 1024, + [FileSizeUnit.MEGABYTES]: 1024 ** 2, + [FileSizeUnit.GIGABYTES]: 1024 ** 3, + [FileSizeUnit.TERABYTES]: 1024 ** 4, + [FileSizeUnit.PETABYTES]: 1024 ** 5 + } + + constructor(readonly value: number, readonly unit: FileSizeUnit) { + ;[this.value, this.unit] = FileSize.convertToLargestUnit(value, unit) + } + + toString(): string { + const formattedValue = + this.value % 1 === 0 ? this.value.toFixed(0) : (Math.round(this.value * 10) / 10).toString() + return `${formattedValue} ${this.unit}` + } + + toBytes(): number { + return this.value * FileSize.multiplier[this.unit] + } + + static convertToLargestUnit(value: number, unit: FileSizeUnit): [number, FileSizeUnit] { + let convertedValue = value + let convertedUnit = unit + + while (convertedValue >= 1024 && convertedUnit !== FileSizeUnit.PETABYTES) { + convertedValue /= 1024 + convertedUnit = this.getNextUnit(convertedUnit) + } + + return [convertedValue, convertedUnit] + } + + static getNextUnit(unit: FileSizeUnit): FileSizeUnit { + switch (unit) { + case FileSizeUnit.BYTES: + return FileSizeUnit.KILOBYTES + case FileSizeUnit.KILOBYTES: + return FileSizeUnit.MEGABYTES + case FileSizeUnit.MEGABYTES: + return FileSizeUnit.GIGABYTES + case FileSizeUnit.GIGABYTES: + return FileSizeUnit.TERABYTES + case FileSizeUnit.TERABYTES: + return FileSizeUnit.PETABYTES + default: + return unit + } + } +} + +export enum FileDownloadMode { + ORIGINAL = 'original', + ARCHIVAL = 'archival' +} + +export class FileDownloadSize extends FileSize { + constructor( + readonly value: number, + readonly unit: FileSizeUnit, + readonly mode: FileDownloadMode + ) { + super(value, unit) + ;[this.value, this.unit] = FileDownloadSize.convertToLargestUnit(value, unit) + } +} + +export enum FileDateType { + METADATA_RELEASED = 'metadataReleased', + PUBLISHED = 'published', + DEPOSITED = 'deposited' +} + +export interface FileDate { + type: FileDateType + date: Date +} + +export class FileEmbargo { + constructor(readonly dateAvailable: Date, readonly reason?: string) {} + + get isActive(): boolean { + return this.dateAvailable > new Date() + } +} + +export interface FileTabularData { + variablesCount: number + observationsCount: number + unf?: string +} + +export enum FileLabelType { + CATEGORY = 'category', + TAG = 'tag' +} + +export interface FileLabel { + type: FileLabelType + value: string +} + +export class FileType { + constructor(readonly value: string, readonly original?: string) {} + + toDisplayFormat(): string { + return FileTypeToFriendlyTypeMap[this.value] || FileTypeToFriendlyTypeMap.unknown + } + + get displayFormatIsUnknown(): boolean { + return this.toDisplayFormat() === FileTypeToFriendlyTypeMap.unknown + } + + get originalFormatIsUnknown(): boolean { + return this.original === undefined || this.original === FileTypeToFriendlyTypeMap.unknown + } +} + +export interface FileChecksum { + algorithm: string + value: string +} + +export interface FileDownloadUrls { + original: string + tabular?: string + rData?: string +} + +export class FileMetadata { + constructor( + readonly type: FileType, + readonly size: FileSize, + readonly date: FileDate, + readonly downloadCount: number, + readonly labels: FileLabel[], + public readonly isDeleted: boolean, + public readonly downloadUrls: FileDownloadUrls, + readonly depositDate: Date, + readonly publicationDate?: Date, + public thumbnail?: string, + readonly directory?: string, + readonly embargo?: FileEmbargo, + readonly tabularData?: FileTabularData, + readonly description?: string, + readonly checksum?: FileChecksum, + readonly persistentId?: string + ) {} + + get isActivelyEmbargoed(): boolean { + if (this.embargo) { + return this.embargo.isActive + } + return false + } + + get isTabular(): boolean { + return this.tabularData !== undefined + } +} diff --git a/src/files/domain/models/FilePreview.ts b/src/files/domain/models/FilePreview.ts index bfec5f422..b4f11755a 100644 --- a/src/files/domain/models/FilePreview.ts +++ b/src/files/domain/models/FilePreview.ts @@ -1,199 +1,13 @@ -import FileTypeToFriendlyTypeMap from './FileTypeToFriendlyTypeMap' - -export enum FileSizeUnit { - BYTES = 'B', - KILOBYTES = 'KB', - MEGABYTES = 'MB', - GIGABYTES = 'GB', - TERABYTES = 'TB', - PETABYTES = 'PB' -} - -export class FileSize { - static readonly multiplier = { - [FileSizeUnit.BYTES]: 1, - [FileSizeUnit.KILOBYTES]: 1024, - [FileSizeUnit.MEGABYTES]: 1024 ** 2, - [FileSizeUnit.GIGABYTES]: 1024 ** 3, - [FileSizeUnit.TERABYTES]: 1024 ** 4, - [FileSizeUnit.PETABYTES]: 1024 ** 5 - } - - constructor(readonly value: number, readonly unit: FileSizeUnit) { - ;[this.value, this.unit] = FileSize.convertToLargestUnit(value, unit) - } - - toString(): string { - const formattedValue = - this.value % 1 === 0 ? this.value.toFixed(0) : (Math.round(this.value * 10) / 10).toString() - return `${formattedValue} ${this.unit}` - } - - toBytes(): number { - return this.value * FileSize.multiplier[this.unit] - } - - static convertToLargestUnit(value: number, unit: FileSizeUnit): [number, FileSizeUnit] { - let convertedValue = value - let convertedUnit = unit - - while (convertedValue >= 1024 && convertedUnit !== FileSizeUnit.PETABYTES) { - convertedValue /= 1024 - convertedUnit = this.getNextUnit(convertedUnit) - } - - return [convertedValue, convertedUnit] - } - - static getNextUnit(unit: FileSizeUnit): FileSizeUnit { - switch (unit) { - case FileSizeUnit.BYTES: - return FileSizeUnit.KILOBYTES - case FileSizeUnit.KILOBYTES: - return FileSizeUnit.MEGABYTES - case FileSizeUnit.MEGABYTES: - return FileSizeUnit.GIGABYTES - case FileSizeUnit.GIGABYTES: - return FileSizeUnit.TERABYTES - case FileSizeUnit.TERABYTES: - return FileSizeUnit.PETABYTES - default: - return unit - } - } -} - -export enum FileDownloadMode { - ORIGINAL = 'original', - ARCHIVAL = 'archival' -} - -export class FileDownloadSize extends FileSize { - constructor( - readonly value: number, - readonly unit: FileSizeUnit, - readonly mode: FileDownloadMode - ) { - super(value, unit) - ;[this.value, this.unit] = FileDownloadSize.convertToLargestUnit(value, unit) - } -} - -export interface FileAccess { - restricted: boolean - latestVersionRestricted: boolean - canBeRequested: boolean - requested: boolean -} - -export enum FilePublishingStatus { - DRAFT = 'draft', - RELEASED = 'released', - DEACCESSIONED = 'deaccessioned' -} - -export interface FileVersion { - number: number - publishingStatus: FilePublishingStatus -} - -export enum FileDateType { - METADATA_RELEASED = 'metadataReleased', - PUBLISHED = 'published', - DEPOSITED = 'deposited' -} - -export enum FileVersionNotNumber { - LATEST = 'latest', - DRAFT = 'draft' -} - -export interface FileDate { - type: FileDateType - date: Date -} - -export class FileEmbargo { - constructor(readonly dateAvailable: Date, readonly reason?: string) {} - - get isActive(): boolean { - return this.dateAvailable > new Date() - } -} - -export interface FileTabularData { - variablesCount: number - observationsCount: number - unf?: string -} - -export enum FileLabelType { - CATEGORY = 'category', - TAG = 'tag' -} - -export interface FileLabel { - type: FileLabelType - value: string -} - -export class FileType { - constructor(readonly value: string, readonly original?: string) {} - - toDisplayFormat(): string { - return FileTypeToFriendlyTypeMap[this.value] || FileTypeToFriendlyTypeMap.unknown - } -} - -export interface FileChecksum { - algorithm: string - value: string -} - -export enum FileIngestStatus { - NONE = 'none', - IN_PROGRESS = 'inProgress', - SCHEDULED = 'scheduled', - ERROR = 'error' -} - -export interface FileIngest { - status: FileIngestStatus - reportMessage?: string -} - -export interface FileDownloadUrls { - original: string - tabular?: string - rData?: string -} - -export class FilePreview { - constructor( - readonly id: number, - readonly version: FileVersion, - readonly name: string, - readonly access: FileAccess, - readonly type: FileType, - readonly size: FileSize, - readonly date: FileDate, - readonly downloadCount: number, - readonly labels: FileLabel[], - public readonly isDeleted: boolean, - public readonly ingest: FileIngest, - public readonly downloadUrls: FileDownloadUrls, - public thumbnail?: string, - readonly directory?: string, - readonly embargo?: FileEmbargo, - readonly tabularData?: FileTabularData, - readonly description?: string, - readonly checksum?: FileChecksum - ) {} - - get isActivelyEmbargoed(): boolean { - if (this.embargo) { - return this.embargo.isActive - } - return false - } +import { FileMetadata } from './FileMetadata' +import { FileVersion } from './FileVersion' +import { FileIngest } from './FileIngest' +import { FileAccess } from './FileAccess' + +export interface FilePreview { + id: number + name: string + version: FileVersion + access: FileAccess + ingest: FileIngest + metadata: FileMetadata } diff --git a/src/files/domain/models/FileVersion.ts b/src/files/domain/models/FileVersion.ts new file mode 100644 index 000000000..e3aab8cd6 --- /dev/null +++ b/src/files/domain/models/FileVersion.ts @@ -0,0 +1,10 @@ +export enum FilePublishingStatus { + DRAFT = 'draft', + RELEASED = 'released', + DEACCESSIONED = 'deaccessioned' +} + +export interface FileVersion { + number: number + publishingStatus: FilePublishingStatus +} diff --git a/src/files/domain/models/FilesCountInfo.ts b/src/files/domain/models/FilesCountInfo.ts index bc7aae4ef..f615b602a 100644 --- a/src/files/domain/models/FilesCountInfo.ts +++ b/src/files/domain/models/FilesCountInfo.ts @@ -1,4 +1,4 @@ -import { FileType } from './FilePreview' +import { FileType } from './FileMetadata' import { FileAccessOption, FileTag } from './FileCriteria' export interface FilesCountInfo { diff --git a/src/files/domain/repositories/FileRepository.ts b/src/files/domain/repositories/FileRepository.ts index 5a9e0a76a..f4c860e78 100644 --- a/src/files/domain/repositories/FileRepository.ts +++ b/src/files/domain/repositories/FileRepository.ts @@ -1,10 +1,11 @@ -import { FilePreview, FileDownloadMode } from '../models/FilePreview' +import { FileDownloadMode } from '../models/FileMetadata' import { File } from '../models/File' import { FileCriteria } from '../models/FileCriteria' import { FilesCountInfo } from '../models/FilesCountInfo' import { FileUserPermissions } from '../models/FileUserPermissions' import { DatasetVersion, DatasetVersionNumber } from '../../../dataset/domain/models/Dataset' import { FilePaginationInfo } from '../models/FilePaginationInfo' +import { FilePreview } from '../models/FilePreview' export interface FileRepository { getAllByDatasetPersistentId: ( diff --git a/src/files/domain/useCases/checkFileDownloadPermission.ts b/src/files/domain/useCases/checkFileDownloadPermission.ts index 091064a07..15480a8a8 100644 --- a/src/files/domain/useCases/checkFileDownloadPermission.ts +++ b/src/files/domain/useCases/checkFileDownloadPermission.ts @@ -1,5 +1,6 @@ import { FileRepository } from '../repositories/FileRepository' -import { FilePreview, FilePublishingStatus } from '../models/FilePreview' +import { FilePreview } from '../models/FilePreview' +import { FilePublishingStatus } from '../models/FileVersion' export async function checkFileDownloadPermission( fileRepository: FileRepository, @@ -12,7 +13,7 @@ export async function checkFileDownloadPermission( } const isRestricted = file.access.restricted || file.access.latestVersionRestricted - if (!isRestricted && !file.isActivelyEmbargoed) { + if (!isRestricted && !file.metadata.isActivelyEmbargoed) { return true } diff --git a/src/files/domain/useCases/getMultipleFileDownloadUrl.ts b/src/files/domain/useCases/getMultipleFileDownloadUrl.ts index a6a1ac247..85f1940aa 100644 --- a/src/files/domain/useCases/getMultipleFileDownloadUrl.ts +++ b/src/files/domain/useCases/getMultipleFileDownloadUrl.ts @@ -1,5 +1,5 @@ import { FileRepository } from '../repositories/FileRepository' -import { FileDownloadMode } from '../models/FilePreview' +import { FileDownloadMode } from '../models/FileMetadata' const ONLY_ONE_FILE = 1 export function getMultipleFileDownloadUrl( diff --git a/src/files/infrastructure/FileJSDataverseRepository.ts b/src/files/infrastructure/FileJSDataverseRepository.ts index 658460e68..7ad930fe7 100644 --- a/src/files/infrastructure/FileJSDataverseRepository.ts +++ b/src/files/infrastructure/FileJSDataverseRepository.ts @@ -1,5 +1,5 @@ import { FileRepository } from '../domain/repositories/FileRepository' -import { FilePreview, FileDownloadMode } from '../domain/models/FilePreview' +import { FileDownloadMode } from '../domain/models/FileMetadata' import { FilesCountInfo } from '../domain/models/FilesCountInfo' import { FileUserPermissions } from '../domain/models/FileUserPermissions' import { @@ -22,6 +22,9 @@ import { File } from '../domain/models/File' import { FileMother } from '../../../tests/component/files/domain/models/FileMother' import { FilePaginationInfo } from '../domain/models/FilePaginationInfo' import { BASE_URL } from '../../config' +import { FilePreview } from '../domain/models/FilePreview' +import { JSFileUserPermissionsMapper } from './mappers/JSFileUserPermissionsMapper' +import { JSFilesCountInfoMapper } from './mappers/JSFilesCountInfoMapper' const includeDeaccessioned = true @@ -121,7 +124,7 @@ export class FileJSDataverseRepository implements FileRepository { DomainFileMapper.toJSFileSearchCriteria(criteria) ) .then((jsFilesCountInfo) => { - return JSFileMapper.toFilesCountInfo(jsFilesCountInfo) + return JSFilesCountInfoMapper.toFilesCountInfo(jsFilesCountInfo) }) .catch((error: ReadError) => { throw new Error(error.message) @@ -150,7 +153,7 @@ export class FileJSDataverseRepository implements FileRepository { return getFileUserPermissions .execute(id) .then((jsFileUserPermissions) => - JSFileMapper.toFileUserPermissions(id, jsFileUserPermissions) + JSFileUserPermissionsMapper.toFileUserPermissions(id, jsFileUserPermissions) ) .catch((error: ReadError) => { throw new Error(error.message) diff --git a/src/files/infrastructure/mappers/DomainFileMapper.ts b/src/files/infrastructure/mappers/DomainFileMapper.ts index e87c38b40..871d61ad9 100644 --- a/src/files/infrastructure/mappers/DomainFileMapper.ts +++ b/src/files/infrastructure/mappers/DomainFileMapper.ts @@ -9,7 +9,7 @@ import { FileSearchCriteria as JSFileSearchCriteria, FileOrderCriteria as JSFileOrderCriteria } from '@iqss/dataverse-client-javascript' -import { FileType } from '../../domain/models/FilePreview' +import { FileType } from '../../domain/models/FileMetadata' export class DomainFileMapper { static toJSFileSearchCriteria(criteria: FileCriteria): JSFileSearchCriteria { diff --git a/src/files/infrastructure/mappers/JSFileAccessMapper.ts b/src/files/infrastructure/mappers/JSFileAccessMapper.ts new file mode 100644 index 000000000..512d42717 --- /dev/null +++ b/src/files/infrastructure/mappers/JSFileAccessMapper.ts @@ -0,0 +1,13 @@ +import { FileAccess } from '../../domain/models/FileAccess' + +export class JSFileAccessMapper { + static toFileAccess(jsFileRestricted: boolean): FileAccess { + return { + restricted: jsFileRestricted, + // TODO - Implement the rest of the properties when they are added to js-dataverse + latestVersionRestricted: false, + canBeRequested: false, + requested: false + } + } +} diff --git a/src/files/infrastructure/mappers/JSFileIngestMapper.ts b/src/files/infrastructure/mappers/JSFileIngestMapper.ts new file mode 100644 index 000000000..a18192b79 --- /dev/null +++ b/src/files/infrastructure/mappers/JSFileIngestMapper.ts @@ -0,0 +1,7 @@ +import { FileIngest, FileIngestStatus } from '../../domain/models/FileIngest' + +export class JSFileIngestMapper { + static toFileIngest() { + return new FileIngest(FileIngestStatus.NONE) // TODO - Implement this when it is added to js-dataverse + } +} diff --git a/src/files/infrastructure/mappers/JSFileMapper.ts b/src/files/infrastructure/mappers/JSFileMapper.ts index b6ea1128e..fe4b7e1c8 100644 --- a/src/files/infrastructure/mappers/JSFileMapper.ts +++ b/src/files/infrastructure/mappers/JSFileMapper.ts @@ -1,41 +1,13 @@ -import { - FilePreview, - FileAccess, - FileChecksum, - FileDate, - FileDateType, - FileDownloadUrls, - FileEmbargo, - FileIngestStatus, - FileLabel, - FileLabelType, - FilePublishingStatus, - FileSize, - FileSizeUnit, - FileTabularData, - FileType, - FileVersion -} from '../../domain/models/FilePreview' import { File as JSFile, - FileEmbargo as JSFileEmbargo, - FileChecksum as JSFileChecksum, - FileCounts as JSFilesCountInfo, - FileContentTypeCount as JSFileContentTypeCount, - FileCategoryNameCount as JSFileCategoryNameCount, - FileAccessStatusCount as JSFileAccessStatusCount, - FileAccessStatus as JSFileAccessStatus, FileDataTable as JSFileTabularData } from '@iqss/dataverse-client-javascript' -import { DatasetPublishingStatus, DatasetVersion } from '../../../dataset/domain/models/Dataset' -import { FileUserPermissions } from '../../domain/models/FileUserPermissions' -import { - FileAccessCount, - FilesCountInfo, - FileTagCount, - FileTypeCount -} from '../../domain/models/FilesCountInfo' -import { FileAccessOption, FileTag } from '../../domain/models/FileCriteria' +import { DatasetVersion } from '../../../dataset/domain/models/Dataset' +import { FilePreview } from '../../domain/models/FilePreview' +import { JSFileMetadataMapper } from './JSFileMetadataMapper' +import { JSFileVersionMapper } from './JSFileVersionMapper' +import { JSFileAccessMapper } from './JSFileAccessMapper' +import { JSFileIngestMapper } from './JSFileIngestMapper' export class JSFileMapper { static toFile( @@ -45,39 +17,22 @@ export class JSFileMapper { thumbnail?: string, jsTabularData?: JSFileTabularData[] ): FilePreview { - return new FilePreview( - this.toFileId(jsFile.id), - this.toFileVersion(jsFile.version, datasetVersion, jsFile.publicationDate), - this.toFileName(jsFile.name), - this.toFileAccess(jsFile.restricted), - this.toFileType(jsFile.contentType, jsFile.originalFormatLabel), - this.toFileSize(jsFile.sizeBytes), - this.toFileDate(jsFile.creationDate, jsFile.publicationDate, jsFile.embargo), - this.toFileDownloads(downloadsCount), - this.toFileLabels(jsFile.categories, jsFile.tabularTags), - this.toFileIsDeleted(jsFile.deleted), - { status: FileIngestStatus.NONE }, // TODO - Implement this when it is added to js-dataverse - this.toFileOriginalFileDownloadUrl(jsFile.id), - this.toFileThumbnail(thumbnail), - this.toFileDirectory(jsFile.directoryLabel), - this.toFileEmbargo(jsFile.embargo), - this.toFileTabularData(jsTabularData), - this.toFileDescription(jsFile.description), - this.toFileChecksum(jsFile.checksum) - ) - } - - static toFileUserPermissions( - jsFileId: number, - jsFileUserPermissions: { - canDownloadFile: boolean - canEditOwnerDataset: boolean - } - ): FileUserPermissions { return { - fileId: jsFileId, - canDownloadFile: jsFileUserPermissions.canDownloadFile, - canEditDataset: jsFileUserPermissions.canEditOwnerDataset + id: this.toFileId(jsFile.id), + name: this.toFileName(jsFile.name), + version: JSFileVersionMapper.toFileVersion( + jsFile.version, + datasetVersion, + jsFile.publicationDate + ), + access: JSFileAccessMapper.toFileAccess(jsFile.restricted), + ingest: JSFileIngestMapper.toFileIngest(), + metadata: JSFileMetadataMapper.toFileMetadata( + jsFile, + downloadsCount, + thumbnail, + jsTabularData + ) } } @@ -85,178 +40,7 @@ export class JSFileMapper { return jsFileId } - static toFileVersion( - jsVersion: number, - datasetVersion: DatasetVersion, - jsPublicationDate?: Date - ): FileVersion { - const fileVersion = { number: jsVersion, publishingStatus: FilePublishingStatus.DRAFT } - - if (jsPublicationDate) { - fileVersion.publishingStatus = FilePublishingStatus.RELEASED - } - - if (datasetVersion.publishingStatus === DatasetPublishingStatus.DEACCESSIONED) { - fileVersion.publishingStatus = FilePublishingStatus.DEACCESSIONED - } - - return fileVersion - } - static toFileName(jsFileName: string): string { return jsFileName } - - static toFileAccess(jsFileRestricted: boolean): FileAccess { - return { - restricted: jsFileRestricted, - // TODO - Implement the rest of the properties when they are added to js-dataverse - latestVersionRestricted: false, - canBeRequested: false, - requested: false - } - } - - static toFileType(jsFileContentType: string, jsOriginalFormatLabel?: string): FileType { - return new FileType(jsFileContentType, jsOriginalFormatLabel) - } - - static toFileSize(jsFileSize: number): FileSize { - return new FileSize(jsFileSize, FileSizeUnit.BYTES) - } - - static toFileDate( - jsFileCreationDate?: Date, - jsFilePublicationDate?: Date, - jsFileEmbargo?: JSFileEmbargo - ): FileDate { - if (jsFilePublicationDate) { - if (jsFileEmbargo) { - return { type: FileDateType.METADATA_RELEASED, date: jsFilePublicationDate } - } - return { type: FileDateType.PUBLISHED, date: jsFilePublicationDate } - } - if (jsFileCreationDate) { - return { type: FileDateType.DEPOSITED, date: jsFileCreationDate } - } - throw new Error('File date not found') - } - - static toFileDownloads(downloadsCount: number): number { - return downloadsCount - } - - static toFileLabels(jsFileCategories?: string[], jsFileTabularTags?: string[]): FileLabel[] { - const fileLabels: FileLabel[] = [] - if (jsFileCategories) { - jsFileCategories.forEach((category) => { - fileLabels.push({ value: category, type: FileLabelType.CATEGORY }) - }) - } - if (jsFileTabularTags) { - jsFileTabularTags.forEach((tabularTag) => { - fileLabels.push({ value: tabularTag, type: FileLabelType.TAG }) - }) - } - - return fileLabels - } - - static toFileChecksum(jsFileChecksum?: JSFileChecksum): FileChecksum | undefined { - if (jsFileChecksum) { - return { algorithm: jsFileChecksum.type, value: jsFileChecksum.value } - } - return undefined - } - - 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(thumbnail?: string): string | undefined { - return thumbnail - } - - static toFileDirectory(jsFileDirectory: string | undefined): string | undefined { - return jsFileDirectory - } - - static toFileEmbargo(jsFileEmbargo?: JSFileEmbargo): FileEmbargo | undefined { - if (jsFileEmbargo) { - return new FileEmbargo(jsFileEmbargo.dateAvailable) - } - return undefined - } - - static toFileTabularData(jsTabularData?: JSFileTabularData[]): FileTabularData | undefined { - if (jsTabularData === undefined) { - return undefined - } - return { - variablesCount: jsTabularData[0].varQuantity ?? 0, - observationsCount: jsTabularData[0].caseQuantity ?? 0, - unf: jsTabularData[0].UNF - } - } - - static toFileDescription(jsFileDescription?: string): string | undefined { - return jsFileDescription - } - - static toFilesCountInfo(jsFilesCountInfo: JSFilesCountInfo): FilesCountInfo { - return { - total: jsFilesCountInfo.total, - perFileType: jsFilesCountInfo.perContentType.map((jsFileContentTypeCount) => - JSFileMapper.toFileTypeCount(jsFileContentTypeCount) - ), - perFileTag: jsFilesCountInfo.perCategoryName.map((jsFileCategoryNameCount) => - JSFileMapper.toFileTagCount(jsFileCategoryNameCount) - ), - perAccess: jsFilesCountInfo.perAccessStatus.map((jsFileAccessStatusCount) => - JSFileMapper.toFileAccessCount(jsFileAccessStatusCount) - ) - } - } - - static toFileTypeCount(jsFileContentTypeCount: JSFileContentTypeCount): FileTypeCount { - return { - type: new FileType(jsFileContentTypeCount.contentType), - count: jsFileContentTypeCount.count - } - } - - static toFileTagCount(jsFileCategoryNameCount: JSFileCategoryNameCount): FileTagCount { - return { - tag: new FileTag(jsFileCategoryNameCount.categoryName), - count: jsFileCategoryNameCount.count - } - } - - static toFileAccessCount(jsFileAccessStatusCount: JSFileAccessStatusCount): FileAccessCount { - return { - access: JSFileMapper.toFileAccessOption(jsFileAccessStatusCount.accessStatus), - count: jsFileAccessStatusCount.count - } - } - - static toFileAccessOption(jsFileAccessStatus: JSFileAccessStatus): FileAccessOption { - switch (jsFileAccessStatus) { - case JSFileAccessStatus.RESTRICTED: - return FileAccessOption.RESTRICTED - case JSFileAccessStatus.PUBLIC: - return FileAccessOption.PUBLIC - case JSFileAccessStatus.EMBARGOED: - return FileAccessOption.EMBARGOED - case JSFileAccessStatus.EMBARGOED_RESTRICTED: - return FileAccessOption.EMBARGOED_RESTRICTED - } - } - - static toFileIsDeleted(jsFileIsDeleted: boolean | undefined): boolean { - return jsFileIsDeleted ?? false - } } diff --git a/src/files/infrastructure/mappers/JSFileMetadataMapper.ts b/src/files/infrastructure/mappers/JSFileMetadataMapper.ts new file mode 100644 index 000000000..bb255af74 --- /dev/null +++ b/src/files/infrastructure/mappers/JSFileMetadataMapper.ts @@ -0,0 +1,142 @@ +import { + FileChecksum, + FileDate, + FileDateType, + FileDownloadUrls, + FileEmbargo, + FileLabel, + FileLabelType, + FileMetadata, + FileSize, + FileSizeUnit, + FileTabularData, + FileType +} from '../../domain/models/FileMetadata' +import { + File as JSFile, + FileEmbargo as JSFileEmbargo, + FileChecksum as JSFileChecksum, + FileDataTable as JSFileTabularData +} from '@iqss/dataverse-client-javascript' + +export class JSFileMetadataMapper { + static toFileMetadata( + jsFile: JSFile, + downloadsCount: number, + thumbnail?: string, + jsTabularData?: JSFileTabularData[] + ): FileMetadata { + return new FileMetadata( + this.toFileType(jsFile.contentType, jsFile.originalFormatLabel), + this.toFileSize(jsFile.sizeBytes), + this.toFileDate(jsFile.creationDate, jsFile.publicationDate, jsFile.embargo), + this.toFileDownloads(downloadsCount), + this.toFileLabels(jsFile.categories, jsFile.tabularTags), + this.toFileIsDeleted(jsFile.deleted), + this.toFileOriginalFileDownloadUrl(jsFile.id), + jsFile.creationDate ?? new Date(), + jsFile.publicationDate, + this.toFileThumbnail(thumbnail), + this.toFileDirectory(jsFile.directoryLabel), + this.toFileEmbargo(jsFile.embargo), + this.toFileTabularData(jsTabularData), + this.toFileDescription(jsFile.description), + this.toFileChecksum(jsFile.checksum), + jsFile.persistentId + ) + } + + static toFileType(jsFileContentType: string, jsOriginalFormatLabel?: string): FileType { + return new FileType(jsFileContentType, jsOriginalFormatLabel) + } + + static toFileSize(jsFileSize: number): FileSize { + return new FileSize(jsFileSize, FileSizeUnit.BYTES) + } + + static toFileDate( + jsFileCreationDate?: Date, + jsFilePublicationDate?: Date, + jsFileEmbargo?: JSFileEmbargo + ): FileDate { + if (jsFilePublicationDate) { + if (jsFileEmbargo) { + return { type: FileDateType.METADATA_RELEASED, date: jsFilePublicationDate } + } + return { type: FileDateType.PUBLISHED, date: jsFilePublicationDate } + } + if (jsFileCreationDate) { + return { type: FileDateType.DEPOSITED, date: jsFileCreationDate } + } + throw new Error('File date not found') + } + + static toFileDownloads(downloadsCount: number): number { + return downloadsCount + } + + static toFileLabels(jsFileCategories?: string[], jsFileTabularTags?: string[]): FileLabel[] { + const fileLabels: FileLabel[] = [] + if (jsFileCategories) { + jsFileCategories.forEach((category) => { + fileLabels.push({ value: category, type: FileLabelType.CATEGORY }) + }) + } + if (jsFileTabularTags) { + jsFileTabularTags.forEach((tabularTag) => { + fileLabels.push({ value: tabularTag, type: FileLabelType.TAG }) + }) + } + + return fileLabels + } + + static toFileChecksum(jsFileChecksum?: JSFileChecksum): FileChecksum | undefined { + if (jsFileChecksum) { + return { algorithm: jsFileChecksum.type, value: jsFileChecksum.value } + } + return undefined + } + + 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(thumbnail?: string): string | undefined { + return thumbnail + } + + static toFileDirectory(jsFileDirectory: string | undefined): string | undefined { + return jsFileDirectory + } + + static toFileEmbargo(jsFileEmbargo?: JSFileEmbargo): FileEmbargo | undefined { + if (jsFileEmbargo) { + return new FileEmbargo(jsFileEmbargo.dateAvailable) + } + return undefined + } + + static toFileTabularData(jsTabularData?: JSFileTabularData[]): FileTabularData | undefined { + if (jsTabularData === undefined) { + return undefined + } + return { + variablesCount: jsTabularData[0].varQuantity ?? 0, + observationsCount: jsTabularData[0].caseQuantity ?? 0, + unf: jsTabularData[0].UNF + } + } + + static toFileDescription(jsFileDescription?: string): string | undefined { + return jsFileDescription + } + + static toFileIsDeleted(jsFileIsDeleted: boolean | undefined): boolean { + return jsFileIsDeleted ?? false + } +} diff --git a/src/files/infrastructure/mappers/JSFileUserPermissionsMapper.ts b/src/files/infrastructure/mappers/JSFileUserPermissionsMapper.ts new file mode 100644 index 000000000..50f005713 --- /dev/null +++ b/src/files/infrastructure/mappers/JSFileUserPermissionsMapper.ts @@ -0,0 +1,17 @@ +import { FileUserPermissions } from '../../domain/models/FileUserPermissions' + +export class JSFileUserPermissionsMapper { + static toFileUserPermissions( + jsFileId: number, + jsFileUserPermissions: { + canDownloadFile: boolean + canEditOwnerDataset: boolean + } + ): FileUserPermissions { + return { + fileId: jsFileId, + canDownloadFile: jsFileUserPermissions.canDownloadFile, + canEditDataset: jsFileUserPermissions.canEditOwnerDataset + } + } +} diff --git a/src/files/infrastructure/mappers/JSFileVersionMapper.ts b/src/files/infrastructure/mappers/JSFileVersionMapper.ts new file mode 100644 index 000000000..a0d8ce84a --- /dev/null +++ b/src/files/infrastructure/mappers/JSFileVersionMapper.ts @@ -0,0 +1,22 @@ +import { FilePublishingStatus, FileVersion } from '../../domain/models/FileVersion' +import { DatasetPublishingStatus, DatasetVersion } from '../../../dataset/domain/models/Dataset' + +export class JSFileVersionMapper { + static toFileVersion( + jsVersion: number, + datasetVersion: DatasetVersion, + jsPublicationDate?: Date + ): FileVersion { + const fileVersion = { number: jsVersion, publishingStatus: FilePublishingStatus.DRAFT } + + if (jsPublicationDate) { + fileVersion.publishingStatus = FilePublishingStatus.RELEASED + } + + if (datasetVersion.publishingStatus === DatasetPublishingStatus.DEACCESSIONED) { + fileVersion.publishingStatus = FilePublishingStatus.DEACCESSIONED + } + + return fileVersion + } +} diff --git a/src/files/infrastructure/mappers/JSFilesCountInfoMapper.ts b/src/files/infrastructure/mappers/JSFilesCountInfoMapper.ts new file mode 100644 index 000000000..ec774bcff --- /dev/null +++ b/src/files/infrastructure/mappers/JSFilesCountInfoMapper.ts @@ -0,0 +1,66 @@ +import { + FileAccessCount, + FilesCountInfo, + FileTagCount, + FileTypeCount +} from '../../domain/models/FilesCountInfo' +import { + FileAccessStatusCount as JSFileAccessStatusCount, + FileCategoryNameCount as JSFileCategoryNameCount, + FileContentTypeCount as JSFileContentTypeCount, + FileCounts as JSFilesCountInfo +} from '@iqss/dataverse-client-javascript' +import { FileType } from '../../domain/models/FileMetadata' +import { FileAccessOption, FileTag } from '../../domain/models/FileCriteria' +import { FileAccessStatus as JSFileAccessStatus } from '@iqss/dataverse-client-javascript/dist/files/domain/models/FileCriteria' + +export class JSFilesCountInfoMapper { + static toFilesCountInfo(jsFilesCountInfo: JSFilesCountInfo): FilesCountInfo { + return { + total: jsFilesCountInfo.total, + perFileType: jsFilesCountInfo.perContentType.map((jsFileContentTypeCount) => + this.toFileTypeCount(jsFileContentTypeCount) + ), + perFileTag: jsFilesCountInfo.perCategoryName.map((jsFileCategoryNameCount) => + this.toFileTagCount(jsFileCategoryNameCount) + ), + perAccess: jsFilesCountInfo.perAccessStatus.map((jsFileAccessStatusCount) => + this.toFileAccessCount(jsFileAccessStatusCount) + ) + } + } + + static toFileTypeCount(jsFileContentTypeCount: JSFileContentTypeCount): FileTypeCount { + return { + type: new FileType(jsFileContentTypeCount.contentType), + count: jsFileContentTypeCount.count + } + } + + static toFileTagCount(jsFileCategoryNameCount: JSFileCategoryNameCount): FileTagCount { + return { + tag: new FileTag(jsFileCategoryNameCount.categoryName), + count: jsFileCategoryNameCount.count + } + } + + static toFileAccessCount(jsFileAccessStatusCount: JSFileAccessStatusCount): FileAccessCount { + return { + access: this.toFileAccessOption(jsFileAccessStatusCount.accessStatus), + count: jsFileAccessStatusCount.count + } + } + + static toFileAccessOption(jsFileAccessStatus: JSFileAccessStatus): FileAccessOption { + switch (jsFileAccessStatus) { + case JSFileAccessStatus.RESTRICTED: + return FileAccessOption.RESTRICTED + case JSFileAccessStatus.PUBLIC: + return FileAccessOption.PUBLIC + case JSFileAccessStatus.EMBARGOED: + return FileAccessOption.EMBARGOED + case JSFileAccessStatus.EMBARGOED_RESTRICTED: + return FileAccessOption.EMBARGOED_RESTRICTED + } + } +} 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 a58ad9125..76bacc56f 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 @@ -6,7 +6,7 @@ import { } from '../../../../dataset/domain/models/Dataset' import { DropdownButton, DropdownButtonItem, DropdownHeader } from '@iqss/dataverse-design-system' import { useTranslation } from 'react-i18next' -import { FileDownloadSize, FileDownloadMode } from '../../../../files/domain/models/FilePreview' +import { FileDownloadSize, FileDownloadMode } from '../../../../files/domain/models/FileMetadata' import { Download } from 'react-bootstrap-icons' interface AccessDatasetMenuProps { diff --git a/src/sections/dataset/dataset-files/file-criteria-form/FileCriteriaFilterByType.tsx b/src/sections/dataset/dataset-files/file-criteria-form/FileCriteriaFilterByType.tsx index 4367da6be..968aab0e4 100644 --- a/src/sections/dataset/dataset-files/file-criteria-form/FileCriteriaFilterByType.tsx +++ b/src/sections/dataset/dataset-files/file-criteria-form/FileCriteriaFilterByType.tsx @@ -7,7 +7,7 @@ import { import { FilesCountInfo } from '../../../../files/domain/models/FilesCountInfo' import styles from './FileCriteriaForm.module.scss' import { useState } from 'react' -import { FileType } from '../../../../files/domain/models/FilePreview' +import { FileType } from '../../../../files/domain/models/FileMetadata' import { useTranslation } from 'react-i18next' interface FileCriteriaFilterByTypeProps { diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/download-files/DownloadFilesButton.tsx b/src/sections/dataset/dataset-files/files-table/file-actions/download-files/DownloadFilesButton.tsx index 56f84dd02..a6a112b84 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/download-files/DownloadFilesButton.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-actions/download-files/DownloadFilesButton.tsx @@ -1,4 +1,4 @@ -import { FilePreview, FileDownloadMode } from '../../../../../../files/domain/models/FilePreview' +import { FileDownloadMode } from '../../../../../../files/domain/models/FileMetadata' import { useDataset } from '../../../../DatasetContext' import { Button, DropdownButton, DropdownButtonItem } from '@iqss/dataverse-design-system' import { Download } from 'react-bootstrap-icons' @@ -8,6 +8,7 @@ import { FileSelection } from '../../row-selection/useFileSelection' import { NoSelectedFilesModal } from '../no-selected-files-modal/NoSelectedFilesModal' import { MouseEvent, useState } from 'react' import { useMultipleFileDownload } from '../../../../../file/multiple-file-download/MultipleFileDownloadContext' +import { FilePreview } from '../../../../../../files/domain/models/FilePreview' interface DownloadFilesButtonProps { files: FilePreview[] diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/FileActionButtons.tsx b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/FileActionButtons.tsx index 9703b36d0..1875ba1ae 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/FileActionButtons.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/FileActionButtons.tsx @@ -1,17 +1,29 @@ -import { AccessFileMenu } from './access-file-menu/AccessFileMenu' +import { AccessFileMenu } from '../../../../../../file/file-action-buttons/access-file-menu/AccessFileMenu' import { FilePreview } from '../../../../../../../files/domain/models/FilePreview' import { FileOptionsMenu } from './file-options-menu/FileOptionsMenu' import { ButtonGroup } from '@iqss/dataverse-design-system' import { useTranslation } from 'react-i18next' +import { FilePublishingStatus } from '../../../../../../../files/domain/models/FileVersion' +import { useFileDownloadPermission } from '../../../../../../file/file-permissions/useFileDownloadPermission' interface FileActionButtonsProps { file: FilePreview } export function FileActionButtons({ file }: FileActionButtonsProps) { const { t } = useTranslation('files') + const { sessionUserHasFileDownloadPermission } = useFileDownloadPermission(file) + return ( - + ) diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessFileMenu.tsx b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessFileMenu.tsx deleted file mode 100644 index bc346227c..000000000 --- a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessFileMenu.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { FilePreview } from '../../../../../../../../files/domain/models/FilePreview' -import { Download, FileEarmark } from 'react-bootstrap-icons' -import { AccessStatus } from './AccessStatus' -import { RequestAccessOption } from './RequestAccessOption' -import { DropdownButton, DropdownHeader, Tooltip } from '@iqss/dataverse-design-system' -import { useTranslation } from 'react-i18next' -import { FileDownloadOptions } from './FileDownloadOptions' - -interface FileActionButtonAccessFileProps { - file: FilePreview -} -export function AccessFileMenu({ file }: FileActionButtonAccessFileProps) { - const { t } = useTranslation('files') - return ( - - }> - - {t('actions.accessFileMenu.headers.fileAccess')} - - - - - - - ) -} 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 deleted file mode 100644 index a6a735e8e..000000000 --- a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { DropdownHeader } from '@iqss/dataverse-design-system' -import { Download } from 'react-bootstrap-icons' -import { FilePreview } from '../../../../../../../../files/domain/models/FilePreview' -import { FileTabularDownloadOptions } from './FileTabularDownloadOptions' -import { FileNonTabularDownloadOptions } from './FileNonTabularDownloadOptions' -import { useTranslation } from 'react-i18next' -import { useFileDownloadPermission } from '../../../../../../../file/file-permissions/useFileDownloadPermission' - -interface FileDownloadOptionsProps { - file: FilePreview -} - -export function FileDownloadOptions({ file }: FileDownloadOptionsProps) { - const { t } = useTranslation('files') - const { sessionUserHasFileDownloadPermission } = useFileDownloadPermission(file) - - if (!sessionUserHasFileDownloadPermission) { - return <> - } - - return ( - <> - - {t('actions.accessFileMenu.downloadOptions.title')} - - - {file.tabularData ? ( - - ) : ( - - )} - - ) -} - -// TODO: Add guestbook support -// TODO: Add file package support 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 deleted file mode 100644 index 6dfabd9a8..000000000 --- a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { - FilePreview, - FileIngestStatus -} from '../../../../../../../../files/domain/models/FilePreview' -import FileTypeToFriendlyTypeMap from '../../../../../../../../files/domain/models/FileTypeToFriendlyTypeMap' -import { DropdownButtonItem } from '@iqss/dataverse-design-system' -import { useDataset } from '../../../../../../DatasetContext' -import { useTranslation } from 'react-i18next' - -interface FileNonTabularDownloadOptionsProps { - file: FilePreview -} - -export function FileNonTabularDownloadOptions({ file }: FileNonTabularDownloadOptionsProps) { - const { t } = useTranslation('files') - const { dataset } = useDataset() - const originalFileFormatIsKnown = - file.type.toDisplayFormat() !== FileTypeToFriendlyTypeMap.unknown - - if (file.tabularData) { - return <> - } - - return ( - - {originalFileFormatIsKnown - ? file.type.toDisplayFormat() - : t('actions.accessFileMenu.downloadOptions.options.original')} - - ) -} diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileTabularDownloadOptions.tsx b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileTabularDownloadOptions.tsx deleted file mode 100644 index 3e7e8bcf6..000000000 --- a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileTabularDownloadOptions.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { - FilePreview, - FileIngestStatus -} from '../../../../../../../../files/domain/models/FilePreview' -import { DropdownButtonItem } from '@iqss/dataverse-design-system' -import { useDataset } from '../../../../../../DatasetContext' -import { useTranslation } from 'react-i18next' - -interface FileTabularDownloadOptionsProps { - file: FilePreview -} - -export function FileTabularDownloadOptions({ file }: FileTabularDownloadOptionsProps) { - const { t } = useTranslation('files') - const { dataset } = useDataset() - const originalFileFormatIsKnown = file.type.original && file.type.original !== 'Unknown' - const downloadDisabled = - file.ingest.status === FileIngestStatus.IN_PROGRESS || - (dataset && dataset.isLockedFromFileDownload) - - if (!file.tabularData) { - return <> - } - - return ( - <> - {originalFileFormatIsKnown && ( - {`${ - 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/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/file-options-menu/FileOptionsMenu.tsx b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/file-options-menu/FileOptionsMenu.tsx index 4bf4f89a8..eb9c8159a 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/file-options-menu/FileOptionsMenu.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/file-options-menu/FileOptionsMenu.tsx @@ -18,7 +18,7 @@ export function FileOptionsMenu({ file }: { file: FilePreview }) { return <> } - if (file.isDeleted) { + if (file.metadata.isDeleted) { return ( <> {t('actions.optionsMenu.title')}}> diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-info-messages/IngestInfoMessage.tsx b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-info-messages/IngestInfoMessage.tsx index 8dbf671af..a9ce3c387 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-info-messages/IngestInfoMessage.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-info-messages/IngestInfoMessage.tsx @@ -1,4 +1,4 @@ -import { FileIngest, FileIngestStatus } from '../../../../../../../files/domain/models/FilePreview' +import { FileIngest, FileIngestStatus } from '../../../../../../../files/domain/models/FileIngest' import { QuestionMarkTooltip } from '@iqss/dataverse-design-system' import { InfoMessageBox } from './FileInfoMessages' import { useTranslation } from 'react-i18next' @@ -31,9 +31,9 @@ export function IngestInfoMessage({ ingest }: IngestInfoMessageProps) { {t('ingest.error.tabularIngest')} {' '} - {ingest.reportMessage + {ingest.message ? t('ingest.error.reportMessage', { - reportMessage: ingest.reportMessage + reportMessage: ingest.message }) : t('ingest.error.reportMessageDefault')}

diff --git a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/FileInfoCell.tsx b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/FileInfoCell.tsx index 1f2ccaa11..95806eb0e 100644 --- a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/FileInfoCell.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/FileInfoCell.tsx @@ -21,22 +21,22 @@ export function FileInfoCell({ file }: { file: FilePreview }) {
- - - + + + - - + +
- - + +
) diff --git a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileChecksum.tsx b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileChecksum.tsx index a853c2ad2..f4bbba549 100644 --- a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileChecksum.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileChecksum.tsx @@ -1,6 +1,6 @@ import styles from '../FileInfoCell.module.scss' import { CopyToClipboardButton } from './copy-to-clipboard-button/CopyToClipboardButton' -import { FileChecksum as FileChecksumModel } from '../../../../../../../files/domain/models/FilePreview' +import { FileChecksum as FileChecksumModel } from '../../../../../../../files/domain/models/FileMetadata' export function FileChecksum({ checksum }: { checksum: FileChecksumModel | undefined }) { if (!checksum) { diff --git a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileDate.tsx b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileDate.tsx index 59076096b..c47a7de3b 100644 --- a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileDate.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileDate.tsx @@ -1,4 +1,4 @@ -import { FileDate as FileDateModel } from '../../../../../../../files/domain/models/FilePreview' +import { FileDate as FileDateModel } from '../../../../../../../files/domain/models/FileMetadata' import { useTranslation } from 'react-i18next' import { DateHelper } from '../../../../../../../shared/domain/helpers/DateHelper' diff --git a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileDownloads.tsx b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileDownloads.tsx index b829859fb..d1b05b176 100644 --- a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileDownloads.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileDownloads.tsx @@ -1,4 +1,4 @@ -import { FilePublishingStatus } from '../../../../../../../files/domain/models/FilePreview' +import { FilePublishingStatus } from '../../../../../../../files/domain/models/FileVersion' import { useTranslation } from 'react-i18next' interface FileDownloadsProps { diff --git a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileTabularData.tsx b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileTabularData.tsx index c61a5b9d6..19e854db7 100644 --- a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileTabularData.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileTabularData.tsx @@ -1,4 +1,4 @@ -import { FileTabularData as FileTabularDataModel } from '../../../../../../../files/domain/models/FilePreview' +import { FileTabularData as FileTabularDataModel } from '../../../../../../../files/domain/models/FileMetadata' import { CopyToClipboardButton } from './copy-to-clipboard-button/CopyToClipboardButton' import { useTranslation } from 'react-i18next' diff --git a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileType.tsx b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileType.tsx index c4ab50a0c..457a96054 100644 --- a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileType.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileType.tsx @@ -1,7 +1,7 @@ import { FileSize, FileType as FileTypeModel -} from '../../../../../../../files/domain/models/FilePreview' +} from '../../../../../../../files/domain/models/FileMetadata' import { useTranslation } from 'react-i18next' interface FileTypeProps { diff --git a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.tsx b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.tsx index 3c5d454f8..fd7f949da 100644 --- a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.tsx @@ -15,14 +15,14 @@ export function FileThumbnail({ file }: FileThumbnailProps) { return (
- {file.thumbnail && sessionUserHasFileDownloadPermission ? ( - + {file.metadata.thumbnail && sessionUserHasFileDownloadPermission ? ( + ) : ( - + )}
file != undefined) - .reduce((totalSize, file) => totalSize + (file ? file.size.toBytes() : 0), 0) + .reduce((totalSize, file) => totalSize + (file ? file.metadata.size.toBytes() : 0), 0) } function bytesToHumanReadable(bytes: number) { diff --git a/src/sections/file/File.module.scss b/src/sections/file/File.module.scss index 1d4c600db..69b04f28c 100644 --- a/src/sections/file/File.module.scss +++ b/src/sections/file/File.module.scss @@ -38,4 +38,10 @@ .restricted-icon { margin-right: 6px; +} + +.group { + display: flex; + width: 100%; + margin: 0.5rem 0; } \ No newline at end of file diff --git a/src/sections/file/File.tsx b/src/sections/file/File.tsx index ab7d786a0..8ff124f28 100644 --- a/src/sections/file/File.tsx +++ b/src/sections/file/File.tsx @@ -1,7 +1,7 @@ import { useTranslation } from 'react-i18next' import { PageNotFound } from '../page-not-found/PageNotFound' import styles from './File.module.scss' -import { Col, Row, Tabs } from '@iqss/dataverse-design-system' +import { ButtonGroup, Col, Row, Tabs } from '@iqss/dataverse-design-system' import { FileRepository } from '../../files/domain/repositories/FileRepository' import { useFile } from './useFile' import { useEffect } from 'react' @@ -12,6 +12,8 @@ import { FileCitation } from './file-citation/FileCitation' import { DatasetLabels } from '../dataset/dataset-labels/DatasetLabels' import { FileAccessRestrictedIcon } from './file-access/FileAccessRestrictedIcon' import { FileMetadata } from './file-metadata/FileMetadata' +import { AccessFileMenu } from './file-action-buttons/access-file-menu/AccessFileMenu' +import { FilePublishingStatus } from '../../files/domain/models/FileVersion' interface FileProps { repository: FileRepository @@ -42,10 +44,10 @@ export function File({ repository, id }: FileProps) { {t('subtext', { datasetTitle: file.datasetVersion.title })}

- {file.restricted && ( + {file.access.restricted && (
@@ -61,11 +63,33 @@ export function File({ repository, id }: FileProps) { {t('datasetCitationTitle')} + + + + +
- +
diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessFileMenu.module.scss b/src/sections/file/file-action-buttons/access-file-menu/AccessFileMenu.module.scss similarity index 100% rename from src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessFileMenu.module.scss rename to src/sections/file/file-action-buttons/access-file-menu/AccessFileMenu.module.scss diff --git a/src/sections/file/file-action-buttons/access-file-menu/AccessFileMenu.tsx b/src/sections/file/file-action-buttons/access-file-menu/AccessFileMenu.tsx new file mode 100644 index 000000000..46871775b --- /dev/null +++ b/src/sections/file/file-action-buttons/access-file-menu/AccessFileMenu.tsx @@ -0,0 +1,75 @@ +import { Download, FileEarmark } from 'react-bootstrap-icons' +import { AccessStatus } from './AccessStatus' +import { RequestAccessOption } from './RequestAccessOption' +import { DropdownButton, DropdownHeader, Tooltip } from '@iqss/dataverse-design-system' +import { useTranslation } from 'react-i18next' +import { FileDownloadOptions } from './FileDownloadOptions' +import { FileAccess } from '../../../../files/domain/models/FileAccess' +import { FileMetadata } from '../../../../files/domain/models/FileMetadata' +import { ReactElement } from 'react' + +interface FileActionButtonAccessFileProps { + id: number + access: FileAccess + userHasDownloadPermission: boolean + metadata: FileMetadata + ingestInProgress: boolean + isDeaccessioned: boolean + asIcon?: boolean +} + +export function AccessFileMenu({ + id, + access, + userHasDownloadPermission, + metadata, + ingestInProgress, + isDeaccessioned, + asIcon = false +}: FileActionButtonAccessFileProps) { + const { t } = useTranslation('files') + function MenuWrapper({ children }: { children: ReactElement }) { + if (asIcon) { + return ( + + {children} + + ) + } + return children + } + + return ( + + : undefined}> + + {t('actions.accessFileMenu.headers.fileAccess')} + + + + + + + ) +} diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessStatus.tsx b/src/sections/file/file-action-buttons/access-file-menu/AccessStatus.tsx similarity index 50% rename from src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessStatus.tsx rename to src/sections/file/file-action-buttons/access-file-menu/AccessStatus.tsx index 02509ec3c..e5b2cfa01 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessStatus.tsx +++ b/src/sections/file/file-action-buttons/access-file-menu/AccessStatus.tsx @@ -1,27 +1,30 @@ -import { FilePreview } from '../../../../../../../../files/domain/models/FilePreview' import { Globe, LockFill, UnlockFill } from 'react-bootstrap-icons' import { useTranslation } from 'react-i18next' import styles from './AccessFileMenu.module.scss' import { DropdownButtonItem } from '@iqss/dataverse-design-system' -import { useFileDownloadPermission } from '../../../../../../../file/file-permissions/useFileDownloadPermission' interface AccessStatusProps { - file: FilePreview + userHasDownloadPermission: boolean + isRestricted: boolean + isActivelyEmbargoed: boolean } -export function AccessStatus({ file }: AccessStatusProps) { - const { sessionUserHasFileDownloadPermission } = useFileDownloadPermission(file) - +export function AccessStatus({ + userHasDownloadPermission, + isRestricted, + isActivelyEmbargoed +}: AccessStatusProps) { return ( {' '} @@ -29,15 +32,15 @@ export function AccessStatus({ file }: AccessStatusProps) { } function AccessStatusIcon({ - sessionUserHasFileDownloadPermission, - restricted + userHasDownloadPermission, + isRestricted }: { - sessionUserHasFileDownloadPermission: boolean - restricted: boolean + userHasDownloadPermission: boolean + isRestricted: boolean }) { const { t } = useTranslation('file') - if (restricted) { - if (sessionUserHasFileDownloadPermission) { + if (isRestricted) { + if (userHasDownloadPermission) { return ( ) @@ -48,20 +51,22 @@ function AccessStatusIcon({ } function AccessStatusText({ - file, - sessionUserHasFileDownloadPermission + isActivelyEmbargoed, + isRestricted, + userHasDownloadPermission }: { - file: FilePreview - sessionUserHasFileDownloadPermission: boolean + isActivelyEmbargoed: boolean + isRestricted: boolean + userHasDownloadPermission: boolean }) { const { t } = useTranslation('file') const getAccessStatus = () => { - if (file.isActivelyEmbargoed) { + if (isActivelyEmbargoed) { return 'embargoed' } - if (file.access.restricted) { - if (!sessionUserHasFileDownloadPermission) { + if (isRestricted) { + if (!userHasDownloadPermission) { return 'restricted' } @@ -74,11 +79,7 @@ function AccessStatusText({ return ( {t(`fileAccess.${getAccessStatus()}.name`)} diff --git a/src/sections/file/file-action-buttons/access-file-menu/FileDownloadOptions.tsx b/src/sections/file/file-action-buttons/access-file-menu/FileDownloadOptions.tsx new file mode 100644 index 000000000..9b605de8e --- /dev/null +++ b/src/sections/file/file-action-buttons/access-file-menu/FileDownloadOptions.tsx @@ -0,0 +1,53 @@ +import { DropdownHeader } from '@iqss/dataverse-design-system' +import { Download } from 'react-bootstrap-icons' +import { FileTabularDownloadOptions } from './FileTabularDownloadOptions' +import { FileNonTabularDownloadOptions } from './FileNonTabularDownloadOptions' +import { useTranslation } from 'react-i18next' +import { FileDownloadUrls, FileType } from '../../../../files/domain/models/FileMetadata' + +interface FileDownloadOptionsProps { + type: FileType + isTabular: boolean + ingestInProgress: boolean + downloadUrls: FileDownloadUrls + userHasDownloadPermission: boolean +} + +export function FileDownloadOptions({ + type, + isTabular, + ingestInProgress, + downloadUrls, + userHasDownloadPermission +}: FileDownloadOptionsProps) { + const { t } = useTranslation('files') + + if (!userHasDownloadPermission) { + return <> + } + + return ( + <> + + {t('actions.accessFileMenu.downloadOptions.title')} + + + {isTabular ? ( + + ) : ( + + )} + + ) +} + +// TODO: Add guestbook support +// TODO: Add file package support diff --git a/src/sections/file/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.tsx b/src/sections/file/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.tsx new file mode 100644 index 000000000..ee0fce16e --- /dev/null +++ b/src/sections/file/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.tsx @@ -0,0 +1,29 @@ +import { DropdownButtonItem } from '@iqss/dataverse-design-system' +import { useDataset } from '../../../dataset/DatasetContext' +import { useTranslation } from 'react-i18next' +import { FileType } from '../../../../files/domain/models/FileMetadata' + +interface FileNonTabularDownloadOptionsProps { + type: FileType + downloadUrlOriginal: string + ingestIsInProgress: boolean +} + +export function FileNonTabularDownloadOptions({ + type, + downloadUrlOriginal, + ingestIsInProgress +}: FileNonTabularDownloadOptionsProps) { + const { t } = useTranslation('files') + const { dataset } = useDataset() + + return ( + + {type.displayFormatIsUnknown + ? t('actions.accessFileMenu.downloadOptions.options.original') + : type.toDisplayFormat()} + + ) +} diff --git a/src/sections/file/file-action-buttons/access-file-menu/FileTabularDownloadOptions.tsx b/src/sections/file/file-action-buttons/access-file-menu/FileTabularDownloadOptions.tsx new file mode 100644 index 000000000..cb458dde8 --- /dev/null +++ b/src/sections/file/file-action-buttons/access-file-menu/FileTabularDownloadOptions.tsx @@ -0,0 +1,39 @@ +import { DropdownButtonItem } from '@iqss/dataverse-design-system' +import { useDataset } from '../../../dataset/DatasetContext' +import { useTranslation } from 'react-i18next' +import { FileDownloadUrls, FileType } from '../../../../files/domain/models/FileMetadata' +import FileTypeToFriendlyTypeMap from '../../../../files/domain/models/FileTypeToFriendlyTypeMap' + +interface FileTabularDownloadOptionsProps { + type: FileType + ingestInProgress: boolean + downloadUrls: FileDownloadUrls +} + +export function FileTabularDownloadOptions({ + type, + ingestInProgress, + downloadUrls +}: FileTabularDownloadOptionsProps) { + const { t } = useTranslation('files') + const { dataset } = useDataset() + const downloadDisabled = ingestInProgress || (dataset && dataset.isLockedFromFileDownload) + + return ( + <> + {!type.originalFormatIsUnknown && ( + {`${ + type.original || '' + } (${t('actions.accessFileMenu.downloadOptions.options.original')})`} + )} + + {t('actions.accessFileMenu.downloadOptions.options.tabular')} + + {type.original !== FileTypeToFriendlyTypeMap['application/x-r-data'] && ( + + {t('actions.accessFileMenu.downloadOptions.options.RData')} + + )} + + ) +} diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/RequestAccessModal.tsx b/src/sections/file/file-action-buttons/access-file-menu/RequestAccessModal.tsx similarity index 95% rename from src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/RequestAccessModal.tsx rename to src/sections/file/file-action-buttons/access-file-menu/RequestAccessModal.tsx index eea369e4d..fbcfddbca 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/RequestAccessModal.tsx +++ b/src/sections/file/file-action-buttons/access-file-menu/RequestAccessModal.tsx @@ -1,9 +1,9 @@ import { Button, DropdownButtonItem, Modal } from '@iqss/dataverse-design-system' -import { useSession } from '../../../../../../../session/SessionContext' +import { useSession } from '../../../session/SessionContext' import { FormEvent, useState } from 'react' import { Form } from '@iqss/dataverse-design-system' import { ExclamationTriangle } from 'react-bootstrap-icons' -import { Route } from '../../../../../../../Route.enum' +import { Route } from '../../../Route.enum' import styles from './AccessFileMenu.module.scss' import { useTranslation } from 'react-i18next' diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/RequestAccessOption.tsx b/src/sections/file/file-action-buttons/access-file-menu/RequestAccessOption.tsx similarity index 54% rename from src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/RequestAccessOption.tsx rename to src/sections/file/file-action-buttons/access-file-menu/RequestAccessOption.tsx index c2ce0687a..e530008a1 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/RequestAccessOption.tsx +++ b/src/sections/file/file-action-buttons/access-file-menu/RequestAccessOption.tsx @@ -1,28 +1,31 @@ import { DropdownButtonItem } from '@iqss/dataverse-design-system' import styles from './AccessFileMenu.module.scss' import { RequestAccessModal } from './RequestAccessModal' -import { - FilePreview, - FilePublishingStatus -} from '../../../../../../../../files/domain/models/FilePreview' import { useTranslation } from 'react-i18next' -import { useFileDownloadPermission } from '../../../../../../../file/file-permissions/useFileDownloadPermission' +import { FileAccess } from '../../../../files/domain/models/FileAccess' interface RequestAccessButtonProps { - file: FilePreview + id: number + userHasDownloadPermission: boolean + access: FileAccess + isActivelyEmbargoed: boolean + isDeaccessioned: boolean } -export function RequestAccessOption({ file }: RequestAccessButtonProps) { + +export function RequestAccessOption({ + id, + access, + userHasDownloadPermission, + isActivelyEmbargoed, + isDeaccessioned +}: RequestAccessButtonProps) { const { t } = useTranslation('files') - const { sessionUserHasFileDownloadPermission } = useFileDownloadPermission(file) - if ( - file.version.publishingStatus === FilePublishingStatus.DEACCESSIONED || - sessionUserHasFileDownloadPermission - ) { + if (isDeaccessioned || userHasDownloadPermission) { return <> } - if (file.isActivelyEmbargoed) { - if (file.access.restricted) { + if (isActivelyEmbargoed) { + if (access.restricted) { return ( {t('requestAccess.embargoedThenRestricted')}. @@ -31,15 +34,15 @@ export function RequestAccessOption({ file }: RequestAccessButtonProps) { } return {t('requestAccess.embargoed')}. } - if (!file.access.canBeRequested) { + if (!access.canBeRequested) { return {t('requestAccess.requestNotAllowed')}. } - if (file.access.requested) { + if (access.requested) { return ( {t('requestAccess.accessRequested')} ) } - return + return } diff --git a/src/sections/file/file-embargo/FileEmbargoDate.tsx b/src/sections/file/file-embargo/FileEmbargoDate.tsx index 2c84bfe41..ab22f0a58 100644 --- a/src/sections/file/file-embargo/FileEmbargoDate.tsx +++ b/src/sections/file/file-embargo/FileEmbargoDate.tsx @@ -1,6 +1,7 @@ -import { FileEmbargo, FilePublishingStatus } from '../../../files/domain/models/FilePreview' +import { FileEmbargo } from '../../../files/domain/models/FileMetadata' import { useTranslation } from 'react-i18next' import { DateHelper } from '../../../shared/domain/helpers/DateHelper' +import { FilePublishingStatus } from '../../../files/domain/models/FileVersion' interface FileEmbargoDateProps { embargo: FileEmbargo | undefined diff --git a/src/sections/file/file-labels/FileLabels.tsx b/src/sections/file/file-labels/FileLabels.tsx index dd4afa881..a6eb67634 100644 --- a/src/sections/file/file-labels/FileLabels.tsx +++ b/src/sections/file/file-labels/FileLabels.tsx @@ -1,4 +1,4 @@ -import { FileLabel, FileLabelType } from '../../../files/domain/models/FilePreview' +import { FileLabel, FileLabelType } from '../../../files/domain/models/FileMetadata' import { Badge } from '@iqss/dataverse-design-system' import styles from './FileLabels.module.scss' diff --git a/src/sections/file/file-metadata/FileMetadata.tsx b/src/sections/file/file-metadata/FileMetadata.tsx index b72c381cd..a935ad55d 100644 --- a/src/sections/file/file-metadata/FileMetadata.tsx +++ b/src/sections/file/file-metadata/FileMetadata.tsx @@ -1,5 +1,4 @@ import { Accordion, Col, Row } from '@iqss/dataverse-design-system' -import { File } from '../../../files/domain/models/File' import { FilePreview } from '../file-preview/FilePreview' import { FileLabels } from '../file-labels/FileLabels' import styles from './FileMetadata.module.scss' @@ -7,12 +6,18 @@ import { DateHelper } from '../../../shared/domain/helpers/DateHelper' import { FileEmbargoDate } from '../file-embargo/FileEmbargoDate' import { BASE_URL } from '../../../config' import { Trans, useTranslation } from 'react-i18next' +import { FileMetadata as FileMetadataModel } from '../../../files/domain/models/FileMetadata' +import { FilePublishingStatus } from '../../../files/domain/models/FileVersion' +import { FileUserPermissions } from '../../../files/domain/models/FileUserPermissions' interface FileMetadataProps { - file: File + name: string + metadata: FileMetadataModel + permissions: FileUserPermissions + publishingStatus: FilePublishingStatus } -export function FileMetadata({ file }: FileMetadataProps) { +export function FileMetadata({ name, metadata, permissions, publishingStatus }: FileMetadataProps) { const { t } = useTranslation('file') return ( @@ -24,28 +29,28 @@ export function FileMetadata({ file }: FileMetadataProps) { {t('metadata.fields.preview')} - + - {file.labels.length > 0 && ( + {metadata.labels.length > 0 && ( {t('metadata.fields.labels')} - + )} - {file.persistentId && ( + {metadata.persistentId && ( {t('metadata.fields.persistentId')} - {file.persistentId} + {metadata.persistentId} )} - {file.permissions.canDownloadFile && ( + {permissions.canDownloadFile && ( {t('metadata.fields.downloadUrl.title')} @@ -62,109 +67,109 @@ export function FileMetadata({ file }: FileMetadataProps) { {BASE_URL} - {file.downloadUrls.original} + {metadata.downloadUrls.original} )} - {file.tabularData?.unf && ( + {metadata.tabularData?.unf && ( {t('metadata.fields.unf')} - {file.tabularData.unf} + {metadata.tabularData.unf} )} - {file.checksum && ( + {metadata.checksum && ( - {file.checksum.algorithm} + {metadata.checksum.algorithm} - {file.checksum.value} + {metadata.checksum.value} )} {t('metadata.fields.depositDate')} - {DateHelper.toDisplayFormatYYYYMMDD(file.depositDate)} + {DateHelper.toDisplayFormatYYYYMMDD(metadata.depositDate)} - {file.publicationDate && ( + {metadata.publicationDate && ( {t('metadata.fields.metadataReleaseDate')} - {DateHelper.toDisplayFormatYYYYMMDD(file.publicationDate)} + {DateHelper.toDisplayFormatYYYYMMDD(metadata.publicationDate)} )} - {(file.publicationDate || file.embargo) && ( + {(metadata.publicationDate || metadata.embargo) && ( {t('metadata.fields.publicationDate')} - {file.embargo ? ( + {metadata.embargo ? ( ) : ( - DateHelper.toDisplayFormatYYYYMMDD(file.publicationDate) + DateHelper.toDisplayFormatYYYYMMDD(metadata.publicationDate) )} )} - {file.embargo && file.embargo.reason && ( + {metadata.embargo && metadata.embargo.reason && ( {t('metadata.fields.embargoReason')} - {file.embargo.reason} + {metadata.embargo.reason} )} {t('metadata.fields.size')} - {file.size.toString()} + {metadata.size.toString()} {t('metadata.fields.type')} - {file.type.toDisplayFormat()} + {metadata.type.toDisplayFormat()} - {file.tabularData && ( + {metadata.tabularData && ( <> {t('metadata.fields.variables')} - {file.tabularData.variablesCount} + {metadata.tabularData.variablesCount} {t('metadata.fields.observations')} - {file.tabularData.observationsCount} + {metadata.tabularData.observationsCount} )} - {file.directory && ( + {metadata.directory && ( {t('metadata.fields.directory')} - {file.directory} + {metadata.directory} )} - {file.description && ( + {metadata.description && ( {t('metadata.fields.description')} - {file.description} + {metadata.description} )} diff --git a/src/sections/file/file-preview/FileIcon.tsx b/src/sections/file/file-preview/FileIcon.tsx index 30d51d243..3887219c8 100644 --- a/src/sections/file/file-preview/FileIcon.tsx +++ b/src/sections/file/file-preview/FileIcon.tsx @@ -1,5 +1,5 @@ import styles from './FileIcon.module.scss' -import { FileType } from '../../../files/domain/models/FilePreview' +import { FileType } from '../../../files/domain/models/FileMetadata' import { FileTypeToFileIconMap } from './FileTypeToFileIconMap' import { IconName } from '@iqss/dataverse-design-system' diff --git a/src/sections/file/file-preview/FilePreview.tsx b/src/sections/file/file-preview/FilePreview.tsx index 0f3bc8c1b..572491317 100644 --- a/src/sections/file/file-preview/FilePreview.tsx +++ b/src/sections/file/file-preview/FilePreview.tsx @@ -1,6 +1,6 @@ import { FileImage } from './FileImage' import { FileIcon } from './FileIcon' -import { FileType } from '../../../files/domain/models/FilePreview' +import { FileType } from '../../../files/domain/models/FileMetadata' interface FilePreviewProps { thumbnail?: string diff --git a/src/sections/file/multiple-file-download/MultipleFileDownloadContext.ts b/src/sections/file/multiple-file-download/MultipleFileDownloadContext.ts index 0f02a78fd..aa85abcc2 100644 --- a/src/sections/file/multiple-file-download/MultipleFileDownloadContext.ts +++ b/src/sections/file/multiple-file-download/MultipleFileDownloadContext.ts @@ -1,5 +1,5 @@ import { createContext, useContext } from 'react' -import { FileDownloadMode } from '../../../files/domain/models/FilePreview' +import { FileDownloadMode } from '../../../files/domain/models/FileMetadata' interface MultipleFileDownloadContextProps { getMultipleFileDownloadUrl: (ids: number[], downloadMode: FileDownloadMode) => string diff --git a/src/sections/file/multiple-file-download/MultipleFileDownloadProvider.tsx b/src/sections/file/multiple-file-download/MultipleFileDownloadProvider.tsx index 5ca81e327..fb3dce6b5 100644 --- a/src/sections/file/multiple-file-download/MultipleFileDownloadProvider.tsx +++ b/src/sections/file/multiple-file-download/MultipleFileDownloadProvider.tsx @@ -1,7 +1,7 @@ import { PropsWithChildren } from 'react' import { FileRepository } from '../../../files/domain/repositories/FileRepository' import { MultipleFileDownloadContext } from './MultipleFileDownloadContext' -import { FileDownloadMode } from '../../../files/domain/models/FilePreview' +import { FileDownloadMode } from '../../../files/domain/models/FileMetadata' import { getMultipleFileDownloadUrl } from '../../../files/domain/useCases/getMultipleFileDownloadUrl' interface MultipleFileDownloadProviderProps { diff --git a/src/settings/domain/models/ZipDownloadLimit.ts b/src/settings/domain/models/ZipDownloadLimit.ts index 335847212..a432a32e1 100644 --- a/src/settings/domain/models/ZipDownloadLimit.ts +++ b/src/settings/domain/models/ZipDownloadLimit.ts @@ -1,3 +1,3 @@ -import { FileSize } from '../../../files/domain/models/FilePreview' +import { FileSize } from '../../../files/domain/models/FileMetadata' export class ZipDownloadLimit extends FileSize {} diff --git a/src/settings/infrastructure/SettingJSDataverseRepository.ts b/src/settings/infrastructure/SettingJSDataverseRepository.ts index 009b4fbe2..cb257bc32 100644 --- a/src/settings/infrastructure/SettingJSDataverseRepository.ts +++ b/src/settings/infrastructure/SettingJSDataverseRepository.ts @@ -1,7 +1,7 @@ import { SettingRepository } from '../domain/repositories/SettingRepository' import { Setting, SettingName } from '../domain/models/Setting' import { ZipDownloadLimit } from '../domain/models/ZipDownloadLimit' -import { FileSizeUnit } from '../../files/domain/models/FilePreview' +import { FileSizeUnit } from '../../files/domain/models/FileMetadata' export class SettingJSDataverseRepository implements SettingRepository { // eslint-disable-next-line unused-imports/no-unused-vars diff --git a/src/stories/WithSettings.tsx b/src/stories/WithSettings.tsx index efe9a44fb..95ac7b136 100644 --- a/src/stories/WithSettings.tsx +++ b/src/stories/WithSettings.tsx @@ -3,7 +3,7 @@ import { SettingsContext } from '../sections/settings/SettingsContext' import { Setting, SettingName } from '../settings/domain/models/Setting' import { SettingMother } from '../../tests/component/settings/domain/models/SettingMother' import { ZipDownloadLimit } from '../settings/domain/models/ZipDownloadLimit' -import { FileSizeUnit } from '../files/domain/models/FilePreview' +import { FileSizeUnit } from '../files/domain/models/FileMetadata' const zipDownloadLimitMock = new ZipDownloadLimit(1, FileSizeUnit.BYTES) export const WithSettings = (Story: StoryFn) => { diff --git a/src/stories/dataset/dataset-files/files-table/file-actions/download-files/DownloadFilesButton.stories.tsx b/src/stories/dataset/dataset-files/files-table/file-actions/download-files/DownloadFilesButton.stories.tsx index 8083e507f..e332e43dd 100644 --- a/src/stories/dataset/dataset-files/files-table/file-actions/download-files/DownloadFilesButton.stories.tsx +++ b/src/stories/dataset/dataset-files/files-table/file-actions/download-files/DownloadFilesButton.stories.tsx @@ -4,8 +4,9 @@ import { WithI18next } from '../../../../../WithI18next' import { WithSettings } from '../../../../../WithSettings' import { WithLoggedInUser } from '../../../../../WithLoggedInUser' import { WithDatasetAllPermissionsGranted } from '../../../../WithDatasetAllPermissionsGranted' -import { FilePreviewMother } from '../../../../../../../tests/component/files/domain/models/FilePreviewMother' +import { FileMetadataMother } from '../../../../../../../tests/component/files/domain/models/FileMetadataMother' import { DownloadFilesButton } from '../../../../../../sections/dataset/dataset-files/files-table/file-actions/download-files/DownloadFilesButton' +import { FilePreviewMother } from '../../../../../../../tests/component/files/domain/models/FilePreviewMother' const meta: Meta = { title: 'Sections/Dataset Page/DatasetFiles/FilesTable/DownloadFilesButton', @@ -19,7 +20,9 @@ type Story = StoryObj export const NonTabularFiles: Story = { render: () => ( ) @@ -29,11 +32,7 @@ export const TabularFiles: Story = { render: () => ( diff --git a/src/stories/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesMenu.stories.tsx b/src/stories/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesMenu.stories.tsx index cec8c2889..58700a5f4 100644 --- a/src/stories/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesMenu.stories.tsx +++ b/src/stories/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesMenu.stories.tsx @@ -1,10 +1,10 @@ import { Meta, StoryObj } from '@storybook/react' import { WithI18next } from '../../../../../WithI18next' import { WithSettings } from '../../../../../WithSettings' -import { FilePreviewMother } from '../../../../../../../tests/component/files/domain/models/FilePreviewMother' import { EditFilesMenu } from '../../../../../../sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesMenu' import { WithLoggedInUser } from '../../../../../WithLoggedInUser' import { WithDatasetAllPermissionsGranted } from '../../../../WithDatasetAllPermissionsGranted' +import { FilePreviewMother } from '../../../../../../../tests/component/files/domain/models/FilePreviewMother' const meta: Meta = { title: 'Sections/Dataset Page/DatasetFiles/FilesTable/EditFilesMenu', 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 deleted file mode 100644 index 7120e4b52..000000000 --- a/src/stories/dataset/dataset-files/files-table/file-actions/file-action-buttons/access-file-menu/AccessFileMenu.stories.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react' -import { AccessFileMenu } from '../../../../../../../sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessFileMenu' -import { WithI18next } from '../../../../../../WithI18next' -import { WithSettings } from '../../../../../../WithSettings' -import { WithFilePermissionsGranted } from '../../../../../../file/file-permission/WithFilePermissionsGranted' -import { FilePreviewMother } from '../../../../../../../../tests/component/files/domain/models/FilePreviewMother' - -const meta: Meta = { - title: - 'Sections/Dataset Page/DatasetFiles/FilesTable/FileActionsCell/FileActionButtons/AccessFileMenu', - component: AccessFileMenu, - decorators: [WithI18next, WithSettings] -} - -export default meta -type Story = StoryObj - -export const Default: Story = { - decorators: [WithFilePermissionsGranted], - render: () => -} - -export const NonTabularFiles: Story = { - render: () => -} - -export const TabularFiles: Story = { - render: () => -} - -export const Restricted: Story = { - render: () => -} - -export const RestrictedWithAccessRequestAllowed: Story = { - render: () => -} - -export const RestrictedWithAccessRequestPending: Story = { - render: () => -} - -export const RestrictedWithAccessGranted: Story = { - decorators: [WithFilePermissionsGranted], - render: () => ( - - ) -} - -export const WithEmbargo: Story = { - decorators: [WithFilePermissionsGranted], - render: () => -} - -export const WithEmbargoAndRestricted: Story = { - render: () => -} diff --git a/src/stories/dataset/dataset-files/files-table/file-actions/file-action-buttons/access-file-menu/RequestAccessModal.stories.tsx b/src/stories/dataset/dataset-files/files-table/file-actions/file-action-buttons/access-file-menu/RequestAccessModal.stories.tsx deleted file mode 100644 index ac21b4c43..000000000 --- a/src/stories/dataset/dataset-files/files-table/file-actions/file-action-buttons/access-file-menu/RequestAccessModal.stories.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react' -import { WithI18next } from '../../../../../../WithI18next' -import { WithSettings } from '../../../../../../WithSettings' -import { RequestAccessModal } from '../../../../../../../sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/RequestAccessModal' -import { WithLoggedInUser } from '../../../../../../WithLoggedInUser' - -const meta: Meta = { - title: - 'Sections/Dataset Page/DatasetFiles/FilesTable/FileActionsCell/FileActionButtons/RequestAccessModal', - component: RequestAccessModal, - decorators: [WithI18next, WithSettings] -} - -export default meta -type Story = StoryObj - -export const LoggedOut: Story = { - render: () => -} - -export const LoggedIn: Story = { - decorators: [WithLoggedInUser], - render: () => -} diff --git a/src/stories/dataset/dataset-files/files-table/file-actions/file-action-buttons/file-options-menu/FileOptionsMenu.stories.tsx b/src/stories/dataset/dataset-files/files-table/file-actions/file-action-buttons/file-options-menu/FileOptionsMenu.stories.tsx index 9ab9cbe0d..d5da2089e 100644 --- a/src/stories/dataset/dataset-files/files-table/file-actions/file-action-buttons/file-options-menu/FileOptionsMenu.stories.tsx +++ b/src/stories/dataset/dataset-files/files-table/file-actions/file-action-buttons/file-options-menu/FileOptionsMenu.stories.tsx @@ -3,9 +3,9 @@ import { FileOptionsMenu } from '../../../../../../../sections/dataset/dataset-f import { WithI18next } from '../../../../../../WithI18next' import { WithSettings } from '../../../../../../WithSettings' import { WithLoggedInUser } from '../../../../../../WithLoggedInUser' -import { FilePreviewMother } from '../../../../../../../../tests/component/files/domain/models/FilePreviewMother' import { WithDatasetAllPermissionsGranted } from '../../../../../WithDatasetAllPermissionsGranted' import { WithDatasetLockedFromEdits } from '../../../../../WithDatasetLockedFromEdits' +import { FilePreviewMother } from '../../../../../../../../tests/component/files/domain/models/FilePreviewMother' const meta: Meta = { title: @@ -24,7 +24,7 @@ export const DefaultWithLoggedInUser: Story = { export const Restricted: Story = { decorators: [WithDatasetAllPermissionsGranted], - render: () => + render: () => } export const WithDatasetLocked: Story = { diff --git a/src/stories/dataset/dataset-files/files-table/file-actions/file-info-messages/FileInfoMessages.stories.tsx b/src/stories/dataset/dataset-files/files-table/file-actions/file-info-messages/FileInfoMessages.stories.tsx index 9bb9f376d..504306f2e 100644 --- a/src/stories/dataset/dataset-files/files-table/file-actions/file-info-messages/FileInfoMessages.stories.tsx +++ b/src/stories/dataset/dataset-files/files-table/file-actions/file-info-messages/FileInfoMessages.stories.tsx @@ -2,8 +2,8 @@ import { Meta, StoryObj } from '@storybook/react' import { WithI18next } from '../../../../../WithI18next' import { WithSettings } from '../../../../../WithSettings' import { FileInfoMessages } from '../../../../../../sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-info-messages/FileInfoMessages' -import { FilePreviewMother } from '../../../../../../../tests/component/files/domain/models/FilePreviewMother' import { WithDatasetAllPermissionsGranted } from '../../../../WithDatasetAllPermissionsGranted' +import { FilePreviewMother } from '../../../../../../../tests/component/files/domain/models/FilePreviewMother' const meta: Meta = { title: diff --git a/src/stories/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.stories.tsx b/src/stories/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.stories.tsx index f654d23a5..3737e69c6 100644 --- a/src/stories/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.stories.tsx +++ b/src/stories/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.stories.tsx @@ -1,8 +1,8 @@ import { Meta, StoryObj } from '@storybook/react' import { FileThumbnail } from '../../../../../../../../sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail' import { WithI18next } from '../../../../../../../WithI18next' -import { FilePreviewMother } from '../../../../../../../../../tests/component/files/domain/models/FilePreviewMother' import { WithFilePermissionsGranted } from '../../../../../../../file/file-permission/WithFilePermissionsGranted' +import { FilePreviewMother } from '../../../../../../../../../tests/component/files/domain/models/FilePreviewMother' const meta: Meta = { title: 'Sections/Dataset Page/DatasetFiles/FilesTable/FileInfoCell/FileThumbnail', @@ -31,7 +31,7 @@ export const WithThumbnailPreview: Story = { export const WithThumbnailRestrictedLockedIcon: Story = { render: () => { - const file = FilePreviewMother.createWithRestrictedAccess() + const file = FilePreviewMother.createRestricted() return } } @@ -39,7 +39,7 @@ export const WithThumbnailRestrictedLockedIcon: Story = { export const WithThumbnailRestrictedUnlockedIcon: Story = { decorators: [WithFilePermissionsGranted], render: () => { - const file = FilePreviewMother.createWithRestrictedAccessWithAccessGranted() + const file = FilePreviewMother.createRestricted() return } } @@ -47,7 +47,7 @@ export const WithThumbnailRestrictedUnlockedIcon: Story = { export const WithThumbnailPreviewRestrictedUnlockedIcon: Story = { decorators: [WithFilePermissionsGranted], render: () => { - const file = FilePreviewMother.createWithThumbnailRestrictedWithAccessGranted() + const file = FilePreviewMother.createWithThumbnailRestricted() return } } diff --git a/src/stories/file/FileMockData.ts b/src/stories/file/FileMockData.ts index 366ab78cb..a64b70753 100644 --- a/src/stories/file/FileMockData.ts +++ b/src/stories/file/FileMockData.ts @@ -1,6 +1,8 @@ -import { FilePreview, FileSize, FileSizeUnit } from '../../files/domain/models/FilePreview' -import { FilePreviewMother } from '../../../tests/component/files/domain/models/FilePreviewMother' +import { FileSize, FileSizeUnit } from '../../files/domain/models/FileMetadata' +import { FileMetadataMother } from '../../../tests/component/files/domain/models/FileMetadataMother' import { FilePaginationInfo } from '../../files/domain/models/FilePaginationInfo' +import { FilePreview } from '../../files/domain/models/FilePreview' +import { FilePreviewMother } from '../../../tests/component/files/domain/models/FilePreviewMother' const range = (len: number) => { const arr = [] @@ -14,10 +16,12 @@ export function makeFiles(paginationInfo: FilePaginationInfo): FilePreview[] { return range(paginationInfo.pageSize).map((value, index) => { return FilePreviewMother.create({ id: (paginationInfo.page - 1) * paginationInfo.pageSize + index, - size: new FileSize( - (paginationInfo.page - 1) * paginationInfo.pageSize + index, - FileSizeUnit.BYTES - ) + metadata: FileMetadataMother.createDefault({ + size: new FileSize( + (paginationInfo.page - 1) * paginationInfo.pageSize + index, + FileSizeUnit.BYTES + ) + }) }) }) } diff --git a/src/stories/file/FileMockRepository.ts b/src/stories/file/FileMockRepository.ts index 73a089ccd..372d46299 100644 --- a/src/stories/file/FileMockRepository.ts +++ b/src/stories/file/FileMockRepository.ts @@ -1,16 +1,17 @@ import { FileRepository } from '../../files/domain/repositories/FileRepository' import { FilesMockData } from './FileMockData' -import { FilePreview, FileDownloadMode } from '../../files/domain/models/FilePreview' +import { FileDownloadMode } from '../../files/domain/models/FileMetadata' import { FilesCountInfo } from '../../files/domain/models/FilesCountInfo' import { FilesCountInfoMother } from '../../../tests/component/files/domain/models/FilesCountInfoMother' import { FileUserPermissionsMother } from '../../../tests/component/files/domain/models/FileUserPermissionsMother' import { FileUserPermissions } from '../../files/domain/models/FileUserPermissions' import { DatasetVersion, DatasetVersionNumber } from '../../dataset/domain/models/Dataset' import { FileCriteria } from '../../files/domain/models/FileCriteria' -import { FilePreviewMother } from '../../../tests/component/files/domain/models/FilePreviewMother' +import { FileMetadataMother } from '../../../tests/component/files/domain/models/FileMetadataMother' import { FilePaginationInfo } from '../../files/domain/models/FilePaginationInfo' import { FileMother } from '../../../tests/component/files/domain/models/FileMother' import { File } from '../../files/domain/models/File' +import { FilePreview } from '../../files/domain/models/FilePreview' export class FileMockRepository implements FileRepository { constructor(public readonly fileMock?: File) {} @@ -76,11 +77,11 @@ export class FileMockRepository implements FileRepository { // eslint-disable-next-line unused-imports/no-unused-vars getMultipleFileDownloadUrl(ids: number[], downloadMode: FileDownloadMode): string { - return FilePreviewMother.createDownloadUrl() + return FileMetadataMother.createDownloadUrl() } // eslint-disable-next-line unused-imports/no-unused-vars getFileDownloadUrl(id: number, downloadMode: FileDownloadMode): string { - return FilePreviewMother.createDownloadUrl() + return FileMetadataMother.createDownloadUrl() } } diff --git a/src/stories/file/FileWithDeniedPermissionsRepository.ts b/src/stories/file/FileWithDeniedPermissionsRepository.ts index 4385df633..4f3ba877d 100644 --- a/src/stories/file/FileWithDeniedPermissionsRepository.ts +++ b/src/stories/file/FileWithDeniedPermissionsRepository.ts @@ -11,7 +11,7 @@ export class FileWithDeniedPermissionsRepository getUserPermissionsById(id: number): Promise { return new Promise((resolve) => { setTimeout(() => { - resolve(FileUserPermissionsMother.createWithDeniedPermissions()) + resolve(FileUserPermissionsMother.createWithAllPermissionsDenied()) }, 1000) }) } diff --git a/src/stories/file/FileWithGrantedPermissionsRepository.ts b/src/stories/file/FileWithGrantedPermissionsRepository.ts index c3e66e911..aef0c5242 100644 --- a/src/stories/file/FileWithGrantedPermissionsRepository.ts +++ b/src/stories/file/FileWithGrantedPermissionsRepository.ts @@ -11,7 +11,7 @@ export class FileWithGrantedPermissionsRepository getUserPermissionsById(id: number): Promise { return new Promise((resolve) => { setTimeout(() => { - resolve(FileUserPermissionsMother.createWithGrantedPermissions()) + resolve(FileUserPermissionsMother.createWithAllPermissionsGranted()) }, 1000) }) } diff --git a/src/stories/file/file-action-buttons/access-file-menu/AccessFileMenu.stories.tsx b/src/stories/file/file-action-buttons/access-file-menu/AccessFileMenu.stories.tsx new file mode 100644 index 000000000..00632dc73 --- /dev/null +++ b/src/stories/file/file-action-buttons/access-file-menu/AccessFileMenu.stories.tsx @@ -0,0 +1,162 @@ +import { Meta, StoryObj } from '@storybook/react' +import { AccessFileMenu } from '../../../../sections/file/file-action-buttons/access-file-menu/AccessFileMenu' +import { WithI18next } from '../../../WithI18next' +import { WithSettings } from '../../../WithSettings' +import { WithFilePermissionsGranted } from '../../file-permission/WithFilePermissionsGranted' +import { FileAccessMother } from '../../../../../tests/component/files/domain/models/FileAccessMother' +import { FileMetadataMother } from '../../../../../tests/component/files/domain/models/FileMetadataMother' + +const meta: Meta = { + title: 'Sections/File Page/Action Buttons/AccessFileMenu', + component: AccessFileMenu, + decorators: [WithI18next, WithSettings] +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => ( + + ) +} + +export const AsIcon: Story = { + render: () => ( + + ) +} + +export const NonTabularFiles: Story = { + render: () => ( + + ) +} + +export const TabularFiles: Story = { + render: () => ( + + ) +} + +export const Restricted: Story = { + render: () => ( + + ) +} + +export const RestrictedWithAccessRequestAllowed: Story = { + render: () => ( + + ) +} + +export const RestrictedWithAccessRequestPending: Story = { + render: () => ( + + ) +} + +export const RestrictedWithAccessGranted: Story = { + decorators: [WithFilePermissionsGranted], + render: () => ( + + ) +} + +export const WithEmbargo: Story = { + decorators: [WithFilePermissionsGranted], + render: () => ( + + ) +} + +export const WithEmbargoAndRestricted: Story = { + render: () => ( + + ) +} + +export const WithEmbargoAndRestrictedWithAccessGranted: Story = { + render: () => ( + + ) +} diff --git a/src/stories/file/file-action-buttons/access-file-menu/RequestAccessModal.stories.tsx b/src/stories/file/file-action-buttons/access-file-menu/RequestAccessModal.stories.tsx new file mode 100644 index 000000000..f5ea38c63 --- /dev/null +++ b/src/stories/file/file-action-buttons/access-file-menu/RequestAccessModal.stories.tsx @@ -0,0 +1,23 @@ +import { Meta, StoryObj } from '@storybook/react' +import { WithI18next } from '../../../WithI18next' +import { WithSettings } from '../../../WithSettings' +import { WithLoggedInUser } from '../../../WithLoggedInUser' +import { RequestAccessModal } from '../../../../sections/file/file-action-buttons/access-file-menu/RequestAccessModal' + +const meta: Meta = { + title: 'Sections/File Page/Action Buttons/RequestAccessModal', + component: RequestAccessModal, + decorators: [WithI18next, WithSettings] +} + +export default meta +type Story = StoryObj + +export const LoggedOut: Story = { + render: () => +} + +export const LoggedIn: Story = { + decorators: [WithLoggedInUser], + render: () => +} diff --git a/src/stories/file/file-metadata/FileMetadata.stories.tsx b/src/stories/file/file-metadata/FileMetadata.stories.tsx index 5f0374b32..a97b368e5 100644 --- a/src/stories/file/file-metadata/FileMetadata.stories.tsx +++ b/src/stories/file/file-metadata/FileMetadata.stories.tsx @@ -1,7 +1,9 @@ import { Meta, StoryObj } from '@storybook/react' import { WithI18next } from '../../WithI18next' import { FileMetadata } from '../../../sections/file/file-metadata/FileMetadata' -import { FileMother } from '../../../../tests/component/files/domain/models/FileMother' +import { FileMetadataMother } from '../../../../tests/component/files/domain/models/FileMetadataMother' +import { FilePublishingStatus } from '../../../files/domain/models/FileVersion' +import { FileUserPermissionsMother } from '../../../../tests/component/files/domain/models/FileUserPermissionsMother' const meta: Meta = { title: 'Sections/File Page/FileMetadata', @@ -13,5 +15,12 @@ export default meta type Story = StoryObj export const Default: Story = { - render: () => + render: () => ( + + ) } diff --git a/tests/component/dataset/domain/models/DatasetMother.ts b/tests/component/dataset/domain/models/DatasetMother.ts index 64bd805d7..0c93c63f5 100644 --- a/tests/component/dataset/domain/models/DatasetMother.ts +++ b/tests/component/dataset/domain/models/DatasetMother.ts @@ -19,7 +19,7 @@ import { FileDownloadMode, FileDownloadSize, FileSizeUnit -} from '../../../../../src/files/domain/models/FilePreview' +} from '../../../../../src/files/domain/models/FileMetadata' export class DatasetVersionMother { static create(props?: Partial): DatasetVersion { diff --git a/tests/component/dataset/infrastructure/mappers/JSDatasetMapper.spec.ts b/tests/component/dataset/infrastructure/mappers/JSDatasetMapper.spec.ts index 6a0da652e..8033e77ad 100644 --- a/tests/component/dataset/infrastructure/mappers/JSDatasetMapper.spec.ts +++ b/tests/component/dataset/infrastructure/mappers/JSDatasetMapper.spec.ts @@ -15,7 +15,7 @@ import { FileDownloadMode, FileDownloadSize, FileSizeUnit -} from '../../../../../src/files/domain/models/FilePreview' +} from '../../../../../src/files/domain/models/FileMetadata' chai.use(chaiAsPromised) const expect = chai.expect diff --git a/tests/component/files/domain/models/FileAccessMother.ts b/tests/component/files/domain/models/FileAccessMother.ts new file mode 100644 index 000000000..10e0315c3 --- /dev/null +++ b/tests/component/files/domain/models/FileAccessMother.ts @@ -0,0 +1,68 @@ +import { FileAccess } from '../../../../../src/files/domain/models/FileAccess' +import { faker } from '@faker-js/faker' + +export class FileAccessMother { + static create(props?: Partial): FileAccess { + return { + restricted: faker.datatype.boolean(), + latestVersionRestricted: faker.datatype.boolean(), + canBeRequested: faker.datatype.boolean(), + requested: faker.datatype.boolean(), + ...props + } + } + + static createPublic(): FileAccess { + return this.create({ + restricted: false, + latestVersionRestricted: false, + canBeRequested: false, + requested: false + }) + } + + static createRestricted(): FileAccess { + return this.create({ + restricted: true, + latestVersionRestricted: true, + canBeRequested: false, + requested: false + }) + } + + static createNotRestrictedButLatestVersionRestricted(): FileAccess { + return this.create({ + restricted: false, + latestVersionRestricted: true, + canBeRequested: false, + requested: false + }) + } + + static createWithAccessRequestAllowed(): FileAccess { + return this.create({ + restricted: true, + latestVersionRestricted: true, + canBeRequested: true, + requested: false + }) + } + + static createWithAccessRequestNotAllowed(): FileAccess { + return this.create({ + restricted: true, + latestVersionRestricted: true, + canBeRequested: false, + requested: false + }) + } + + static createWithAccessRequestPending(): FileAccess { + return this.create({ + restricted: true, + latestVersionRestricted: true, + canBeRequested: true, + requested: true + }) + } +} diff --git a/tests/component/files/domain/models/FileIngestMother.ts b/tests/component/files/domain/models/FileIngestMother.ts new file mode 100644 index 000000000..f971a82a0 --- /dev/null +++ b/tests/component/files/domain/models/FileIngestMother.ts @@ -0,0 +1,26 @@ +import { faker } from '@faker-js/faker' +import { FileIngest, FileIngestStatus } from '../../../../../src/files/domain/models/FileIngest' + +export class FileIngestMother { + static create(props?: Partial): FileIngest { + return new FileIngest( + props?.status ?? faker.helpers.arrayElement(Object.values(FileIngestStatus)), + props?.message + ) + } + + static createInProgress(): FileIngest { + return this.create({ status: FileIngestStatus.IN_PROGRESS }) + } + + static createIngestProblem(message?: string): FileIngest { + return this.create({ + status: FileIngestStatus.ERROR, + message: message + }) + } + + static createIngestNone(): FileIngest { + return this.create({ status: FileIngestStatus.NONE }) + } +} diff --git a/tests/component/files/domain/models/FileMetadataMother.ts b/tests/component/files/domain/models/FileMetadataMother.ts new file mode 100644 index 000000000..978e46ed5 --- /dev/null +++ b/tests/component/files/domain/models/FileMetadataMother.ts @@ -0,0 +1,347 @@ +import { faker } from '@faker-js/faker' +import { + FileDateType, + FileEmbargo, + FileSize, + FileSizeUnit, + FileType, + FileChecksum, + FileLabel, + FileLabelType, + FileTabularData, + FileMetadata, + FileDownloadUrls +} from '../../../../../src/files/domain/models/FileMetadata' +import FileTypeToFriendlyTypeMap from '../../../../../src/files/domain/models/FileTypeToFriendlyTypeMap' + +const valueOrUndefined: (value: T) => T | undefined = (value) => { + const shouldShowValue = faker.datatype.boolean() + return shouldShowValue ? value : undefined +} + +export class FileTypeMother { + static create(props?: Partial): FileType { + return new FileType( + props?.value ?? faker.helpers.arrayElement(Object.keys(FileTypeToFriendlyTypeMap)), + props?.original + ) + } + + static createTabular(): FileType { + return new FileType('text/tab-separated-values', 'Comma Separated Values') + } + + static createTabularUnknown(): FileType { + return new FileType('text/tab-separated-values', 'Unknown') + } + + static createText(): FileType { + return new FileType('text/plain') + } + + static createImage(): FileType { + return new FileType('image') + } + + static createRealistic(): FileType { + return new FileType('text/csv', 'Comma Separated Values') + } + + static createUnknown(): FileType { + return new FileType('unknown') + } + + static createRData(): FileType { + return new FileType('text/tab-separated-values', 'R Data') + } +} + +export class FileTabularDataMother { + static create(props?: Partial): FileTabularData { + return { + variablesCount: faker.datatype.number(100), + observationsCount: faker.datatype.number(100), + unf: `UNF:6:xXw6cIZnwHWvmRdwhYCQZA==`, + ...props + } + } +} + +export class FileLabelMother { + static create(props?: Partial): FileLabel { + return { + type: faker.helpers.arrayElement(Object.values(FileLabelType)), + value: faker.lorem.word(), + ...props + } + } + + static createMany(count: number): FileLabel[] { + return Array.from({ length: count }).map(() => this.create()) + } + + static createManyRealistic(): FileLabel[] { + return [ + { value: 'Category 1', type: FileLabelType.CATEGORY }, + { value: 'Tag 1', type: FileLabelType.TAG }, + { value: 'Tag 2', type: FileLabelType.TAG } + ] + } +} + +export class FileEmbargoMother { + static create(props?: Partial): FileEmbargo { + return new FileEmbargo( + props?.dateAvailable ?? faker.date.future(), + props?.reason ?? faker.lorem.sentence() + ) + } + + static createWithNoReason(props?: Partial): FileEmbargo { + return new FileEmbargo(props?.dateAvailable ?? faker.date.future(), undefined) + } +} + +export class FileChecksumMother { + static create(props?: Partial): FileChecksum { + return { + algorithm: faker.lorem.word(), + value: faker.datatype.uuid(), + ...props + } + } + + static createRealistic(props?: Partial): FileChecksum { + return { + algorithm: 'MD5', + value: 'd41d8cd98f00b204e9800998ecf8427e', + ...props + } + } +} + +export class FileSizeMother { + static create(props?: Partial): FileSize { + const size = { + value: faker.datatype.number({ max: 1024, precision: 2 }), + unit: faker.helpers.arrayElement(Object.values(FileSizeUnit)), + ...props + } + + return new FileSize(size.value, size.unit) + } +} + +export class FileDownloadUrlsMother { + static create(props?: Partial): FileDownloadUrls { + return { + original: faker.internet.url(), + tabular: faker.internet.url(), + rData: faker.internet.url(), + ...props + } + } +} + +export class FileMetadataMother { + static create(props?: Partial): FileMetadata { + const thumbnail = valueOrUndefined(faker.image.imageUrl(400)) + const tabularFile = faker.datatype.boolean() + const checksum = valueOrUndefined(faker.datatype.uuid()) + const fileMockedData = { + id: faker.datatype.number(), + type: tabularFile ? FileTypeMother.createTabular() : FileTypeMother.create(), + size: FileSizeMother.create(), + date: { + type: faker.helpers.arrayElement(Object.values(FileDateType)), + date: faker.date.recent() + }, + downloadCount: faker.datatype.number(40), + labels: faker.datatype.boolean() ? FileLabelMother.createMany(3) : [], + checksum: FileChecksumMother.create(), + thumbnail: thumbnail, + directory: valueOrUndefined(faker.system.directoryPath()), + embargo: valueOrUndefined(FileEmbargoMother.create()), + tabularData: tabularFile && !checksum ? FileTabularDataMother.create() : undefined, + description: valueOrUndefined(faker.lorem.paragraph()), + isDeleted: faker.datatype.boolean(), + downloadUrls: FileDownloadUrlsMother.create(), + depositDate: faker.date.past(), + publicationDate: faker.datatype.boolean() ? faker.date.past() : undefined, + persistentId: faker.datatype.uuid(), + ...props + } + + return new FileMetadata( + fileMockedData.type, + fileMockedData.size, + fileMockedData.date, + fileMockedData.downloadCount, + fileMockedData.labels, + fileMockedData.isDeleted, + fileMockedData.downloadUrls, + fileMockedData.depositDate, + fileMockedData.publicationDate, + fileMockedData.thumbnail, + fileMockedData.directory, + fileMockedData.embargo, + fileMockedData.tabularData, + fileMockedData.description, + fileMockedData.checksum, + fileMockedData.persistentId + ) + } + + 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 createDefault(props?: Partial): FileMetadata { + const defaultFile = { + type: FileTypeMother.createText(), + labels: [], + checksum: undefined, + thumbnail: undefined, + directory: undefined, + embargo: undefined, + tabularData: undefined, + description: undefined, + isDeleted: false, + ...props + } + return this.create(defaultFile) + } + + static createWithLabels(): FileMetadata { + return this.createDefault({ labels: FileLabelMother.createMany(4) }) + } + + static createWithLabelsRealistic(): FileMetadata { + return this.createDefault({ labels: FileLabelMother.createManyRealistic() }) + } + + static createWithNoLabels(): FileMetadata { + return this.createDefault({ labels: [] }) + } + + static createWithDirectory(): FileMetadata { + return this.createDefault({ directory: faker.system.directoryPath() }) + } + + static createWithNoDirectory(): FileMetadata { + return this.createDefault({ directory: undefined }) + } + + static createWithEmbargo(): FileMetadata { + return this.createDefault({ + embargo: FileEmbargoMother.create() + }) + } + + static createNotEmbargoed(): FileMetadata { + return this.createDefault({ + embargo: undefined + }) + } + + static createTabular(props?: Partial): FileMetadata { + return this.createDefault({ + type: FileTypeMother.createTabular(), + tabularData: FileTabularDataMother.create(), + ...props + }) + } + + static createNonTabular(props?: Partial): FileMetadata { + return this.createDefault({ + type: FileTypeMother.createText(), + tabularData: undefined, + ...props + }) + } + + static createNonTabularUnknown(props?: Partial): FileMetadata { + return this.createNonTabular({ + type: FileTypeMother.createUnknown(), + ...props + }) + } + + static createWithDescription(): FileMetadata { + return this.createDefault({ + description: faker.lorem.paragraph() + }) + } + + static createWithNoDescription(): FileMetadata { + return this.createDefault({ + description: undefined + }) + } + + static createWithChecksum(): FileMetadata { + return this.createDefault({ + checksum: FileChecksumMother.create() + }) + } + + static createWithNoChecksum(): FileMetadata { + return this.createDefault({ + checksum: undefined + }) + } + + static createWithThumbnail(): FileMetadata { + return this.createDefault({ + thumbnail: faker.image.imageUrl(400), + type: FileTypeMother.createImage() + }) + } + + static createWithoutThumbnail(props?: Partial): FileMetadata { + return this.createDefault({ + thumbnail: undefined, + ...props + }) + } + + static createDeleted(): FileMetadata { + return this.createDefault({ + isDeleted: true + }) + } + + static createWithNoPersistentId(): FileMetadata { + return this.createDefault({ + persistentId: undefined + }) + } + + static createWithPublicationDate(props?: Partial): FileMetadata { + return this.createDefault({ + publicationDate: faker.date.past(), + ...props + }) + } + + static createWithNoPublicationDate(): FileMetadata { + return this.createDefault({ + publicationDate: undefined + }) + } + + static createWithPublicationDateNotEmbargoed(): FileMetadata { + return this.createWithPublicationDate({ + embargo: undefined + }) + } + + static createWithPublicationDateEmbargoed(): FileMetadata { + return this.createWithPublicationDate({ + embargo: FileEmbargoMother.create() + }) + } +} diff --git a/tests/component/files/domain/models/FileMother.ts b/tests/component/files/domain/models/FileMother.ts index 832decf72..85bed0f08 100644 --- a/tests/component/files/domain/models/FileMother.ts +++ b/tests/component/files/domain/models/FileMother.ts @@ -1,45 +1,24 @@ import { File } from '../../../../../src/files/domain/models/File' -import { faker } from '@faker-js/faker' import { DatasetVersionMother } from '../../../dataset/domain/models/DatasetMother' -import { - FileChecksumMother, - FileEmbargoMother, - FileLabelMother, - FileSizeMother, - FileTabularDataMother, - FileTypeMother, - FileVersionMother -} from './FilePreviewMother' +import { FileMetadataMother } from './FileMetadataMother' +import { FileVersionMother } from './FileVersionMother' +import { FileAccessMother } from './FileAccessMother' +import { FileUserPermissionsMother } from './FileUserPermissionsMother' +import { faker } from '@faker-js/faker' +import { FileIngestMother } from './FileIngestMother' export class FileMother { static create(props?: Partial): File { - const name = props?.name ?? faker.system.fileName() return { + id: faker.datatype.number(), name: faker.system.fileName(), version: FileVersionMother.create(), datasetVersion: DatasetVersionMother.create(), - type: FileTypeMother.create(), - size: FileSizeMother.create(), - citation: FileCitationMother.create(name), - restricted: faker.datatype.boolean(), - permissions: { - canDownloadFile: faker.datatype.boolean() - }, - labels: faker.datatype.boolean() ? FileLabelMother.createMany(3) : [], - depositDate: faker.date.past(), - publicationDate: faker.datatype.boolean() ? faker.date.past() : undefined, - thumbnail: faker.datatype.boolean() ? faker.image.imageUrl(400) : undefined, - directory: faker.datatype.boolean() ? faker.system.directoryPath() : undefined, - persistentId: faker.datatype.boolean() ? faker.datatype.uuid() : undefined, - downloadUrls: { - original: '/api/access/datafile/107', - tabular: '/api/access/datafile/107', - rData: '/api/access/datafile/107' - }, - tabularData: faker.datatype.boolean() ? FileTabularDataMother.create() : undefined, - description: faker.datatype.boolean() ? faker.lorem.sentence() : undefined, - checksum: faker.datatype.boolean() ? FileChecksumMother.create() : undefined, - embargo: faker.datatype.boolean() ? FileEmbargoMother.create() : undefined, + citation: FileCitationMother.create('File Title'), + access: FileAccessMother.create(), + metadata: FileMetadataMother.create(), + permissions: FileUserPermissionsMother.create(), + ingest: FileIngestMother.create(), ...props } } @@ -49,54 +28,53 @@ export class FileMother { name: 'File Title', datasetVersion: DatasetVersionMother.createRealistic(), citation: FileCitationMother.create('File Title'), - restricted: false, - permissions: { - canDownloadFile: true - }, - persistentId: 'doi:10.5072/FK2/ABC123', - checksum: FileChecksumMother.createRealistic(), + access: FileAccessMother.createPublic(), + permissions: FileUserPermissionsMother.createWithAllPermissionsGranted(), + metadata: FileMetadataMother.createDefault(), ...props }) } static createRestricted(props?: Partial): File { - return this.createRealistic( - this.createWithDownloadPermissionDenied({ restricted: true, ...props }) - ) + return this.createRealistic({ + access: FileAccessMother.createRestricted(), + permissions: FileUserPermissionsMother.createWithAllPermissionsDenied(), + ...props + }) } static createRestrictedWithAccessGranted(props?: Partial): File { - return this.createRestricted(this.createWithDownloadPermissionGranted(props)) + return this.createRealistic({ + access: FileAccessMother.createRestricted(), + permissions: FileUserPermissionsMother.createWithAllPermissionsGranted(), + ...props + }) } static createWithThumbnail(props?: Partial): File { return this.create({ - thumbnail: faker.image.imageUrl(), + metadata: FileMetadataMother.createWithThumbnail(), ...props }) } static createWithoutThumbnail(props?: Partial): File { return this.create({ - thumbnail: undefined, + metadata: FileMetadataMother.createWithoutThumbnail(), ...props }) } static createWithDownloadPermissionGranted(props?: Partial): File { return this.create({ - permissions: { - canDownloadFile: true - }, + permissions: FileUserPermissionsMother.createWithDownloadFileGranted(), ...props }) } static createWithDownloadPermissionDenied(props?: Partial): File { return this.create({ - permissions: { - canDownloadFile: false - }, + permissions: FileUserPermissionsMother.createWithDownloadFileDenied(), ...props }) } diff --git a/tests/component/files/domain/models/FilePreviewMother.ts b/tests/component/files/domain/models/FilePreviewMother.ts index 2597b7f8b..07cf0a898 100644 --- a/tests/component/files/domain/models/FilePreviewMother.ts +++ b/tests/component/files/domain/models/FilePreviewMother.ts @@ -1,443 +1,157 @@ +import { FilePreview } from '../../../../../src/files/domain/models/FilePreview' +import { FileMetadataMother } from './FileMetadataMother' import { faker } from '@faker-js/faker' -import { - FilePreview, - FileDateType, - FileEmbargo, - FileIngest, - FileIngestStatus, - FileSize, - FileSizeUnit, - FilePublishingStatus, - FileType, - FileChecksum, - FileLabel, - FileLabelType, - FileTabularData, - FileVersion -} from '../../../../../src/files/domain/models/FilePreview' -import FileTypeToFriendlyTypeMap from '../../../../../src/files/domain/models/FileTypeToFriendlyTypeMap' - -const valueOrUndefined: (value: T) => T | undefined = (value) => { - const shouldShowValue = faker.datatype.boolean() - return shouldShowValue ? value : undefined -} - -export class FileTypeMother { - static create(props?: Partial): FileType { - return new FileType( - props?.value ?? faker.helpers.arrayElement(Object.keys(FileTypeToFriendlyTypeMap)), - props?.original - ) - } - - static createTabular(): FileType { - return new FileType('text/tab-separated-values', 'Comma Separated Values') - } - - static createText(): FileType { - return new FileType('text/plain') - } - - static createImage(): FileType { - return new FileType('image') - } - - static createRealistic(): FileType { - return new FileType('text/csv', 'Comma Separated Values') - } -} - -export class FileTabularDataMother { - static create(props?: Partial): FileTabularData { - return { - variablesCount: faker.datatype.number(100), - observationsCount: faker.datatype.number(100), - unf: `UNF:6:xXw6cIZnwHWvmRdwhYCQZA==`, - ...props - } - } -} - -export class FileLabelMother { - static create(props?: Partial): FileLabel { - return { - type: faker.helpers.arrayElement(Object.values(FileLabelType)), - value: faker.lorem.word(), - ...props - } - } - - static createMany(count: number): FileLabel[] { - return Array.from({ length: count }).map(() => this.create()) - } -} - -export class FileEmbargoMother { - static create(props?: Partial): FileEmbargo { - return new FileEmbargo( - props?.dateAvailable ?? faker.date.future(), - props?.reason ?? faker.lorem.sentence() - ) - } - - static createWithNoReason(props?: Partial): FileEmbargo { - return new FileEmbargo(props?.dateAvailable ?? faker.date.future(), undefined) - } -} - -export class FileIngestMother { - static create(props?: Partial): FileIngest { - return { - status: faker.helpers.arrayElement(Object.values(FileIngestStatus)), - reportMessage: valueOrUndefined(faker.lorem.sentence()), - ...props - } - } - - static createInProgress(): FileIngest { - return this.create({ status: FileIngestStatus.IN_PROGRESS }) - } - - static createIngestProblem(reportMessage?: string): FileIngest { - return this.create({ - status: FileIngestStatus.ERROR, - reportMessage: reportMessage - }) - } - - static createIngestNone(): FileIngest { - return this.create({ status: FileIngestStatus.NONE }) - } -} - -export class FileChecksumMother { - static create(props?: Partial): FileChecksum { - return { - algorithm: faker.lorem.word(), - value: faker.datatype.uuid(), - ...props - } - } - - static createRealistic(props?: Partial): FileChecksum { - return { - algorithm: 'MD5', - value: 'd41d8cd98f00b204e9800998ecf8427e', - ...props - } - } -} - -export class FileVersionMother { - static create(props?: Partial): FileVersion { - return { - number: faker.datatype.number(), - publishingStatus: faker.helpers.arrayElement(Object.values(FilePublishingStatus)), - ...props - } - } - - static createReleased(props?: Partial): FileVersion { - return this.create({ - publishingStatus: FilePublishingStatus.RELEASED, - ...props - }) - } - - static createDeaccessioned(props?: Partial): FileVersion { - return this.create({ - publishingStatus: FilePublishingStatus.DEACCESSIONED, - ...props - }) - } -} - -export class FileSizeMother { - static create(props?: Partial): FileSize { - const size = { - value: faker.datatype.number({ max: 1024, precision: 2 }), - unit: faker.helpers.arrayElement(Object.values(FileSizeUnit)), - ...props - } - - return new FileSize(size.value, size.unit) - } -} +import { FileAccessMother } from './FileAccessMother' +import { FileVersionMother } from './FileVersionMother' +import { FileIngestMother } from './FileIngestMother' export class FilePreviewMother { static create(props?: Partial): FilePreview { - const thumbnail = valueOrUndefined(faker.image.imageUrl()) - const tabularFile = faker.datatype.boolean() - const checksum = valueOrUndefined(faker.datatype.uuid()) - const fileMockedData = { + return { id: faker.datatype.number(), name: faker.system.fileName(), - access: { - restricted: faker.datatype.boolean(), - latestVersionRestricted: faker.datatype.boolean(), - canBeRequested: faker.datatype.boolean(), - requested: faker.datatype.boolean() - }, version: FileVersionMother.create(), - type: tabularFile ? FileTypeMother.createTabular() : FileTypeMother.create(), - size: FileSizeMother.create(), - date: { - type: faker.helpers.arrayElement(Object.values(FileDateType)), - date: faker.date.recent() - }, - downloadCount: faker.datatype.number(40), - labels: faker.datatype.boolean() ? FileLabelMother.createMany(3) : [], - checksum: FileChecksumMother.create(), - thumbnail: thumbnail, - directory: valueOrUndefined(faker.system.directoryPath()), - embargo: valueOrUndefined(FileEmbargoMother.create()), - tabularData: tabularFile && !checksum ? FileTabularDataMother.create() : undefined, - description: valueOrUndefined(faker.lorem.paragraph()), - isDeleted: faker.datatype.boolean(), - ingest: { status: FileIngestStatus.NONE }, - downloadUrls: { - original: this.createDownloadUrl(), - tabular: this.createDownloadUrl(), - rData: this.createDownloadUrl() - }, + access: FileAccessMother.create(), + ingest: FileIngestMother.create(), + metadata: FileMetadataMother.create(), ...props } - - return new FilePreview( - fileMockedData.id, - fileMockedData.version, - fileMockedData.name, - fileMockedData.access, - fileMockedData.type, - fileMockedData.size, - fileMockedData.date, - fileMockedData.downloadCount, - fileMockedData.labels, - fileMockedData.isDeleted, - fileMockedData.ingest, - fileMockedData.downloadUrls, - fileMockedData.thumbnail, - fileMockedData.directory, - fileMockedData.embargo, - fileMockedData.tabularData, - fileMockedData.description, - fileMockedData.checksum - ) } - 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 createMany(quantity: number, props?: Partial): FilePreview[] { - return Array.from({ length: quantity }).map(() => this.create(props)) + static createMany(amount: number, props?: Partial): FilePreview[] { + return Array.from({ length: amount }).map(() => this.create(props)) } static createDefault(props?: Partial): FilePreview { - const defaultFile = { - type: FileTypeMother.createText(), + return this.create({ + name: 'File Title', version: FileVersionMother.createReleased(), - access: { - restricted: false, - latestVersionRestricted: false, - canBeRequested: false, - requested: false - }, - permissions: { canDownload: true }, - labels: [], - checksum: undefined, - thumbnail: undefined, - directory: undefined, - embargo: undefined, - tabularData: undefined, - description: undefined, - isDeleted: false, + access: FileAccessMother.createPublic(), + ingest: FileIngestMother.createIngestNone(), + metadata: FileMetadataMother.createDefault(), ...props - } - return this.create(defaultFile) - } - - static createWithLabels(): FilePreview { - return this.createDefault({ labels: FileLabelMother.createMany(4) }) - } - - static createWithDirectory(): FilePreview { - return this.createDefault({ directory: faker.system.directoryPath() }) + }) } static createWithEmbargo(): FilePreview { return this.createDefault({ - embargo: FileEmbargoMother.create() + metadata: FileMetadataMother.createWithEmbargo() }) } static createWithEmbargoRestricted(): FilePreview { return this.createDefault({ - access: { - restricted: true, - latestVersionRestricted: true, - canBeRequested: false, - requested: false - }, - embargo: FileEmbargoMother.create() + access: FileAccessMother.createRestricted(), + metadata: FileMetadataMother.createWithEmbargo() }) } - static createTabular(props?: Partial): FilePreview { + static createWithPublicAccess(): FilePreview { return this.createDefault({ - type: FileTypeMother.createTabular(), - tabularData: FileTabularDataMother.create(), - ...props + access: FileAccessMother.createPublic(), + metadata: FileMetadataMother.createNotEmbargoed() }) } - static createNonTabular(props?: Partial): FilePreview { + static createWithPublicAccessButLatestVersionRestricted(): FilePreview { return this.createDefault({ - type: FileTypeMother.createText(), - tabularData: undefined, - ...props + access: FileAccessMother.createNotRestrictedButLatestVersionRestricted(), + metadata: FileMetadataMother.createNotEmbargoed() }) } - static createWithDescription(): FilePreview { + static createRestricted(): FilePreview { return this.createDefault({ - description: faker.lorem.paragraph() + access: FileAccessMother.createRestricted(), + metadata: FileMetadataMother.createNotEmbargoed() }) } - static createWithChecksum(): FilePreview { + static createWithAccessRequestAllowed(): FilePreview { return this.createDefault({ - checksum: FileChecksumMother.create() + access: FileAccessMother.createWithAccessRequestAllowed(), + metadata: FileMetadataMother.createNotEmbargoed() }) } - static createWithPublicAccess(): FilePreview { + static createWithAccessRequestPending(): FilePreview { return this.createDefault({ - access: { - restricted: false, - latestVersionRestricted: false, - canBeRequested: false, - requested: false - }, - embargo: undefined + access: FileAccessMother.createWithAccessRequestPending(), + metadata: FileMetadataMother.createNotEmbargoed() }) } - static createWithPublicAccessButLatestVersionRestricted(): FilePreview { + static createWithThumbnail(): FilePreview { return this.createDefault({ - access: { - restricted: false, - latestVersionRestricted: true, - canBeRequested: false, - requested: false - }, - embargo: undefined + metadata: FileMetadataMother.createWithThumbnail() }) } - static createWithRestrictedAccess(): FilePreview { + static createWithThumbnailRestricted(): FilePreview { return this.createDefault({ - access: { - restricted: true, - latestVersionRestricted: true, - canBeRequested: false, - requested: false - }, - embargo: undefined + access: FileAccessMother.createRestricted(), + metadata: FileMetadataMother.createWithThumbnail() }) } - static createWithRestrictedAccessWithAccessGranted(): FilePreview { + static createDeaccessioned(): FilePreview { return this.createDefault({ - access: { - restricted: true, - latestVersionRestricted: true, - canBeRequested: true, - requested: false - }, - embargo: undefined + version: FileVersionMother.createDeaccessioned() }) } - static createWithAccessRequestAllowed(): FilePreview { + static createIngestInProgress(): FilePreview { return this.createDefault({ - access: { - restricted: true, - latestVersionRestricted: true, - canBeRequested: true, - requested: false - }, - embargo: undefined + ingest: FileIngestMother.createInProgress() }) } - static createWithAccessRequestPending(): FilePreview { + static createIngestProblem(reportMessage?: string): FilePreview { return this.createDefault({ - access: { - restricted: true, - latestVersionRestricted: true, - canBeRequested: true, - requested: true - }, - embargo: undefined + ingest: FileIngestMother.createIngestProblem(reportMessage) }) } - static createWithThumbnail(): FilePreview { + static createTabular(props?: Partial): FilePreview { return this.createDefault({ - thumbnail: faker.image.imageUrl() + metadata: FileMetadataMother.createTabular(), + ...props }) } - static createWithThumbnailRestrictedWithAccessGranted(): FilePreview { + static createNonTabular(): FilePreview { return this.createDefault({ - access: { - restricted: true, - latestVersionRestricted: true, - canBeRequested: true, - requested: false - }, - thumbnail: faker.image.imageUrl(), - type: FileTypeMother.createImage() + metadata: FileMetadataMother.createNonTabular() }) } - static createWithThumbnailRestricted(): FilePreview { + static createDeleted(): FilePreview { return this.createDefault({ - access: { - restricted: true, - latestVersionRestricted: true, - canBeRequested: false, - requested: false - }, - thumbnail: faker.image.imageUrl(), - type: FileTypeMother.createImage() + metadata: FileMetadataMother.createDeleted() }) } - static createDeaccessioned(): FilePreview { + static createWithLabels(): FilePreview { return this.createDefault({ - version: FileVersionMother.createDeaccessioned() + metadata: FileMetadataMother.createWithLabels() }) } - static createDeleted(): FilePreview { + + static createWithDirectory(): FilePreview { return this.createDefault({ - isDeleted: true + metadata: FileMetadataMother.createWithDirectory() }) } - static createIngestInProgress(): FilePreview { + static createWithDescription(): FilePreview { return this.createDefault({ - ingest: FileIngestMother.createInProgress() + metadata: FileMetadataMother.createWithDescription() }) } - static createIngestProblem(reportMessage?: string): FilePreview { + static createWithChecksum(): FilePreview { return this.createDefault({ - ingest: FileIngestMother.createIngestProblem(reportMessage) + metadata: FileMetadataMother.createWithChecksum() }) } } diff --git a/tests/component/files/domain/models/FileUserPermissionsMother.ts b/tests/component/files/domain/models/FileUserPermissionsMother.ts index d10f4271b..2fd603376 100644 --- a/tests/component/files/domain/models/FileUserPermissionsMother.ts +++ b/tests/component/files/domain/models/FileUserPermissionsMother.ts @@ -11,17 +11,25 @@ export class FileUserPermissionsMother { } } - static createWithGrantedPermissions(): FileUserPermissions { - return FileUserPermissionsMother.create({ + static createWithAllPermissionsGranted(): FileUserPermissions { + return this.create({ canDownloadFile: true, canEditDataset: true }) } - static createWithDeniedPermissions(): FileUserPermissions { - return FileUserPermissionsMother.create({ + static createWithAllPermissionsDenied(): FileUserPermissions { + return this.create({ canDownloadFile: false, canEditDataset: false }) } + + static createWithDownloadFileGranted(): FileUserPermissions { + return this.create({ canDownloadFile: true }) + } + + static createWithDownloadFileDenied(): FileUserPermissions { + return this.create({ canDownloadFile: false }) + } } diff --git a/tests/component/files/domain/models/FileVersionMother.ts b/tests/component/files/domain/models/FileVersionMother.ts new file mode 100644 index 000000000..4d93c6355 --- /dev/null +++ b/tests/component/files/domain/models/FileVersionMother.ts @@ -0,0 +1,29 @@ +import { faker } from '@faker-js/faker' +import { + FilePublishingStatus, + FileVersion +} from '../../../../../src/files/domain/models/FileVersion' + +export class FileVersionMother { + static create(props?: Partial): FileVersion { + return { + number: faker.datatype.number(), + publishingStatus: faker.helpers.arrayElement(Object.values(FilePublishingStatus)), + ...props + } + } + + static createReleased(props?: Partial): FileVersion { + return this.create({ + publishingStatus: FilePublishingStatus.RELEASED, + ...props + }) + } + + static createDeaccessioned(props?: Partial): FileVersion { + return this.create({ + publishingStatus: FilePublishingStatus.DEACCESSIONED, + ...props + }) + } +} diff --git a/tests/component/files/domain/models/FilesCountInfoMother.tsx b/tests/component/files/domain/models/FilesCountInfoMother.tsx index 0ad542504..d0a19b9f6 100644 --- a/tests/component/files/domain/models/FilesCountInfoMother.tsx +++ b/tests/component/files/domain/models/FilesCountInfoMother.tsx @@ -1,4 +1,4 @@ -import { FileType } from '../../../../../src/files/domain/models/FilePreview' +import { FileType } from '../../../../../src/files/domain/models/FileMetadata' import { faker } from '@faker-js/faker' import { FilesCountInfo } from '../../../../../src/files/domain/models/FilesCountInfo' import { FileAccessOption, FileTag } from '../../../../../src/files/domain/models/FileCriteria' 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 53926122f..501e51966 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 @@ -5,7 +5,7 @@ import { DatasetPermissionsMother, DatasetVersionMother } from '../../../../dataset/domain/models/DatasetMother' -import { FileSizeUnit } from '../../../../../../src/files/domain/models/FilePreview' +import { FileSizeUnit } from '../../../../../../src/files/domain/models/FileMetadata' const downloadUrls = DatasetDownloadUrlsMother.create() describe('AccessDatasetMenu', () => { diff --git a/tests/component/sections/dataset/dataset-files/DatasetFiles.spec.tsx b/tests/component/sections/dataset/dataset-files/DatasetFiles.spec.tsx index 409388958..acc35c2ea 100644 --- a/tests/component/sections/dataset/dataset-files/DatasetFiles.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/DatasetFiles.spec.tsx @@ -1,4 +1,4 @@ -import { FilePreviewMother } from '../../../files/domain/models/FilePreviewMother' +import { FileMetadataMother } from '../../../files/domain/models/FileMetadataMother' import { DatasetFiles } from '../../../../../src/sections/dataset/dataset-files/DatasetFiles' import { FileRepository } from '../../../../../src/files/domain/repositories/FileRepository' import { @@ -12,7 +12,7 @@ import { FileSize, FileSizeUnit, FileType -} from '../../../../../src/files/domain/models/FilePreview' +} from '../../../../../src/files/domain/models/FileMetadata' import styles from '../../../../../src/sections/dataset/dataset-files/files-table/FilesTable.module.scss' import { DatasetMother } from '../../../dataset/domain/models/DatasetMother' import { SettingMother } from '../../../settings/domain/models/SettingMother' @@ -20,8 +20,10 @@ import { ZipDownloadLimit } from '../../../../../src/settings/domain/models/ZipD import { SettingsProvider } from '../../../../../src/sections/settings/SettingsProvider' import { SettingRepository } from '../../../../../src/settings/domain/repositories/SettingRepository' import { FilePaginationInfo } from '../../../../../src/files/domain/models/FilePaginationInfo' +import { FilePreviewMother } from '../../../files/domain/models/FilePreviewMother' +import { FilePreview } from '../../../../../src/files/domain/models/FilePreview' -const testFiles = FilePreviewMother.createMany(10) +const testFiles: FilePreview[] = FilePreviewMother.createMany(10) const datasetPersistentId = 'test-dataset-persistent-id' const datasetVersion = DatasetMother.create().version const fileRepository: FileRepository = {} as FileRepository @@ -310,11 +312,13 @@ describe('DatasetFiles', () => { it('renders the zip download limit message when selecting rows from different pages', () => { testFiles[1] = FilePreviewMother.create({ - size: new FileSize(1, FileSizeUnit.BYTES) + metadata: FileMetadataMother.create({ + size: new FileSize(1, FileSizeUnit.BYTES) + }) }) testFiles[2] = FilePreviewMother.create({ - size: new FileSize(2, FileSizeUnit.BYTES) + metadata: FileMetadataMother.create({ size: new FileSize(2, FileSizeUnit.BYTES) }) }) cy.customMount( diff --git a/tests/component/sections/dataset/dataset-files/file-criteria-form/FileCriteriaFilterByType.spec.tsx b/tests/component/sections/dataset/dataset-files/file-criteria-form/FileCriteriaFilterByType.spec.tsx index bda967772..5b0c2af92 100644 --- a/tests/component/sections/dataset/dataset-files/file-criteria-form/FileCriteriaFilterByType.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/file-criteria-form/FileCriteriaFilterByType.spec.tsx @@ -1,6 +1,6 @@ import { FileCriteria } from '../../../../../../src/files/domain/models/FileCriteria' import { FilesCountInfoMother } from '../../../../files/domain/models/FilesCountInfoMother' -import { FileType } from '../../../../../../src/files/domain/models/FilePreview' +import { FileType } from '../../../../../../src/files/domain/models/FileMetadata' import styles from '../../../../../../src/sections/dataset/dataset-files/file-criteria-form/FileCriteriaForm.module.scss' import { FileCriteriaFilterByType } from '../../../../../../src/sections/dataset/dataset-files/file-criteria-form/FileCriteriaFilterByType' diff --git a/tests/component/sections/dataset/dataset-files/file-criteria-form/FileCriteriaFilters.spec.tsx b/tests/component/sections/dataset/dataset-files/file-criteria-form/FileCriteriaFilters.spec.tsx index 1bb22ba44..ef514d773 100644 --- a/tests/component/sections/dataset/dataset-files/file-criteria-form/FileCriteriaFilters.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/file-criteria-form/FileCriteriaFilters.spec.tsx @@ -1,7 +1,7 @@ import { FileCriteria } from '../../../../../../src/files/domain/models/FileCriteria' import { FileCriteriaFilters } from '../../../../../../src/sections/dataset/dataset-files/file-criteria-form/FileCriteriaFilters' import { FilesCountInfoMother } from '../../../../files/domain/models/FilesCountInfoMother' -import { FileType } from '../../../../../../src/files/domain/models/FilePreview' +import { FileType } from '../../../../../../src/files/domain/models/FileMetadata' const defaultCriteria = new FileCriteria() const filesCountInfo = FilesCountInfoMother.create({ diff --git a/tests/component/sections/dataset/dataset-files/file-criteria-form/FileCriteriaForm.spec.tsx b/tests/component/sections/dataset/dataset-files/file-criteria-form/FileCriteriaForm.spec.tsx index 9809caff6..17da78f08 100644 --- a/tests/component/sections/dataset/dataset-files/file-criteria-form/FileCriteriaForm.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/file-criteria-form/FileCriteriaForm.spec.tsx @@ -6,7 +6,7 @@ import { FileTag } from '../../../../../../src/files/domain/models/FileCriteria' import { FilesCountInfoMother } from '../../../../files/domain/models/FilesCountInfoMother' -import { FileType } from '../../../../../../src/files/domain/models/FilePreview' +import { FileType } from '../../../../../../src/files/domain/models/FileMetadata' import { DatasetRepository } from '../../../../../../src/dataset/domain/repositories/DatasetRepository' import { DatasetMother, diff --git a/tests/component/sections/dataset/dataset-files/files-table/FilesTable.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/FilesTable.spec.tsx index e9d10fc6e..78956fd22 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/FilesTable.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/FilesTable.spec.tsx @@ -1,15 +1,16 @@ -import { FilePreviewMother } from '../../../../files/domain/models/FilePreviewMother' +import { FileMetadataMother } from '../../../../files/domain/models/FileMetadataMother' import { FilesTable, getCellStyle } from '../../../../../../src/sections/dataset/dataset-files/files-table/FilesTable' -import { FileSize, FileSizeUnit } from '../../../../../../src/files/domain/models/FilePreview' +import { FileSize, FileSizeUnit } from '../../../../../../src/files/domain/models/FileMetadata' import { SettingMother } from '../../../../settings/domain/models/SettingMother' import { ZipDownloadLimit } from '../../../../../../src/settings/domain/models/ZipDownloadLimit' import { SettingsContext } from '../../../../../../src/sections/settings/SettingsContext' import styles from '../../../../../../src/sections/dataset/dataset-files/files-table/FilesTable.module.scss' import { FileCriteria } from '../../../../../../src/files/domain/models/FileCriteria' import { FilePaginationInfo } from '../../../../../../src/files/domain/models/FilePaginationInfo' +import { FilePreviewMother } from '../../../../files/domain/models/FilePreviewMother' const testFiles = FilePreviewMother.createMany(10) const paginationInfo = new FilePaginationInfo(1, 10, 200) @@ -169,8 +170,12 @@ describe('FilesTable', () => { it('renders the zip download limit message when the zip download limit is reached', () => { const testFiles = [ - FilePreviewMother.create({ size: new FileSize(1024, FileSizeUnit.BYTES) }), - FilePreviewMother.create({ size: new FileSize(2048, FileSizeUnit.BYTES) }) + FilePreviewMother.create({ + metadata: FileMetadataMother.create({ size: new FileSize(1024, FileSizeUnit.BYTES) }) + }), + FilePreviewMother.create({ + metadata: FileMetadataMother.create({ size: new FileSize(2048, FileSizeUnit.BYTES) }) + }) ] const getSettingByName = cy .stub() diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/FileActionsHeader.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/FileActionsHeader.spec.tsx index df3315c07..4e2d9aa3f 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/FileActionsHeader.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/FileActionsHeader.spec.tsx @@ -1,11 +1,11 @@ import { FileActionsHeader } from '../../../../../../../src/sections/dataset/dataset-files/files-table/file-actions/FileActionsHeader' -import { FilePreviewMother } from '../../../../../files/domain/models/FilePreviewMother' import { DatasetProvider } from '../../../../../../../src/sections/dataset/DatasetProvider' import { DatasetRepository } from '../../../../../../../src/dataset/domain/repositories/DatasetRepository' import { DatasetMother, DatasetPermissionsMother } from '../../../../../dataset/domain/models/DatasetMother' +import { FilePreviewMother } from '../../../../../files/domain/models/FilePreviewMother' describe('FileActionsHeader', () => { it('renders the file actions header', () => { diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/download-files/DownloadFilesButton.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/download-files/DownloadFilesButton.spec.tsx index 29db77e6f..897ec17e1 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/download-files/DownloadFilesButton.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/download-files/DownloadFilesButton.spec.tsx @@ -7,9 +7,10 @@ import { DatasetPermissionsMother } from '../../../../../../dataset/domain/models/DatasetMother' import { DownloadFilesButton } from '../../../../../../../../src/sections/dataset/dataset-files/files-table/file-actions/download-files/DownloadFilesButton' -import { FilePreviewMother } from '../../../../../../files/domain/models/FilePreviewMother' +import { FileMetadataMother } from '../../../../../../files/domain/models/FileMetadataMother' import { MultipleFileDownloadProvider } from '../../../../../../../../src/sections/file/multiple-file-download/MultipleFileDownloadProvider' import { FileRepository } from '../../../../../../../../src/files/domain/repositories/FileRepository' +import { FilePreviewMother } from '../../../../../../files/domain/models/FilePreviewMother' const datasetRepository: DatasetRepository = {} as DatasetRepository const fileRepository = {} as FileRepository @@ -84,11 +85,7 @@ describe('DownloadFilesButton', () => { hasOneTabularFileAtLeast: true }) const files = FilePreviewMother.createMany(2, { - tabularData: { - variablesCount: 2, - observationsCount: 3, - unf: 'some-unf' - } + metadata: FileMetadataMother.createTabular() }) cy.mountAuthenticated( withDataset( @@ -107,7 +104,9 @@ describe('DownloadFilesButton', () => { permissions: DatasetPermissionsMother.createWithFilesDownloadAllowed(), hasOneTabularFileAtLeast: false }) - const files = FilePreviewMother.createMany(2, { tabularData: undefined }) + const files = FilePreviewMother.createMany(2, { + metadata: FileMetadataMother.createNonTabular() + }) cy.mountAuthenticated( withDataset( , @@ -125,7 +124,9 @@ describe('DownloadFilesButton', () => { permissions: DatasetPermissionsMother.createWithFilesDownloadAllowed(), hasOneTabularFileAtLeast: false }) - const files = FilePreviewMother.createMany(2, { tabularData: undefined }) + const files = FilePreviewMother.createMany(2, { + metadata: FileMetadataMother.createNonTabular() + }) cy.mountAuthenticated( withDataset( , @@ -142,7 +143,9 @@ describe('DownloadFilesButton', () => { permissions: DatasetPermissionsMother.createWithFilesDownloadAllowed(), hasOneTabularFileAtLeast: false }) - const files = FilePreviewMother.createMany(2, { tabularData: undefined }) + const files = FilePreviewMother.createMany(2, { + metadata: FileMetadataMother.createNonTabular() + }) const fileSelection = { 'some-file-id': files[0], 'some-other-file-id': files[1] @@ -167,11 +170,7 @@ describe('DownloadFilesButton', () => { hasOneTabularFileAtLeast: true }) const files = FilePreviewMother.createMany(2, { - tabularData: { - variablesCount: 2, - observationsCount: 3, - unf: 'some-unf' - } + metadata: FileMetadataMother.createTabular() }) const fileSelection = { 'some-file-id': files[0], @@ -209,11 +208,7 @@ describe('DownloadFilesButton', () => { } }) const files = FilePreviewMother.createMany(2, { - tabularData: { - variablesCount: 2, - observationsCount: 3, - unf: 'some-unf' - } + metadata: FileMetadataMother.createTabular() }) const fileSelection = { 'some-file-id': undefined, @@ -245,11 +240,7 @@ describe('DownloadFilesButton', () => { hasOneTabularFileAtLeast: true }) const files = FilePreviewMother.createMany(2, { - tabularData: { - variablesCount: 2, - observationsCount: 3, - unf: 'some-unf' - } + metadata: FileMetadataMother.createTabular() }) const fileSelection = { 'some-file-id': files[0] diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesMenu.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesMenu.spec.tsx index b60acf569..12e6cabeb 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesMenu.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesMenu.spec.tsx @@ -1,5 +1,4 @@ import { EditFilesMenu } from '../../../../../../../../src/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesMenu' -import { FilePreviewMother } from '../../../../../../files/domain/models/FilePreviewMother' import { ReactNode } from 'react' import { Dataset as DatasetModel } from '../../../../../../../../src/dataset/domain/models/Dataset' import { DatasetProvider } from '../../../../../../../../src/sections/dataset/DatasetProvider' @@ -9,6 +8,7 @@ import { DatasetMother, DatasetPermissionsMother } from '../../../../../../dataset/domain/models/DatasetMother' +import { FilePreviewMother } from '../../../../../../files/domain/models/FilePreviewMother' const datasetRepository: DatasetRepository = {} as DatasetRepository const datasetWithUpdatePermissions = DatasetMother.create({ diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesOptions.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesOptions.spec.tsx index 1ea198c90..531691a69 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesOptions.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesOptions.spec.tsx @@ -23,7 +23,7 @@ describe('EditFilesOptions', () => { }) it('renders the unrestrict option if some file is restricted', () => { - const fileRestricted = FilePreviewMother.createWithRestrictedAccess() + const fileRestricted = FilePreviewMother.createRestricted() cy.customMount() cy.findByRole('button', { name: 'Unrestrict' }).should('exist').click() diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/FileActionButtons.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/FileActionButtons.spec.tsx index 466c2751f..d9ae941f2 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/FileActionButtons.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/FileActionButtons.spec.tsx @@ -1,11 +1,11 @@ import { FileActionButtons } from '../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/FileActionButtons' -import { FilePreviewMother } from '../../../../../../../files/domain/models/FilePreviewMother' import { DatasetRepository } from '../../../../../../../../../src/dataset/domain/repositories/DatasetRepository' import { DatasetMother, DatasetPermissionsMother } from '../../../../../../../dataset/domain/models/DatasetMother' import { DatasetProvider } from '../../../../../../../../../src/sections/dataset/DatasetProvider' +import { FilePreviewMother } from '../../../../../../../files/domain/models/FilePreviewMother' const file = FilePreviewMother.createDefault() describe('FileActionButtons', () => { 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 deleted file mode 100644 index d49d6b0d5..000000000 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessFileMenu.spec.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import { AccessFileMenu } from '../../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessFileMenu' -import { FilePreviewMother } from '../../../../../../../../files/domain/models/FilePreviewMother' -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 = FilePreviewMother.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() - - cy.findByRole('button', { name: 'Access File' }).should('exist') - }) - - it('renders the access file menu with tooltip', () => { - cy.customMount() - - cy.findByRole('button', { name: 'Access File' }).trigger('mouseover') - cy.findByRole('tooltip', { name: 'Access File' }).should('exist') - }) - - it('renders the menu headers', () => { - cy.customMount( - - - - ) - - cy.findByRole('button', { name: 'Access File' }).should('exist').click() - cy.findByRole('heading', { name: 'File Access' }).should('exist') - }) - - it('renders the access status of the file', () => { - const filePublic = FilePreviewMother.createWithPublicAccess() - cy.customMount( - - - - ) - - cy.findByRole('button', { name: 'Access File' }).click() - cy.findByText('Public').should('exist') - }) - - it('renders the request access button', () => { - const fileRestrictedWithAccessRequestAllowed = - FilePreviewMother.createWithAccessRequestAllowed() - cy.customMount( - - - - ) - - cy.findByRole('button', { name: 'Access File' }).click() - cy.findByRole('button', { name: 'Request Access' }).should('exist') - }) - - it('renders the download options header', () => { - const filePublic = FilePreviewMother.createWithPublicAccess() - cy.customMount( - - - - ) - - cy.findByRole('button', { name: 'Access File' }).click() - cy.findByRole('heading', { name: 'Download Options' }).should('exist') - }) -}) diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessStatus.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessStatus.spec.tsx deleted file mode 100644 index 3003b6c29..000000000 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessStatus.spec.tsx +++ /dev/null @@ -1,94 +0,0 @@ -import { FilePreviewMother } from '../../../../../../../../files/domain/models/FilePreviewMother' -import { AccessStatus } from '../../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessStatus' -import styles from '../../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessFileMenu.module.scss' -import { FileRepository } from '../../../../../../../../../../src/files/domain/repositories/FileRepository' -import { FileUserPermissionsMother } from '../../../../../../../../files/domain/models/FileUserPermissionsMother' -import { FilePermissionsProvider } from '../../../../../../../../../../src/sections/file/file-permissions/FilePermissionsProvider' - -describe('AccessStatus', () => { - it('renders the access status public', () => { - const filePublic = FilePreviewMother.createWithPublicAccess() - cy.customMount() - - cy.findByText('Public').should('exist').should('have.class', styles.success) - cy.findByText('Public File Icon').should('exist') - }) - - it('renders the access status restricted', () => { - const fileRestricted = FilePreviewMother.createWithRestrictedAccess() - cy.customMount() - - cy.findByText('Restricted').should('exist').should('have.class', styles.danger) - cy.findByText('Restricted File Icon').should('exist') - }) - - it('renders the access status restricted with access', () => { - const fileRestrictedWithAccess = FilePreviewMother.createWithRestrictedAccessWithAccessGranted() - const fileRepository: FileRepository = {} as FileRepository - fileRepository.getUserPermissionsById = cy.stub().resolves( - FileUserPermissionsMother.create({ - fileId: fileRestrictedWithAccess.id, - canDownloadFile: true - }) - ) - - cy.customMount( - - - - ) - - cy.findByText('Restricted with Access Granted') - .should('exist') - .should('have.class', styles.success) - cy.findByText('Restricted with access Icon').should('exist') - }) - - it('renders the access status embargoed', () => { - const fileRestrictedWithAccess = FilePreviewMother.createWithRestrictedAccessWithAccessGranted() - const fileRepository: FileRepository = {} as FileRepository - fileRepository.getUserPermissionsById = cy.stub().resolves( - FileUserPermissionsMother.create({ - fileId: fileRestrictedWithAccess.id, - canDownloadFile: true - }) - ) - const fileEmbargoed = FilePreviewMother.createWithEmbargo() - cy.customMount( - - {' '} - - ) - - cy.findByText('Embargoed').should('exist').should('have.class', styles.success) - cy.findByText('Public File Icon').should('exist') - }) - - it('renders the access status embargoed restricted', () => { - const fileEmbargoedRestricted = FilePreviewMother.createWithEmbargoRestricted() - cy.customMount() - - cy.findByText('Embargoed').should('exist').should('have.class', styles.danger) - cy.findByText('Restricted File Icon').should('exist') - }) - - it('renders the access status embargoed restricted with access', () => { - const fileRestrictedWithAccess = FilePreviewMother.createWithRestrictedAccessWithAccessGranted() - const fileRepository: FileRepository = {} as FileRepository - fileRepository.getUserPermissionsById = cy.stub().resolves( - FileUserPermissionsMother.create({ - fileId: fileRestrictedWithAccess.id, - canDownloadFile: true - }) - ) - const fileEmbargoedRestricted = FilePreviewMother.createWithEmbargoRestricted() - cy.customMount( - - {' '} - - ) - - cy.findByText('Embargoed').should('exist').should('have.class', styles.success) - cy.findByText('Restricted with access Icon').should('exist') - }) -}) 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 deleted file mode 100644 index 4eb9e7ff8..000000000 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions.spec.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import { FileDownloadOptions } from '../../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileDownloadOptions' -import { FilePreviewMother } from '../../../../../../../../files/domain/models/FilePreviewMother' -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 = FilePreviewMother.createNonTabular() -const fileTabular = FilePreviewMother.createTabular() -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.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.findByRole('link', { name: 'Plain Text' }).should('exist') - }) - - it('renders the download options for a tabular file', () => { - cy.customMount( - - - - ) - - 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 deleted file mode 100644 index b767a7ba0..000000000 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import { FilePreviewMother } from '../../../../../../../../files/domain/models/FilePreviewMother' -import { - FileIngestStatus, - FileType -} from '../../../../../../../../../../src/files/domain/models/FilePreview' -import { FileNonTabularDownloadOptions } from '../../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions' -import { DatasetProvider } from '../../../../../../../../../../src/sections/dataset/DatasetProvider' -import { DatasetRepository } from '../../../../../../../../../../src/dataset/domain/repositories/DatasetRepository' -import { - DatasetLockMother, - DatasetMother -} from '../../../../../../../../dataset/domain/models/DatasetMother' - -const fileNonTabular = FilePreviewMother.create({ - tabularData: undefined, - type: new FileType('text/plain') -}) -describe('FileNonTabularDownloadOptions', () => { - it('renders the download options for a non-tabular file of unknown type', () => { - const fileNonTabularUnknown = FilePreviewMother.create({ - tabularData: undefined, - type: new FileType('unknown') - }) - cy.customMount() - - cy.findByRole('link', { name: 'Original File Format' }) - .should('exist') - .should('not.have.class', 'disabled') - .should('have.attr', 'href', fileNonTabularUnknown.downloadUrls.original) - }) - - it('renders the download options for a non-tabular file', () => { - cy.customMount() - - cy.findByRole('link', { name: 'Plain Text' }) - .should('exist') - .should('not.have.class', 'disabled') - .should('have.attr', 'href', fileNonTabular.downloadUrls.original) - }) - - it('does not render the download options for a tabular file', () => { - const fileTabular = FilePreviewMother.createTabular() - cy.customMount() - - 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', () => { - const fileNonTabularInProgress = FilePreviewMother.create({ - tabularData: undefined, - type: new FileType('text/plain'), - ingest: { - status: FileIngestStatus.IN_PROGRESS - } - }) - cy.customMount() - - cy.findByRole('link', { name: 'Plain Text' }).should('have.class', 'disabled') - }) - - it('renders the options as disabled when the dataset is locked from file download', () => { - const datasetRepository: DatasetRepository = {} as DatasetRepository - const datasetLockedFromFileDownload = DatasetMother.create({ - locks: [DatasetLockMother.createLockedFromFileDownload()] - }) - datasetRepository.getByPersistentId = cy.stub().resolves(datasetLockedFromFileDownload) - - cy.customMount( - - - - ) - - cy.findByRole('link', { name: 'Plain Text' }).should('have.class', 'disabled') - }) -}) diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/RequestAccessOption.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/RequestAccessOption.spec.tsx deleted file mode 100644 index ef6f0e668..000000000 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/RequestAccessOption.spec.tsx +++ /dev/null @@ -1,122 +0,0 @@ -import { RequestAccessOption } from '../../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/RequestAccessOption' -import { FilePreviewMother } from '../../../../../../../../files/domain/models/FilePreviewMother' -import { FileRepository } from '../../../../../../../../../../src/files/domain/repositories/FileRepository' -import { FileUserPermissionsMother } from '../../../../../../../../files/domain/models/FileUserPermissionsMother' -import { FilePermissionsProvider } from '../../../../../../../../../../src/sections/file/file-permissions/FilePermissionsProvider' - -describe('RequestAccessOption', () => { - it('renders the embargoed message when the file is embargoed', () => { - const fileEmbargoed = FilePreviewMother.createWithEmbargo() - cy.customMount() - - cy.findByRole('button', { name: 'Files are unavailable during the specified embargo.' }) - .should('exist') - .should('have.class', 'disabled') - }) - - it('renders the embargo then restricted message when the file is embargoed and restricted', () => { - const fileEmbargoedRestricted = FilePreviewMother.createWithEmbargoRestricted() - cy.customMount() - - cy.findByRole('button', { - name: 'Files are unavailable during the specified embargo and restricted after that.' - }) - .should('exist') - .should('have.class', 'disabled') - }) - - it('renders the Users may not request access to files. message when the file is restricted and access request is not allowed', () => { - const fileRestricted = FilePreviewMother.createWithRestrictedAccess() - cy.customMount() - - cy.findByRole('button', { name: 'Users may not request access to files.' }) - .should('exist') - .should('have.class', 'disabled') - }) - - it('renders the request access button when the file is restricted and can be requested', () => { - const fileRestrictedCanBeRequested = FilePreviewMother.createWithAccessRequestAllowed() - cy.customMount() - - cy.findByRole('button', { name: 'Request Access' }).should('exist') - }) - - it('renders the access requested message when hen the file is restricted and the access has already been requested', () => { - const fileAlreadyRequested = FilePreviewMother.createWithAccessRequestPending() - - cy.customMount() - - cy.findByRole('button', { name: 'Access Requested' }) - .should('exist') - .should('have.class', 'disabled') - }) - - it('does not render the request access button when the file is deaccessioned', () => { - const fileDeaccessioned = FilePreviewMother.createDeaccessioned() - cy.customMount() - - cy.findByRole('button', { name: 'Users may not request access to files.' }).should('not.exist') - cy.findByRole('button', { name: 'Request Access' }).should('not.exist') - cy.findByRole('button', { name: 'Access Requested' }).should('not.exist') - cy.findByRole('button', { name: 'Files are unavailable during the specified embargo.' }).should( - 'not.exist' - ) - cy.findByRole('button', { - name: 'Files are unavailable during the specified embargo and restricted after that.' - }).should('not.exist') - }) - - it('does not render the request access button when the file status is public', () => { - const filePublic = FilePreviewMother.createWithPublicAccess() - const fileRepository: FileRepository = {} as FileRepository - fileRepository.getUserPermissionsById = cy.stub().resolves( - FileUserPermissionsMother.create({ - fileId: filePublic.id, - canDownloadFile: true - }) - ) - - cy.customMount( - - - - ) - - cy.findByRole('button', { name: 'Users may not request access to files.' }).should('not.exist') - cy.findByRole('button', { name: 'Request Access' }).should('not.exist') - cy.findByRole('button', { name: 'Access Requested' }).should('not.exist') - cy.findByRole('button', { name: 'Files are unavailable during the specified embargo.' }).should( - 'not.exist' - ) - cy.findByRole('button', { - name: 'Files are unavailable during the specified embargo and restricted after that.' - }).should('not.exist') - }) - - it('does not render the request access button when the file status is restricted with access granted', () => { - const fileRestrictedWithAccess = FilePreviewMother.createWithRestrictedAccessWithAccessGranted() - const fileRepository: FileRepository = {} as FileRepository - fileRepository.getUserPermissionsById = cy.stub().resolves( - FileUserPermissionsMother.create({ - fileId: fileRestrictedWithAccess.id, - canDownloadFile: true - }) - ) - - cy.customMount( - - - - ) - - cy.findByRole('button', { name: 'Users may not request access to files.' }).should('not.exist') - cy.findByRole('button', { name: 'Request Access' }).should('not.exist') - cy.findByRole('button', { name: 'Access Requested' }).should('not.exist') - cy.findByRole('button', { name: 'Files are unavailable during the specified embargo.' }).should( - 'not.exist' - ) - cy.findByRole('button', { - name: 'Files are unavailable during the specified embargo and restricted after that.' - }).should('not.exist') - }) -}) diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/file-options-menu/FileOptionsMenu.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/file-options-menu/FileOptionsMenu.spec.tsx index d69579e11..9ade570a4 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/file-options-menu/FileOptionsMenu.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/file-options-menu/FileOptionsMenu.spec.tsx @@ -1,5 +1,4 @@ import { FileOptionsMenu } from '../../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/file-options-menu/FileOptionsMenu' -import { FilePreviewMother } from '../../../../../../../../files/domain/models/FilePreviewMother' import { ReactNode } from 'react' import { Dataset as DatasetModel } from '../../../../../../../../../../src/dataset/domain/models/Dataset' import { DatasetProvider } from '../../../../../../../../../../src/sections/dataset/DatasetProvider' @@ -9,6 +8,7 @@ import { DatasetMother, DatasetPermissionsMother } from '../../../../../../../../dataset/domain/models/DatasetMother' +import { FilePreviewMother } from '../../../../../../../../files/domain/models/FilePreviewMother' const file = FilePreviewMother.createDefault() const datasetRepository: DatasetRepository = {} as DatasetRepository diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-info-messages/IngestInfoMessage.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-info-messages/IngestInfoMessage.spec.tsx index 3ac7e9ea6..5562f28e2 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-info-messages/IngestInfoMessage.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-info-messages/IngestInfoMessage.spec.tsx @@ -1,5 +1,5 @@ import { IngestInfoMessage } from '../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-info-messages/IngestInfoMessage' -import { FileIngestMother } from '../../../../../../../files/domain/models/FilePreviewMother' +import { FileIngestMother } from '../../../../../../../files/domain/models/FileIngestMother' import { ReactNode } from 'react' import { Dataset as DatasetModel } from '../../../../../../../../../src/dataset/domain/models/Dataset' import { DatasetProvider } from '../../../../../../../../../src/sections/dataset/DatasetProvider' diff --git a/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileChecksum.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileChecksum.spec.tsx index 671817a72..2cca6490e 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileChecksum.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileChecksum.spec.tsx @@ -1,6 +1,6 @@ import { FileChecksum } from '../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileChecksum' import styles from '../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/FileInfoCell.module.scss' -import { FileChecksumMother } from '../../../../../../../files/domain/models/FilePreviewMother' +import { FileChecksumMother } from '../../../../../../../files/domain/models/FileMetadataMother' describe('FileChecksum', () => { it('renders the checksum and CopyToClipboardButton when checksum is provided', () => { diff --git a/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileDate.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileDate.spec.tsx index a8192fdde..f866e8708 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileDate.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileDate.spec.tsx @@ -1,5 +1,5 @@ import { FileDate } from '../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileDate' -import { FileDateType } from '../../../../../../../../../src/files/domain/models/FilePreview' +import { FileDateType } from '../../../../../../../../../src/files/domain/models/FileMetadata' import { DateHelper } from '../../../../../../../../../src/shared/domain/helpers/DateHelper' describe('FileDate', () => { diff --git a/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileDownloads.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileDownloads.spec.tsx index 1e9bddcb3..08863b0b9 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileDownloads.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileDownloads.spec.tsx @@ -1,4 +1,4 @@ -import { FilePublishingStatus } from '../../../../../../../../../src/files/domain/models/FilePreview' +import { FilePublishingStatus } from '../../../../../../../../../src/files/domain/models/FileVersion' import { FileDownloads } from '../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileDownloads' describe('FileDownloads', () => { diff --git a/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileTitle.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileTitle.spec.tsx index 55c45df94..0db129a0d 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileTitle.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileTitle.spec.tsx @@ -1,16 +1,11 @@ -import { FilePreviewMother } from '../../../../../../../files/domain/models/FilePreviewMother' import { FileTitle } from '../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileTitle' describe('FileTitle', () => { it('renders the link and name correctly', () => { const id = 12345 const name = 'file-name.txt' - const file = FilePreviewMother.create({ - id: id, - name: name - }) - cy.customMount() + cy.customMount() cy.findByRole('link', { name: name }).should('have.attr', 'href', `/files?id=${id}`) }) 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 47731f3b8..cef678498 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 @@ -1,14 +1,14 @@ -import { FilePreviewMother } from '../../../../../../../files/domain/models/FilePreviewMother' +import { FileMetadataMother } from '../../../../../../../files/domain/models/FileMetadataMother' import { FileType } from '../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileType' import { FileSize, FileSizeUnit, FileType as FileTypeModel -} from '../../../../../../../../../src/files/domain/models/FilePreview' +} from '../../../../../../../../../src/files/domain/models/FileMetadata' describe('FileType', () => { it('renders the type and size correctly when there are no decimals', () => { - const file = FilePreviewMother.create({ + const file = FileMetadataMother.create({ type: new FileTypeModel('text/plain'), size: new FileSize(123.03932894722, FileSizeUnit.BYTES) }) @@ -18,7 +18,7 @@ describe('FileType', () => { }) it('renders the type and size correctly when there are decimals', () => { - const file = FilePreviewMother.create({ + const file = FileMetadataMother.create({ type: new FileTypeModel('text/plain'), size: new FileSize(123.932894722, FileSizeUnit.MEGABYTES) }) @@ -28,7 +28,7 @@ describe('FileType', () => { }) it('renders the type correctly when is a tabular file', () => { - const file = FilePreviewMother.createTabular({ + const file = FileMetadataMother.createTabular({ size: new FileSize(123.03932894722, FileSizeUnit.BYTES) }) diff --git a/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.spec.tsx index adb725c25..2428861fa 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.spec.tsx @@ -1,9 +1,10 @@ import { FileThumbnail } from '../../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail' -import { FilePreviewMother } from '../../../../../../../../files/domain/models/FilePreviewMother' +import { FileMetadataMother } from '../../../../../../../../files/domain/models/FileMetadataMother' import { FileRepository } from '../../../../../../../../../../src/files/domain/repositories/FileRepository' import { FileUserPermissionsMother } from '../../../../../../../../files/domain/models/FileUserPermissionsMother' import { FilePermissionsProvider } from '../../../../../../../../../../src/sections/file/file-permissions/FilePermissionsProvider' -import { FileType } from '../../../../../../../../../../src/files/domain/models/FilePreview' +import { FileType } from '../../../../../../../../../../src/files/domain/models/FileMetadata' +import { FilePreviewMother } from '../../../../../../../../files/domain/models/FilePreviewMother' const fileRepository: FileRepository = {} as FileRepository describe('FileThumbnail', () => { @@ -40,7 +41,7 @@ describe('FileThumbnail', () => { }) it('renders FilePreviewImage when thumbnail is provided with unlocked icon if restricted with access', () => { - const file = FilePreviewMother.createWithThumbnailRestrictedWithAccessGranted() + const file = FilePreviewMother.createWithThumbnailRestricted() fileRepository.getUserPermissionsById = cy.stub().resolves( FileUserPermissionsMother.create({ fileId: file.id, @@ -77,7 +78,9 @@ describe('FileThumbnail', () => { }) it('renders FileIcon when thumbnail is not provided', () => { - const file = FilePreviewMother.createDefault({ type: new FileType('application/pdf') }) + const file = FilePreviewMother.createDefault({ + metadata: FileMetadataMother.create({ type: new FileType('application/pdf') }) + }) cy.customMount() @@ -88,7 +91,7 @@ describe('FileThumbnail', () => { }) it('renders FileIcon when thumbnail is not provided with lock icon when restricted with no access', () => { - const file = FilePreviewMother.createWithRestrictedAccess() + const file = FilePreviewMother.createRestricted() cy.customMount() @@ -101,7 +104,7 @@ describe('FileThumbnail', () => { }) it('renders FileIcon when thumbnail is not provided with unlock icon when restricted with access', () => { - const file = FilePreviewMother.createWithRestrictedAccessWithAccessGranted() + const file = FilePreviewMother.createRestricted() fileRepository.getUserPermissionsById = cy.stub().resolves( FileUserPermissionsMother.create({ fileId: file.id, diff --git a/tests/component/sections/dataset/dataset-files/files-table/row-selection/RowSelectionMessage.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/row-selection/RowSelectionMessage.spec.tsx index 39a673bb0..6dfb0c7a0 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/row-selection/RowSelectionMessage.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/row-selection/RowSelectionMessage.spec.tsx @@ -1,5 +1,5 @@ import { RowSelectionMessage } from '../../../../../../../src/sections/dataset/dataset-files/files-table/row-selection/RowSelectionMessage' -import { FilePreviewMother } from '../../../../../files/domain/models/FilePreviewMother' +import { FileMetadataMother } from '../../../../../files/domain/models/FileMetadataMother' let selectAllRows = () => {} let clearRowSelection = () => {} @@ -12,7 +12,7 @@ describe('RowSelectionMessage', () => { it('renders the message when there are more than 10 files and some row is selected', () => { cy.customMount( { it('does not render the message when there are less than 10 files', () => { cy.customMount( { it('renders the plural form of the message when there is more than 1 row selected', () => { cy.customMount( { it("calls selectAllRows when the 'Select all' button is clicked", () => { cy.customMount( { it("calls clearRowSelection when the 'Clear selection.' button is clicked", () => { cy.customMount( { { { { { { { cy.findByText('Version 1.0').should('exist') cy.findByRole('tab', { name: 'Metadata' }).should('exist') cy.findByRole('button', { name: 'File Metadata' }).should('exist') + cy.findByRole('group', { name: 'File Action Buttons' }).should('exist') }) it('renders skeleton while loading', () => { diff --git a/tests/component/sections/file/file-action-buttons/access-file-menu/AccessFileMenu.spec.tsx b/tests/component/sections/file/file-action-buttons/access-file-menu/AccessFileMenu.spec.tsx new file mode 100644 index 000000000..e3821e522 --- /dev/null +++ b/tests/component/sections/file/file-action-buttons/access-file-menu/AccessFileMenu.spec.tsx @@ -0,0 +1,138 @@ +import { AccessFileMenu } from '../../../../../../src/sections/file/file-action-buttons/access-file-menu/AccessFileMenu' +import { FileAccessMother } from '../../../../files/domain/models/FileAccessMother' +import { FileMetadataMother } from '../../../../files/domain/models/FileMetadataMother' +import { Suspense } from 'react' + +describe('AccessFileMenu', () => { + it('renders the access file menu', () => { + cy.customMount( + + ) + + cy.findByRole('button', { name: 'Access File' }).should('exist') + }) + + it('renders the access file menu with tooltip when asIcon is true', () => { + cy.customMount( + + ) + + cy.findByRole('button', { name: 'Access File' }).trigger('mouseover') + cy.findByRole('tooltip', { name: 'Access File' }).should('exist') + }) + + it('does not render the access file menu with tooltip when asIcon is false', () => { + cy.customMount( + + ) + + cy.findByRole('button', { name: 'Access File' }).trigger('mouseover') + cy.findByRole('tooltip', { name: 'Access File' }).should('not.exist') + }) + + it('renders the menu headers', () => { + cy.customMount( + + + + ) + + cy.findByRole('button', { name: 'Access File' }).should('exist').click() + cy.findByRole('heading', { name: 'File Access' }).should('exist') + }) + + it('renders the access status of the file', () => { + cy.customMount( + + ) + + cy.findByRole('button', { name: 'Access File' }).click() + cy.findByText('Public').should('exist') + }) + + it('renders the request access button', () => { + cy.customMount( + + ) + + cy.findByRole('button', { name: 'Access File' }).click() + cy.findByRole('button', { name: 'Request Access' }).should('exist') + }) + + it('renders the download options header', () => { + cy.customMount( + + ) + + cy.findByRole('button', { name: 'Access File' }).click() + cy.findByRole('heading', { name: 'Download Options' }).should('exist') + }) + + it('renders the button as an icon when asIcon is true', () => { + cy.customMount( + + ) + + cy.findByRole('button', { name: 'Access File' }).should('exist') + cy.get('svg').should('exist') + }) +}) diff --git a/tests/component/sections/file/file-action-buttons/access-file-menu/AccessStatus.spec.tsx b/tests/component/sections/file/file-action-buttons/access-file-menu/AccessStatus.spec.tsx new file mode 100644 index 000000000..93d86bf4f --- /dev/null +++ b/tests/component/sections/file/file-action-buttons/access-file-menu/AccessStatus.spec.tsx @@ -0,0 +1,80 @@ +import { AccessStatus } from '../../../../../../src/sections/file/file-action-buttons/access-file-menu/AccessStatus' +import styles from '../../../../../../src/sections/file/file-action-buttons/access-file-menu/AccessFileMenu.module.scss' + +describe('AccessStatus', () => { + it('renders the access status public when is not restricted and the user does not have permissions', () => { + cy.customMount( + + ) + + cy.findByText('Public').should('exist').should('have.class', styles.success) + cy.findByText('Public File Icon').should('exist') + }) + + it('renders the the public embargoed status then the file is not restricted but its embargoed', () => { + cy.customMount( + + ) + + cy.findByText('Embargoed').should('exist').should('have.class', styles.danger) + cy.findByText('Public File Icon').should('exist') + }) + + it('renders the access status public', () => { + cy.customMount( + + ) + + cy.findByText('Public').should('exist').should('have.class', styles.success) + cy.findByText('Public File Icon').should('exist') + }) + + it('renders the access status restricted', () => { + cy.customMount( + + ) + + cy.findByText('Restricted').should('exist').should('have.class', styles.danger) + cy.findByText('Restricted File Icon').should('exist') + }) + + it('renders the access status restricted with access', () => { + cy.customMount( + + ) + + cy.findByText('Restricted with Access Granted') + .should('exist') + .should('have.class', styles.success) + cy.findByText('Restricted with access Icon').should('exist') + }) + + it('renders the access status embargoed', () => { + cy.customMount( + + ) + + cy.findByText('Embargoed').should('exist').should('have.class', styles.success) + cy.findByText('Public File Icon').should('exist') + }) + + it('renders the access status embargoed restricted', () => { + cy.customMount( + + ) + + cy.findByText('Embargoed').should('exist').should('have.class', styles.danger) + cy.findByText('Restricted File Icon').should('exist') + }) + + it('renders the access status embargoed restricted with access', () => { + cy.customMount() + + cy.findByText('Embargoed').should('exist').should('have.class', styles.success) + cy.findByText('Restricted with access Icon').should('exist') + }) +}) diff --git a/tests/component/sections/file/file-action-buttons/access-file-menu/FileDownloadOptions.spec.tsx b/tests/component/sections/file/file-action-buttons/access-file-menu/FileDownloadOptions.spec.tsx new file mode 100644 index 000000000..64f80369b --- /dev/null +++ b/tests/component/sections/file/file-action-buttons/access-file-menu/FileDownloadOptions.spec.tsx @@ -0,0 +1,66 @@ +import { FileDownloadOptions } from '../../../../../../src/sections/file/file-action-buttons/access-file-menu/FileDownloadOptions' +import { + FileDownloadUrlsMother, + FileTypeMother +} from '../../../../files/domain/models/FileMetadataMother' + +const nonTabularType = FileTypeMother.createText() +const downloadUrls = FileDownloadUrlsMother.create() +describe('FileDownloadOptions', () => { + it('renders the download options header', () => { + cy.customMount( + + ) + + cy.findByRole('heading', { name: 'Download Options' }).should('exist') + }) + + it('does not render the download options if the user does not have permissions', () => { + cy.customMount( + + ) + + cy.findByRole('heading', { name: 'Download Options' }).should('not.exist') + }) + + it('renders the download options for a non-tabular file', () => { + cy.customMount( + + ) + + cy.findByRole('link', { name: 'Plain Text' }).should('exist') + }) + + it('renders the download options for a tabular file', () => { + const tabularType = FileTypeMother.createTabular() + cy.customMount( + + ) + + cy.findByRole('link', { name: 'Comma Separated Values (Original File Format)' }).should('exist') + }) +}) diff --git a/tests/component/sections/file/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx b/tests/component/sections/file/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx new file mode 100644 index 000000000..dc03dda69 --- /dev/null +++ b/tests/component/sections/file/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions.spec.tsx @@ -0,0 +1,78 @@ +import { + FileDownloadUrlsMother, + FileTypeMother +} from '../../../../files/domain/models/FileMetadataMother' + +import { FileNonTabularDownloadOptions } from '../../../../../../src/sections/file/file-action-buttons/access-file-menu/FileNonTabularDownloadOptions' +import { DatasetProvider } from '../../../../../../src/sections/dataset/DatasetProvider' +import { DatasetRepository } from '../../../../../../src/dataset/domain/repositories/DatasetRepository' +import { DatasetLockMother, DatasetMother } from '../../../../dataset/domain/models/DatasetMother' + +const unknownType = FileTypeMother.createUnknown() +const downloadUrls = FileDownloadUrlsMother.create() +const textType = FileTypeMother.createText() +describe('FileNonTabularDownloadOptions', () => { + it('renders the download options for a file of unknown type', () => { + cy.customMount( + + ) + + cy.findByRole('link', { name: 'Original File Format' }) + .should('exist') + .should('not.have.class', 'disabled') + .should('have.attr', 'href', downloadUrls.original) + }) + + it('renders the download options for a file of known type', () => { + cy.customMount( + + ) + + cy.findByRole('link', { name: 'Plain Text' }) + .should('exist') + .should('not.have.class', 'disabled') + .should('have.attr', 'href', downloadUrls.original) + }) + + it('renders the options as disabled when the file ingest is in progress', () => { + cy.customMount( + + ) + + cy.findByRole('link', { name: 'Plain Text' }).should('have.class', 'disabled') + }) + + it('renders the options as disabled when the dataset is locked from file download', () => { + const datasetRepository: DatasetRepository = {} as DatasetRepository + const datasetLockedFromFileDownload = DatasetMother.create({ + locks: [DatasetLockMother.createLockedFromFileDownload()] + }) + datasetRepository.getByPersistentId = cy.stub().resolves(datasetLockedFromFileDownload) + + cy.customMount( + + + + ) + + cy.findByRole('link', { name: 'Plain Text' }).should('have.class', 'disabled') + }) +}) 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/file/file-action-buttons/access-file-menu/FileTabularDownloadOptions.spec.tsx similarity index 54% rename from tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileTabularDownloadOptions.spec.tsx rename to tests/component/sections/file/file-action-buttons/access-file-menu/FileTabularDownloadOptions.spec.tsx index 85f9d3582..5316b691b 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/file/file-action-buttons/access-file-menu/FileTabularDownloadOptions.spec.tsx @@ -1,43 +1,46 @@ -import { FilePreviewMother } from '../../../../../../../../files/domain/models/FilePreviewMother' import { - FileIngestStatus, - FileType -} from '../../../../../../../../../../src/files/domain/models/FilePreview' -import { FileTabularDownloadOptions } from '../../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/FileTabularDownloadOptions' -import { DatasetRepository } from '../../../../../../../../../../src/dataset/domain/repositories/DatasetRepository' -import { - DatasetLockMother, - DatasetMother -} from '../../../../../../../../dataset/domain/models/DatasetMother' -import { DatasetProvider } from '../../../../../../../../../../src/sections/dataset/DatasetProvider' + FileDownloadUrlsMother, + FileTypeMother +} from '../../../../files/domain/models/FileMetadataMother' +import { FileTabularDownloadOptions } from '../../../../../../src/sections/file/file-action-buttons/access-file-menu/FileTabularDownloadOptions' +import { DatasetRepository } from '../../../../../../src/dataset/domain/repositories/DatasetRepository' +import { DatasetLockMother, DatasetMother } from '../../../../dataset/domain/models/DatasetMother' +import { DatasetProvider } from '../../../../../../src/sections/dataset/DatasetProvider' -const fileNonTabular = FilePreviewMother.create({ - tabularData: undefined, - type: new FileType('text/plain') -}) -const fileTabular = FilePreviewMother.createTabular() -const fileTabularUnknown = FilePreviewMother.createTabular({ - type: new FileType('text/tab-separated-values', 'Unknown') -}) +const tabularType = FileTypeMother.createTabular() +const downloadUrls = FileDownloadUrlsMother.create() describe('FileTabularDownloadOptions', () => { it('renders the download options for a tabular file', () => { - cy.customMount() + cy.customMount( + + ) cy.findByRole('link', { name: 'Comma Separated Values (Original File Format)' }) .should('exist') - .should('have.attr', 'href', fileTabular.downloadUrls.original) + .should('have.attr', 'href', downloadUrls.original) cy.findByRole('link', { name: 'Tab-Delimited' }) .should('exist') - .should('have.attr', 'href', fileTabular.downloadUrls.tabular) + .should('have.attr', 'href', downloadUrls.tabular) .should('not.have.class', 'disabled') cy.findByRole('link', { name: 'R Data' }) .should('exist') .should('not.have.class', 'disabled') - .should('have.attr', 'href', fileTabular.downloadUrls.rData) + .should('have.attr', 'href', downloadUrls.rData) }) it('renders the download options for a tabular file of unknown original type', () => { - cy.customMount() + const unknownType = FileTypeMother.createTabularUnknown() + cy.customMount( + + ) cy.findByRole('link', { name: /(Original File Format)/ }).should('not.exist') cy.findByRole('link', { name: 'Tab-Delimited' }) @@ -46,21 +49,10 @@ describe('FileTabularDownloadOptions', () => { 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('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', () => { - const fileTabularInProgress = FilePreviewMother.createTabular({ - ingest: { - status: FileIngestStatus.IN_PROGRESS - } - }) - cy.customMount() + cy.customMount( + + ) cy.findByRole('link', { name: 'Comma Separated Values (Original File Format)' }) .should('exist') @@ -82,7 +74,11 @@ describe('FileTabularDownloadOptions', () => { - + ) @@ -96,10 +92,14 @@ describe('FileTabularDownloadOptions', () => { }) it('does not render the RData option if the file type is already R Data', () => { - const fileTabularRData = FilePreviewMother.createTabular({ - type: new FileType('text/tab-separated-values', 'R Data') - }) - cy.customMount() + const rDataType = FileTypeMother.createRData() + cy.customMount( + + ) cy.findByRole('link', { name: 'R Data (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/RequestAccessModal.spec.tsx b/tests/component/sections/file/file-action-buttons/access-file-menu/RequestAccessModal.spec.tsx similarity index 76% rename from tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/RequestAccessModal.spec.tsx rename to tests/component/sections/file/file-action-buttons/access-file-menu/RequestAccessModal.spec.tsx index d1190a20e..b0faad15f 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/RequestAccessModal.spec.tsx +++ b/tests/component/sections/file/file-action-buttons/access-file-menu/RequestAccessModal.spec.tsx @@ -1,9 +1,10 @@ -import { RequestAccessModal } from '../../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/RequestAccessModal' -import { FilePreviewMother } from '../../../../../../../../files/domain/models/FilePreviewMother' -import { UserMother } from '../../../../../../../../users/domain/models/UserMother' -import { UserRepository } from '../../../../../../../../../../src/users/domain/repositories/UserRepository' -import { SessionProvider } from '../../../../../../../../../../src/sections/session/SessionProvider' -import { Route } from '../../../../../../../../../../src/sections/Route.enum' +import { RequestAccessModal } from '../../../../../../src/sections/file/file-action-buttons/access-file-menu/RequestAccessModal' +import { UserMother } from '../../../../users/domain/models/UserMother' +import { UserRepository } from '../../../../../../src/users/domain/repositories/UserRepository' +import { SessionProvider } from '../../../../../../src/sections/session/SessionProvider' +import { Route } from '../../../../../../src/sections/Route.enum' +import { FilePreviewMother } from '../../../../files/domain/models/FilePreviewMother' + describe('RequestAccessModal', () => { it('renders the RequestAccessModal', () => { const file = FilePreviewMother.create() diff --git a/tests/component/sections/file/file-action-buttons/access-file-menu/RequestAccessOption.spec.tsx b/tests/component/sections/file/file-action-buttons/access-file-menu/RequestAccessOption.spec.tsx new file mode 100644 index 000000000..18c39fa31 --- /dev/null +++ b/tests/component/sections/file/file-action-buttons/access-file-menu/RequestAccessOption.spec.tsx @@ -0,0 +1,135 @@ +import { RequestAccessOption } from '../../../../../../src/sections/file/file-action-buttons/access-file-menu/RequestAccessOption' +import { FileAccessMother } from '../../../../files/domain/models/FileAccessMother' + +const access = FileAccessMother.create() +describe('RequestAccessOption', () => { + it('renders the embargoed message when the file is embargoed', () => { + const accessPublic = FileAccessMother.createPublic() + cy.customMount( + + ) + + cy.findByRole('button', { name: 'Files are unavailable during the specified embargo.' }) + .should('exist') + .should('have.class', 'disabled') + }) + + it('renders the embargo then restricted message when the file is embargoed and restricted', () => { + const accessRestricted = FileAccessMother.createRestricted() + cy.customMount( + + ) + + cy.findByRole('button', { + name: 'Files are unavailable during the specified embargo and restricted after that.' + }) + .should('exist') + .should('have.class', 'disabled') + }) + + it('renders the Users may not request access to files. message when the file is restricted and access request is not allowed', () => { + const accessRequestNotAllowed = FileAccessMother.createWithAccessRequestNotAllowed() + cy.customMount( + + ) + + cy.findByRole('button', { name: 'Users may not request access to files.' }) + .should('exist') + .should('have.class', 'disabled') + }) + + it('renders the request access button when the file is restricted and can be requested', () => { + const accessRequestAllowed = FileAccessMother.createWithAccessRequestAllowed() + cy.customMount( + + ) + + cy.findByRole('button', { name: 'Request Access' }).should('exist') + }) + + it('renders the access requested message when hen the file is restricted and the access has already been requested', () => { + const accessRequestPending = FileAccessMother.createWithAccessRequestPending() + + cy.customMount( + + ) + + cy.findByRole('button', { name: 'Access Requested' }) + .should('exist') + .should('have.class', 'disabled') + }) + + it('does not render the request access button when the file is deaccessioned', () => { + cy.customMount( + + ) + + cy.findByRole('button', { name: 'Users may not request access to files.' }).should('not.exist') + cy.findByRole('button', { name: 'Request Access' }).should('not.exist') + cy.findByRole('button', { name: 'Access Requested' }).should('not.exist') + cy.findByRole('button', { name: 'Files are unavailable during the specified embargo.' }).should( + 'not.exist' + ) + cy.findByRole('button', { + name: 'Files are unavailable during the specified embargo and restricted after that.' + }).should('not.exist') + }) + + it('does not render the request access button when the user has download permission', () => { + cy.customMount( + + ) + + cy.findByRole('button', { name: 'Users may not request access to files.' }).should('not.exist') + cy.findByRole('button', { name: 'Request Access' }).should('not.exist') + cy.findByRole('button', { name: 'Access Requested' }).should('not.exist') + cy.findByRole('button', { name: 'Files are unavailable during the specified embargo.' }).should( + 'not.exist' + ) + cy.findByRole('button', { + name: 'Files are unavailable during the specified embargo and restricted after that.' + }).should('not.exist') + }) +}) diff --git a/tests/component/sections/file/file-embargo/FileEmbargoDate.spec.tsx b/tests/component/sections/file/file-embargo/FileEmbargoDate.spec.tsx index 9a0aa0ef6..d81b373ae 100644 --- a/tests/component/sections/file/file-embargo/FileEmbargoDate.spec.tsx +++ b/tests/component/sections/file/file-embargo/FileEmbargoDate.spec.tsx @@ -1,6 +1,6 @@ import { FileEmbargoDate } from '../../../../../src/sections/file/file-embargo/FileEmbargoDate' -import { FilePublishingStatus } from '../../../../../src/files/domain/models/FilePreview' -import { FileEmbargoMother } from '../../../files/domain/models/FilePreviewMother' +import { FilePublishingStatus } from '../../../../../src/files/domain/models/FileVersion' +import { FileEmbargoMother } from '../../../files/domain/models/FileMetadataMother' describe('FileEmbargoDate', () => { it('renders the embargo date when embargo exists', () => { diff --git a/tests/component/sections/file/file-labels/FileLabels.spec.tsx b/tests/component/sections/file/file-labels/FileLabels.spec.tsx index c18cebbe0..a206c78d1 100644 --- a/tests/component/sections/file/file-labels/FileLabels.spec.tsx +++ b/tests/component/sections/file/file-labels/FileLabels.spec.tsx @@ -1,4 +1,4 @@ -import { FileLabelType } from '../../../../../src/files/domain/models/FilePreview' +import { FileLabelType } from '../../../../../src/files/domain/models/FileMetadata' import { FileLabels } from '../../../../../src/sections/file/file-labels/FileLabels' import styles from '../../../../../src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/FileInfoCell.module.scss' diff --git a/tests/component/sections/file/file-metadata/FileMetadata.spec.tsx b/tests/component/sections/file/file-metadata/FileMetadata.spec.tsx index 62ea3682b..605f8ccdd 100644 --- a/tests/component/sections/file/file-metadata/FileMetadata.spec.tsx +++ b/tests/component/sections/file/file-metadata/FileMetadata.spec.tsx @@ -1,35 +1,56 @@ import { FileMetadata } from '../../../../../src/sections/file/file-metadata/FileMetadata' import { FileMother } from '../../../files/domain/models/FileMother' -import { FileLabelType, FileSizeUnit } from '../../../../../src/files/domain/models/FilePreview' +import { FileSizeUnit } from '../../../../../src/files/domain/models/FileMetadata' import { FileEmbargoMother, + FileMetadataMother, FileSizeMother, FileTabularDataMother, FileTypeMother -} from '../../../files/domain/models/FilePreviewMother' +} from '../../../files/domain/models/FileMetadataMother' import { DateHelper } from '../../../../../src/shared/domain/helpers/DateHelper' +import { FileUserPermissionsMother } from '../../../files/domain/models/FileUserPermissionsMother' +import { FilePublishingStatus } from '../../../../../src/files/domain/models/FileVersion' +const file = FileMother.create() describe('FileMetadata', () => { it('renders the File Metadata tab', () => { - cy.customMount() + cy.customMount( + + ) cy.findByRole('button', { name: 'File Metadata' }).should('exist') }) it('renders the file preview', () => { - cy.customMount() + cy.customMount( + + ) cy.findByText('Preview').should('exist') cy.findByRole('img').should('exist') }) it('renders the file labels', () => { - const labels = [ - { value: 'Category 1', type: FileLabelType.CATEGORY }, - { value: 'Tag 1', type: FileLabelType.TAG }, - { value: 'Tag 2', type: FileLabelType.TAG } - ] - cy.customMount() + const metadataWithLabels = FileMetadataMother.createWithLabelsRealistic() + cy.customMount( + + ) cy.findByText('File Tags').should('exist') cy.findByText('Category 1').should('have.class', 'bg-secondary') @@ -37,14 +58,30 @@ describe('FileMetadata', () => { }) it('does not render the file labels when there are no labels', () => { - cy.customMount() + const metadataWithoutLabels = FileMetadataMother.createWithNoLabels() + cy.customMount( + + ) cy.findByText('File Tags').should('not.exist') }) it('renders the file persistent id', () => { + const metadataWithPersistentId = FileMetadataMother.create({ + persistentId: 'doi:10.5072/FK2/ABC123' + }) cy.customMount( - + ) cy.findByText('File Persistent ID').should('exist') @@ -52,22 +89,33 @@ describe('FileMetadata', () => { }) it('does not render the file persistent id when there is no persistent id', () => { - cy.customMount() + const metadataWithoutPersistentId = FileMetadataMother.createWithNoPersistentId() + cy.customMount( + + ) cy.findByText('File Persistent ID').should('not.exist') }) it('renders the download url if the user has file download permissions', () => { + const permissions = FileUserPermissionsMother.createWithDownloadFileGranted() + cy.customMount( ) cy.findByText('Download URL').should('exist') - cy.findByText('/api/access/datafile/123', { exact: false }).should('exist') + cy.findByText(file.metadata.downloadUrls.original, { exact: false }).should('exist') cy.findByText( 'Use the Download URL in a Wget command or a download manager to avoid interrupted downloads, time outs or other failures.' ).should('exist') @@ -79,11 +127,13 @@ describe('FileMetadata', () => { }) it('does not render the download url if the user does not have file download permissions', () => { + const permissions = FileUserPermissionsMother.createWithDownloadFileDenied() cy.customMount( ) @@ -91,9 +141,15 @@ describe('FileMetadata', () => { }) it('renders the file unf if it exists', () => { + const metadataWithUnf = FileMetadataMother.create({ + tabularData: FileTabularDataMother.create({ unf: 'some-unf' }) + }) cy.customMount( ) @@ -102,17 +158,29 @@ describe('FileMetadata', () => { }) it('does not render the file unf if it does not exist', () => { - cy.customMount() + const metadataWithoutTabularData = FileMetadataMother.createNonTabular() + cy.customMount( + + ) cy.findByText('File UNF').should('not.exist') }) it('renders the file checksum', () => { + const metadataWithChecksum = FileMetadataMother.create({ + checksum: { algorithm: 'SHA-1', value: 'some-checksum' } + }) cy.customMount( ) @@ -121,89 +189,128 @@ describe('FileMetadata', () => { }) it('does not render the file checksum if it does not exist', () => { - cy.customMount() + const metadataWithoutChecksum = FileMetadataMother.createWithNoChecksum() + cy.customMount( + + ) cy.findByText('SHA-1').should('not.exist') }) it('renders the file deposit date', () => { - const date = new Date('2021-01-01') cy.customMount( ) cy.findByText('Deposit Date').should('exist') - cy.findByText(DateHelper.toDisplayFormatYYYYMMDD(date)).should('exist') + cy.findByText(DateHelper.toDisplayFormatYYYYMMDD(file.metadata.depositDate)).should('exist') }) it('renders the file Metadata Release Date', () => { - const date = new Date('2021-01-01') + const metadataWithPublicationDate = FileMetadataMother.createWithPublicationDate() cy.customMount( ) cy.findByText('Metadata Release Date').should('exist') - cy.findAllByText(DateHelper.toDisplayFormatYYYYMMDD(date)).should('exist') + cy.findAllByText( + DateHelper.toDisplayFormatYYYYMMDD(metadataWithPublicationDate.publicationDate) + ).should('exist') }) it('does not render the file Metadata Release Date if the publication date does not exist', () => { - cy.customMount() + const metadataWithNoPublicationDate = FileMetadataMother.createWithNoPublicationDate() + cy.customMount( + + ) cy.findByText('Metadata Release Date').should('not.exist') }) it('renders the file Publication Date', () => { - const date = new Date('2021-10-01') + const metadataWithPublicationDate = FileMetadataMother.createWithPublicationDateNotEmbargoed() cy.customMount( ) cy.findByText('Publication Date').should('exist') - cy.findAllByText(DateHelper.toDisplayFormatYYYYMMDD(date)).should('exist') + cy.findAllByText( + DateHelper.toDisplayFormatYYYYMMDD(metadataWithPublicationDate.publicationDate) + ).should('exist') }) it('renders the file Publication Date with embargo', () => { - const date = new Date('2021-05-01') + const metadataWithPublicationDateEmbargoed = + FileMetadataMother.createWithPublicationDateEmbargoed() cy.customMount( ) cy.findByText('Publication Date').should('exist') - cy.findByText(DateHelper.toDisplayFormatYYYYMMDD(date)).should('exist') + cy.findByText( + `Embargoed until ${DateHelper.toDisplayFormatYYYYMMDD( + metadataWithPublicationDateEmbargoed.embargo?.dateAvailable + )}` + ).should('exist') }) it('does not render the file Publication Date if the publication date and embargo do not exist', () => { + const metadataWithNoPublicationDate = FileMetadataMother.create({ + publicationDate: undefined, + embargo: undefined + }) cy.customMount( - + ) cy.findByText('Publication Date').should('not.exist') }) it('renders the file Embargo Reason', () => { + const metadataWithEmbargoReason = FileMetadataMother.create({ + embargo: FileEmbargoMother.create({ reason: 'Some reason' }) + }) cy.customMount( ) @@ -212,17 +319,29 @@ describe('FileMetadata', () => { }) it('does not render the file Embargo Reason if the embargo does not exist', () => { - cy.customMount() + const metadataWithNoEmbargo = FileMetadataMother.createNotEmbargoed() + cy.customMount( + + ) cy.findByText('Embargo Reason').should('not.exist') }) it('does not render the file Embargo Reason if the embargo reason does not exist', () => { + const metadataWithNoEmbargoReason = FileMetadataMother.create({ + embargo: FileEmbargoMother.createWithNoReason({ reason: undefined }) + }) cy.customMount( ) @@ -230,11 +349,15 @@ describe('FileMetadata', () => { }) it('renders the file size', () => { + const metadataWithFileSize = FileMetadataMother.create({ + size: FileSizeMother.create({ value: 123.03932894722, unit: FileSizeUnit.BYTES }) + }) cy.customMount( ) @@ -243,11 +366,15 @@ describe('FileMetadata', () => { }) it('renders the file type', () => { + const metadataWithFileType = FileMetadataMother.create({ + type: FileTypeMother.createText() + }) cy.customMount( ) @@ -256,11 +383,15 @@ describe('FileMetadata', () => { }) it('renders the tabular data if it exists', () => { + const metadataWithTabularData = FileMetadataMother.create({ + tabularData: FileTabularDataMother.create({ variablesCount: 123, observationsCount: 321 }) + }) cy.customMount( ) @@ -271,18 +402,30 @@ describe('FileMetadata', () => { }) it('does not render the tabular data if it does not exist', () => { - cy.customMount() + const metadataWithoutTabularData = FileMetadataMother.createNonTabular() + cy.customMount( + + ) cy.findByText('Variables').should('not.exist') cy.findByText('Observations').should('not.exist') }) it('renders the file directory', () => { + const metadataWithDirectory = FileMetadataMother.create({ + directory: '/some/path' + }) cy.customMount( ) @@ -291,17 +434,30 @@ describe('FileMetadata', () => { }) it('does not render the file directory if it does not exist', () => { - cy.customMount() + const metadataWithoutDirectory = FileMetadataMother.createWithNoDirectory() + cy.customMount( + + ) cy.findByText('File Path').should('not.exist') }) it('renders the file description', () => { + const metadataWithDescription = FileMetadataMother.create({ + description: 'Some description' + }) + cy.customMount( ) @@ -310,7 +466,16 @@ describe('FileMetadata', () => { }) it('does not render the file description if it does not exist', () => { - cy.customMount() + const metadataWithoutDescription = FileMetadataMother.createWithNoDescription() + + cy.customMount( + + ) cy.findByText('Description').should('not.exist') }) diff --git a/tests/component/sections/file/file-permissions/useFileDownloadPermission.spec.tsx b/tests/component/sections/file/file-permissions/useFileDownloadPermission.spec.tsx index 6254bcad8..8bc093c44 100644 --- a/tests/component/sections/file/file-permissions/useFileDownloadPermission.spec.tsx +++ b/tests/component/sections/file/file-permissions/useFileDownloadPermission.spec.tsx @@ -1,10 +1,10 @@ -import { FilePreviewMother } from '../../../files/domain/models/FilePreviewMother' import { FilePermissionsProvider } from '../../../../../src/sections/file/file-permissions/FilePermissionsProvider' import { FileRepository } from '../../../../../src/files/domain/repositories/FileRepository' import { FilePreview } from '../../../../../src/files/domain/models/FilePreview' import { FileUserPermissionsMother } from '../../../files/domain/models/FileUserPermissionsMother' import { FilesCountInfoMother } from '../../../files/domain/models/FilesCountInfoMother' import { useFileDownloadPermission } from '../../../../../src/sections/file/file-permissions/useFileDownloadPermission' +import { FilePreviewMother } from '../../../files/domain/models/FilePreviewMother' const fileRepository: FileRepository = {} as FileRepository function TestComponent({ file }: { file: FilePreview }) { diff --git a/tests/component/sections/file/file-permissions/useFilePermissions.spec.tsx b/tests/component/sections/file/file-permissions/useFilePermissions.spec.tsx index 89ae6215d..20f5b1d4b 100644 --- a/tests/component/sections/file/file-permissions/useFilePermissions.spec.tsx +++ b/tests/component/sections/file/file-permissions/useFilePermissions.spec.tsx @@ -1,6 +1,5 @@ import { useFilePermissions } from '../../../../../src/sections/file/file-permissions/FilePermissionsContext' import { FilePermission } from '../../../../../src/files/domain/models/FileUserPermissions' -import { FilePreviewMother } from '../../../files/domain/models/FilePreviewMother' import { useEffect, useState } from 'react' import { FilePermissionsProvider } from '../../../../../src/sections/file/file-permissions/FilePermissionsProvider' import { FileRepository } from '../../../../../src/files/domain/repositories/FileRepository' @@ -8,6 +7,7 @@ import { FilePreview } from '../../../../../src/files/domain/models/FilePreview' import { FileUserPermissionsMother } from '../../../files/domain/models/FileUserPermissionsMother' import { FilesCountInfoMother } from '../../../files/domain/models/FilesCountInfoMother' import { AnonymizedContext } from '../../../../../src/sections/dataset/anonymized/AnonymizedContext' +import { FilePreviewMother } from '../../../files/domain/models/FilePreviewMother' const fileRepository: FileRepository = {} as FileRepository @@ -117,7 +117,7 @@ describe('useFilePermissions', () => { }) it('should call getFileUserPermissionsById when the file is restricted', () => { - const file = FilePreviewMother.createWithRestrictedAccess() + const file = FilePreviewMother.createRestricted() fileRepository.getUserPermissionsById = cy .stub() .resolves(FileUserPermissionsMother.create({ fileId: file.id, canDownloadFile: true })) @@ -177,7 +177,7 @@ describe('useFilePermissions', () => { }) it('should use the saved state of the permission the second time the file is being consulted', () => { - const file = FilePreviewMother.createWithRestrictedAccess() + const file = FilePreviewMother.createRestricted() fileRepository.getUserPermissionsById = cy .stub() .resolves(FileUserPermissionsMother.create({ fileId: file.id, canDownloadFile: true })) @@ -193,7 +193,7 @@ describe('useFilePermissions', () => { }) it('should always allow to download if the user is in anonymized view (privateUrl)', () => { - const file = FilePreviewMother.createWithRestrictedAccess() + const file = FilePreviewMother.createRestricted() fileRepository.getUserPermissionsById = cy .stub() .resolves(FileUserPermissionsMother.create({ fileId: file.id, canDownloadFile: false })) diff --git a/tests/component/sections/file/file-preview/FilePreview.spec.tsx b/tests/component/sections/file/file-preview/FilePreview.spec.tsx index 1ca7e9247..f84995bd8 100644 --- a/tests/component/sections/file/file-preview/FilePreview.spec.tsx +++ b/tests/component/sections/file/file-preview/FilePreview.spec.tsx @@ -1,18 +1,25 @@ import { FilePreview } from '../../../../../src/sections/file/file-preview/FilePreview' import { FileMother } from '../../../files/domain/models/FileMother' -import { FileType } from '../../../../../src/files/domain/models/FilePreview' +import { FileType } from '../../../../../src/files/domain/models/FileMetadata' +import { FileMetadataMother } from '../../../files/domain/models/FileMetadataMother' describe('FilePreview', () => { it('renders the file image', () => { const file = FileMother.createWithThumbnail() - cy.customMount() + cy.customMount( + + ) - cy.findByAltText(file.name).should('exist').should('have.attr', 'src', file.thumbnail) + cy.findByAltText(file.name).should('exist').should('have.attr', 'src', file.metadata.thumbnail) }) it('renders the file icon', () => { - const file = FileMother.createWithoutThumbnail({ type: new FileType('text/plain') }) - cy.customMount() + const file = FileMother.create({ + metadata: FileMetadataMother.createWithoutThumbnail({ type: new FileType('text/plain') }) + }) + cy.customMount( + + ) cy.findByLabelText('icon-document').should('exist') }) diff --git a/tests/component/settings/domain/models/SettingMother.ts b/tests/component/settings/domain/models/SettingMother.ts index b3066153c..e109530ba 100644 --- a/tests/component/settings/domain/models/SettingMother.ts +++ b/tests/component/settings/domain/models/SettingMother.ts @@ -1,7 +1,7 @@ import { faker } from '@faker-js/faker' import { Setting, SettingName } from '../../../../../src/settings/domain/models/Setting' import { ZipDownloadLimit } from '../../../../../src/settings/domain/models/ZipDownloadLimit' -import { FileSizeUnit } from '../../../../../src/files/domain/models/FilePreview' +import { FileSizeUnit } from '../../../../../src/files/domain/models/FileMetadata' export class SettingMother { static createZipDownloadLimit(value?: ZipDownloadLimit): Setting { diff --git a/tests/e2e-integration/integration/datasets/DatasetJSDataverseRepository.spec.ts b/tests/e2e-integration/integration/datasets/DatasetJSDataverseRepository.spec.ts index dcdbcefd6..e4ff9a162 100644 --- a/tests/e2e-integration/integration/datasets/DatasetJSDataverseRepository.spec.ts +++ b/tests/e2e-integration/integration/datasets/DatasetJSDataverseRepository.spec.ts @@ -14,7 +14,7 @@ import { FileDownloadMode, FileDownloadSize, FileSizeUnit -} from '../../../../src/files/domain/models/FilePreview' +} from '../../../../src/files/domain/models/FileMetadata' import { DatasetPaginationInfo } from '../../../../src/dataset/domain/models/DatasetPaginationInfo' chai.use(chaiAsPromised) diff --git a/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts b/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts index 92825b822..b61999e7a 100644 --- a/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts +++ b/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts @@ -1,16 +1,13 @@ import { TestsUtils } from '../../shared/TestsUtils' import { FileJSDataverseRepository } from '../../../../src/files/infrastructure/FileJSDataverseRepository' import { - FilePreview, FileDateType, FileEmbargo, - FileIngestStatus, FileLabelType, - FilePublishingStatus, FileSize, FileSizeUnit, FileType -} from '../../../../src/files/domain/models/FilePreview' +} from '../../../../src/files/domain/models/FileMetadata' import chai from 'chai' import chaiAsPromised from 'chai-as-promised' import { DatasetJSDataverseRepository } from '../../../../src/dataset/infrastructure/repositories/DatasetJSDataverseRepository' @@ -25,6 +22,9 @@ import { FileData, FileHelper } from '../../shared/files/FileHelper' import { FilesCountInfo } from '../../../../src/files/domain/models/FilesCountInfo' import { DatasetVersionMother } from '../../../component/dataset/domain/models/DatasetMother' import { FilePaginationInfo } from '../../../../src/files/domain/models/FilePaginationInfo' +import { FilePreview } from '../../../../src/files/domain/models/FilePreview' +import { FilePublishingStatus } from '../../../../src/files/domain/models/FileVersion' +import { FileIngestStatus } from '../../../../src/files/domain/models/FileIngest' chai.use(chaiAsPromised) const expect = chai.expect @@ -33,42 +33,48 @@ const fileRepository = new FileJSDataverseRepository() const datasetRepository = new DatasetJSDataverseRepository() const dateNow = new Date() dateNow.setHours(2, 0, 0, 0) -const fileData = (id: number) => { - return new FilePreview( - id, - { number: 1, publishingStatus: FilePublishingStatus.DRAFT }, - 'blob', - { +const fileData = (id: number): FilePreview => { + return { + id: id, + name: 'blob', + version: { number: 1, publishingStatus: FilePublishingStatus.DRAFT }, + access: { 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 }, - { - original: `/api/access/datafile/${id}?format=original`, - tabular: `/api/access/datafile/${id}`, - rData: `/api/access/datafile/${id}?format=RData` - }, - undefined, - undefined, - undefined, - undefined, - 'This is an example file', - { - algorithm: 'MD5', - value: '0187a54071542738aa47939e8218e5f2' + ingest: { status: FileIngestStatus.NONE }, + metadata: { + type: new FileType('text/plain'), + size: new FileSize(25, FileSizeUnit.BYTES), + date: { + type: FileDateType.DEPOSITED, + date: dateNow + }, + downloadCount: 0, + labels: [], + isDeleted: false, + downloadUrls: { + original: `/api/access/datafile/${id}?format=original`, + tabular: `/api/access/datafile/${id}`, + rData: `/api/access/datafile/${id}?format=RData` + }, + depositDate: dateNow, + publicationDate: undefined, + thumbnail: undefined, + directory: undefined, + embargo: undefined, + tabularData: undefined, + description: 'This is an example file', + checksum: { + algorithm: 'MD5', + value: '0187a54071542738aa47939e8218e5f2' + }, + persistentId: undefined, + isActivelyEmbargoed: false } - ) + } } describe('File JSDataverse Repository', () => { @@ -95,18 +101,20 @@ describe('File JSDataverse Repository', () => { expect(file.name).to.deep.equal(expectedFileNames[index]) expect(file.version).to.deep.equal(expectedFile.version) expect(file.access).to.deep.equal(expectedFile.access) - expect(file.type).to.deep.equal(expectedFile.type) - cy.compareDate(file.date.date, expectedFile.date.date) - expect(file.downloadCount).to.deep.equal(expectedFile.downloadCount) - expect(file.labels).to.deep.equal(expectedFile.labels) - expect(file.checksum?.algorithm).to.deep.equal(expectedFile.checksum?.algorithm) - expect(file.thumbnail).to.deep.equal(expectedFile.thumbnail) - expect(file.directory).to.deep.equal(expectedFile.directory) - 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.downloadUrls).to.deep.equal(expectedFile.downloadUrls) - expect(file.isDeleted).to.deep.equal(expectedFile.isDeleted) + expect(file.metadata.type).to.deep.equal(expectedFile.metadata.type) + cy.compareDate(file.metadata.date.date, expectedFile.metadata.date.date) + expect(file.metadata.downloadCount).to.deep.equal(expectedFile.metadata.downloadCount) + expect(file.metadata.labels).to.deep.equal(expectedFile.metadata.labels) + expect(file.metadata.checksum?.algorithm).to.deep.equal( + expectedFile.metadata.checksum?.algorithm + ) + expect(file.metadata.thumbnail).to.deep.equal(expectedFile.metadata.thumbnail) + expect(file.metadata.directory).to.deep.equal(expectedFile.metadata.directory) + expect(file.metadata.embargo).to.deep.equal(expectedFile.metadata.embargo) + expect(file.metadata.tabularData).to.deep.equal(expectedFile.metadata.tabularData) + expect(file.metadata.description).to.deep.equal(expectedFile.metadata.description) + expect(file.metadata.downloadUrls).to.deep.equal(expectedFile.metadata.downloadUrls) + expect(file.metadata.isDeleted).to.deep.equal(expectedFile.metadata.isDeleted) }) }) }) @@ -125,7 +133,7 @@ describe('File JSDataverse Repository', () => { await fileRepository .getAllByDatasetPersistentId(dataset.persistentId, dataset.version) .then((files) => { - expect(files[0].size).to.deep.equal(expectedSize) + expect(files[0].metadata.size).to.deep.equal(expectedSize) }) }) @@ -146,11 +154,11 @@ describe('File JSDataverse Repository', () => { .then((files) => { const expectedPublishedFile = fileData(files[0].id) expectedPublishedFile.version.publishingStatus = FilePublishingStatus.RELEASED - expectedPublishedFile.date.type = FileDateType.PUBLISHED + expectedPublishedFile.metadata.date.type = FileDateType.PUBLISHED files.forEach((file) => { expect(file.version).to.deep.equal(expectedPublishedFile.version) - cy.compareDate(file.date.date, fileData(file.id).date.date) + cy.compareDate(file.metadata.date.date, fileData(file.id).metadata.date.date) }) }) }) @@ -198,7 +206,7 @@ describe('File JSDataverse Repository', () => { .getAllByDatasetPersistentId(dataset.persistentId, dataset.version) .then((files) => { const expectedDownloadCount = 1 - expect(files[0].downloadCount).to.deep.equal(expectedDownloadCount) + expect(files[0].metadata.downloadCount).to.deep.equal(expectedDownloadCount) }) }) @@ -218,7 +226,7 @@ describe('File JSDataverse Repository', () => { await fileRepository .getAllByDatasetPersistentId(dataset.persistentId, dataset.version) .then((files) => { - expect(files[0].labels).to.deep.equal(expectedLabels) + expect(files[0].metadata.labels).to.deep.equal(expectedLabels) }) }) @@ -235,7 +243,7 @@ describe('File JSDataverse Repository', () => { await fileRepository .getAllByDatasetPersistentId(dataset.persistentId, dataset.version) .then((files) => { - expect(files[0].labels).to.deep.equal(expectedLabels) + expect(files[0].metadata.labels).to.deep.equal(expectedLabels) }) }) @@ -251,7 +259,7 @@ describe('File JSDataverse Repository', () => { await fileRepository .getAllByDatasetPersistentId(dataset.persistentId, dataset.version) .then((files) => { - expect(files[0].thumbnail).to.not.be.undefined + expect(files[0].metadata.thumbnail).to.not.be.undefined }) }) @@ -274,7 +282,7 @@ describe('File JSDataverse Repository', () => { .getAllByDatasetPersistentId(dataset.persistentId, dataset.version) .then((files) => { const expectedEmbargo = new FileEmbargo(new Date(embargoDate)) - expect(files[0].embargo).to.deep.equal(expectedEmbargo) + expect(files[0].metadata.embargo).to.deep.equal(expectedEmbargo) }) }) @@ -293,13 +301,13 @@ describe('File JSDataverse Repository', () => { observationsCount: 10 } files.forEach((file) => { - expect(file.tabularData?.variablesCount).to.deep.equal( + expect(file.metadata.tabularData?.variablesCount).to.deep.equal( expectedTabularData.variablesCount ) - expect(file.tabularData?.observationsCount).to.deep.equal( + expect(file.metadata.tabularData?.observationsCount).to.deep.equal( expectedTabularData.observationsCount ) - expect(file.tabularData?.unf).to.not.be.undefined + expect(file.metadata.tabularData?.unf).to.not.be.undefined }) }) }) @@ -446,7 +454,7 @@ describe('File JSDataverse Repository', () => { .getAllByDatasetPersistentId(dataset.persistentId, dataset.version) .then((files) => { files.forEach((file) => { - expect(file.isDeleted).to.equal(true) + expect(file.metadata.isDeleted).to.equal(true) }) }) }) @@ -692,7 +700,7 @@ describe('File JSDataverse Repository', () => { .getAllByDatasetPersistentId(dataset.persistentId, dataset.version) .then((files) => { return files.reduce((totalDownloadSize, file) => { - return totalDownloadSize + file.size.toBytes() + return totalDownloadSize + file.metadata.size.toBytes() }, 0) }) await fileRepository @@ -738,7 +746,7 @@ describe('File JSDataverse Repository', () => { ) .then((files) => { return files.reduce((totalDownloadSize, file) => { - return totalDownloadSize + file.size.toBytes() + return totalDownloadSize + file.metadata.size.toBytes() }, 0) }) await fileRepository diff --git a/tests/e2e-integration/shared/files/FileHelper.ts b/tests/e2e-integration/shared/files/FileHelper.ts index ad59011ec..73dc4c068 100644 --- a/tests/e2e-integration/shared/files/FileHelper.ts +++ b/tests/e2e-integration/shared/files/FileHelper.ts @@ -1,5 +1,5 @@ import { DataverseApiHelper } from '../DataverseApiHelper' -import { FileLabel, FileLabelType } from '../../../../src/files/domain/models/FilePreview' +import { FileLabel, FileLabelType } from '../../../../src/files/domain/models/FileMetadata' import { faker } from '@faker-js/faker' interface FileResponse {