From 727d06f82bdaf6c3e31a31410779f57619da2bb9 Mon Sep 17 00:00:00 2001 From: MellyGray Date: Tue, 6 Feb 2024 16:34:02 +0100 Subject: [PATCH 1/5] feat(GetFileCitation): add use case --- .../domain/repositories/IFilesRepository.ts | 1 + src/files/domain/useCases/GetFileCitation.ts | 19 +++++++++ src/files/index.ts | 3 ++ .../infra/repositories/FilesRepository.ts | 10 +++++ test/unit/files/GetFileCitation.test.ts | 39 +++++++++++++++++++ 5 files changed, 72 insertions(+) create mode 100644 src/files/domain/useCases/GetFileCitation.ts create mode 100644 test/unit/files/GetFileCitation.test.ts diff --git a/src/files/domain/repositories/IFilesRepository.ts b/src/files/domain/repositories/IFilesRepository.ts index fc9b6dda..efd38b2d 100644 --- a/src/files/domain/repositories/IFilesRepository.ts +++ b/src/files/domain/repositories/IFilesRepository.ts @@ -39,4 +39,5 @@ export interface IFilesRepository { getFileDataTables(fileId: number | string): Promise; getFile(fileId: number | string, datasetVersionId: string): Promise; + getFileCitation(fileId: number | string, datasetVersionId: string, includeDeaccessioned: boolean): Promise; } diff --git a/src/files/domain/useCases/GetFileCitation.ts b/src/files/domain/useCases/GetFileCitation.ts new file mode 100644 index 00000000..2daccc1d --- /dev/null +++ b/src/files/domain/useCases/GetFileCitation.ts @@ -0,0 +1,19 @@ +import { UseCase } from '../../../core/domain/useCases/UseCase'; +import { IFilesRepository } from '../repositories/IFilesRepository'; +import { DatasetNotNumberedVersion } from '../../../datasets'; + +export class GetFileCitation implements UseCase { + private filesRepository: IFilesRepository; + + constructor(filesRepository: IFilesRepository) { + this.filesRepository = filesRepository; + } + + async execute( + fileId: number, + datasetVersionId: string | DatasetNotNumberedVersion = DatasetNotNumberedVersion.LATEST, + includeDeaccessioned = false, + ): Promise { + return await this.filesRepository.getFileCitation(fileId, datasetVersionId, includeDeaccessioned); + } +} diff --git a/src/files/index.ts b/src/files/index.ts index 45b8f270..c50c3785 100644 --- a/src/files/index.ts +++ b/src/files/index.ts @@ -6,6 +6,7 @@ import { GetFileUserPermissions } from './domain/useCases/GetFileUserPermissions import { GetFileDataTables } from './domain/useCases/GetFileDataTables'; import { GetDatasetFilesTotalDownloadSize } from './domain/useCases/GetDatasetFilesTotalDownloadSize'; import { GetFile } from './domain/useCases/GetFile'; +import { GetFileCitation } from './domain/useCases/GetFileCitation'; const filesRepository = new FilesRepository(); @@ -16,6 +17,7 @@ const getFileUserPermissions = new GetFileUserPermissions(filesRepository); const getFileDataTables = new GetFileDataTables(filesRepository); const getDatasetFilesTotalDownloadSize = new GetDatasetFilesTotalDownloadSize(filesRepository); const getFile = new GetFile(filesRepository); +const getFileCitation = new GetFileCitation(filesRepository); export { getDatasetFiles, @@ -25,6 +27,7 @@ export { getDatasetFileCounts, getDatasetFilesTotalDownloadSize, getFile, + getFileCitation, }; export { File, FileEmbargo, FileChecksum } from './domain/models/File'; diff --git a/src/files/infra/repositories/FilesRepository.ts b/src/files/infra/repositories/FilesRepository.ts index dff4031b..aed27b73 100644 --- a/src/files/infra/repositories/FilesRepository.ts +++ b/src/files/infra/repositories/FilesRepository.ts @@ -153,6 +153,16 @@ export class FilesRepository extends ApiRepository implements IFilesRepository { }); } + public async getFileCitation( + fileId: number | string, + datasetVersionId: string, + includeDeaccessioned: boolean, + ): Promise { + return Promise.resolve( + `Requesting a file citation is not yet supported. ${fileId} ${datasetVersionId} ${includeDeaccessioned}`, + ); + } + private getFileEndpoint(fileId: number | string, datasetVersionId: string): string { if (datasetVersionId === DatasetNotNumberedVersion.DRAFT) { return this.buildApiEndpoint(this.filesResourceName, 'draft', fileId); diff --git a/test/unit/files/GetFileCitation.test.ts b/test/unit/files/GetFileCitation.test.ts new file mode 100644 index 00000000..ac40b547 --- /dev/null +++ b/test/unit/files/GetFileCitation.test.ts @@ -0,0 +1,39 @@ +import {assert, createSandbox, SinonSandbox} from "sinon"; +import {DatasetNotNumberedVersion, ReadError} from "../../../src"; +import {IFilesRepository} from "../../../src/files/domain/repositories/IFilesRepository"; +import {GetFileCitation} from "../../../src/files/domain/useCases/GetFileCitation"; + +describe('execute', () => { + const sandbox: SinonSandbox = createSandbox(); + const testId = 1; + + afterEach(() => { + sandbox.restore(); + }); + + test('should return successful result with file citation on repository success', async () => { + const testCitation = 'test citation'; + const filesRepositoryStub = {}; + const getFileCitation = sandbox.stub().returns(testCitation); + filesRepositoryStub.getFileCitation = getFileCitation; + + const sut = new GetFileCitation(filesRepositoryStub); + + const actual = await sut.execute(testId); + + assert.match(actual, testCitation); + assert.calledWithExactly(getFileCitation, testId, DatasetNotNumberedVersion.LATEST, false); + }); + + test('should return error result on repository error', async () => { + const filesRepositoryStub = {}; + const testReadError = new ReadError(); + filesRepositoryStub.getFileCitation = sandbox.stub().throwsException(testReadError); + const sut = new GetFileCitation(filesRepositoryStub); + + let actualError: ReadError = undefined; + await sut.execute(testId).catch((e) => (actualError = e)); + + assert.match(actualError, testReadError); + }); +}) \ No newline at end of file From 32291ed9024c32fb59137e74f104cf662709da44 Mon Sep 17 00:00:00 2001 From: MellyGray Date: Wed, 7 Feb 2024 12:28:40 +0100 Subject: [PATCH 2/5] feat(GetFileCitation): add integration with Dataverse API --- .../infra/repositories/FilesRepository.ts | 12 +++-- .../datasets/DatasetsRepository.test.ts | 7 +-- test/integration/environment/.env | 4 +- .../integration/files/FilesRepository.test.ts | 48 +++++++++++++++++ test/unit/files/FilesRepository.test.ts | 53 +++++++++++++++++++ 5 files changed, 113 insertions(+), 11 deletions(-) diff --git a/src/files/infra/repositories/FilesRepository.ts b/src/files/infra/repositories/FilesRepository.ts index aed27b73..25a54296 100644 --- a/src/files/infra/repositories/FilesRepository.ts +++ b/src/files/infra/repositories/FilesRepository.ts @@ -158,9 +158,15 @@ export class FilesRepository extends ApiRepository implements IFilesRepository { datasetVersionId: string, includeDeaccessioned: boolean, ): Promise { - return Promise.resolve( - `Requesting a file citation is not yet supported. ${fileId} ${datasetVersionId} ${includeDeaccessioned}`, - ); + return this.doGet( + this.buildApiEndpoint(this.filesResourceName, `versions/${datasetVersionId}/citation`, fileId), + true, + { includeDeaccessioned: includeDeaccessioned }, + ) + .then((response) => response.data.data.message) + .catch((error) => { + throw error; + }); } private getFileEndpoint(fileId: number | string, datasetVersionId: string): string { diff --git a/test/integration/datasets/DatasetsRepository.test.ts b/test/integration/datasets/DatasetsRepository.test.ts index 3ce4fe82..ff14e769 100644 --- a/test/integration/datasets/DatasetsRepository.test.ts +++ b/test/integration/datasets/DatasetsRepository.test.ts @@ -81,11 +81,6 @@ describe('DatasetsRepository', () => { expect(actual.id).toBe(TestConstants.TEST_CREATED_DATASET_1_ID); }); - test('should return dataset when it exists filtering by id and version id', async () => { - const actual = await sut.getDataset(TestConstants.TEST_CREATED_DATASET_1_ID, latestVersionId, false); - expect(actual.id).toBe(TestConstants.TEST_CREATED_DATASET_1_ID); - }); - test('should return dataset when it is deaccessioned and includeDeaccessioned param is set', async () => { await publishDatasetViaApi(TestConstants.TEST_CREATED_DATASET_2_ID) .then() @@ -238,7 +233,7 @@ describe('DatasetsRepository', () => { assert.match(actual.length, 1); assert.match(actual[0].lockType, DatasetLockType.FINALIZE_PUBLICATION); assert.match(actual[0].userId, 'dataverseAdmin'); - assert.match(actual[0].message, 'Publishing the dataset; Validating Datafiles Asynchronously'); + assert.match(actual[0].message, 'Publishing the dataset; Registering PIDs for Datafiles; Validating Datafiles Asynchronously'); }); test('should return error when dataset does not exist', async () => { diff --git a/test/integration/environment/.env b/test/integration/environment/.env index 80e9a14e..fd0e469f 100644 --- a/test/integration/environment/.env +++ b/test/integration/environment/.env @@ -1,6 +1,6 @@ POSTGRES_VERSION=13 DATAVERSE_DB_USER=dataverse SOLR_VERSION=9.3.0 -DATAVERSE_IMAGE_REGISTRY=docker.io -DATAVERSE_IMAGE_TAG=unstable +DATAVERSE_IMAGE_REGISTRY=ghcr.io +DATAVERSE_IMAGE_TAG=10240-file-citation DATAVERSE_BOOTSTRAP_TIMEOUT=5m diff --git a/test/integration/files/FilesRepository.test.ts b/test/integration/files/FilesRepository.test.ts index e0d9897c..7241f163 100644 --- a/test/integration/files/FilesRepository.test.ts +++ b/test/integration/files/FilesRepository.test.ts @@ -11,6 +11,7 @@ import { DatasetNotNumberedVersion } from '../../../src/datasets'; import { FileCounts } from '../../../src/files/domain/models/FileCounts'; import { FileDownloadSizeMode } from '../../../src'; import { fail } from 'assert'; +import {deaccessionDatasetViaApi, publishDatasetViaApi, waitForNoLocks} from "../../testHelpers/datasets/datasetHelper"; describe('FilesRepository', () => { const sut: FilesRepository = new FilesRepository(); @@ -519,4 +520,51 @@ describe('FilesRepository', () => { }); }); }); + describe('getFileCitation', () => { + test('should return citation when file exists', async () => { + const actualFileCitation = await sut.getFileCitation( + testFileId, + DatasetNotNumberedVersion.LATEST, + false, + ); + expect(typeof actualFileCitation).to.be.a('string'); + }); + + test('should return citation when dataset is deaccessioned', async () => { + await publishDatasetViaApi(TestConstants.TEST_CREATED_DATASET_1_ID) + .then() + .catch(() => { + assert.fail('Error while publishing test Dataset'); + }); + + await waitForNoLocks(TestConstants.TEST_CREATED_DATASET_1_ID, 10) + .then() + .catch(() => { + assert.fail('Error while waiting for no locks'); + }); + + await deaccessionDatasetViaApi(TestConstants.TEST_CREATED_DATASET_1_ID, '1.0') + .then() + .catch(() => { + assert.fail('Error while deaccessioning test Dataset'); + }); + + const actualFileCitation = await sut.getFileCitation( + testFileId, + DatasetNotNumberedVersion.LATEST, + true, + ); + expect(typeof actualFileCitation).to.be.a('string'); + }); + + test('should return error when file does not exist', async () => { + let error: ReadError = undefined; + await sut.getFileCitation(nonExistentFiledId, DatasetNotNumberedVersion.LATEST, false).catch((e) => (error = e)); + + assert.match( + error.message, + `There was an error when reading the resource. Reason was: [404] File with ID ${nonExistentFiledId} not found.`, + ); + }); + }); }); diff --git a/test/unit/files/FilesRepository.test.ts b/test/unit/files/FilesRepository.test.ts index 4348d1d6..38cd4d92 100644 --- a/test/unit/files/FilesRepository.test.ts +++ b/test/unit/files/FilesRepository.test.ts @@ -874,4 +874,57 @@ describe('FilesRepository', () => { }); }); }); + + describe('getFileCitation', () => { + const testIncludeDeaccessioned = true; + const testCitation = 'test citation'; + const testCitationSuccessfulResponse = { + data: { + status: 'OK', + data: { + message: testCitation, + }, + }, + }; + test('should return citation when response is successful', async () => { + const axiosGetStub = sandbox.stub(axios, 'get').resolves(testCitationSuccessfulResponse); + const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/files/${testFile.id}/versions/${DatasetNotNumberedVersion.LATEST}/citation`; + + // API Key auth + let actual = await sut.getFileCitation(testFile.id, DatasetNotNumberedVersion.LATEST, testIncludeDeaccessioned); + + assert.calledWithExactly( + axiosGetStub, + expectedApiEndpoint, + TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY_INCLUDE_DEACCESSIONED, + ); + assert.match(actual, testCitation); + + // Session cookie auth + ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.SESSION_COOKIE); + + actual = await sut.getFileCitation(testFile.id, DatasetNotNumberedVersion.LATEST, testIncludeDeaccessioned); + + assert.calledWithExactly( + axiosGetStub, + expectedApiEndpoint, + TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_SESSION_COOKIE_INCLUDE_DEACCESSIONED, + ); + assert.match(actual, testCitation); + }); + + 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.getFileCitation(1, DatasetNotNumberedVersion.LATEST, testIncludeDeaccessioned).catch((e) => (error = e)); + + assert.calledWithExactly( + axiosGetStub, + `${TestConstants.TEST_API_URL}/files/${testFile.id}/versions/${DatasetNotNumberedVersion.LATEST}/citation`, + TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY_INCLUDE_DEACCESSIONED, + ); + expect(error).to.be.instanceOf(Error); + }); + }); }); From c0259c70573e72b2886f6d6c4a223806d1b581fc Mon Sep 17 00:00:00 2001 From: MellyGray Date: Thu, 15 Feb 2024 13:07:39 +0100 Subject: [PATCH 3/5] feat(GetFileCitation): set latest-published as the default version --- .../models/DatasetNotNumberedVersion.ts | 1 + src/files/domain/useCases/GetFileCitation.ts | 2 +- .../integration/files/FilesRepository.test.ts | 102 ++++---- test/unit/files/FilesRepository.test.ts | 226 +++++++++--------- test/unit/files/GetFileCitation.test.ts | 58 ++--- 5 files changed, 203 insertions(+), 186 deletions(-) diff --git a/src/datasets/domain/models/DatasetNotNumberedVersion.ts b/src/datasets/domain/models/DatasetNotNumberedVersion.ts index a646b5be..00f46a25 100644 --- a/src/datasets/domain/models/DatasetNotNumberedVersion.ts +++ b/src/datasets/domain/models/DatasetNotNumberedVersion.ts @@ -1,4 +1,5 @@ export enum DatasetNotNumberedVersion { DRAFT = ':draft', LATEST = ':latest', + LATEST_PUBLISHED = ':latest-published', } diff --git a/src/files/domain/useCases/GetFileCitation.ts b/src/files/domain/useCases/GetFileCitation.ts index 2daccc1d..385adfa7 100644 --- a/src/files/domain/useCases/GetFileCitation.ts +++ b/src/files/domain/useCases/GetFileCitation.ts @@ -11,7 +11,7 @@ export class GetFileCitation implements UseCase { async execute( fileId: number, - datasetVersionId: string | DatasetNotNumberedVersion = DatasetNotNumberedVersion.LATEST, + datasetVersionId: string | DatasetNotNumberedVersion = DatasetNotNumberedVersion.LATEST_PUBLISHED, includeDeaccessioned = false, ): Promise { return await this.filesRepository.getFileCitation(fileId, datasetVersionId, includeDeaccessioned); diff --git a/test/integration/files/FilesRepository.test.ts b/test/integration/files/FilesRepository.test.ts index 7241f163..7dfa1bb7 100644 --- a/test/integration/files/FilesRepository.test.ts +++ b/test/integration/files/FilesRepository.test.ts @@ -3,7 +3,7 @@ import { ApiConfig, DataverseApiAuthMechanism } from '../../../src/core/infra/re import { assert } from 'sinon'; import { expect } from 'chai'; import { TestConstants } from '../../testHelpers/TestConstants'; -import {registerFileViaApi, uploadFileViaApi} from '../../testHelpers/files/filesHelper'; +import { registerFileViaApi, uploadFileViaApi } from '../../testHelpers/files/filesHelper'; import { DatasetsRepository } from '../../../src/datasets/infra/repositories/DatasetsRepository'; import { ReadError } from '../../../src/core/domain/repositories/ReadError'; import { FileSearchCriteria, FileAccessStatus, FileOrderCriteria } from '../../../src/files/domain/models/FileCriteria'; @@ -11,7 +11,11 @@ import { DatasetNotNumberedVersion } from '../../../src/datasets'; import { FileCounts } from '../../../src/files/domain/models/FileCounts'; import { FileDownloadSizeMode } from '../../../src'; import { fail } from 'assert'; -import {deaccessionDatasetViaApi, publishDatasetViaApi, waitForNoLocks} from "../../testHelpers/datasets/datasetHelper"; +import { + deaccessionDatasetViaApi, + publishDatasetViaApi, + waitForNoLocks, +} from '../../testHelpers/datasets/datasetHelper'; describe('FilesRepository', () => { const sut: FilesRepository = new FilesRepository(); @@ -33,7 +37,9 @@ describe('FilesRepository', () => { beforeAll(async () => { ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.API_KEY, process.env.TEST_API_KEY); // Uploading test file 1 with some categories - const uploadFileResponse = await uploadFileViaApi(TestConstants.TEST_CREATED_DATASET_1_ID, testTextFile1Name, { categories: [testCategoryName] }) + const uploadFileResponse = await uploadFileViaApi(TestConstants.TEST_CREATED_DATASET_1_ID, testTextFile1Name, { + categories: [testCategoryName], + }) .then() .catch((e) => { console.log(e); @@ -63,11 +69,11 @@ describe('FilesRepository', () => { // Registering test file 1 await registerFileViaApi(uploadFileResponse.data.data.files[0].dataFile.id); const filesSubset = await sut.getDatasetFiles( - TestConstants.TEST_CREATED_DATASET_1_ID, - latestDatasetVersionId, - false, - FileOrderCriteria.NAME_AZ, - ) + TestConstants.TEST_CREATED_DATASET_1_ID, + latestDatasetVersionId, + false, + FileOrderCriteria.NAME_AZ, + ); testFileId = filesSubset.files[0].id; testFilePersistentId = filesSubset.files[0].persistentId; }); @@ -447,11 +453,11 @@ describe('FilesRepository', () => { describe('getFile', () => { describe('by numeric id', () => { - test('should return file when providing a valid id', async () => { - const actual = await sut.getFile(testFileId, DatasetNotNumberedVersion.LATEST); + test('should return file when providing a valid id', async () => { + const actual = await sut.getFile(testFileId, DatasetNotNumberedVersion.LATEST); - assert.match(actual.name, testTextFile1Name); - }); + assert.match(actual.name, testTextFile1Name); + }); test('should return file draft when providing a valid id and version is draft', async () => { const actual = await sut.getFile(testFileId, DatasetNotNumberedVersion.DRAFT); @@ -466,21 +472,21 @@ describe('FilesRepository', () => { await sut.getFile(testFileId, '1.0').catch((e) => (error = e)); assert.match( - error.message, - `Requesting a file by its dataset version is not yet supported. Requested version: 1.0. Please try using the :latest or :draft version instead.`, + error.message, + `Requesting a file by its dataset version is not yet supported. Requested version: 1.0. Please try using the :latest or :draft version instead.`, ); }); - test('should return error when file does not exist', async () => { - let error: ReadError = undefined; + test('should return error when file does not exist', async () => { + let error: ReadError = undefined; - await sut.getFile(nonExistentFiledId, DatasetNotNumberedVersion.LATEST).catch((e) => (error = e)); + await sut.getFile(nonExistentFiledId, DatasetNotNumberedVersion.LATEST).catch((e) => (error = e)); - assert.match( - error.message, - `There was an error when reading the resource. Reason was: [400] Error attempting get the requested data file.`, - ); - }); + assert.match( + error.message, + `There was an error when reading the resource. Reason was: [400] Error attempting get the requested data file.`, + ); + }); }); describe('by persistent id', () => { test('should return file when providing a valid persistent id', async () => { @@ -502,8 +508,8 @@ describe('FilesRepository', () => { await sut.getFile(testFilePersistentId, '1.0').catch((e) => (error = e)); assert.match( - error.message, - `Requesting a file by its dataset version is not yet supported. Requested version: 1.0. Please try using the :latest or :draft version instead.`, + error.message, + `Requesting a file by its dataset version is not yet supported. Requested version: 1.0. Please try using the :latest or :draft version instead.`, ); }); @@ -514,56 +520,54 @@ describe('FilesRepository', () => { await sut.getFile(nonExistentFiledPersistentId, DatasetNotNumberedVersion.LATEST).catch((e) => (error = e)); assert.match( - error.message, - `There was an error when reading the resource. Reason was: [400] Error attempting get the requested data file.`, + error.message, + `There was an error when reading the resource. Reason was: [400] Error attempting get the requested data file.`, ); }); }); }); describe('getFileCitation', () => { test('should return citation when file exists', async () => { - const actualFileCitation = await sut.getFileCitation( - testFileId, - DatasetNotNumberedVersion.LATEST, - false, - ); + const actualFileCitation = await sut.getFileCitation(testFileId, DatasetNotNumberedVersion.DRAFT, false); expect(typeof actualFileCitation).to.be.a('string'); }); test('should return citation when dataset is deaccessioned', async () => { await publishDatasetViaApi(TestConstants.TEST_CREATED_DATASET_1_ID) - .then() - .catch(() => { - assert.fail('Error while publishing test Dataset'); - }); + .then() + .catch(() => { + assert.fail('Error while publishing test Dataset'); + }); await waitForNoLocks(TestConstants.TEST_CREATED_DATASET_1_ID, 10) - .then() - .catch(() => { - assert.fail('Error while waiting for no locks'); - }); + .then() + .catch(() => { + assert.fail('Error while waiting for no locks'); + }); await deaccessionDatasetViaApi(TestConstants.TEST_CREATED_DATASET_1_ID, '1.0') - .then() - .catch(() => { - assert.fail('Error while deaccessioning test Dataset'); - }); + .then() + .catch(() => { + assert.fail('Error while deaccessioning test Dataset'); + }); const actualFileCitation = await sut.getFileCitation( - testFileId, - DatasetNotNumberedVersion.LATEST, - true, + testFileId, + DatasetNotNumberedVersion.LATEST_PUBLISHED, + true, ); expect(typeof actualFileCitation).to.be.a('string'); }); test('should return error when file does not exist', async () => { let error: ReadError = undefined; - await sut.getFileCitation(nonExistentFiledId, DatasetNotNumberedVersion.LATEST, false).catch((e) => (error = e)); + await sut + .getFileCitation(nonExistentFiledId, DatasetNotNumberedVersion.LATEST_PUBLISHED, false) + .catch((e) => (error = e)); assert.match( - error.message, - `There was an error when reading the resource. Reason was: [404] File with ID ${nonExistentFiledId} not found.`, + error.message, + `There was an error when reading the resource. Reason was: [404] File with ID ${nonExistentFiledId} not found.`, ); }); }); diff --git a/test/unit/files/FilesRepository.test.ts b/test/unit/files/FilesRepository.test.ts index 38cd4d92..469f25d5 100644 --- a/test/unit/files/FilesRepository.test.ts +++ b/test/unit/files/FilesRepository.test.ts @@ -9,7 +9,7 @@ import { createFileModel, createManyFilesPayload, createFilesSubsetModel, - createFilePayload + createFilePayload, } from '../../testHelpers/files/filesHelper'; import { createFileDataTablePayload, createFileDataTableModel } from '../../testHelpers/files/fileDataTablesHelper'; import { createFileUserPermissionsModel } from '../../testHelpers/files/fileUserPermissionsHelper'; @@ -776,102 +776,104 @@ describe('FilesRepository', () => { }); }); }); - describe('getFile' , () => { + describe('getFile', () => { describe('by numeric id', () => { - const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/files/${testFile.id}/`; - const testGetFileResponse = { - data: { - status: 'OK', - data: createFilePayload(), - }, - }; - test('should return file when providing id and response is successful', async () => { - const axiosGetStub = sandbox.stub(axios, 'get').resolves(testGetFileResponse); - - // API Key auth - let actual = await sut.getFile(testFile.id, DatasetNotNumberedVersion.LATEST); - - assert.calledWithExactly( - axiosGetStub, - expectedApiEndpoint, - TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, - ); - assert.match(actual, createFileModel()); - - // Session cookie auth - ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.SESSION_COOKIE); - - actual = await sut.getFile(testFile.id, DatasetNotNumberedVersion.LATEST); - - assert.calledWithExactly( - axiosGetStub, - expectedApiEndpoint, - TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_SESSION_COOKIE, - ); - assert.match(actual, createFileModel()); - }); - - test('should return error result on error response', async () => { - const axiosGetStub = sandbox.stub(axios, 'get').rejects(TestConstants.TEST_ERROR_RESPONSE); - - let error: ReadError = undefined; - await sut.getFile(testFile.id, DatasetNotNumberedVersion.LATEST).catch((e) => (error = e)); - - assert.calledWithExactly( - axiosGetStub, - expectedApiEndpoint, - TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, - ); - expect(error).to.be.instanceOf(Error); - }); + const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/files/${testFile.id}/`; + const testGetFileResponse = { + data: { + status: 'OK', + data: createFilePayload(), + }, + }; + test('should return file when providing id and response is successful', async () => { + const axiosGetStub = sandbox.stub(axios, 'get').resolves(testGetFileResponse); + + // API Key auth + let actual = await sut.getFile(testFile.id, DatasetNotNumberedVersion.LATEST); + + assert.calledWithExactly( + axiosGetStub, + expectedApiEndpoint, + TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, + ); + assert.match(actual, createFileModel()); + + // Session cookie auth + ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.SESSION_COOKIE); + + actual = await sut.getFile(testFile.id, DatasetNotNumberedVersion.LATEST); + + assert.calledWithExactly( + axiosGetStub, + expectedApiEndpoint, + TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_SESSION_COOKIE, + ); + assert.match(actual, createFileModel()); + }); + + test('should return error result on error response', async () => { + const axiosGetStub = sandbox.stub(axios, 'get').rejects(TestConstants.TEST_ERROR_RESPONSE); + + let error: ReadError = undefined; + await sut.getFile(testFile.id, DatasetNotNumberedVersion.LATEST).catch((e) => (error = e)); + + assert.calledWithExactly( + axiosGetStub, + expectedApiEndpoint, + TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, + ); + expect(error).to.be.instanceOf(Error); + }); }); describe('by persistent id', () => { - const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/files/:persistentId/?persistentId=${TestConstants.TEST_DUMMY_PERSISTENT_ID}`; - const testGetFileResponse = { - data: { - status: 'OK', - data: createFilePayload(), - }, - }; - test('should return file when providing persistent id and response is successful', async () => { - const axiosGetStub = sandbox.stub(axios, 'get').resolves(testGetFileResponse); - - // API Key auth - let actual = await sut.getFile(TestConstants.TEST_DUMMY_PERSISTENT_ID, DatasetNotNumberedVersion.LATEST); - - assert.calledWithExactly( - axiosGetStub, - expectedApiEndpoint, - TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, - ); - assert.match(actual, createFileModel()); - - // Session cookie auth - ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.SESSION_COOKIE); - - actual = await sut.getFile(TestConstants.TEST_DUMMY_PERSISTENT_ID, DatasetNotNumberedVersion.LATEST); - - assert.calledWithExactly( - axiosGetStub, - expectedApiEndpoint, - TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_SESSION_COOKIE, - ); - assert.match(actual, createFileModel()); - }); - - test('should return error result on error response', async () => { - const axiosGetStub = sandbox.stub(axios, 'get').rejects(TestConstants.TEST_ERROR_RESPONSE); - - let error: ReadError = undefined; - await sut.getFile(TestConstants.TEST_DUMMY_PERSISTENT_ID, DatasetNotNumberedVersion.LATEST).catch((e) => (error = e)); - - assert.calledWithExactly( - axiosGetStub, - expectedApiEndpoint, - TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, - ); - expect(error).to.be.instanceOf(Error); - }); + const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/files/:persistentId/?persistentId=${TestConstants.TEST_DUMMY_PERSISTENT_ID}`; + const testGetFileResponse = { + data: { + status: 'OK', + data: createFilePayload(), + }, + }; + test('should return file when providing persistent id and response is successful', async () => { + const axiosGetStub = sandbox.stub(axios, 'get').resolves(testGetFileResponse); + + // API Key auth + let actual = await sut.getFile(TestConstants.TEST_DUMMY_PERSISTENT_ID, DatasetNotNumberedVersion.LATEST); + + assert.calledWithExactly( + axiosGetStub, + expectedApiEndpoint, + TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, + ); + assert.match(actual, createFileModel()); + + // Session cookie auth + ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.SESSION_COOKIE); + + actual = await sut.getFile(TestConstants.TEST_DUMMY_PERSISTENT_ID, DatasetNotNumberedVersion.LATEST); + + assert.calledWithExactly( + axiosGetStub, + expectedApiEndpoint, + TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_SESSION_COOKIE, + ); + assert.match(actual, createFileModel()); + }); + + test('should return error result on error response', async () => { + const axiosGetStub = sandbox.stub(axios, 'get').rejects(TestConstants.TEST_ERROR_RESPONSE); + + let error: ReadError = undefined; + await sut + .getFile(TestConstants.TEST_DUMMY_PERSISTENT_ID, DatasetNotNumberedVersion.LATEST) + .catch((e) => (error = e)); + + assert.calledWithExactly( + axiosGetStub, + expectedApiEndpoint, + TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, + ); + expect(error).to.be.instanceOf(Error); + }); }); }); @@ -888,27 +890,35 @@ describe('FilesRepository', () => { }; test('should return citation when response is successful', async () => { const axiosGetStub = sandbox.stub(axios, 'get').resolves(testCitationSuccessfulResponse); - const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/files/${testFile.id}/versions/${DatasetNotNumberedVersion.LATEST}/citation`; + const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/files/${testFile.id}/versions/${DatasetNotNumberedVersion.LATEST_PUBLISHED}/citation`; // API Key auth - let actual = await sut.getFileCitation(testFile.id, DatasetNotNumberedVersion.LATEST, testIncludeDeaccessioned); + let actual = await sut.getFileCitation( + testFile.id, + DatasetNotNumberedVersion.LATEST_PUBLISHED, + testIncludeDeaccessioned, + ); assert.calledWithExactly( - axiosGetStub, - expectedApiEndpoint, - TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY_INCLUDE_DEACCESSIONED, + axiosGetStub, + expectedApiEndpoint, + TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY_INCLUDE_DEACCESSIONED, ); assert.match(actual, testCitation); // Session cookie auth ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.SESSION_COOKIE); - actual = await sut.getFileCitation(testFile.id, DatasetNotNumberedVersion.LATEST, testIncludeDeaccessioned); + actual = await sut.getFileCitation( + testFile.id, + DatasetNotNumberedVersion.LATEST_PUBLISHED, + testIncludeDeaccessioned, + ); assert.calledWithExactly( - axiosGetStub, - expectedApiEndpoint, - TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_SESSION_COOKIE_INCLUDE_DEACCESSIONED, + axiosGetStub, + expectedApiEndpoint, + TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_SESSION_COOKIE_INCLUDE_DEACCESSIONED, ); assert.match(actual, testCitation); }); @@ -917,12 +927,14 @@ describe('FilesRepository', () => { const axiosGetStub = sandbox.stub(axios, 'get').rejects(TestConstants.TEST_ERROR_RESPONSE); let error: ReadError = undefined; - await sut.getFileCitation(1, DatasetNotNumberedVersion.LATEST, testIncludeDeaccessioned).catch((e) => (error = e)); + await sut + .getFileCitation(1, DatasetNotNumberedVersion.LATEST_PUBLISHED, testIncludeDeaccessioned) + .catch((e) => (error = e)); assert.calledWithExactly( - axiosGetStub, - `${TestConstants.TEST_API_URL}/files/${testFile.id}/versions/${DatasetNotNumberedVersion.LATEST}/citation`, - TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY_INCLUDE_DEACCESSIONED, + axiosGetStub, + `${TestConstants.TEST_API_URL}/files/${testFile.id}/versions/${DatasetNotNumberedVersion.LATEST_PUBLISHED}/citation`, + TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY_INCLUDE_DEACCESSIONED, ); expect(error).to.be.instanceOf(Error); }); diff --git a/test/unit/files/GetFileCitation.test.ts b/test/unit/files/GetFileCitation.test.ts index ac40b547..103fdae1 100644 --- a/test/unit/files/GetFileCitation.test.ts +++ b/test/unit/files/GetFileCitation.test.ts @@ -1,39 +1,39 @@ -import {assert, createSandbox, SinonSandbox} from "sinon"; -import {DatasetNotNumberedVersion, ReadError} from "../../../src"; -import {IFilesRepository} from "../../../src/files/domain/repositories/IFilesRepository"; -import {GetFileCitation} from "../../../src/files/domain/useCases/GetFileCitation"; +import { assert, createSandbox, SinonSandbox } from 'sinon'; +import { DatasetNotNumberedVersion, ReadError } from '../../../src'; +import { IFilesRepository } from '../../../src/files/domain/repositories/IFilesRepository'; +import { GetFileCitation } from '../../../src/files/domain/useCases/GetFileCitation'; describe('execute', () => { - const sandbox: SinonSandbox = createSandbox(); - const testId = 1; + const sandbox: SinonSandbox = createSandbox(); + const testId = 1; - afterEach(() => { - sandbox.restore(); - }); + afterEach(() => { + sandbox.restore(); + }); - test('should return successful result with file citation on repository success', async () => { - const testCitation = 'test citation'; - const filesRepositoryStub = {}; - const getFileCitation = sandbox.stub().returns(testCitation); - filesRepositoryStub.getFileCitation = getFileCitation; + test('should return successful result with file citation on repository success', async () => { + const testCitation = 'test citation'; + const filesRepositoryStub = {}; + const getFileCitation = sandbox.stub().returns(testCitation); + filesRepositoryStub.getFileCitation = getFileCitation; - const sut = new GetFileCitation(filesRepositoryStub); + const sut = new GetFileCitation(filesRepositoryStub); - const actual = await sut.execute(testId); + const actual = await sut.execute(testId); - assert.match(actual, testCitation); - assert.calledWithExactly(getFileCitation, testId, DatasetNotNumberedVersion.LATEST, false); - }); + assert.match(actual, testCitation); + assert.calledWithExactly(getFileCitation, testId, DatasetNotNumberedVersion.LATEST_PUBLISHED, false); + }); - test('should return error result on repository error', async () => { - const filesRepositoryStub = {}; - const testReadError = new ReadError(); - filesRepositoryStub.getFileCitation = sandbox.stub().throwsException(testReadError); - const sut = new GetFileCitation(filesRepositoryStub); + test('should return error result on repository error', async () => { + const filesRepositoryStub = {}; + const testReadError = new ReadError(); + filesRepositoryStub.getFileCitation = sandbox.stub().throwsException(testReadError); + const sut = new GetFileCitation(filesRepositoryStub); - let actualError: ReadError = undefined; - await sut.execute(testId).catch((e) => (actualError = e)); + let actualError: ReadError = undefined; + await sut.execute(testId).catch((e) => (actualError = e)); - assert.match(actualError, testReadError); - }); -}) \ No newline at end of file + assert.match(actualError, testReadError); + }); +}); From 463d37236bc31424ff3aca6d429488d0d7928b29 Mon Sep 17 00:00:00 2001 From: MellyGray Date: Fri, 16 Feb 2024 18:17:55 +0100 Subject: [PATCH 4/5] Revert "feat(GetFileCitation): set latest-published as the default version" This reverts commit c0259c70573e72b2886f6d6c4a223806d1b581fc. --- .../models/DatasetNotNumberedVersion.ts | 1 - src/files/domain/useCases/GetFileCitation.ts | 2 +- .../integration/files/FilesRepository.test.ts | 102 ++++---- test/unit/files/FilesRepository.test.ts | 226 +++++++++--------- test/unit/files/GetFileCitation.test.ts | 58 ++--- 5 files changed, 186 insertions(+), 203 deletions(-) diff --git a/src/datasets/domain/models/DatasetNotNumberedVersion.ts b/src/datasets/domain/models/DatasetNotNumberedVersion.ts index 00f46a25..a646b5be 100644 --- a/src/datasets/domain/models/DatasetNotNumberedVersion.ts +++ b/src/datasets/domain/models/DatasetNotNumberedVersion.ts @@ -1,5 +1,4 @@ export enum DatasetNotNumberedVersion { DRAFT = ':draft', LATEST = ':latest', - LATEST_PUBLISHED = ':latest-published', } diff --git a/src/files/domain/useCases/GetFileCitation.ts b/src/files/domain/useCases/GetFileCitation.ts index 385adfa7..2daccc1d 100644 --- a/src/files/domain/useCases/GetFileCitation.ts +++ b/src/files/domain/useCases/GetFileCitation.ts @@ -11,7 +11,7 @@ export class GetFileCitation implements UseCase { async execute( fileId: number, - datasetVersionId: string | DatasetNotNumberedVersion = DatasetNotNumberedVersion.LATEST_PUBLISHED, + datasetVersionId: string | DatasetNotNumberedVersion = DatasetNotNumberedVersion.LATEST, includeDeaccessioned = false, ): Promise { return await this.filesRepository.getFileCitation(fileId, datasetVersionId, includeDeaccessioned); diff --git a/test/integration/files/FilesRepository.test.ts b/test/integration/files/FilesRepository.test.ts index 7dfa1bb7..7241f163 100644 --- a/test/integration/files/FilesRepository.test.ts +++ b/test/integration/files/FilesRepository.test.ts @@ -3,7 +3,7 @@ import { ApiConfig, DataverseApiAuthMechanism } from '../../../src/core/infra/re import { assert } from 'sinon'; import { expect } from 'chai'; import { TestConstants } from '../../testHelpers/TestConstants'; -import { registerFileViaApi, uploadFileViaApi } from '../../testHelpers/files/filesHelper'; +import {registerFileViaApi, uploadFileViaApi} from '../../testHelpers/files/filesHelper'; import { DatasetsRepository } from '../../../src/datasets/infra/repositories/DatasetsRepository'; import { ReadError } from '../../../src/core/domain/repositories/ReadError'; import { FileSearchCriteria, FileAccessStatus, FileOrderCriteria } from '../../../src/files/domain/models/FileCriteria'; @@ -11,11 +11,7 @@ import { DatasetNotNumberedVersion } from '../../../src/datasets'; import { FileCounts } from '../../../src/files/domain/models/FileCounts'; import { FileDownloadSizeMode } from '../../../src'; import { fail } from 'assert'; -import { - deaccessionDatasetViaApi, - publishDatasetViaApi, - waitForNoLocks, -} from '../../testHelpers/datasets/datasetHelper'; +import {deaccessionDatasetViaApi, publishDatasetViaApi, waitForNoLocks} from "../../testHelpers/datasets/datasetHelper"; describe('FilesRepository', () => { const sut: FilesRepository = new FilesRepository(); @@ -37,9 +33,7 @@ describe('FilesRepository', () => { beforeAll(async () => { ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.API_KEY, process.env.TEST_API_KEY); // Uploading test file 1 with some categories - const uploadFileResponse = await uploadFileViaApi(TestConstants.TEST_CREATED_DATASET_1_ID, testTextFile1Name, { - categories: [testCategoryName], - }) + const uploadFileResponse = await uploadFileViaApi(TestConstants.TEST_CREATED_DATASET_1_ID, testTextFile1Name, { categories: [testCategoryName] }) .then() .catch((e) => { console.log(e); @@ -69,11 +63,11 @@ describe('FilesRepository', () => { // Registering test file 1 await registerFileViaApi(uploadFileResponse.data.data.files[0].dataFile.id); const filesSubset = await sut.getDatasetFiles( - TestConstants.TEST_CREATED_DATASET_1_ID, - latestDatasetVersionId, - false, - FileOrderCriteria.NAME_AZ, - ); + TestConstants.TEST_CREATED_DATASET_1_ID, + latestDatasetVersionId, + false, + FileOrderCriteria.NAME_AZ, + ) testFileId = filesSubset.files[0].id; testFilePersistentId = filesSubset.files[0].persistentId; }); @@ -453,11 +447,11 @@ describe('FilesRepository', () => { describe('getFile', () => { describe('by numeric id', () => { - test('should return file when providing a valid id', async () => { - const actual = await sut.getFile(testFileId, DatasetNotNumberedVersion.LATEST); + test('should return file when providing a valid id', async () => { + const actual = await sut.getFile(testFileId, DatasetNotNumberedVersion.LATEST); - assert.match(actual.name, testTextFile1Name); - }); + assert.match(actual.name, testTextFile1Name); + }); test('should return file draft when providing a valid id and version is draft', async () => { const actual = await sut.getFile(testFileId, DatasetNotNumberedVersion.DRAFT); @@ -472,21 +466,21 @@ describe('FilesRepository', () => { await sut.getFile(testFileId, '1.0').catch((e) => (error = e)); assert.match( - error.message, - `Requesting a file by its dataset version is not yet supported. Requested version: 1.0. Please try using the :latest or :draft version instead.`, + error.message, + `Requesting a file by its dataset version is not yet supported. Requested version: 1.0. Please try using the :latest or :draft version instead.`, ); }); - test('should return error when file does not exist', async () => { - let error: ReadError = undefined; + test('should return error when file does not exist', async () => { + let error: ReadError = undefined; - await sut.getFile(nonExistentFiledId, DatasetNotNumberedVersion.LATEST).catch((e) => (error = e)); + await sut.getFile(nonExistentFiledId, DatasetNotNumberedVersion.LATEST).catch((e) => (error = e)); - assert.match( - error.message, - `There was an error when reading the resource. Reason was: [400] Error attempting get the requested data file.`, - ); - }); + assert.match( + error.message, + `There was an error when reading the resource. Reason was: [400] Error attempting get the requested data file.`, + ); + }); }); describe('by persistent id', () => { test('should return file when providing a valid persistent id', async () => { @@ -508,8 +502,8 @@ describe('FilesRepository', () => { await sut.getFile(testFilePersistentId, '1.0').catch((e) => (error = e)); assert.match( - error.message, - `Requesting a file by its dataset version is not yet supported. Requested version: 1.0. Please try using the :latest or :draft version instead.`, + error.message, + `Requesting a file by its dataset version is not yet supported. Requested version: 1.0. Please try using the :latest or :draft version instead.`, ); }); @@ -520,54 +514,56 @@ describe('FilesRepository', () => { await sut.getFile(nonExistentFiledPersistentId, DatasetNotNumberedVersion.LATEST).catch((e) => (error = e)); assert.match( - error.message, - `There was an error when reading the resource. Reason was: [400] Error attempting get the requested data file.`, + error.message, + `There was an error when reading the resource. Reason was: [400] Error attempting get the requested data file.`, ); }); }); }); describe('getFileCitation', () => { test('should return citation when file exists', async () => { - const actualFileCitation = await sut.getFileCitation(testFileId, DatasetNotNumberedVersion.DRAFT, false); + const actualFileCitation = await sut.getFileCitation( + testFileId, + DatasetNotNumberedVersion.LATEST, + false, + ); expect(typeof actualFileCitation).to.be.a('string'); }); test('should return citation when dataset is deaccessioned', async () => { await publishDatasetViaApi(TestConstants.TEST_CREATED_DATASET_1_ID) - .then() - .catch(() => { - assert.fail('Error while publishing test Dataset'); - }); + .then() + .catch(() => { + assert.fail('Error while publishing test Dataset'); + }); await waitForNoLocks(TestConstants.TEST_CREATED_DATASET_1_ID, 10) - .then() - .catch(() => { - assert.fail('Error while waiting for no locks'); - }); + .then() + .catch(() => { + assert.fail('Error while waiting for no locks'); + }); await deaccessionDatasetViaApi(TestConstants.TEST_CREATED_DATASET_1_ID, '1.0') - .then() - .catch(() => { - assert.fail('Error while deaccessioning test Dataset'); - }); + .then() + .catch(() => { + assert.fail('Error while deaccessioning test Dataset'); + }); const actualFileCitation = await sut.getFileCitation( - testFileId, - DatasetNotNumberedVersion.LATEST_PUBLISHED, - true, + testFileId, + DatasetNotNumberedVersion.LATEST, + true, ); expect(typeof actualFileCitation).to.be.a('string'); }); test('should return error when file does not exist', async () => { let error: ReadError = undefined; - await sut - .getFileCitation(nonExistentFiledId, DatasetNotNumberedVersion.LATEST_PUBLISHED, false) - .catch((e) => (error = e)); + await sut.getFileCitation(nonExistentFiledId, DatasetNotNumberedVersion.LATEST, false).catch((e) => (error = e)); assert.match( - error.message, - `There was an error when reading the resource. Reason was: [404] File with ID ${nonExistentFiledId} not found.`, + error.message, + `There was an error when reading the resource. Reason was: [404] File with ID ${nonExistentFiledId} not found.`, ); }); }); diff --git a/test/unit/files/FilesRepository.test.ts b/test/unit/files/FilesRepository.test.ts index 469f25d5..38cd4d92 100644 --- a/test/unit/files/FilesRepository.test.ts +++ b/test/unit/files/FilesRepository.test.ts @@ -9,7 +9,7 @@ import { createFileModel, createManyFilesPayload, createFilesSubsetModel, - createFilePayload, + createFilePayload } from '../../testHelpers/files/filesHelper'; import { createFileDataTablePayload, createFileDataTableModel } from '../../testHelpers/files/fileDataTablesHelper'; import { createFileUserPermissionsModel } from '../../testHelpers/files/fileUserPermissionsHelper'; @@ -776,104 +776,102 @@ describe('FilesRepository', () => { }); }); }); - describe('getFile', () => { + describe('getFile' , () => { describe('by numeric id', () => { - const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/files/${testFile.id}/`; - const testGetFileResponse = { - data: { - status: 'OK', - data: createFilePayload(), - }, - }; - test('should return file when providing id and response is successful', async () => { - const axiosGetStub = sandbox.stub(axios, 'get').resolves(testGetFileResponse); - - // API Key auth - let actual = await sut.getFile(testFile.id, DatasetNotNumberedVersion.LATEST); - - assert.calledWithExactly( - axiosGetStub, - expectedApiEndpoint, - TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, - ); - assert.match(actual, createFileModel()); - - // Session cookie auth - ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.SESSION_COOKIE); - - actual = await sut.getFile(testFile.id, DatasetNotNumberedVersion.LATEST); - - assert.calledWithExactly( - axiosGetStub, - expectedApiEndpoint, - TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_SESSION_COOKIE, - ); - assert.match(actual, createFileModel()); - }); - - test('should return error result on error response', async () => { - const axiosGetStub = sandbox.stub(axios, 'get').rejects(TestConstants.TEST_ERROR_RESPONSE); - - let error: ReadError = undefined; - await sut.getFile(testFile.id, DatasetNotNumberedVersion.LATEST).catch((e) => (error = e)); - - assert.calledWithExactly( - axiosGetStub, - expectedApiEndpoint, - TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, - ); - expect(error).to.be.instanceOf(Error); - }); + const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/files/${testFile.id}/`; + const testGetFileResponse = { + data: { + status: 'OK', + data: createFilePayload(), + }, + }; + test('should return file when providing id and response is successful', async () => { + const axiosGetStub = sandbox.stub(axios, 'get').resolves(testGetFileResponse); + + // API Key auth + let actual = await sut.getFile(testFile.id, DatasetNotNumberedVersion.LATEST); + + assert.calledWithExactly( + axiosGetStub, + expectedApiEndpoint, + TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, + ); + assert.match(actual, createFileModel()); + + // Session cookie auth + ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.SESSION_COOKIE); + + actual = await sut.getFile(testFile.id, DatasetNotNumberedVersion.LATEST); + + assert.calledWithExactly( + axiosGetStub, + expectedApiEndpoint, + TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_SESSION_COOKIE, + ); + assert.match(actual, createFileModel()); + }); + + test('should return error result on error response', async () => { + const axiosGetStub = sandbox.stub(axios, 'get').rejects(TestConstants.TEST_ERROR_RESPONSE); + + let error: ReadError = undefined; + await sut.getFile(testFile.id, DatasetNotNumberedVersion.LATEST).catch((e) => (error = e)); + + assert.calledWithExactly( + axiosGetStub, + expectedApiEndpoint, + TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, + ); + expect(error).to.be.instanceOf(Error); + }); }); describe('by persistent id', () => { - const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/files/:persistentId/?persistentId=${TestConstants.TEST_DUMMY_PERSISTENT_ID}`; - const testGetFileResponse = { - data: { - status: 'OK', - data: createFilePayload(), - }, - }; - test('should return file when providing persistent id and response is successful', async () => { - const axiosGetStub = sandbox.stub(axios, 'get').resolves(testGetFileResponse); - - // API Key auth - let actual = await sut.getFile(TestConstants.TEST_DUMMY_PERSISTENT_ID, DatasetNotNumberedVersion.LATEST); - - assert.calledWithExactly( - axiosGetStub, - expectedApiEndpoint, - TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, - ); - assert.match(actual, createFileModel()); - - // Session cookie auth - ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.SESSION_COOKIE); - - actual = await sut.getFile(TestConstants.TEST_DUMMY_PERSISTENT_ID, DatasetNotNumberedVersion.LATEST); - - assert.calledWithExactly( - axiosGetStub, - expectedApiEndpoint, - TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_SESSION_COOKIE, - ); - assert.match(actual, createFileModel()); - }); - - test('should return error result on error response', async () => { - const axiosGetStub = sandbox.stub(axios, 'get').rejects(TestConstants.TEST_ERROR_RESPONSE); - - let error: ReadError = undefined; - await sut - .getFile(TestConstants.TEST_DUMMY_PERSISTENT_ID, DatasetNotNumberedVersion.LATEST) - .catch((e) => (error = e)); - - assert.calledWithExactly( - axiosGetStub, - expectedApiEndpoint, - TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, - ); - expect(error).to.be.instanceOf(Error); - }); + const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/files/:persistentId/?persistentId=${TestConstants.TEST_DUMMY_PERSISTENT_ID}`; + const testGetFileResponse = { + data: { + status: 'OK', + data: createFilePayload(), + }, + }; + test('should return file when providing persistent id and response is successful', async () => { + const axiosGetStub = sandbox.stub(axios, 'get').resolves(testGetFileResponse); + + // API Key auth + let actual = await sut.getFile(TestConstants.TEST_DUMMY_PERSISTENT_ID, DatasetNotNumberedVersion.LATEST); + + assert.calledWithExactly( + axiosGetStub, + expectedApiEndpoint, + TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, + ); + assert.match(actual, createFileModel()); + + // Session cookie auth + ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.SESSION_COOKIE); + + actual = await sut.getFile(TestConstants.TEST_DUMMY_PERSISTENT_ID, DatasetNotNumberedVersion.LATEST); + + assert.calledWithExactly( + axiosGetStub, + expectedApiEndpoint, + TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_SESSION_COOKIE, + ); + assert.match(actual, createFileModel()); + }); + + test('should return error result on error response', async () => { + const axiosGetStub = sandbox.stub(axios, 'get').rejects(TestConstants.TEST_ERROR_RESPONSE); + + let error: ReadError = undefined; + await sut.getFile(TestConstants.TEST_DUMMY_PERSISTENT_ID, DatasetNotNumberedVersion.LATEST).catch((e) => (error = e)); + + assert.calledWithExactly( + axiosGetStub, + expectedApiEndpoint, + TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, + ); + expect(error).to.be.instanceOf(Error); + }); }); }); @@ -890,35 +888,27 @@ describe('FilesRepository', () => { }; test('should return citation when response is successful', async () => { const axiosGetStub = sandbox.stub(axios, 'get').resolves(testCitationSuccessfulResponse); - const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/files/${testFile.id}/versions/${DatasetNotNumberedVersion.LATEST_PUBLISHED}/citation`; + const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/files/${testFile.id}/versions/${DatasetNotNumberedVersion.LATEST}/citation`; // API Key auth - let actual = await sut.getFileCitation( - testFile.id, - DatasetNotNumberedVersion.LATEST_PUBLISHED, - testIncludeDeaccessioned, - ); + let actual = await sut.getFileCitation(testFile.id, DatasetNotNumberedVersion.LATEST, testIncludeDeaccessioned); assert.calledWithExactly( - axiosGetStub, - expectedApiEndpoint, - TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY_INCLUDE_DEACCESSIONED, + axiosGetStub, + expectedApiEndpoint, + TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY_INCLUDE_DEACCESSIONED, ); assert.match(actual, testCitation); // Session cookie auth ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.SESSION_COOKIE); - actual = await sut.getFileCitation( - testFile.id, - DatasetNotNumberedVersion.LATEST_PUBLISHED, - testIncludeDeaccessioned, - ); + actual = await sut.getFileCitation(testFile.id, DatasetNotNumberedVersion.LATEST, testIncludeDeaccessioned); assert.calledWithExactly( - axiosGetStub, - expectedApiEndpoint, - TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_SESSION_COOKIE_INCLUDE_DEACCESSIONED, + axiosGetStub, + expectedApiEndpoint, + TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_SESSION_COOKIE_INCLUDE_DEACCESSIONED, ); assert.match(actual, testCitation); }); @@ -927,14 +917,12 @@ describe('FilesRepository', () => { const axiosGetStub = sandbox.stub(axios, 'get').rejects(TestConstants.TEST_ERROR_RESPONSE); let error: ReadError = undefined; - await sut - .getFileCitation(1, DatasetNotNumberedVersion.LATEST_PUBLISHED, testIncludeDeaccessioned) - .catch((e) => (error = e)); + await sut.getFileCitation(1, DatasetNotNumberedVersion.LATEST, testIncludeDeaccessioned).catch((e) => (error = e)); assert.calledWithExactly( - axiosGetStub, - `${TestConstants.TEST_API_URL}/files/${testFile.id}/versions/${DatasetNotNumberedVersion.LATEST_PUBLISHED}/citation`, - TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY_INCLUDE_DEACCESSIONED, + axiosGetStub, + `${TestConstants.TEST_API_URL}/files/${testFile.id}/versions/${DatasetNotNumberedVersion.LATEST}/citation`, + TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY_INCLUDE_DEACCESSIONED, ); expect(error).to.be.instanceOf(Error); }); diff --git a/test/unit/files/GetFileCitation.test.ts b/test/unit/files/GetFileCitation.test.ts index 103fdae1..ac40b547 100644 --- a/test/unit/files/GetFileCitation.test.ts +++ b/test/unit/files/GetFileCitation.test.ts @@ -1,39 +1,39 @@ -import { assert, createSandbox, SinonSandbox } from 'sinon'; -import { DatasetNotNumberedVersion, ReadError } from '../../../src'; -import { IFilesRepository } from '../../../src/files/domain/repositories/IFilesRepository'; -import { GetFileCitation } from '../../../src/files/domain/useCases/GetFileCitation'; +import {assert, createSandbox, SinonSandbox} from "sinon"; +import {DatasetNotNumberedVersion, ReadError} from "../../../src"; +import {IFilesRepository} from "../../../src/files/domain/repositories/IFilesRepository"; +import {GetFileCitation} from "../../../src/files/domain/useCases/GetFileCitation"; describe('execute', () => { - const sandbox: SinonSandbox = createSandbox(); - const testId = 1; + const sandbox: SinonSandbox = createSandbox(); + const testId = 1; - afterEach(() => { - sandbox.restore(); - }); + afterEach(() => { + sandbox.restore(); + }); - test('should return successful result with file citation on repository success', async () => { - const testCitation = 'test citation'; - const filesRepositoryStub = {}; - const getFileCitation = sandbox.stub().returns(testCitation); - filesRepositoryStub.getFileCitation = getFileCitation; + test('should return successful result with file citation on repository success', async () => { + const testCitation = 'test citation'; + const filesRepositoryStub = {}; + const getFileCitation = sandbox.stub().returns(testCitation); + filesRepositoryStub.getFileCitation = getFileCitation; - const sut = new GetFileCitation(filesRepositoryStub); + const sut = new GetFileCitation(filesRepositoryStub); - const actual = await sut.execute(testId); + const actual = await sut.execute(testId); - assert.match(actual, testCitation); - assert.calledWithExactly(getFileCitation, testId, DatasetNotNumberedVersion.LATEST_PUBLISHED, false); - }); + assert.match(actual, testCitation); + assert.calledWithExactly(getFileCitation, testId, DatasetNotNumberedVersion.LATEST, false); + }); - test('should return error result on repository error', async () => { - const filesRepositoryStub = {}; - const testReadError = new ReadError(); - filesRepositoryStub.getFileCitation = sandbox.stub().throwsException(testReadError); - const sut = new GetFileCitation(filesRepositoryStub); + test('should return error result on repository error', async () => { + const filesRepositoryStub = {}; + const testReadError = new ReadError(); + filesRepositoryStub.getFileCitation = sandbox.stub().throwsException(testReadError); + const sut = new GetFileCitation(filesRepositoryStub); - let actualError: ReadError = undefined; - await sut.execute(testId).catch((e) => (actualError = e)); + let actualError: ReadError = undefined; + await sut.execute(testId).catch((e) => (actualError = e)); - assert.match(actualError, testReadError); - }); -}); + assert.match(actualError, testReadError); + }); +}) \ No newline at end of file From e6f662997cc668bff2003001cc6dbed5c8529279 Mon Sep 17 00:00:00 2001 From: MellyGray Date: Fri, 16 Feb 2024 18:26:02 +0100 Subject: [PATCH 5/5] fix: change env to point to unstable image --- test/integration/environment/.env | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/environment/.env b/test/integration/environment/.env index fd0e469f..80e9a14e 100644 --- a/test/integration/environment/.env +++ b/test/integration/environment/.env @@ -1,6 +1,6 @@ POSTGRES_VERSION=13 DATAVERSE_DB_USER=dataverse SOLR_VERSION=9.3.0 -DATAVERSE_IMAGE_REGISTRY=ghcr.io -DATAVERSE_IMAGE_TAG=10240-file-citation +DATAVERSE_IMAGE_REGISTRY=docker.io +DATAVERSE_IMAGE_TAG=unstable DATAVERSE_BOOTSTRAP_TIMEOUT=5m