diff --git a/src/files/domain/models/File.ts b/src/files/domain/models/File.ts index b6f685c75..41067bd89 100644 --- a/src/files/domain/models/File.ts +++ b/src/files/domain/models/File.ts @@ -1,4 +1,5 @@ import FileTypeToFriendlyTypeMap from './FileTypeToFriendlyTypeMap' +import { FileUserPermissions } from './FileUserPermissions' export enum FileSizeUnit { BYTES = 'B', @@ -115,6 +116,7 @@ export enum FileLabelType { CATEGORY = 'category', TAG = 'tag' } + export interface FileLabel { type: FileLabelType value: string @@ -158,6 +160,7 @@ export class File { readonly labels: FileLabel[], public readonly isDeleted: boolean, public readonly ingest: FileIngest, + public userPermissions?: FileUserPermissions, readonly checksum?: FileChecksum, public thumbnail?: string, readonly directory?: string, diff --git a/src/files/domain/useCases/checkFileDownloadPermission.ts b/src/files/domain/useCases/checkFileDownloadPermission.ts index 974f0dd5b..cdc82a025 100644 --- a/src/files/domain/useCases/checkFileDownloadPermission.ts +++ b/src/files/domain/useCases/checkFileDownloadPermission.ts @@ -1,14 +1,14 @@ import { FileRepository } from '../repositories/FileRepository' import { File, FilePublishingStatus } from '../models/File' +// TODO: remove async when ready and then remove eslint-disable +// eslint-disable-next-line @typescript-eslint/require-await export async function checkFileDownloadPermission( fileRepository: FileRepository, file: File ): Promise { if (file.version.publishingStatus === FilePublishingStatus.DEACCESSIONED) { - return fileRepository.getUserPermissionsById(file.id).then((permissions) => { - return permissions.canEditDataset - }) + return file.userPermissions?.canEditDataset || false } const isRestricted = file.access.restricted || file.access.latestVersionRestricted @@ -16,7 +16,5 @@ export async function checkFileDownloadPermission( return true } - return fileRepository.getUserPermissionsById(file.id).then((permissions) => { - return permissions.canDownloadFile - }) + return file.userPermissions?.canDownloadFile || false } diff --git a/src/files/domain/useCases/checkFileEditDatasetPermission.ts b/src/files/domain/useCases/checkFileEditDatasetPermission.ts index a2a69206f..bf3a85e00 100644 --- a/src/files/domain/useCases/checkFileEditDatasetPermission.ts +++ b/src/files/domain/useCases/checkFileEditDatasetPermission.ts @@ -1,11 +1,10 @@ import { FileRepository } from '../repositories/FileRepository' import { File } from '../models/File' - +// TODO: remove async when ready and then remove eslint-disable +// eslint-disable-next-line @typescript-eslint/require-await export async function checkFileEditDatasetPermission( fileRepository: FileRepository, file: File ): Promise { - return fileRepository.getUserPermissionsById(file.id).then((permissions) => { - return permissions.canEditDataset - }) + return file.userPermissions?.canEditDataset || false } diff --git a/src/files/infrastructure/FileJSDataverseRepository.ts b/src/files/infrastructure/FileJSDataverseRepository.ts index e16c3c004..266a9447d 100644 --- a/src/files/infrastructure/FileJSDataverseRepository.ts +++ b/src/files/infrastructure/FileJSDataverseRepository.ts @@ -44,6 +44,7 @@ export class FileJSDataverseRepository implements FileRepository { .then((jsFiles) => jsFiles.map((jsFile) => JSFileMapper.toFile(jsFile, datasetVersion))) .then((files) => FileJSDataverseRepository.getAllWithDownloadCount(files)) .then((files) => FileJSDataverseRepository.getAllWithThumbnail(files)) + .then((files) => FileJSDataverseRepository.getAllWithPermissions(files)) .catch((error: ReadError) => { throw new Error(error.message) }) @@ -83,6 +84,23 @@ export class FileJSDataverseRepository implements FileRepository { ) } + private static getAllWithPermissions(files: File[]): Promise { + console.log('BEGIN getAllWithPermissions') + return Promise.all( + files.map((file) => + getFileUserPermissions.execute(file.id).then((jsFileUserPermissions) => { + file.userPermissions = { + fileId: file.id, + canDownloadFile: jsFileUserPermissions.canDownloadFile, + canEditDataset: jsFileUserPermissions.canEditOwnerDataset + } + console.log('jsFileUserPermissions', jsFileUserPermissions) + return file + }) + ) + ) + } + private static getThumbnailById(id: number): Promise { return fetch(`${this.DATAVERSE_BACKEND_URL}/api/access/datafile/${id}?imageThumb=400`) .then((response) => { diff --git a/src/files/infrastructure/mappers/JSFileMapper.ts b/src/files/infrastructure/mappers/JSFileMapper.ts index 3956b6d25..7562e8f14 100644 --- a/src/files/infrastructure/mappers/JSFileMapper.ts +++ b/src/files/infrastructure/mappers/JSFileMapper.ts @@ -48,6 +48,7 @@ export class JSFileMapper { this.toFileLabels(jsFile.categories, jsFile.tabularTags), false, // TODO - Implement this when it is added to js-dataverse { status: FileIngestStatus.NONE }, // TODO - Implement this when it is added to js-dataverse + undefined, // TODO - revisit this, do I need to have a method here? this.toFileChecksum(jsFile.checksum), this.toFileThumbnail(), this.toFileDirectory(jsFile.directoryLabel), diff --git a/src/sections/dataset/dataset-files/useFiles.tsx b/src/sections/dataset/dataset-files/useFiles.tsx index 538da0921..3b9ff3305 100644 --- a/src/sections/dataset/dataset-files/useFiles.tsx +++ b/src/sections/dataset/dataset-files/useFiles.tsx @@ -44,6 +44,7 @@ export function useFiles( } const getFiles = (filesCount: FilesCountInfo) => { + console.log('GET FILES', filesCount) if (filesCount) { if (filesCount.total === 0) { setIsLoading(false) @@ -58,11 +59,9 @@ export function useFiles( ) .then((files: File[]) => { setFiles(files) + setIsLoading(false) return files }) - .then((files: File[]) => - fetchFilesPermission(FilePermission.DOWNLOAD_FILE, files).then(() => setIsLoading(false)) - ) .catch(() => { throw new Error('There was an error getting the files') }) @@ -71,7 +70,15 @@ export function useFiles( useEffect(() => { setIsLoading(true) - + console.log( + 'USE EFFECT FILE COUNT INFO', + filesRepository, + datasetPersistentId, + datasetVersion, + paginationInfo.page, + paginationInfo.pageSize, + criteria + ) getFilesCountInfo() .then((filesCount) => getFiles(filesCount)) .catch(() => { @@ -88,6 +95,13 @@ export function useFiles( ]) useEffect(() => { + console.log( + 'USE EFFECT FILE DOWNLOAD SIZE', + filesRepository, + datasetPersistentId, + datasetVersion, + criteria + ) getFilesTotalDownloadSize(filesRepository, datasetPersistentId, datasetVersion, criteria) .then((filesTotalDownloadSize: number) => { setFilesTotalDownloadSize(filesTotalDownloadSize) diff --git a/src/sections/file/file-permissions/useFileDownloadPermission.tsx b/src/sections/file/file-permissions/useFileDownloadPermission.tsx index 61e02bff7..0c0d3b67f 100644 --- a/src/sections/file/file-permissions/useFileDownloadPermission.tsx +++ b/src/sections/file/file-permissions/useFileDownloadPermission.tsx @@ -1,22 +1,22 @@ import { useEffect, useState } from 'react' -import { FilePermission } from '../../../files/domain/models/FileUserPermissions' -import { useFilePermissions } from './FilePermissionsContext' +//import { FilePermission } from '../../../files/domain/models/FileUserPermissions' + import { File } from '../../../files/domain/models/File' export function useFileDownloadPermission(file: File) { - const { checkSessionUserHasFilePermission } = useFilePermissions() const [sessionUserHasFileDownloadPermission, setSessionUserHasFileDownloadPermission] = useState(false) useEffect(() => { - checkSessionUserHasFilePermission(FilePermission.DOWNLOAD_FILE, file) - .then((hasPermission) => { - setSessionUserHasFileDownloadPermission(hasPermission) - }) - .catch((error) => { - setSessionUserHasFileDownloadPermission(false) - console.error('There was an error getting the file download permission', error) - }) + /*checkSessionUserHasFilePermission(FilePermission.DOWNLOAD_FILE, file) + .then((hasPermission) => { + setSessionUserHasFileDownloadPermission(hasPermission) + }) + .catch((error) => { + setSessionUserHasFileDownloadPermission(false) + console.error('There was an error getting the file download permission', error) + })*/ + setSessionUserHasFileDownloadPermission(file.userPermissions?.canDownloadFile || false) }, [file]) return { sessionUserHasFileDownloadPermission } diff --git a/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx b/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx index 5ba50fdcc..50a335732 100644 --- a/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx +++ b/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx @@ -5,7 +5,15 @@ import { FileHelper } from '../../../shared/files/FileHelper' import moment from 'moment-timezone' type Dataset = { - datasetVersion: { metadataBlocks: { citation: { fields: { value: string }[] } } } + datasetVersion: { + metadataBlocks: { + citation: { + fields: { + value: string + }[] + } + } + } } describe('Dataset', () => { @@ -283,28 +291,34 @@ describe('Dataset', () => { ) .its('persistentId') .then((persistentId: string) => { + /* + http://localhost:8000/api/v1/access/datafile/894/userPermissions + */ cy.wait(1500) // Wait for the dataset to be published cy.wrap(TestsUtils.logout()) - cy.visit(`/spa/datasets?persistentId=${persistentId}`) + cy.intercept('/api/v1/access/datafile/*/userPermissions').as('userPermissions') - cy.wait(1500) // Wait for the files to be loaded + cy.visit(`/spa/datasets?persistentId=${persistentId}`) - cy.findByText('Files').should('exist') + cy.wait('@userPermissions').then(() => { + cy.wait('@userPermissions').then(() => { + cy.findByText('Files').should('exist') - cy.findByText('Restricted with access Icon').should('not.exist') - cy.findByText('Restricted File Icon').should('exist') + cy.findByText('Restricted with access Icon').should('not.exist') + cy.findByText('Restricted File Icon').should('exist') - // use alias below to avoid a timing error - cy.findByRole('button', { name: 'Access File' }).as('accessButton') - cy.get('@accessButton').should('exist') - cy.get('@accessButton').click() - cy.findByText('Restricted').should('exist') + // use alias below to avoid a timing error + cy.findByRole('button', { name: 'Access File' }).as('accessButton') + cy.get('@accessButton').should('exist') + cy.get('@accessButton').click() + cy.findByText('Restricted').should('exist') + }) + }) }) }) - - it('loads the embargoed files', () => { + it.only('loads the embargoed files', () => { cy.window().then((win) => { // Get the browser's locale from the window object const browserLocale = win.navigator.language @@ -339,19 +353,23 @@ describe('Dataset', () => { .then((persistentId: string) => { cy.wait(1500) // Wait for the files to be embargoed - cy.visit(`/spa/datasets?persistentId=${persistentId}`) - - cy.wait(1500) // Wait for the files to be loaded + cy.intercept('/api/v1/access/datafile/*/userPermissions').as('userPermissions') - cy.findByText('Files').should('exist') + cy.visit(`/spa/datasets?persistentId=${persistentId}`) - cy.findByText(/Deposited/).should('exist') - cy.findByText(`Draft: will be embargoed until ${expectedDate}`).should('exist') + cy.wait('@userPermissions').then(() => { + cy.wait('@userPermissions').then(() => { + cy.findByText('Files').should('exist') + cy.findByText(/Deposited/).should('exist') + cy.findByText(`Draft: will be embargoed until ${expectedDate}`).should('exist') - cy.findByText('Edit Files').should('exist') + cy.findByText('Edit Files').should('exist') - cy.findByRole('button', { name: 'Access File' }).should('exist').click() - cy.findByText('Embargoed').should('exist') + cy.findByRole('button', { name: 'Access File' }).should('be.visible') + cy.findByRole('button', { name: 'Access File' }).should('be.visible').click() + cy.findByText('Embargoed').should('exist') + }) + }) }) }) }) diff --git a/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts b/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts index 09c7de97c..eb870f162 100644 --- a/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts +++ b/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts @@ -56,6 +56,7 @@ const expectedFile = new File( [], false, { status: FileIngestStatus.NONE }, + undefined, { algorithm: 'MD5', value: '0187a54071542738aa47939e8218e5f2'