Skip to content

Commit 937fc26

Browse files
committed
feat: update includeDeaccessioned to GetFile use case
1 parent 531b543 commit 937fc26

File tree

8 files changed

+146
-27
lines changed

8 files changed

+146
-27
lines changed

docs/useCases.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,8 @@ The `fileId` parameter can be a string, for persistent identifiers, or a number,
10071007

10081008
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`.
10091009

1010+
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`.
1011+
10101012
#### Get a File and its Dataset
10111013

10121014
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.
@@ -1036,6 +1038,8 @@ The `fileId` parameter can be a string, for persistent identifiers, or a number,
10361038

10371039
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`.
10381040

1041+
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`.
1042+
10391043
#### Get File Citation Text
10401044

10411045
Returns the File citation text.

src/files/domain/repositories/IFilesRepository.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ export interface IFilesRepository {
4747
getFile(
4848
fileId: number | string,
4949
datasetVersionId: string,
50-
returnDatasetVersion: boolean
50+
returnDatasetVersion: boolean,
51+
includeDeaccessioned: boolean
5152
): Promise<FileModel | [FileModel, Dataset]>
5253

5354
getFileCitation(

src/files/domain/useCases/GetFile.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,19 @@ export class GetFile implements UseCase<FileModel> {
1111
*
1212
* @param {number | string} [fileId] - The File identifier, which can be a string (for persistent identifiers), or a number (for numeric identifiers).
1313
* @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
14+
* @param {boolean} [includeDeaccessioned=false] - If true, the file will be returned even if it has been deaccessioned.
1415
* @returns {Promise<FileModel>}
1516
*/
1617
async execute(
1718
fileId: number | string,
18-
datasetVersionId: string | DatasetNotNumberedVersion = DatasetNotNumberedVersion.LATEST
19+
datasetVersionId: string | DatasetNotNumberedVersion = DatasetNotNumberedVersion.LATEST,
20+
includeDeaccessioned = false
1921
): Promise<FileModel> {
20-
return (await this.filesRepository.getFile(fileId, datasetVersionId, false)) as FileModel
22+
return (await this.filesRepository.getFile(
23+
fileId,
24+
datasetVersionId,
25+
false,
26+
includeDeaccessioned
27+
)) as FileModel
2128
}
2229
}

src/files/domain/useCases/GetFileAndDataset.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,19 @@ export class GetFileAndDataset implements UseCase<[FileModel, Dataset]> {
1111
*
1212
* @param {number | string} [fileId] - The File identifier, which can be a string (for persistent identifiers), or a number (for numeric identifiers).
1313
* @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
14+
* @param {boolean} [includeDeaccessioned=false] - If true, the file will be returned even if it has been deaccessioned.
1415
* @returns {Promise<[FileModel, Dataset]>}
1516
*/
1617
async execute(
1718
fileId: number | string,
18-
datasetVersionId: string | DatasetNotNumberedVersion = DatasetNotNumberedVersion.LATEST
19+
datasetVersionId: string | DatasetNotNumberedVersion = DatasetNotNumberedVersion.LATEST,
20+
includeDeaccessioned = false
1921
): Promise<[FileModel, Dataset]> {
20-
return (await this.filesRepository.getFile(fileId, datasetVersionId, true)) as [
21-
FileModel,
22-
Dataset
23-
]
22+
return (await this.filesRepository.getFile(
23+
fileId,
24+
datasetVersionId,
25+
true,
26+
includeDeaccessioned
27+
)) as [FileModel, Dataset]
2428
}
2529
}

src/files/infra/repositories/FilesRepository.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,14 +196,16 @@ export class FilesRepository extends ApiRepository implements IFilesRepository {
196196
public async getFile(
197197
fileId: number | string,
198198
datasetVersionId: string,
199-
returnDatasetVersion: boolean
199+
returnDatasetVersion: boolean,
200+
includeDeaccessioned: boolean
200201
): Promise<FileModel | [FileModel, Dataset]> {
201202
return this.doGet(
202203
this.buildApiEndpoint(this.filesResourceName, `versions/${datasetVersionId}`, fileId),
203204
true,
204205
{
205206
returnDatasetVersion: returnDatasetVersion,
206-
returnOwners: true
207+
returnOwners: true,
208+
includeDeaccessioned: includeDeaccessioned
207209
}
208210
)
209211
.then((response) => transformFileResponseToFile(response, returnDatasetVersion))

test/integration/files/FilesRepository.test.ts

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import {
2323
} from '../../../src/files/domain/models/FileCriteria'
2424
import {
2525
DatasetNotNumberedVersion,
26-
Dataset,
2726
CreatedDatasetIdentifiers,
2827
createDataset
2928
} from '../../../src/datasets'
@@ -63,6 +62,8 @@ describe('FilesRepository', () => {
6362

6463
let testFileId: number
6564
let testFilePersistentId: string
65+
let deaccessionedTestFileId: number
66+
let deaccessionedFileTestDatasetIds: CreatedDatasetIdentifiers
6667

6768
beforeAll(async () => {
6869
ApiConfig.init(
@@ -474,6 +475,7 @@ describe('FilesRepository', () => {
474475
const actual: FileModel = (await sut.getFile(
475476
testFileId,
476477
DatasetNotNumberedVersion.LATEST,
478+
false,
477479
false
478480
)) as FileModel
479481

@@ -484,35 +486,75 @@ describe('FilesRepository', () => {
484486
const actual: FileModel = (await sut.getFile(
485487
testFileId,
486488
DatasetNotNumberedVersion.DRAFT,
489+
false,
487490
false
488491
)) as FileModel
489492

490493
expect(actual.name).toBe(testTextFile1Name)
491494
})
492495

493-
test('should return file and dataset when providing id, version, and returnDatasetVersion is true', async () => {
494-
const actual = (await sut.getFile(testFileId, DatasetNotNumberedVersion.DRAFT, true)) as [
495-
FileModel,
496-
Dataset
497-
]
498-
499-
expect(actual[0].name).toBe(testTextFile1Name)
500-
expect(actual[1].id).toBe(testDatasetIds.numericId)
501-
})
502-
503496
test('should return error when file does not exist', async () => {
504497
const expectedError = new ReadError(`[404] File with ID ${nonExistentFiledId} not found.`)
505498

506499
await expect(
507-
sut.getFile(nonExistentFiledId, DatasetNotNumberedVersion.LATEST, false)
500+
sut.getFile(nonExistentFiledId, DatasetNotNumberedVersion.LATEST, false, false)
508501
).rejects.toThrow(expectedError)
509502
})
510503
})
504+
505+
describe('getFile with deaccessioned dataset', () => {
506+
test('should return file if dataset is deaccessioned, and includeDeaccessioned is true', async () => {
507+
const testTextFile1Name = 'test-file-1.txt'
508+
deaccessionedFileTestDatasetIds = await createDataset.execute(
509+
TestConstants.TEST_NEW_DATASET_DTO
510+
)
511+
512+
await publishDatasetViaApi(deaccessionedFileTestDatasetIds.numericId)
513+
await waitForNoLocks(deaccessionedFileTestDatasetIds.numericId, 10)
514+
515+
uploadFileViaApi(deaccessionedFileTestDatasetIds.numericId, testTextFile1Name).catch(() => {
516+
throw new Error(`Error while uploading file ${testTextFile1Name}`)
517+
})
518+
519+
await deaccessionDatasetViaApi(deaccessionedFileTestDatasetIds.numericId, '1.0')
520+
521+
const datasetFiles = await sut.getDatasetFiles(
522+
deaccessionedFileTestDatasetIds.numericId,
523+
latestDatasetVersionId,
524+
false,
525+
FileOrderCriteria.NAME_AZ
526+
)
527+
deaccessionedTestFileId = datasetFiles.files[0].id
528+
529+
const actual = (await sut.getFile(
530+
deaccessionedTestFileId,
531+
DatasetNotNumberedVersion.LATEST,
532+
false,
533+
true
534+
)) as FileModel
535+
536+
expect(actual.name).toBe(testTextFile1Name)
537+
})
538+
539+
test('should return error if dataset is deaccessioned, and includeDeaccessioned is false', async () => {
540+
const expectedError = new ReadError(
541+
`[404] "File metadata for file with id ${deaccessionedTestFileId} in dataset version 1.0 not found"`
542+
)
543+
544+
await expect(sut.getFile(deaccessionedTestFileId, '1.0', false, false)).rejects.toThrow(
545+
expectedError
546+
)
547+
548+
deletePublishedDatasetViaApi(deaccessionedFileTestDatasetIds.persistentId)
549+
})
550+
})
551+
511552
describe('by persistent id', () => {
512553
test('should return file when providing a valid persistent id', async () => {
513554
const actual = (await sut.getFile(
514555
testFilePersistentId,
515556
DatasetNotNumberedVersion.LATEST,
557+
false,
516558
false
517559
)) as FileModel
518560

@@ -523,6 +565,7 @@ describe('FilesRepository', () => {
523565
const actual = (await sut.getFile(
524566
testFilePersistentId,
525567
DatasetNotNumberedVersion.DRAFT,
568+
false,
526569
false
527570
)) as FileModel
528571

@@ -536,7 +579,7 @@ describe('FilesRepository', () => {
536579
)
537580

538581
await expect(
539-
sut.getFile(nonExistentFiledPersistentId, DatasetNotNumberedVersion.LATEST, false)
582+
sut.getFile(nonExistentFiledPersistentId, DatasetNotNumberedVersion.LATEST, false, false)
540583
).rejects.toThrow(expectedError)
541584
})
542585
})
@@ -672,6 +715,7 @@ describe('FilesRepository', () => {
672715
const fileInfo: FileModel = (await sut.getFile(
673716
testFileId,
674717
DatasetNotNumberedVersion.LATEST,
718+
false,
675719
false
676720
)) as FileModel
677721

test/unit/files/GetFile.test.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ describe('execute', () => {
1616
expect(filesRepositoryStub.getFile).toHaveBeenCalledWith(
1717
1,
1818
DatasetNotNumberedVersion.LATEST,
19+
false,
1920
false
2021
)
2122
})
@@ -33,6 +34,7 @@ describe('execute', () => {
3334
expect(filesRepositoryStub.getFile).toHaveBeenCalledWith(
3435
'doi:10.5072/FK2/J8SJZB',
3536
DatasetNotNumberedVersion.LATEST,
37+
false,
3638
false
3739
)
3840
})
@@ -47,7 +49,34 @@ describe('execute', () => {
4749
const actual = await sut.execute('doi:10.5072/FK2/J8SJZB', '2.0')
4850

4951
expect(actual).toEqual(testFile)
50-
expect(filesRepositoryStub.getFile).toHaveBeenCalledWith('doi:10.5072/FK2/J8SJZB', '2.0', false)
52+
expect(filesRepositoryStub.getFile).toHaveBeenCalledWith(
53+
'doi:10.5072/FK2/J8SJZB',
54+
'2.0',
55+
false,
56+
false
57+
)
58+
})
59+
60+
test('should return file on repository success when includeDeaccession is true', async () => {
61+
const testFile = createFileModel()
62+
const filesRepositoryStub: IFilesRepository = {} as IFilesRepository
63+
filesRepositoryStub.getFile = jest.fn().mockResolvedValue(testFile)
64+
65+
const sut = new GetFile(filesRepositoryStub)
66+
67+
const actual = await sut.execute(
68+
'doi:10.5072/FK2/J8SJZB',
69+
DatasetNotNumberedVersion.LATEST,
70+
true
71+
)
72+
73+
expect(actual).toEqual(testFile)
74+
expect(filesRepositoryStub.getFile).toHaveBeenCalledWith(
75+
'doi:10.5072/FK2/J8SJZB',
76+
DatasetNotNumberedVersion.LATEST,
77+
false,
78+
true
79+
)
5180
})
5281

5382
test('should return error result on repository error', async () => {

test/unit/files/GetFileAndDataset.test.ts

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ describe('execute', () => {
2121
expect(filesRepositoryStub.getFile).toHaveBeenCalledWith(
2222
1,
2323
DatasetNotNumberedVersion.LATEST,
24-
true
24+
true,
25+
false
2526
)
2627
})
2728

@@ -37,7 +38,8 @@ describe('execute', () => {
3738
expect(filesRepositoryStub.getFile).toHaveBeenCalledWith(
3839
'doi:10.5072/FK2/J8SJZB',
3940
DatasetNotNumberedVersion.LATEST,
40-
true
41+
true,
42+
false
4143
)
4244
})
4345

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

5153
expect(actual[0]).toEqual(testFile)
5254
expect(actual[1]).toEqual(testDataset)
53-
expect(filesRepositoryStub.getFile).toHaveBeenCalledWith('doi:10.5072/FK2/J8SJZB', '2.0', true)
55+
expect(filesRepositoryStub.getFile).toHaveBeenCalledWith(
56+
'doi:10.5072/FK2/J8SJZB',
57+
'2.0',
58+
true,
59+
false
60+
)
61+
})
62+
63+
test('should return file and dataset on repository success when includeDeaccession is true', async () => {
64+
const filesRepositoryStub = <IFilesRepository>{}
65+
filesRepositoryStub.getFile = jest.fn().mockResolvedValue(testTuple)
66+
const sut = new GetFileAndDataset(filesRepositoryStub)
67+
68+
const actual = await sut.execute(
69+
'doi:10.5072/FK2/J8SJZB',
70+
DatasetNotNumberedVersion.LATEST,
71+
true
72+
)
73+
74+
expect(actual[0]).toEqual(testFile)
75+
expect(actual[1]).toEqual(testDataset)
76+
expect(filesRepositoryStub.getFile).toHaveBeenCalledWith(
77+
'doi:10.5072/FK2/J8SJZB',
78+
DatasetNotNumberedVersion.LATEST,
79+
true,
80+
true
81+
)
5482
})
5583

5684
test('should return error result on repository error', async () => {

0 commit comments

Comments
 (0)