diff --git a/src/core/infra/repositories/ApiRepository.ts b/src/core/infra/repositories/ApiRepository.ts index 6730e712..a1d1e0e4 100644 --- a/src/core/infra/repositories/ApiRepository.ts +++ b/src/core/infra/repositories/ApiRepository.ts @@ -4,8 +4,6 @@ import { ReadError } from '../../domain/repositories/ReadError'; import { WriteError } from '../../domain/repositories/WriteError'; export abstract class ApiRepository { - DATASET_VERSION_LATEST = ':latest'; - public async doGet(apiEndpoint: string, authRequired = false, queryParams: object = {}): Promise { return await axios .get(this.buildRequestUrl(apiEndpoint), this.buildRequestConfig(authRequired, queryParams)) diff --git a/src/datasets/domain/models/DatasetNotNumberedVersion.ts b/src/datasets/domain/models/DatasetNotNumberedVersion.ts new file mode 100644 index 00000000..a646b5be --- /dev/null +++ b/src/datasets/domain/models/DatasetNotNumberedVersion.ts @@ -0,0 +1,4 @@ +export enum DatasetNotNumberedVersion { + DRAFT = ':draft', + LATEST = ':latest', +} diff --git a/src/datasets/domain/repositories/IDatasetsRepository.ts b/src/datasets/domain/repositories/IDatasetsRepository.ts index dae4c042..f7bd7218 100644 --- a/src/datasets/domain/repositories/IDatasetsRepository.ts +++ b/src/datasets/domain/repositories/IDatasetsRepository.ts @@ -2,8 +2,8 @@ import { Dataset } from '../models/Dataset'; export interface IDatasetsRepository { getDatasetSummaryFieldNames(): Promise; - getDataset(datasetId: number | string, datasetVersionId?: string): Promise; + getDataset(datasetId: number | string, datasetVersionId: string): Promise; getPrivateUrlDataset(token: string): Promise; - getDatasetCitation(datasetId: number, datasetVersionId?: string): Promise; + getDatasetCitation(datasetId: number, datasetVersionId: string): Promise; getPrivateUrlDatasetCitation(token: string): Promise; } diff --git a/src/datasets/domain/useCases/GetDataset.ts b/src/datasets/domain/useCases/GetDataset.ts index 959c0929..8cd5d932 100644 --- a/src/datasets/domain/useCases/GetDataset.ts +++ b/src/datasets/domain/useCases/GetDataset.ts @@ -1,6 +1,7 @@ import { UseCase } from '../../../core/domain/useCases/UseCase'; import { IDatasetsRepository } from '../repositories/IDatasetsRepository'; import { Dataset } from '../models/Dataset'; +import { DatasetNotNumberedVersion } from '../models/DatasetNotNumberedVersion'; export class GetDataset implements UseCase { private datasetsRepository: IDatasetsRepository; @@ -9,7 +10,10 @@ export class GetDataset implements UseCase { this.datasetsRepository = datasetsRepository; } - async execute(datasetId: number | string, datasetVersionId?: string): Promise { + async execute( + datasetId: number | string, + datasetVersionId: string | DatasetNotNumberedVersion = DatasetNotNumberedVersion.LATEST, + ): Promise { return await this.datasetsRepository.getDataset(datasetId, datasetVersionId); } } diff --git a/src/datasets/domain/useCases/GetDatasetCitation.ts b/src/datasets/domain/useCases/GetDatasetCitation.ts index ac418df3..e919b4b5 100644 --- a/src/datasets/domain/useCases/GetDatasetCitation.ts +++ b/src/datasets/domain/useCases/GetDatasetCitation.ts @@ -1,5 +1,6 @@ import { UseCase } from '../../../core/domain/useCases/UseCase'; import { IDatasetsRepository } from '../repositories/IDatasetsRepository'; +import { DatasetNotNumberedVersion } from '../models/DatasetNotNumberedVersion'; export class GetDatasetCitation implements UseCase { private datasetsRepository: IDatasetsRepository; @@ -8,7 +9,10 @@ export class GetDatasetCitation implements UseCase { this.datasetsRepository = datasetsRepository; } - async execute(datasetId: number, datasetVersionId?: string): Promise { + async execute( + datasetId: number, + datasetVersionId: string | DatasetNotNumberedVersion = DatasetNotNumberedVersion.LATEST, + ): Promise { return await this.datasetsRepository.getDatasetCitation(datasetId, datasetVersionId); } } diff --git a/src/datasets/index.ts b/src/datasets/index.ts index dfd59277..6a23fa85 100644 --- a/src/datasets/index.ts +++ b/src/datasets/index.ts @@ -20,6 +20,7 @@ export { getDatasetCitation, getPrivateUrlDatasetCitation, }; +export { DatasetNotNumberedVersion } from './domain/models/DatasetNotNumberedVersion'; export { Dataset, DatasetVersionInfo, diff --git a/src/datasets/infra/repositories/DatasetsRepository.ts b/src/datasets/infra/repositories/DatasetsRepository.ts index f1d1dc52..32af4b12 100644 --- a/src/datasets/infra/repositories/DatasetsRepository.ts +++ b/src/datasets/infra/repositories/DatasetsRepository.ts @@ -20,10 +20,7 @@ export class DatasetsRepository extends ApiRepository implements IDatasetsReposi }); } - public async getDataset(datasetId: number | string, datasetVersionId?: string): Promise { - if (datasetVersionId === undefined) { - datasetVersionId = this.DATASET_VERSION_LATEST; - } + public async getDataset(datasetId: number | string, datasetVersionId: string): Promise { let endpoint; if (typeof datasetId === 'number') { endpoint = `/datasets/${datasetId}/versions/${datasetVersionId}`; @@ -37,10 +34,7 @@ export class DatasetsRepository extends ApiRepository implements IDatasetsReposi }); } - public async getDatasetCitation(datasetId: number, datasetVersionId?: string): Promise { - if (datasetVersionId === undefined) { - datasetVersionId = this.DATASET_VERSION_LATEST; - } + public async getDatasetCitation(datasetId: number, datasetVersionId: string): Promise { return this.doGet(`/datasets/${datasetId}/versions/${datasetVersionId}/citation`, true) .then((response) => response.data.data.message) .catch((error) => { diff --git a/src/files/domain/models/File.ts b/src/files/domain/models/File.ts index 496515fa..e5b0746f 100644 --- a/src/files/domain/models/File.ts +++ b/src/files/domain/models/File.ts @@ -7,6 +7,7 @@ export interface File { version: number; description?: string; restricted: boolean; + latestRestricted: boolean; directoryLabel?: string; datasetVersionId?: number; categories?: string[]; diff --git a/src/files/domain/models/FileCriteria.ts b/src/files/domain/models/FileCriteria.ts new file mode 100644 index 00000000..98bea349 --- /dev/null +++ b/src/files/domain/models/FileCriteria.ts @@ -0,0 +1,45 @@ +export class FileCriteria { + constructor( + public readonly orderCriteria: FileOrderCriteria = FileOrderCriteria.NAME_AZ, + public readonly contentType?: string, + public readonly accessStatus?: FileAccessStatus, + public readonly categoryName?: string, + public readonly searchText?: string, + ) {} + + withOrderCriteria(orderCriteria: FileOrderCriteria): FileCriteria { + return new FileCriteria(orderCriteria, this.contentType, this.accessStatus, this.categoryName); + } + + withContentType(contentType: string | undefined): FileCriteria { + return new FileCriteria(this.orderCriteria, contentType, this.accessStatus, this.categoryName); + } + + withAccessStatus(accessStatus: FileAccessStatus | undefined): FileCriteria { + return new FileCriteria(this.orderCriteria, this.contentType, accessStatus, this.categoryName); + } + + withCategoryName(categoryName: string | undefined): FileCriteria { + return new FileCriteria(this.orderCriteria, this.contentType, this.accessStatus, categoryName); + } + + withSearchText(searchText: string | undefined): FileCriteria { + return new FileCriteria(this.orderCriteria, this.contentType, this.accessStatus, this.categoryName, searchText); + } +} + +export enum FileOrderCriteria { + NAME_AZ = 'NameAZ', + NAME_ZA = 'NameZA', + NEWEST = 'Newest', + OLDEST = 'Oldest', + SIZE = 'Size', + TYPE = 'Type', +} + +export enum FileAccessStatus { + PUBLIC = 'Public', + RESTRICTED = 'Restricted', + EMBARGOED = 'EmbargoedThenRestricted', + EMBARGOED_RESTRICTED = 'EmbargoedThenPublic', +} diff --git a/src/files/domain/models/FileOrderCriteria.ts b/src/files/domain/models/FileOrderCriteria.ts deleted file mode 100644 index 49dc2b73..00000000 --- a/src/files/domain/models/FileOrderCriteria.ts +++ /dev/null @@ -1,8 +0,0 @@ -export enum FileOrderCriteria { - NAME_AZ = 'NameAZ', - NAME_ZA = 'NameZA', - NEWEST = 'Newest', - OLDEST = 'Oldest', - SIZE = 'Size', - TYPE = 'Type', -} diff --git a/src/files/domain/repositories/IFilesRepository.ts b/src/files/domain/repositories/IFilesRepository.ts index 9cc94591..7a6c116f 100644 --- a/src/files/domain/repositories/IFilesRepository.ts +++ b/src/files/domain/repositories/IFilesRepository.ts @@ -1,15 +1,15 @@ -import { FileOrderCriteria } from '../models/FileOrderCriteria'; import { File } from '../models/File'; import { FileDataTable } from '../models/FileDataTable'; import { FileUserPermissions } from '../models/FileUserPermissions'; +import { FileCriteria } from '../models/FileCriteria'; export interface IFilesRepository { getDatasetFiles( datasetId: number | string, - datasetVersionId?: string, + datasetVersionId: string, limit?: number, offset?: number, - orderCriteria?: FileOrderCriteria, + fileCriteria?: FileCriteria, ): Promise; getFileDownloadCount(fileId: number | string): Promise; diff --git a/src/files/domain/useCases/GetDatasetFiles.ts b/src/files/domain/useCases/GetDatasetFiles.ts index e8e62bf7..eb6d1150 100644 --- a/src/files/domain/useCases/GetDatasetFiles.ts +++ b/src/files/domain/useCases/GetDatasetFiles.ts @@ -1,7 +1,8 @@ import { UseCase } from '../../../core/domain/useCases/UseCase'; -import { FileOrderCriteria } from '../models/FileOrderCriteria'; import { IFilesRepository } from '../repositories/IFilesRepository'; import { File } from '../models/File'; +import { FileCriteria } from '../models/FileCriteria'; +import { DatasetNotNumberedVersion } from '../../../datasets'; export class GetDatasetFiles implements UseCase { private filesRepository: IFilesRepository; @@ -12,11 +13,11 @@ export class GetDatasetFiles implements UseCase { async execute( datasetId: number | string, - datasetVersionId?: string, + datasetVersionId: string | DatasetNotNumberedVersion = DatasetNotNumberedVersion.LATEST, limit?: number, offset?: number, - orderCriteria?: FileOrderCriteria, + fileCriteria?: FileCriteria, ): Promise { - return await this.filesRepository.getDatasetFiles(datasetId, datasetVersionId, limit, offset, orderCriteria); + return await this.filesRepository.getDatasetFiles(datasetId, datasetVersionId, limit, offset, fileCriteria); } } diff --git a/src/files/index.ts b/src/files/index.ts index 8dad404b..02fc8ebc 100644 --- a/src/files/index.ts +++ b/src/files/index.ts @@ -14,7 +14,8 @@ const getFileDataTables = new GetFileDataTables(filesRepository); export { getDatasetFiles, getFileDownloadCount, getFileUserPermissions, getFileDataTables }; export { File, FileEmbargo, FileChecksum } from './domain/models/File'; -export { FileOrderCriteria } from './domain/models/FileOrderCriteria'; +export { FileUserPermissions } from './domain/models/FileUserPermissions'; +export { FileCriteria, FileOrderCriteria, FileAccessStatus } from './domain/models/FileCriteria'; export { FileDataTable, FileDataVariable, diff --git a/src/files/infra/repositories/FilesRepository.ts b/src/files/infra/repositories/FilesRepository.ts index ec1231bd..44eec219 100644 --- a/src/files/infra/repositories/FilesRepository.ts +++ b/src/files/infra/repositories/FilesRepository.ts @@ -1,30 +1,31 @@ import { ApiRepository } from '../../../core/infra/repositories/ApiRepository'; import { IFilesRepository } from '../../domain/repositories/IFilesRepository'; -import { FileOrderCriteria } from '../../domain/models/FileOrderCriteria'; import { File } from '../../domain/models/File'; import { transformFilesResponseToFiles } from './transformers/fileTransformers'; import { FileDataTable } from '../../domain/models/FileDataTable'; import { transformDataTablesResponseToDataTables } from './transformers/fileDataTableTransformers'; import { FileUserPermissions } from '../../domain/models/FileUserPermissions'; import { transformFileUserPermissionsResponseToFileUserPermissions } from './transformers/fileUserPermissionsTransformers'; +import { FileCriteria } from '../../domain/models/FileCriteria'; export interface GetFilesQueryParams { limit?: number; offset?: number; orderCriteria?: string; + contentType?: string; + accessStatus?: string; + categoryName?: string; + searchText?: string; } export class FilesRepository extends ApiRepository implements IFilesRepository { public async getDatasetFiles( datasetId: number | string, - datasetVersionId?: string, + datasetVersionId: string, limit?: number, offset?: number, - orderCriteria?: FileOrderCriteria, + fileCriteria?: FileCriteria, ): Promise { - if (datasetVersionId === undefined) { - datasetVersionId = this.DATASET_VERSION_LATEST; - } let endpoint; if (typeof datasetId === 'number') { endpoint = `/datasets/${datasetId}/versions/${datasetVersionId}/files`; @@ -38,8 +39,8 @@ export class FilesRepository extends ApiRepository implements IFilesRepository { if (offset !== undefined) { queryParams.offset = offset; } - if (orderCriteria !== undefined) { - queryParams.orderCriteria = orderCriteria.toString(); + if (fileCriteria !== undefined) { + this.applyFileCriteriaToQueryParams(queryParams, fileCriteria); } return this.doGet(endpoint, true, queryParams) .then((response) => transformFilesResponseToFiles(response)) @@ -89,4 +90,22 @@ export class FilesRepository extends ApiRepository implements IFilesRepository { throw error; }); } + + private applyFileCriteriaToQueryParams(queryParams: GetFilesQueryParams, fileCriteria: FileCriteria) { + if (fileCriteria.accessStatus !== undefined) { + queryParams.accessStatus = fileCriteria.accessStatus.toString(); + } + if (fileCriteria.categoryName !== undefined) { + queryParams.categoryName = fileCriteria.categoryName; + } + if (fileCriteria.contentType !== undefined) { + queryParams.contentType = fileCriteria.contentType; + } + if (fileCriteria.searchText !== undefined) { + queryParams.searchText = fileCriteria.searchText; + } + if (fileCriteria.orderCriteria !== undefined) { + queryParams.orderCriteria = fileCriteria.orderCriteria.toString(); + } + } } diff --git a/src/files/infra/repositories/transformers/fileTransformers.ts b/src/files/infra/repositories/transformers/fileTransformers.ts index 28319592..c860e456 100644 --- a/src/files/infra/repositories/transformers/fileTransformers.ts +++ b/src/files/infra/repositories/transformers/fileTransformers.ts @@ -22,6 +22,7 @@ const transformFilePayloadToFile = (filePayload: any): File => { version: filePayload.version, ...(filePayload.dataFile.description && { description: filePayload.dataFile.description }), restricted: filePayload.restricted, + latestRestricted: filePayload.dataFile.restricted, ...(filePayload.dataFile.directoryLabel && { directoryLabel: filePayload.dataFile.directoryLabel }), ...(filePayload.dataFile.datasetVersionId && { datasetVersionId: filePayload.dataFile.datasetVersionId }), ...(filePayload.dataFile.categories && { categories: filePayload.dataFile.categories }), diff --git a/test/integration/datasets/DatasetsRepository.test.ts b/test/integration/datasets/DatasetsRepository.test.ts index 9d81bab6..dbabb10c 100644 --- a/test/integration/datasets/DatasetsRepository.test.ts +++ b/test/integration/datasets/DatasetsRepository.test.ts @@ -4,11 +4,14 @@ import { ApiConfig, DataverseApiAuthMechanism } from '../../../src/core/infra/re import { TestConstants } from '../../testHelpers/TestConstants'; import { createDatasetViaApi, createPrivateUrlViaApi } from '../../testHelpers/datasets/datasetHelper'; import { ReadError } from '../../../src/core/domain/repositories/ReadError'; +import { DatasetNotNumberedVersion } from '../../../src/datasets'; describe('DatasetsRepository', () => { const sut: DatasetsRepository = new DatasetsRepository(); const nonExistentTestDatasetId = 100; + const latestVersionId = DatasetNotNumberedVersion.LATEST; + beforeAll(async () => { ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.API_KEY, process.env.TEST_API_KEY); await createDatasetViaApi() @@ -28,19 +31,19 @@ describe('DatasetsRepository', () => { describe('getDataset', () => { describe('by numeric id', () => { - test('should return dataset when it exists filtering by id', async () => { - const actual = await sut.getDataset(TestConstants.TEST_CREATED_DATASET_ID); + test('should return dataset when it exists filtering by id and version id', async () => { + const actual = await sut.getDataset(TestConstants.TEST_CREATED_DATASET_ID, latestVersionId); expect(actual.id).toBe(TestConstants.TEST_CREATED_DATASET_ID); }); test('should return dataset when it exists filtering by id and version id', async () => { - const actual = await sut.getDataset(TestConstants.TEST_CREATED_DATASET_ID, ':draft'); + const actual = await sut.getDataset(TestConstants.TEST_CREATED_DATASET_ID, latestVersionId); expect(actual.id).toBe(TestConstants.TEST_CREATED_DATASET_ID); }); test('should return error when dataset does not exist', async () => { let error: ReadError = undefined; - await sut.getDataset(nonExistentTestDatasetId).catch((e) => (error = e)); + await sut.getDataset(nonExistentTestDatasetId, latestVersionId).catch((e) => (error = e)); assert.match( error.message, @@ -49,15 +52,15 @@ describe('DatasetsRepository', () => { }); }); describe('by persistent id', () => { - test('should return dataset when it exists filtering by persistent id', async () => { - const createdDataset = await sut.getDataset(TestConstants.TEST_CREATED_DATASET_ID); - const actual = await sut.getDataset(createdDataset.persistentId); + test('should return dataset when it exists filtering by persistent id and version id', async () => { + const createdDataset = await sut.getDataset(TestConstants.TEST_CREATED_DATASET_ID, latestVersionId); + const actual = await sut.getDataset(createdDataset.persistentId, latestVersionId); expect(actual.id).toBe(TestConstants.TEST_CREATED_DATASET_ID); }); test('should return dataset when it exists filtering by persistent id and version id', async () => { - const createdDataset = await sut.getDataset(TestConstants.TEST_CREATED_DATASET_ID); - const actual = await sut.getDataset(createdDataset.persistentId, ':draft'); + const createdDataset = await sut.getDataset(TestConstants.TEST_CREATED_DATASET_ID, latestVersionId); + const actual = await sut.getDataset(createdDataset.persistentId, latestVersionId); expect(actual.id).toBe(TestConstants.TEST_CREATED_DATASET_ID); }); @@ -65,7 +68,7 @@ describe('DatasetsRepository', () => { let error: ReadError = undefined; const testWrongPersistentId = 'wrongPersistentId'; - await sut.getDataset(testWrongPersistentId).catch((e) => (error = e)); + await sut.getDataset(testWrongPersistentId, latestVersionId).catch((e) => (error = e)); assert.match( error.message, @@ -77,14 +80,17 @@ describe('DatasetsRepository', () => { describe('getDatasetCitation', () => { test('should return citation when dataset exists', async () => { - const actualDatasetCitation = await sut.getDatasetCitation(TestConstants.TEST_CREATED_DATASET_ID); + const actualDatasetCitation = await sut.getDatasetCitation( + TestConstants.TEST_CREATED_DATASET_ID, + latestVersionId, + ); expect(typeof actualDatasetCitation).toBe('string'); }); test('should return error when dataset does not exist', async () => { let error: ReadError = undefined; - await sut.getDatasetCitation(nonExistentTestDatasetId).catch((e) => (error = e)); + await sut.getDatasetCitation(nonExistentTestDatasetId, latestVersionId).catch((e) => (error = e)); assert.match( error.message, diff --git a/test/integration/environment/.env b/test/integration/environment/.env index cb181a92..0ca2696d 100644 --- a/test/integration/environment/.env +++ b/test/integration/environment/.env @@ -2,5 +2,5 @@ POSTGRES_VERSION=13 DATAVERSE_DB_USER=dataverse SOLR_VERSION=8.11.1 DATAVERSE_IMAGE_REGISTRY=ghcr.io -DATAVERSE_IMAGE_TAG=9692-files-api-extension-display-data +DATAVERSE_IMAGE_TAG=9714-files-api-extension-filters DATAVERSE_BOOTSTRAP_TIMEOUT=5m diff --git a/test/integration/files/FilesRepository.test.ts b/test/integration/files/FilesRepository.test.ts index 263f5aa4..351dd546 100644 --- a/test/integration/files/FilesRepository.test.ts +++ b/test/integration/files/FilesRepository.test.ts @@ -4,9 +4,10 @@ import { assert } from 'sinon'; import { TestConstants } from '../../testHelpers/TestConstants'; import { createDatasetViaApi } from '../../testHelpers/datasets/datasetHelper'; import { uploadFileViaApi } from '../../testHelpers/files/filesHelper'; -import { FileOrderCriteria } from '../../../src/files/domain/models/FileOrderCriteria'; import { DatasetsRepository } from '../../../src/datasets/infra/repositories/DatasetsRepository'; import { ReadError } from '../../../src/core/domain/repositories/ReadError'; +import { FileCriteria, FileAccessStatus, FileOrderCriteria } from '../../../src/files/domain/models/FileCriteria'; +import { DatasetNotNumberedVersion } from '../../../src/datasets'; describe('FilesRepository', () => { const sut: FilesRepository = new FilesRepository(); @@ -18,6 +19,8 @@ describe('FilesRepository', () => { const nonExistentFiledId = 200; + const latestDatasetVersionId = DatasetNotNumberedVersion.LATEST; + beforeAll(async () => { ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.API_KEY, process.env.TEST_API_KEY); await createDatasetViaApi() @@ -56,9 +59,14 @@ describe('FilesRepository', () => { }); describe('getDatasetFiles', () => { + const testFileCriteria = new FileCriteria() + .withOrderCriteria(FileOrderCriteria.NEWEST) + .withContentType('text/plain') + .withAccessStatus(FileAccessStatus.PUBLIC); + describe('by numeric id', () => { - test('should return all files filtering by dataset id', async () => { - const actual = await sut.getDatasetFiles(TestConstants.TEST_CREATED_DATASET_ID); + test('should return all files filtering by dataset id and version id', async () => { + const actual = await sut.getDatasetFiles(TestConstants.TEST_CREATED_DATASET_ID, latestDatasetVersionId); assert.match(actual.length, 4); assert.match(actual[0].name, testTextFile1Name); assert.match(actual[1].name, testTextFile2Name); @@ -66,32 +74,37 @@ describe('FilesRepository', () => { assert.match(actual[3].name, testTabFile4Name); }); - test('should return correct files filtering by dataset id and paginating', async () => { - const actual = await sut.getDatasetFiles(TestConstants.TEST_CREATED_DATASET_ID, undefined, 3, 3, undefined); + test('should return correct files filtering by dataset id, version id, and paginating', async () => { + const actual = await sut.getDatasetFiles( + TestConstants.TEST_CREATED_DATASET_ID, + latestDatasetVersionId, + 3, + 3, + undefined, + ); assert.match(actual.length, 1); assert.match(actual[0].name, testTabFile4Name); }); - test('should return correct files filtering by dataset id and applying order criteria', async () => { + test('should return correct files filtering by dataset id, version id, and applying file criteria', async () => { let actual = await sut.getDatasetFiles( TestConstants.TEST_CREATED_DATASET_ID, + latestDatasetVersionId, undefined, undefined, - undefined, - FileOrderCriteria.NEWEST, + testFileCriteria, ); - assert.match(actual.length, 4); - assert.match(actual[0].name, testTabFile4Name); - assert.match(actual[1].name, testTextFile3Name); - assert.match(actual[2].name, testTextFile2Name); - assert.match(actual[3].name, testTextFile1Name); + assert.match(actual.length, 3); + assert.match(actual[0].name, testTextFile3Name); + assert.match(actual[1].name, testTextFile2Name); + assert.match(actual[2].name, testTextFile1Name); }); test('should return error when dataset does not exist', async () => { let error: ReadError = undefined; const nonExistentTestDatasetId = 100; - await sut.getDatasetFiles(nonExistentTestDatasetId).catch((e) => (error = e)); + await sut.getDatasetFiles(nonExistentTestDatasetId, latestDatasetVersionId).catch((e) => (error = e)); assert.match( error.message, @@ -103,9 +116,12 @@ describe('FilesRepository', () => { describe('by persistent id', () => { const datasetRepository = new DatasetsRepository(); - test('should return all files filtering by persistent id', async () => { - const testDataset = await datasetRepository.getDataset(TestConstants.TEST_CREATED_DATASET_ID); - const actual = await sut.getDatasetFiles(testDataset.persistentId); + test('should return all files filtering by persistent id and version id', async () => { + const testDataset = await datasetRepository.getDataset( + TestConstants.TEST_CREATED_DATASET_ID, + latestDatasetVersionId, + ); + const actual = await sut.getDatasetFiles(testDataset.persistentId, latestDatasetVersionId); assert.match(actual.length, 4); assert.match(actual[0].name, testTextFile1Name); assert.match(actual[1].name, testTextFile2Name); @@ -113,34 +129,39 @@ describe('FilesRepository', () => { assert.match(actual[3].name, testTabFile4Name); }); - test('should return correct files filtering by persistent id and paginating', async () => { - const testDataset = await datasetRepository.getDataset(TestConstants.TEST_CREATED_DATASET_ID); - const actual = await sut.getDatasetFiles(testDataset.persistentId, undefined, 3, 3, undefined); + test('should return correct files filtering by persistent id, version id, and paginating', async () => { + const testDataset = await datasetRepository.getDataset( + TestConstants.TEST_CREATED_DATASET_ID, + latestDatasetVersionId, + ); + const actual = await sut.getDatasetFiles(testDataset.persistentId, latestDatasetVersionId, 3, 3, undefined); assert.match(actual.length, 1); assert.match(actual[0].name, testTabFile4Name); }); - test('should return correct files filtering by persistent id and applying order criteria', async () => { - const testDataset = await datasetRepository.getDataset(TestConstants.TEST_CREATED_DATASET_ID); + test('should return correct files filtering by persistent id, version id, and applying file criteria', async () => { + const testDataset = await datasetRepository.getDataset( + TestConstants.TEST_CREATED_DATASET_ID, + latestDatasetVersionId, + ); let actual = await sut.getDatasetFiles( testDataset.persistentId, + latestDatasetVersionId, undefined, undefined, - undefined, - FileOrderCriteria.NEWEST, + testFileCriteria, ); - assert.match(actual.length, 4); - assert.match(actual[0].name, testTabFile4Name); - assert.match(actual[1].name, testTextFile3Name); - assert.match(actual[2].name, testTextFile2Name); - assert.match(actual[3].name, testTextFile1Name); + assert.match(actual.length, 3); + assert.match(actual[0].name, testTextFile3Name); + assert.match(actual[1].name, testTextFile2Name); + assert.match(actual[2].name, testTextFile1Name); }); test('should return error when dataset does not exist', async () => { let error: ReadError = undefined; const testWrongPersistentId = 'wrongPersistentId'; - await sut.getDatasetFiles(testWrongPersistentId).catch((e) => (error = e)); + await sut.getDatasetFiles(testWrongPersistentId, latestDatasetVersionId).catch((e) => (error = e)); assert.match( error.message, @@ -151,8 +172,8 @@ describe('FilesRepository', () => { }); describe('getFileDownloadCount', () => { - test('should return count filtering by file id', async () => { - const currentTestFiles = await sut.getDatasetFiles(TestConstants.TEST_CREATED_DATASET_ID); + test('should return count filtering by file id and version id', async () => { + const currentTestFiles = await sut.getDatasetFiles(TestConstants.TEST_CREATED_DATASET_ID, latestDatasetVersionId); const testFile = currentTestFiles[0]; const actual = await sut.getFileDownloadCount(testFile.id); assert.match(actual, 0); @@ -171,8 +192,8 @@ describe('FilesRepository', () => { }); describe('getFileUserPermissions', () => { - test('should return user permissions filtering by file id', async () => { - const currentTestFiles = await sut.getDatasetFiles(TestConstants.TEST_CREATED_DATASET_ID); + test('should return user permissions filtering by file id and version id', async () => { + const currentTestFiles = await sut.getDatasetFiles(TestConstants.TEST_CREATED_DATASET_ID, latestDatasetVersionId); const testFile = currentTestFiles[0]; const actual = await sut.getFileUserPermissions(testFile.id); assert.match(actual.canDownloadFile, true); @@ -192,15 +213,15 @@ describe('FilesRepository', () => { }); describe('getFileDataTables', () => { - test('should return data tables filtering by tabular file id', async () => { - const currentTestFiles = await sut.getDatasetFiles(TestConstants.TEST_CREATED_DATASET_ID); + test('should return data tables filtering by tabular file id and version id', async () => { + const currentTestFiles = await sut.getDatasetFiles(TestConstants.TEST_CREATED_DATASET_ID, latestDatasetVersionId); const testFile = currentTestFiles[3]; const actual = await sut.getFileDataTables(testFile.id); assert.match(actual[0].varQuantity, 3); }); - test('should return error when file is not tabular', async () => { - const currentTestFiles = await sut.getDatasetFiles(TestConstants.TEST_CREATED_DATASET_ID); + test('should return error when file is not tabular and version id', async () => { + const currentTestFiles = await sut.getDatasetFiles(TestConstants.TEST_CREATED_DATASET_ID, latestDatasetVersionId); const testFile = currentTestFiles[0]; let error: ReadError = undefined; diff --git a/test/testHelpers/files/filesHelper.ts b/test/testHelpers/files/filesHelper.ts index 97dab816..d67afdbd 100644 --- a/test/testHelpers/files/filesHelper.ts +++ b/test/testHelpers/files/filesHelper.ts @@ -11,6 +11,7 @@ export const createFileModel = (): File => { sizeBytes: 127426, version: 1, restricted: false, + latestRestricted: false, contentType: 'image/png', storageIdentifier: 'local://18945a85439-9fa52783e5cb', rootDataFileId: 4, @@ -42,6 +43,7 @@ export const createFilePayload = (): any => { contentType: 'image/png', filesize: 127426, storageIdentifier: 'local://18945a85439-9fa52783e5cb', + restricted: false, rootDataFileId: 4, previousDataFileId: 4, md5: '29e413e0c881e17314ce8116fed4d1a7', diff --git a/test/unit/datasets/DatasetsRepository.test.ts b/test/unit/datasets/DatasetsRepository.test.ts index ca7004cf..b9dbdc54 100644 --- a/test/unit/datasets/DatasetsRepository.test.ts +++ b/test/unit/datasets/DatasetsRepository.test.ts @@ -10,6 +10,7 @@ import { createDatasetLicenseModel, } from '../../testHelpers/datasets/datasetHelper'; import { TestConstants } from '../../testHelpers/TestConstants'; +import { DatasetNotNumberedVersion } from '../../../src/datasets'; describe('DatasetsRepository', () => { const sandbox: SinonSandbox = createSandbox(); @@ -31,6 +32,7 @@ describe('DatasetsRepository', () => { }; const testPrivateUrlToken = 'testToken'; const testDatasetModel = createDatasetModel(); + const testVersionId = DatasetNotNumberedVersion.LATEST; beforeEach(() => { ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.API_KEY, TestConstants.TEST_DUMMY_API_KEY); @@ -78,12 +80,12 @@ describe('DatasetsRepository', () => { describe('getDataset', () => { describe('by numeric id', () => { - test('should return Dataset when providing id, no version, and response is successful', async () => { + test('should return Dataset when providing id, version id, and response is successful', async () => { const axiosGetStub = sandbox.stub(axios, 'get').resolves(testDatasetVersionSuccessfulResponse); - const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/datasets/${testDatasetModel.id}/versions/:latest`; + const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/datasets/${testDatasetModel.id}/versions/${testVersionId}`; // API Key auth - let actual = await sut.getDataset(testDatasetModel.id); + let actual = await sut.getDataset(testDatasetModel.id, testVersionId); assert.calledWithExactly( axiosGetStub, @@ -94,7 +96,7 @@ describe('DatasetsRepository', () => { // Session cookie auth ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.SESSION_COOKIE); - actual = await sut.getDataset(testDatasetModel.id); + actual = await sut.getDataset(testDatasetModel.id, testVersionId); assert.calledWithExactly( axiosGetStub, expectedApiEndpoint, @@ -103,20 +105,7 @@ describe('DatasetsRepository', () => { assert.match(actual, testDatasetModel); }); - test('should return Dataset when providing id, version, and response is successful', async () => { - const axiosGetStub = sandbox.stub(axios, 'get').resolves(testDatasetVersionSuccessfulResponse); - - const actual = await sut.getDataset(testDatasetModel.id, String(testDatasetModel.versionId)); - - assert.calledWithExactly( - axiosGetStub, - `${TestConstants.TEST_API_URL}/datasets/${testDatasetModel.id}/versions/${testDatasetModel.versionId}`, - TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, - ); - assert.match(actual, testDatasetModel); - }); - - test('should return Dataset when providing id, version, and response with license is successful', async () => { + test('should return Dataset when providing id, version id, and response with license is successful', async () => { const testDatasetLicense = createDatasetLicenseModel(); const testDatasetVersionWithLicenseSuccessfulResponse = { data: { @@ -126,17 +115,17 @@ describe('DatasetsRepository', () => { }; const axiosGetStub = sandbox.stub(axios, 'get').resolves(testDatasetVersionWithLicenseSuccessfulResponse); - const actual = await sut.getDataset(testDatasetModel.id, String(testDatasetModel.versionId)); + const actual = await sut.getDataset(testDatasetModel.id, testVersionId); assert.calledWithExactly( axiosGetStub, - `${TestConstants.TEST_API_URL}/datasets/${testDatasetModel.id}/versions/${testDatasetModel.versionId}`, + `${TestConstants.TEST_API_URL}/datasets/${testDatasetModel.id}/versions/${testVersionId}`, TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, ); assert.match(actual, createDatasetModel(testDatasetLicense)); }); - test('should return Dataset when providing id, version, and response with license without icon URI is successful', async () => { + test('should return Dataset when providing id, version id, and response with license without icon URI is successful', async () => { const testDatasetLicenseWithoutIconUri = createDatasetLicenseModel(false); const testDatasetVersionWithLicenseSuccessfulResponse = { data: { @@ -146,11 +135,11 @@ describe('DatasetsRepository', () => { }; const axiosGetStub = sandbox.stub(axios, 'get').resolves(testDatasetVersionWithLicenseSuccessfulResponse); - const actual = await sut.getDataset(testDatasetModel.id, String(testDatasetModel.versionId)); + const actual = await sut.getDataset(testDatasetModel.id, testVersionId); assert.calledWithExactly( axiosGetStub, - `${TestConstants.TEST_API_URL}/datasets/${testDatasetModel.id}/versions/${testDatasetModel.versionId}`, + `${TestConstants.TEST_API_URL}/datasets/${testDatasetModel.id}/versions/${testVersionId}`, TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, ); assert.match(actual, createDatasetModel(testDatasetLicenseWithoutIconUri)); @@ -160,23 +149,23 @@ describe('DatasetsRepository', () => { const axiosGetStub = sandbox.stub(axios, 'get').rejects(TestConstants.TEST_ERROR_RESPONSE); let error: ReadError = undefined; - await sut.getDataset(testDatasetModel.id).catch((e) => (error = e)); + await sut.getDataset(testDatasetModel.id, testVersionId).catch((e) => (error = e)); assert.calledWithExactly( axiosGetStub, - `${TestConstants.TEST_API_URL}/datasets/${testDatasetModel.id}/versions/:latest`, + `${TestConstants.TEST_API_URL}/datasets/${testDatasetModel.id}/versions/${testVersionId}`, TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, ); expect(error).to.be.instanceOf(Error); }); }); describe('by persistent id', () => { - test('should return Dataset when providing persistent id, no version, and response is successful', async () => { + test('should return Dataset when providing persistent id, version id, and response is successful', async () => { const axiosGetStub = sandbox.stub(axios, 'get').resolves(testDatasetVersionSuccessfulResponse); - const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/datasets/:persistentId/versions/:latest?persistentId=${testDatasetModel.persistentId}`; + const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/datasets/:persistentId/versions/${testVersionId}?persistentId=${testDatasetModel.persistentId}`; // API Key auth - let actual = await sut.getDataset(testDatasetModel.persistentId); + let actual = await sut.getDataset(testDatasetModel.persistentId, testVersionId); assert.calledWithExactly( axiosGetStub, @@ -188,7 +177,7 @@ describe('DatasetsRepository', () => { // Session cookie auth ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.SESSION_COOKIE); - actual = await sut.getDataset(testDatasetModel.persistentId); + actual = await sut.getDataset(testDatasetModel.persistentId, testVersionId); assert.calledWithExactly( axiosGetStub, @@ -198,28 +187,15 @@ describe('DatasetsRepository', () => { assert.match(actual, testDatasetModel); }); - test('should return Dataset when providing persistent id, version, and response is successful', async () => { - const axiosGetStub = sandbox.stub(axios, 'get').resolves(testDatasetVersionSuccessfulResponse); - - const actual = await sut.getDataset(testDatasetModel.persistentId, String(testDatasetModel.versionId)); - - assert.calledWithExactly( - axiosGetStub, - `${TestConstants.TEST_API_URL}/datasets/:persistentId/versions/${testDatasetModel.versionId}?persistentId=${testDatasetModel.persistentId}`, - TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, - ); - assert.match(actual, testDatasetModel); - }); - test('should return error on repository read error', async () => { const axiosGetStub = sandbox.stub(axios, 'get').rejects(TestConstants.TEST_ERROR_RESPONSE); let error: ReadError = undefined; - await sut.getDataset(testDatasetModel.persistentId).catch((e) => (error = e)); + await sut.getDataset(testDatasetModel.persistentId, testVersionId).catch((e) => (error = e)); assert.calledWithExactly( axiosGetStub, - `${TestConstants.TEST_API_URL}/datasets/:persistentId/versions/:latest?persistentId=${testDatasetModel.persistentId}`, + `${TestConstants.TEST_API_URL}/datasets/:persistentId/versions/${testVersionId}?persistentId=${testDatasetModel.persistentId}`, TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, ); expect(error).to.be.instanceOf(Error); @@ -259,10 +235,10 @@ describe('DatasetsRepository', () => { describe('getDatasetCitation', () => { test('should return citation when response is successful', async () => { const axiosGetStub = sandbox.stub(axios, 'get').resolves(testCitationSuccessfulResponse); - const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/datasets/${testDatasetModel.id}/versions/:latest/citation`; + const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/datasets/${testDatasetModel.id}/versions/${testVersionId}/citation`; // API Key auth - let actual = await sut.getDatasetCitation(testDatasetModel.id, undefined); + let actual = await sut.getDatasetCitation(testDatasetModel.id, testVersionId); assert.calledWithExactly( axiosGetStub, @@ -274,7 +250,7 @@ describe('DatasetsRepository', () => { // Session cookie auth ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.SESSION_COOKIE); - actual = await sut.getDatasetCitation(testDatasetModel.id, undefined); + actual = await sut.getDatasetCitation(testDatasetModel.id, testVersionId); assert.calledWithExactly( axiosGetStub, @@ -288,11 +264,11 @@ describe('DatasetsRepository', () => { const axiosGetStub = sandbox.stub(axios, 'get').rejects(TestConstants.TEST_ERROR_RESPONSE); let error: ReadError = undefined; - await sut.getDatasetCitation(1, undefined).catch((e) => (error = e)); + await sut.getDatasetCitation(1, testVersionId).catch((e) => (error = e)); assert.calledWithExactly( axiosGetStub, - `${TestConstants.TEST_API_URL}/datasets/${testDatasetModel.id}/versions/:latest/citation`, + `${TestConstants.TEST_API_URL}/datasets/${testDatasetModel.id}/versions/${testVersionId}/citation`, TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, ); expect(error).to.be.instanceOf(Error); diff --git a/test/unit/datasets/GetDataset.test.ts b/test/unit/datasets/GetDataset.test.ts index 9e11aa45..bfa9b1ef 100644 --- a/test/unit/datasets/GetDataset.test.ts +++ b/test/unit/datasets/GetDataset.test.ts @@ -3,6 +3,7 @@ import { IDatasetsRepository } from '../../../src/datasets/domain/repositories/I import { assert, createSandbox, SinonSandbox } from 'sinon'; import { createDatasetModel } from '../../testHelpers/datasets/datasetHelper'; import { ReadError } from '../../../src/core/domain/repositories/ReadError'; +import { DatasetNotNumberedVersion } from '../../../src/datasets/domain/models/DatasetNotNumberedVersion'; describe('execute', () => { const sandbox: SinonSandbox = createSandbox(); @@ -21,7 +22,7 @@ describe('execute', () => { const actual = await sut.execute(1); assert.match(actual, testDataset); - assert.calledWithExactly(getDatasetStub, 1, undefined); + assert.calledWithExactly(getDatasetStub, 1, DatasetNotNumberedVersion.LATEST); }); test('should return error result on repository error', async () => { diff --git a/test/unit/datasets/GetDatasetCitation.test.ts b/test/unit/datasets/GetDatasetCitation.test.ts index 141fb3af..3c48f009 100644 --- a/test/unit/datasets/GetDatasetCitation.test.ts +++ b/test/unit/datasets/GetDatasetCitation.test.ts @@ -2,6 +2,7 @@ import { GetDatasetCitation } from '../../../src/datasets/domain/useCases/GetDat import { IDatasetsRepository } from '../../../src/datasets/domain/repositories/IDatasetsRepository'; import { ReadError } from '../../../src/core/domain/repositories/ReadError'; import { assert, createSandbox, SinonSandbox } from 'sinon'; +import { DatasetNotNumberedVersion } from '../../../src/datasets/domain/models/DatasetNotNumberedVersion'; describe('execute', () => { const sandbox: SinonSandbox = createSandbox(); @@ -22,7 +23,7 @@ describe('execute', () => { const actual = await sut.execute(testId); assert.match(actual, testCitation); - assert.calledWithExactly(getDatasetCitationStub, testId, undefined); + assert.calledWithExactly(getDatasetCitationStub, testId, DatasetNotNumberedVersion.LATEST); }); test('should return error result on repository error', async () => { diff --git a/test/unit/files/FilesRepository.test.ts b/test/unit/files/FilesRepository.test.ts index d6cecfa8..6c1b132b 100644 --- a/test/unit/files/FilesRepository.test.ts +++ b/test/unit/files/FilesRepository.test.ts @@ -5,10 +5,11 @@ import { expect } from 'chai'; import { ReadError } from '../../../src/core/domain/repositories/ReadError'; import { ApiConfig, DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig'; import { TestConstants } from '../../testHelpers/TestConstants'; -import { FileOrderCriteria } from '../../../src/files/domain/models/FileOrderCriteria'; import { createFilePayload, createFileModel } from '../../testHelpers/files/filesHelper'; import { createFileDataTablePayload, createFileDataTableModel } from '../../testHelpers/files/fileDataTablesHelper'; import { createFileUserPermissionsModel } from '../../testHelpers/files/fileUserPermissionsHelper'; +import { FileCriteria, FileAccessStatus, FileOrderCriteria } from '../../../src/files/domain/models/FileCriteria'; +import { DatasetNotNumberedVersion } from '../../../src/datasets'; describe('FilesRepository', () => { const sandbox: SinonSandbox = createSandbox(); @@ -30,17 +31,37 @@ describe('FilesRepository', () => { }); describe('getDatasetFiles', () => { - describe('by numeric id', () => { + const testDatasetVersionId = DatasetNotNumberedVersion.LATEST; + const testLimit = 10; + const testOffset = 20; + const testCategory = 'testCategory'; + const testContentType = 'testContentType'; + const testFileCriteria = new FileCriteria() + .withOrderCriteria(FileOrderCriteria.NAME_ZA) + .withCategoryName(testCategory) + .withContentType(testContentType) + .withAccessStatus(FileAccessStatus.PUBLIC); + + const expectedRequestParams = { + limit: testLimit, + offset: testOffset, + orderCriteria: testFileCriteria.orderCriteria.toString(), + categoryName: testFileCriteria.categoryName, + contentType: testFileCriteria.contentType, + accessStatus: testFileCriteria.accessStatus.toString(), + }; + + describe('by numeric id and version id', () => { const testDatasetId = 1; - test('should return files on successful response', async () => { + test('should return files when providing id, version id, and response is successful', async () => { const axiosGetStub = sandbox.stub(axios, 'get').resolves(testFilesSuccessfulResponse); - const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/datasets/${testDatasetId}/versions/:latest/files`; + const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/datasets/${testDatasetId}/versions/${testDatasetVersionId}/files`; const expectedFiles = [testFile]; // API Key auth - let actual = await sut.getDatasetFiles(testDatasetId); + let actual = await sut.getDatasetFiles(testDatasetId, testDatasetVersionId); assert.calledWithExactly( axiosGetStub, @@ -52,7 +73,7 @@ describe('FilesRepository', () => { // Session cookie auth ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.SESSION_COOKIE); - actual = await sut.getDatasetFiles(testDatasetId); + actual = await sut.getDatasetFiles(testDatasetId, testDatasetVersionId); assert.calledWithExactly( axiosGetStub, @@ -62,34 +83,19 @@ describe('FilesRepository', () => { assert.match(actual, expectedFiles); }); - test('should return files when providing id, optional params, and response is successful', async () => { + test('should return files when providing id, version id, optional params, and response is successful', async () => { const axiosGetStub = sandbox.stub(axios, 'get').resolves(testFilesSuccessfulResponse); - const testVersionId = ':draft'; - const testLimit = 10; - const testOffset = 20; - const testFileOrderCriteria = FileOrderCriteria.NEWEST; - - const actual = await sut.getDatasetFiles( - testDatasetId, - testVersionId, - testLimit, - testOffset, - testFileOrderCriteria, - ); + const actual = await sut.getDatasetFiles(testDatasetId, testDatasetVersionId, testLimit, testOffset, testFileCriteria); const expectedRequestConfig = { - params: { - limit: testLimit, - offset: testOffset, - orderCriteria: testFileOrderCriteria.toString(), - }, + params: expectedRequestParams, headers: TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY.headers, }; assert.calledWithExactly( axiosGetStub, - `${TestConstants.TEST_API_URL}/datasets/${testDatasetId}/versions/${testVersionId}/files`, + `${TestConstants.TEST_API_URL}/datasets/${testDatasetId}/versions/${testDatasetVersionId}/files`, expectedRequestConfig, ); assert.match(actual, [testFile]); @@ -99,11 +105,11 @@ describe('FilesRepository', () => { const axiosGetStub = sandbox.stub(axios, 'get').rejects(TestConstants.TEST_ERROR_RESPONSE); let error: ReadError = undefined; - await sut.getDatasetFiles(testDatasetId).catch((e) => (error = e)); + await sut.getDatasetFiles(testDatasetId, testDatasetVersionId).catch((e) => (error = e)); assert.calledWithExactly( axiosGetStub, - `${TestConstants.TEST_API_URL}/datasets/${testDatasetId}/versions/:latest/files`, + `${TestConstants.TEST_API_URL}/datasets/${testDatasetId}/versions/${testDatasetVersionId}/files`, TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, ); expect(error).to.be.instanceOf(Error); @@ -111,13 +117,13 @@ describe('FilesRepository', () => { }); describe('by persistent id', () => { - test('should return files on successful response', async () => { + test('should return files when providing persistent id, version id, and response is successful', async () => { const axiosGetStub = sandbox.stub(axios, 'get').resolves(testFilesSuccessfulResponse); - const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/datasets/:persistentId/versions/:latest/files?persistentId=${TestConstants.TEST_DUMMY_PERSISTENT_ID}`; + const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/datasets/:persistentId/versions/${testDatasetVersionId}/files?persistentId=${TestConstants.TEST_DUMMY_PERSISTENT_ID}`; const expectedFiles = [testFile]; // API Key auth - let actual = await sut.getDatasetFiles(TestConstants.TEST_DUMMY_PERSISTENT_ID); + let actual = await sut.getDatasetFiles(TestConstants.TEST_DUMMY_PERSISTENT_ID, testDatasetVersionId); assert.calledWithExactly( axiosGetStub, @@ -129,7 +135,7 @@ describe('FilesRepository', () => { // Session cookie auth ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.SESSION_COOKIE); - actual = await sut.getDatasetFiles(TestConstants.TEST_DUMMY_PERSISTENT_ID); + actual = await sut.getDatasetFiles(TestConstants.TEST_DUMMY_PERSISTENT_ID, testDatasetVersionId); assert.calledWithExactly( axiosGetStub, @@ -142,31 +148,22 @@ describe('FilesRepository', () => { test('should return files when providing persistent id, optional params, and response is successful', async () => { const axiosGetStub = sandbox.stub(axios, 'get').resolves(testFilesSuccessfulResponse); - const testVersionId = ':draft'; - const testLimit = 10; - const testOffset = 20; - const testFileOrderCriteria = FileOrderCriteria.NEWEST; - const actual = await sut.getDatasetFiles( TestConstants.TEST_DUMMY_PERSISTENT_ID, - testVersionId, + testDatasetVersionId, testLimit, testOffset, - testFileOrderCriteria, + testFileCriteria, ); const expectedRequestConfig = { - params: { - limit: testLimit, - offset: testOffset, - orderCriteria: testFileOrderCriteria.toString(), - }, + params: expectedRequestParams, headers: TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY.headers, }; assert.calledWithExactly( axiosGetStub, - `${TestConstants.TEST_API_URL}/datasets/:persistentId/versions/${testVersionId}/files?persistentId=${TestConstants.TEST_DUMMY_PERSISTENT_ID}`, + `${TestConstants.TEST_API_URL}/datasets/:persistentId/versions/${testDatasetVersionId}/files?persistentId=${TestConstants.TEST_DUMMY_PERSISTENT_ID}`, expectedRequestConfig, ); assert.match(actual, [testFile]); @@ -176,11 +173,11 @@ describe('FilesRepository', () => { const axiosGetStub = sandbox.stub(axios, 'get').rejects(TestConstants.TEST_ERROR_RESPONSE); let error: ReadError = undefined; - await sut.getDatasetFiles(TestConstants.TEST_DUMMY_PERSISTENT_ID).catch((e) => (error = e)); + await sut.getDatasetFiles(TestConstants.TEST_DUMMY_PERSISTENT_ID, testDatasetVersionId).catch((e) => (error = e)); assert.calledWithExactly( axiosGetStub, - `${TestConstants.TEST_API_URL}/datasets/:persistentId/versions/:latest/files?persistentId=${TestConstants.TEST_DUMMY_PERSISTENT_ID}`, + `${TestConstants.TEST_API_URL}/datasets/:persistentId/versions/${testDatasetVersionId}/files?persistentId=${TestConstants.TEST_DUMMY_PERSISTENT_ID}`, TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, ); expect(error).to.be.instanceOf(Error); diff --git a/test/unit/files/GetDatasetFiles.test.ts b/test/unit/files/GetDatasetFiles.test.ts index 94b449f1..98494bea 100644 --- a/test/unit/files/GetDatasetFiles.test.ts +++ b/test/unit/files/GetDatasetFiles.test.ts @@ -4,6 +4,7 @@ import { assert, createSandbox, SinonSandbox } from 'sinon'; import { ReadError } from '../../../src/core/domain/repositories/ReadError'; import { File } from '../../../src/files/domain/models/File'; import { createFileModel } from '../../testHelpers/files/filesHelper'; +import { DatasetNotNumberedVersion } from '../../../src/datasets'; describe('execute', () => { const sandbox: SinonSandbox = createSandbox(); @@ -22,7 +23,7 @@ describe('execute', () => { const actual = await sut.execute(1); assert.match(actual, testFiles); - assert.calledWithExactly(getDatasetFilesStub, 1, undefined, undefined, undefined, undefined); + assert.calledWithExactly(getDatasetFilesStub, 1, DatasetNotNumberedVersion.LATEST, undefined, undefined, undefined); }); test('should return error result on repository error', async () => {