Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 4 additions & 0 deletions docs/useCases.md
Original file line number Diff line number Diff line change
Expand Up @@ -1007,6 +1007,8 @@ The `fileId` parameter can be a string, for persistent identifiers, or a number,

The optional `datasetVersionId` parameter can correspond to a numeric version identifier, as in the previous example, or a [DatasetNotNumberedVersion](../src/datasets/domain/models/DatasetNotNumberedVersion.ts) enum value. If not set, the default value is `DatasetNotNumberedVersion.LATEST`.

There is an optional third parameter called `includeDeaccessioned`, which indicates whether to consider deaccessioned versions or not in the file search. If not set, the default value is `false`.

#### Get a File and its Dataset

Returns a tuple of [FileModel](../src/files/domain/models/FileModel.ts) and [Dataset](../src/datasets/domain/models/Dataset.ts) objects (`[FileModel, Dataset]`), given the search parameters to identify the file.
Expand Down Expand Up @@ -1036,6 +1038,8 @@ The `fileId` parameter can be a string, for persistent identifiers, or a number,

The optional `datasetVersionId` parameter can correspond to a numeric version identifier, as in the previous example, or a [DatasetNotNumberedVersion](../src/datasets/domain/models/DatasetNotNumberedVersion.ts) enum value. If not set, the default value is `DatasetNotNumberedVersion.LATEST`.

There is an optional third parameter called `includeDeaccessioned`, which indicates whether to consider deaccessioned versions or not in the file search. If not set, the default value is `false`.

#### Get File Citation Text

Returns the File citation text.
Expand Down
3 changes: 2 additions & 1 deletion src/files/domain/repositories/IFilesRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ export interface IFilesRepository {
getFile(
fileId: number | string,
datasetVersionId: string,
returnDatasetVersion: boolean
returnDatasetVersion: boolean,
includeDeaccessioned: boolean
): Promise<FileModel | [FileModel, Dataset]>

getFileCitation(
Expand Down
11 changes: 9 additions & 2 deletions src/files/domain/useCases/GetFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,19 @@ export class GetFile implements UseCase<FileModel> {
*
* @param {number | string} [fileId] - The File identifier, which can be a string (for persistent identifiers), or a number (for numeric identifiers).
* @param {string | DatasetNotNumberedVersion} [datasetVersionId=DatasetNotNumberedVersion.LATEST] - The dataset version identifier, which can be a version-specific numeric string (for example, 1.0) or a DatasetNotNumberedVersion enum value. If this parameter is not set, the default value is: DatasetNotNumberedVersion.LATEST
* @param {boolean} [includeDeaccessioned=false] - If true, the file will be returned even if it has been deaccessioned.
* @returns {Promise<FileModel>}
*/
async execute(
fileId: number | string,
datasetVersionId: string | DatasetNotNumberedVersion = DatasetNotNumberedVersion.LATEST
datasetVersionId: string | DatasetNotNumberedVersion = DatasetNotNumberedVersion.LATEST,
includeDeaccessioned = false
): Promise<FileModel> {
return (await this.filesRepository.getFile(fileId, datasetVersionId, false)) as FileModel
return (await this.filesRepository.getFile(
fileId,
datasetVersionId,
false,
includeDeaccessioned
)) as FileModel
}
}
14 changes: 9 additions & 5 deletions src/files/domain/useCases/GetFileAndDataset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,19 @@ export class GetFileAndDataset implements UseCase<[FileModel, Dataset]> {
*
* @param {number | string} [fileId] - The File identifier, which can be a string (for persistent identifiers), or a number (for numeric identifiers).
* @param {string | DatasetNotNumberedVersion} [datasetVersionId=DatasetNotNumberedVersion.LATEST] - The dataset version identifier, which can be a version-specific numeric string (for example, 1.0) or a DatasetNotNumberedVersion enum value. If this parameter is not set, the default value is: DatasetNotNumberedVersion.LATEST
* @param {boolean} [includeDeaccessioned=false] - If true, the file will be returned even if it has been deaccessioned.
* @returns {Promise<[FileModel, Dataset]>}
*/
async execute(
fileId: number | string,
datasetVersionId: string | DatasetNotNumberedVersion = DatasetNotNumberedVersion.LATEST
datasetVersionId: string | DatasetNotNumberedVersion = DatasetNotNumberedVersion.LATEST,
includeDeaccessioned = false
): Promise<[FileModel, Dataset]> {
return (await this.filesRepository.getFile(fileId, datasetVersionId, true)) as [
FileModel,
Dataset
]
return (await this.filesRepository.getFile(
fileId,
datasetVersionId,
true,
includeDeaccessioned
)) as [FileModel, Dataset]
}
}
6 changes: 4 additions & 2 deletions src/files/infra/repositories/FilesRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,14 +196,16 @@ export class FilesRepository extends ApiRepository implements IFilesRepository {
public async getFile(
fileId: number | string,
datasetVersionId: string,
returnDatasetVersion: boolean
returnDatasetVersion: boolean,
includeDeaccessioned: boolean
): Promise<FileModel | [FileModel, Dataset]> {
return this.doGet(
this.buildApiEndpoint(this.filesResourceName, `versions/${datasetVersionId}`, fileId),
true,
{
returnDatasetVersion: returnDatasetVersion,
returnOwners: true
returnOwners: true,
includeDeaccessioned: includeDeaccessioned
}
)
.then((response) => transformFileResponseToFile(response, returnDatasetVersion))
Expand Down
70 changes: 57 additions & 13 deletions test/integration/files/FilesRepository.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import {
} from '../../../src/files/domain/models/FileCriteria'
import {
DatasetNotNumberedVersion,
Dataset,
CreatedDatasetIdentifiers,
createDataset
} from '../../../src/datasets'
Expand Down Expand Up @@ -63,6 +62,8 @@ describe('FilesRepository', () => {

let testFileId: number
let testFilePersistentId: string
let deaccessionedTestFileId: number
let deaccessionedFileTestDatasetIds: CreatedDatasetIdentifiers

beforeAll(async () => {
ApiConfig.init(
Expand Down Expand Up @@ -474,6 +475,7 @@ describe('FilesRepository', () => {
const actual: FileModel = (await sut.getFile(
testFileId,
DatasetNotNumberedVersion.LATEST,
false,
false
)) as FileModel

Expand All @@ -484,35 +486,75 @@ describe('FilesRepository', () => {
const actual: FileModel = (await sut.getFile(
testFileId,
DatasetNotNumberedVersion.DRAFT,
false,
false
)) as FileModel

expect(actual.name).toBe(testTextFile1Name)
})

test('should return file and dataset when providing id, version, and returnDatasetVersion is true', async () => {
Comment thread
ChengShi-1 marked this conversation as resolved.
const actual = (await sut.getFile(testFileId, DatasetNotNumberedVersion.DRAFT, true)) as [
FileModel,
Dataset
]

expect(actual[0].name).toBe(testTextFile1Name)
expect(actual[1].id).toBe(testDatasetIds.numericId)
})

test('should return error when file does not exist', async () => {
const expectedError = new ReadError(`[404] File with ID ${nonExistentFiledId} not found.`)

await expect(
sut.getFile(nonExistentFiledId, DatasetNotNumberedVersion.LATEST, false)
sut.getFile(nonExistentFiledId, DatasetNotNumberedVersion.LATEST, false, false)
).rejects.toThrow(expectedError)
})
})

describe('getFile with deaccessioned dataset', () => {
test('should return file if dataset is deaccessioned, and includeDeaccessioned is true', async () => {
const testTextFile1Name = 'test-file-1.txt'
deaccessionedFileTestDatasetIds = await createDataset.execute(
TestConstants.TEST_NEW_DATASET_DTO
)

await publishDatasetViaApi(deaccessionedFileTestDatasetIds.numericId)
await waitForNoLocks(deaccessionedFileTestDatasetIds.numericId, 10)

uploadFileViaApi(deaccessionedFileTestDatasetIds.numericId, testTextFile1Name).catch(() => {
throw new Error(`Error while uploading file ${testTextFile1Name}`)
})

await deaccessionDatasetViaApi(deaccessionedFileTestDatasetIds.numericId, '1.0')

const datasetFiles = await sut.getDatasetFiles(
deaccessionedFileTestDatasetIds.numericId,
latestDatasetVersionId,
false,
FileOrderCriteria.NAME_AZ
)
deaccessionedTestFileId = datasetFiles.files[0].id

const actual = (await sut.getFile(
deaccessionedTestFileId,
DatasetNotNumberedVersion.LATEST,
false,
true
)) as FileModel

expect(actual.name).toBe(testTextFile1Name)
})

test('should return error if dataset is deaccessioned, and includeDeaccessioned is false', async () => {
const expectedError = new ReadError(
`[404] "File metadata for file with id ${deaccessionedTestFileId} in dataset version 1.0 not found"`
)

await expect(sut.getFile(deaccessionedTestFileId, '1.0', false, false)).rejects.toThrow(
expectedError
)

deletePublishedDatasetViaApi(deaccessionedFileTestDatasetIds.persistentId)
})
})

describe('by persistent id', () => {
test('should return file when providing a valid persistent id', async () => {
const actual = (await sut.getFile(
testFilePersistentId,
DatasetNotNumberedVersion.LATEST,
false,
false
)) as FileModel

Expand All @@ -523,6 +565,7 @@ describe('FilesRepository', () => {
const actual = (await sut.getFile(
testFilePersistentId,
DatasetNotNumberedVersion.DRAFT,
false,
false
)) as FileModel

Expand All @@ -536,7 +579,7 @@ describe('FilesRepository', () => {
)

await expect(
sut.getFile(nonExistentFiledPersistentId, DatasetNotNumberedVersion.LATEST, false)
sut.getFile(nonExistentFiledPersistentId, DatasetNotNumberedVersion.LATEST, false, false)
).rejects.toThrow(expectedError)
})
})
Expand Down Expand Up @@ -672,6 +715,7 @@ describe('FilesRepository', () => {
const fileInfo: FileModel = (await sut.getFile(
testFileId,
DatasetNotNumberedVersion.LATEST,
false,
false
)) as FileModel

Expand Down
31 changes: 30 additions & 1 deletion test/unit/files/GetFile.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ describe('execute', () => {
expect(filesRepositoryStub.getFile).toHaveBeenCalledWith(
1,
DatasetNotNumberedVersion.LATEST,
false,
false
)
})
Expand All @@ -33,6 +34,7 @@ describe('execute', () => {
expect(filesRepositoryStub.getFile).toHaveBeenCalledWith(
'doi:10.5072/FK2/J8SJZB',
DatasetNotNumberedVersion.LATEST,
false,
false
)
})
Expand All @@ -47,7 +49,34 @@ describe('execute', () => {
const actual = await sut.execute('doi:10.5072/FK2/J8SJZB', '2.0')

expect(actual).toEqual(testFile)
expect(filesRepositoryStub.getFile).toHaveBeenCalledWith('doi:10.5072/FK2/J8SJZB', '2.0', false)
expect(filesRepositoryStub.getFile).toHaveBeenCalledWith(
'doi:10.5072/FK2/J8SJZB',
'2.0',
false,
false
)
})

test('should return file on repository success when includeDeaccession is true', async () => {
const testFile = createFileModel()
const filesRepositoryStub: IFilesRepository = {} as IFilesRepository
filesRepositoryStub.getFile = jest.fn().mockResolvedValue(testFile)

const sut = new GetFile(filesRepositoryStub)

const actual = await sut.execute(
'doi:10.5072/FK2/J8SJZB',
DatasetNotNumberedVersion.LATEST,
true
)

expect(actual).toEqual(testFile)
expect(filesRepositoryStub.getFile).toHaveBeenCalledWith(
'doi:10.5072/FK2/J8SJZB',
DatasetNotNumberedVersion.LATEST,
false,
true
)
})

test('should return error result on repository error', async () => {
Expand Down
34 changes: 31 additions & 3 deletions test/unit/files/GetFileAndDataset.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ describe('execute', () => {
expect(filesRepositoryStub.getFile).toHaveBeenCalledWith(
1,
DatasetNotNumberedVersion.LATEST,
true
true,
false
)
})

Expand All @@ -37,7 +38,8 @@ describe('execute', () => {
expect(filesRepositoryStub.getFile).toHaveBeenCalledWith(
'doi:10.5072/FK2/J8SJZB',
DatasetNotNumberedVersion.LATEST,
true
true,
false
)
})

Expand All @@ -50,7 +52,33 @@ describe('execute', () => {

expect(actual[0]).toEqual(testFile)
expect(actual[1]).toEqual(testDataset)
expect(filesRepositoryStub.getFile).toHaveBeenCalledWith('doi:10.5072/FK2/J8SJZB', '2.0', true)
expect(filesRepositoryStub.getFile).toHaveBeenCalledWith(
'doi:10.5072/FK2/J8SJZB',
'2.0',
true,
false
)
})

test('should return file and dataset on repository success when includeDeaccession is true', async () => {
const filesRepositoryStub = <IFilesRepository>{}
filesRepositoryStub.getFile = jest.fn().mockResolvedValue(testTuple)
const sut = new GetFileAndDataset(filesRepositoryStub)

const actual = await sut.execute(
'doi:10.5072/FK2/J8SJZB',
DatasetNotNumberedVersion.LATEST,
true
)

expect(actual[0]).toEqual(testFile)
expect(actual[1]).toEqual(testDataset)
expect(filesRepositoryStub.getFile).toHaveBeenCalledWith(
'doi:10.5072/FK2/J8SJZB',
DatasetNotNumberedVersion.LATEST,
true,
true
)
})

test('should return error result on repository error', async () => {
Expand Down
Loading