Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion docs/useCases.md
Original file line number Diff line number Diff line change
Expand Up @@ -1359,7 +1359,9 @@ const uploadedFileDTO: UploadedFileDTO = {
mimeType: 'text/plain'
}

replaceFile.execute(fileId, uploadedFileDTO)
replaceFile.execute(fileId, uploadedFileDTO).then((newFileId: number) => {
/* ... */
})

/* ... */
```
Expand All @@ -1370,6 +1372,8 @@ The `fileId` parameter can be a string, for persistent identifiers, or a number,

The `uploadedFileDTO` parameter is a [UploadedFileDTO](../src/files/domain/dtos/UploadedFileDTO.ts) and includes properties related to the uploaded files. Some of these properties should be calculated from the uploaded File Blob objects and the resulting storage identifiers from the Upload File use case.

The use case returns a number, which is the identifier of the new file.

#### Restrict or Unrestrict a File

Restrict or unrestrict an existing file.
Expand Down
2 changes: 1 addition & 1 deletion src/files/domain/repositories/IFilesRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export interface IFilesRepository {

deleteFile(fileId: number | string): Promise<undefined>

replaceFile(fileId: number | string, uploadedFileDTO: UploadedFileDTO): Promise<undefined>
replaceFile(fileId: number | string, uploadedFileDTO: UploadedFileDTO): Promise<number>

restrictFile(fileId: number | string, restrict: boolean): Promise<undefined>
updateFileMetadata(
Expand Down
8 changes: 4 additions & 4 deletions src/files/domain/useCases/ReplaceFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { UseCase } from '../../../core/domain/useCases/UseCase'
import { UploadedFileDTO } from '../dtos/UploadedFileDTO'
import { IFilesRepository } from '../repositories/IFilesRepository'

export class ReplaceFile implements UseCase<void> {
export class ReplaceFile implements UseCase<number> {
private filesRepository: IFilesRepository

constructor(filesRepository: IFilesRepository) {
Expand All @@ -19,10 +19,10 @@ export class ReplaceFile implements UseCase<void> {
*
* @param {number | string} [fileId] - The File identifier, which can be a string (for persistent identifiers), or a number (for numeric identifiers).
* @param {UploadedFileDTO} [uploadedFileDTO] - File DTO associated with the uploaded file.
* @returns {Promise<void>} A promise that resolves when the file has been successfully replaced.
* @returns {Promise<number>} A promise that resolves when the file has been successfully replaced and returns the new file identifier.
* @throws {WriteError} - If there are errors while writing data.
*/
async execute(fileId: number | string, uploadedFileDTO: UploadedFileDTO): Promise<void> {
await this.filesRepository.replaceFile(fileId, uploadedFileDTO)
async execute(fileId: number | string, uploadedFileDTO: UploadedFileDTO): Promise<number> {
return await this.filesRepository.replaceFile(fileId, uploadedFileDTO)
}
}
12 changes: 10 additions & 2 deletions src/files/infra/repositories/FilesRepository.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { AxiosResponse } from 'axios'
import { ApiRepository } from '../../../core/infra/repositories/ApiRepository'
import { IFilesRepository } from '../../domain/repositories/IFilesRepository'
import { FileModel as FileModel } from '../../domain/models/FileModel'
Expand Down Expand Up @@ -60,6 +61,10 @@ export interface ChecksumRequestBody {
'@type': string
}

type ReplaceFileResponseMinimal = {
files: { dataFile: { id: number } }[]
}

export class FilesRepository extends ApiRepository implements IFilesRepository {
private readonly datasetsResourceName: string = 'datasets'
private readonly filesResourceName: string = 'files'
Expand Down Expand Up @@ -307,7 +312,7 @@ export class FilesRepository extends ApiRepository implements IFilesRepository {
public async replaceFile(
fileId: number | string,
uploadedFileDTO: UploadedFileDTO
): Promise<undefined> {
): Promise<number> {
const requestBody: UploadedFileRequestBody = {
fileName: uploadedFileDTO.fileName,
checksum: {
Expand All @@ -332,7 +337,10 @@ export class FilesRepository extends ApiRepository implements IFilesRepository {
{},
ApiConstants.CONTENT_TYPE_MULTIPART_FORM_DATA
)
.then(() => undefined)
.then((response: AxiosResponse<{ data: ReplaceFileResponseMinimal }>) => {
const fileNumber = response.data.data.files[0].dataFile.id
return fileNumber
})
.catch((error) => {
throw error
})
Expand Down
2 changes: 1 addition & 1 deletion src/files/infra/repositories/transformers/FilePayload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ export interface FilePayload {
version: number
description?: string
restricted: boolean
directoryLabel?: string
datasetVersionId?: number
categories?: string[]
contentType: string
Expand All @@ -37,6 +36,7 @@ export interface FilePayload {
}
version: number
restricted: boolean
directoryLabel?: string
label: string
datasetVersionId: number
}
Expand Down
4 changes: 2 additions & 2 deletions src/files/infra/repositories/transformers/fileTransformers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ const transformFilePayloadToFile = (filePayload: FilePayload): FileModel => {
...(filePayload.dataFile.description && { description: filePayload.dataFile.description }),
restricted: filePayload.restricted,
latestRestricted: filePayload.dataFile.restricted,
...(filePayload.dataFile.directoryLabel && {
directoryLabel: filePayload.dataFile.directoryLabel
...(filePayload.directoryLabel && {
directoryLabel: filePayload.directoryLabel
}),
...(filePayload.dataFile.datasetVersionId && {
datasetVersionId: filePayload.dataFile.datasetVersionId
Expand Down
3 changes: 2 additions & 1 deletion test/integration/files/DirectUpload.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ describe('Direct Upload', () => {
mimeType: newSinglepartFile.type
}

await filesRepositorySut.replaceFile(currentFileId, newUploadedFileDTO)
const replaceResponse = await filesRepositorySut.replaceFile(currentFileId, newUploadedFileDTO)

// 4 - Verify that the new file is in the dataset and the old file is not
datasetFiles = await filesRepositorySut.getDatasetFiles(
Expand All @@ -341,6 +341,7 @@ describe('Direct Upload', () => {
)

expect(datasetFiles.totalFilesCount).toBe(1)
expect(replaceResponse).toBe(currentFileId + 1)
expect(datasetFiles.files[0].name).toBe('new-singlepart-file')
expect(datasetFiles.files[0].sizeBytes).toBe(newSinglepartFile.size)
expect(datasetFiles.files[0].storageIdentifier).toContain('localstack1://mybucket:')
Expand Down
2 changes: 1 addition & 1 deletion test/testHelpers/files/filesHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export const createFilePayload = (): FilePayload => {
restricted: false,
version: 1,
datasetVersionId: 2,
directoryLabel: 'directoryLabel',
dataFile: {
id: 1,
version: 1,
Expand Down Expand Up @@ -116,7 +117,6 @@ export const createFilePayload = (): FilePayload => {
isPartOf: { type: DvObjectType.DATAVERSE, identifier: 'root', displayName: 'Root' }
},
description: 'description',
directoryLabel: 'directoryLabel',
datasetVersionId: 1,
originalFormat: 'originalFormat',
originalSize: 127426,
Expand Down
6 changes: 3 additions & 3 deletions test/unit/files/ReplaceFile.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ describe('execute', () => {
mimeType: 'test/type'
}

test('should return undefined on client success', async () => {
test('should return file id on client success', async () => {
const filesRepositoryStub: IFilesRepository = {} as IFilesRepository
filesRepositoryStub.replaceFile = jest.fn().mockResolvedValue(undefined)
filesRepositoryStub.replaceFile = jest.fn().mockResolvedValue(1)

const sut = new ReplaceFile(filesRepositoryStub)

const actual = await sut.execute(1, testUploadedFileDTO)

expect(actual).toEqual(undefined)
expect(actual).toEqual(1)
})

test('should return error on client error', async () => {
Expand Down