diff --git a/docs/useCases.md b/docs/useCases.md index ebe0aee5..3fc847ae 100644 --- a/docs/useCases.md +++ b/docs/useCases.md @@ -23,6 +23,7 @@ The different use cases currently available in the package are classified below, - [Files](#Files) - [Files read use cases](#files-read-use-cases) - [Get a File](#get-a-file) + - [Get a File and its Dataset](#get-a-file-and-its-dataset) - [Get File Citation Text](#get-file-citation-text) - [Get File Counts in a Dataset](#get-file-counts-in-a-dataset) - [Get File Data Tables](#get-file-data-tables) @@ -336,6 +337,35 @@ The `fileId` parameter can be a string, for persistent identifiers, or a number, The optional `datasetVersionId` parameter can correspond to a numeric version identifier, as in the previous example, or a [DatasetNotNumberedVersion](../src/datasets/domain/models/DatasetNotNumberedVersion.ts) enum value. If not set, the default value is `DatasetNotNumberedVersion.LATEST`. +#### Get a File and its Dataset + +Returns a tuple of [File](../src/files/domain/models/File.ts) and [Dataset](../src/datasets/domain/models/Dataset.ts) objects (`[File, Dataset]`), given the search parameters to identify the file. + +The returned dataset object corresponds to the dataset version associated with the requested file. + +##### Example call: + +```typescript +import { getFileAndDataset } from '@iqss/dataverse-client-javascript'; + +/* ... */ + +const fileId = 2; +const datasetVersionId = '1.0'; + +getFileAndDataset.execute(fileId, datasetVersionId).then((fileAndDataset: [File, Dataset]) => { + /* ... */ +}); + +/* ... */ +``` + +_See [use case](../src/files/domain/useCases/GetFileAndDataset.ts)_ definition. + +The `fileId` parameter can be a string, for persistent identifiers, or a number, for numeric identifiers. + +The optional `datasetVersionId` parameter can correspond to a numeric version identifier, as in the previous example, or a [DatasetNotNumberedVersion](../src/datasets/domain/models/DatasetNotNumberedVersion.ts) enum value. If not set, the default value is `DatasetNotNumberedVersion.LATEST`. + #### Get File Citation Text Returns the File citation text. diff --git a/src/datasets/infra/repositories/transformers/datasetTransformers.ts b/src/datasets/infra/repositories/transformers/datasetTransformers.ts index 0e9b1180..1d8b168a 100644 --- a/src/datasets/infra/repositories/transformers/datasetTransformers.ts +++ b/src/datasets/infra/repositories/transformers/datasetTransformers.ts @@ -25,7 +25,7 @@ export const transformVersionResponseToDataset = (response: AxiosResponse): Data return transformVersionPayloadToDataset(versionPayload); }; -const transformVersionPayloadToDataset = (versionPayload: DatasetPayload): Dataset => { +export const transformVersionPayloadToDataset = (versionPayload: DatasetPayload): Dataset => { const datasetModel: Dataset = { id: versionPayload.datasetId, persistentId: versionPayload.datasetPersistentId, @@ -39,7 +39,7 @@ const transformVersionPayloadToDataset = (versionPayload: DatasetPayload): Datas releaseTime: new Date(versionPayload.releaseTime), }, metadataBlocks: transformPayloadToDatasetMetadataBlocks(versionPayload.metadataBlocks), - isPartOf: transformPayloadToOwnerNode(versionPayload.isPartOf), + ...(versionPayload.isPartOf && { isPartOf: transformPayloadToOwnerNode(versionPayload.isPartOf) }), }; if ('license' in versionPayload) { datasetModel.license = transformPayloadToDatasetLicense(versionPayload.license); diff --git a/src/files/domain/repositories/IFilesRepository.ts b/src/files/domain/repositories/IFilesRepository.ts index e3f16127..8dd6fa8b 100644 --- a/src/files/domain/repositories/IFilesRepository.ts +++ b/src/files/domain/repositories/IFilesRepository.ts @@ -5,6 +5,7 @@ import { FileSearchCriteria, FileOrderCriteria } from '../models/FileCriteria'; import { FileCounts } from '../models/FileCounts'; import { FileDownloadSizeMode } from '../models/FileDownloadSizeMode'; import { File } from '../models/File'; +import { Dataset } from '../../../datasets'; export interface IFilesRepository { getDatasetFiles( @@ -38,7 +39,11 @@ export interface IFilesRepository { getFileDataTables(fileId: number | string): Promise; - getFile(fileId: number | string, datasetVersionId: string): Promise; + getFile( + fileId: number | string, + datasetVersionId: string, + returnDatasetVersion: boolean, + ): Promise; getFileCitation(fileId: number | string, datasetVersionId: string, includeDeaccessioned: boolean): Promise; } diff --git a/src/files/domain/useCases/GetFile.ts b/src/files/domain/useCases/GetFile.ts index 6eb65991..dfa2a51e 100644 --- a/src/files/domain/useCases/GetFile.ts +++ b/src/files/domain/useCases/GetFile.ts @@ -1,8 +1,9 @@ import { IFilesRepository } from '../repositories/IFilesRepository'; import { File } from '../models/File'; import { DatasetNotNumberedVersion } from '../../../datasets'; +import { UseCase } from '../../../core/domain/useCases/UseCase'; -export class GetFile { +export class GetFile implements UseCase { constructor(private readonly filesRepository: IFilesRepository) {} /** @@ -16,6 +17,6 @@ export class GetFile { fileId: number | string, datasetVersionId: string | DatasetNotNumberedVersion = DatasetNotNumberedVersion.LATEST, ): Promise { - return await this.filesRepository.getFile(fileId, datasetVersionId); + return (await this.filesRepository.getFile(fileId, datasetVersionId, false)) as File; } } diff --git a/src/files/domain/useCases/GetFileAndDataset.ts b/src/files/domain/useCases/GetFileAndDataset.ts new file mode 100644 index 00000000..de9c22ac --- /dev/null +++ b/src/files/domain/useCases/GetFileAndDataset.ts @@ -0,0 +1,22 @@ +import { IFilesRepository } from '../repositories/IFilesRepository'; +import { File } from '../models/File'; +import { DatasetNotNumberedVersion, Dataset } from '../../../datasets'; +import { UseCase } from '../../../core/domain/useCases/UseCase'; + +export class GetFileAndDataset implements UseCase<[File, Dataset]> { + constructor(private readonly filesRepository: IFilesRepository) {} + + /** + * Returns a tuple including the File instance and the associated Dataset, given the search parameters to identify the File. + * + * @param {number | string} [fileId] - The File identifier, which can be a string (for persistent identifiers), or a number (for numeric identifiers). + * @param {string | DatasetNotNumberedVersion} [datasetVersionId=DatasetNotNumberedVersion.LATEST] - The dataset version identifier, which can be a version-specific numeric string (for example, 1.0) or a DatasetNotNumberedVersion enum value. If this parameter is not set, the default value is: DatasetNotNumberedVersion.LATEST + * @returns {Promise<[File, Dataset]>} + */ + async execute( + fileId: number | string, + datasetVersionId: string | DatasetNotNumberedVersion = DatasetNotNumberedVersion.LATEST, + ): Promise<[File, Dataset]> { + return (await this.filesRepository.getFile(fileId, datasetVersionId, true)) as [File, Dataset]; + } +} diff --git a/src/files/index.ts b/src/files/index.ts index c50c3785..0c17b1ff 100644 --- a/src/files/index.ts +++ b/src/files/index.ts @@ -7,6 +7,7 @@ import { GetFileDataTables } from './domain/useCases/GetFileDataTables'; import { GetDatasetFilesTotalDownloadSize } from './domain/useCases/GetDatasetFilesTotalDownloadSize'; import { GetFile } from './domain/useCases/GetFile'; import { GetFileCitation } from './domain/useCases/GetFileCitation'; +import { GetFileAndDataset } from './domain/useCases/GetFileAndDataset'; const filesRepository = new FilesRepository(); @@ -17,6 +18,7 @@ const getFileUserPermissions = new GetFileUserPermissions(filesRepository); const getFileDataTables = new GetFileDataTables(filesRepository); const getDatasetFilesTotalDownloadSize = new GetDatasetFilesTotalDownloadSize(filesRepository); const getFile = new GetFile(filesRepository); +const getFileAndDataset = new GetFileAndDataset(filesRepository); const getFileCitation = new GetFileCitation(filesRepository); export { @@ -27,6 +29,7 @@ export { getDatasetFileCounts, getDatasetFilesTotalDownloadSize, getFile, + getFileAndDataset, getFileCitation, }; diff --git a/src/files/infra/repositories/FilesRepository.ts b/src/files/infra/repositories/FilesRepository.ts index 7fd4a64a..f9a6907e 100644 --- a/src/files/infra/repositories/FilesRepository.ts +++ b/src/files/infra/repositories/FilesRepository.ts @@ -11,6 +11,7 @@ import { FileSearchCriteria, FileOrderCriteria } from '../../domain/models/FileC import { FileCounts } from '../../domain/models/FileCounts'; import { transformFileCountsResponseToFileCounts } from './transformers/fileCountsTransformers'; import { FileDownloadSizeMode } from '../../domain/models/FileDownloadSizeMode'; +import { Dataset } from '../../../datasets'; export interface GetFilesQueryParams { includeDeaccessioned: boolean; @@ -144,11 +145,16 @@ export class FilesRepository extends ApiRepository implements IFilesRepository { }); } - public async getFile(fileId: number | string, datasetVersionId: string): Promise { + public async getFile( + fileId: number | string, + datasetVersionId: string, + returnDatasetVersion: boolean, + ): Promise { return this.doGet(this.buildApiEndpoint(this.filesResourceName, `versions/${datasetVersionId}`, fileId), true, { + returnDatasetVersion: returnDatasetVersion, returnOwners: true, }) - .then((response) => transformFileResponseToFile(response)) + .then((response) => transformFileResponseToFile(response, returnDatasetVersion)) .catch((error) => { throw error; }); diff --git a/src/files/infra/repositories/transformers/fileTransformers.ts b/src/files/infra/repositories/transformers/fileTransformers.ts index abf4c783..202fcfda 100644 --- a/src/files/infra/repositories/transformers/fileTransformers.ts +++ b/src/files/infra/repositories/transformers/fileTransformers.ts @@ -1,6 +1,8 @@ import { File, FileEmbargo, FileChecksum } from '../../../domain/models/File'; import { AxiosResponse } from 'axios'; import { FilesSubset } from '../../../domain/models/FilesSubset'; +import { Dataset } from '../../../../datasets'; +import { transformVersionPayloadToDataset } from '../../../../datasets/infra/repositories/transformers/datasetTransformers'; import { ChecksumPayload, EmbargoPayload, FilePayload } from './FilePayload'; import { transformPayloadToOwnerNode } from '../../../../core/infra/repositories/transformers/dvObjectOwnerNodeTransformer'; @@ -17,8 +19,14 @@ export const transformFilesResponseToFilesSubset = (response: AxiosResponse): Fi }; }; -export const transformFileResponseToFile = (response: AxiosResponse): File => { +export const transformFileResponseToFile = ( + response: AxiosResponse, + returnDatasetVersion: boolean, +): File | [File, Dataset] => { const filePayload = response.data.data; + if (returnDatasetVersion) { + return [transformFilePayloadToFile(filePayload), transformVersionPayloadToDataset(filePayload.datasetVersion)]; + } return transformFilePayloadToFile(filePayload); }; diff --git a/test/integration/files/FilesRepository.test.ts b/test/integration/files/FilesRepository.test.ts index baafaf2a..fe817bc6 100644 --- a/test/integration/files/FilesRepository.test.ts +++ b/test/integration/files/FilesRepository.test.ts @@ -7,7 +7,8 @@ import { registerFileViaApi, uploadFileViaApi } from '../../testHelpers/files/fi 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'; -import { DatasetNotNumberedVersion } from '../../../src/datasets'; +import { DatasetNotNumberedVersion, Dataset } from '../../../src/datasets'; +import { File } from '../../../src/files/domain/models/File'; import { FileCounts } from '../../../src/files/domain/models/FileCounts'; import { FileDownloadSizeMode } from '../../../src'; import { fail } from 'assert'; @@ -454,21 +455,28 @@ 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); + const actual: File = (await sut.getFile(testFileId, DatasetNotNumberedVersion.LATEST, false)) as File; 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); + const actual: File = (await sut.getFile(testFileId, DatasetNotNumberedVersion.DRAFT, false)) as File; assert.match(actual.name, testTextFile1Name); }); + test('should return file and dataset when providing id, version, and returnDatasetVersion is true', async () => { + const actual = (await sut.getFile(testFileId, DatasetNotNumberedVersion.DRAFT, true)) as [File, Dataset]; + + assert.match(actual[0].name, testTextFile1Name); + assert.match(actual[1].id, TestConstants.TEST_CREATED_DATASET_1_ID); + }); + 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, false).catch((e) => (error = e)); assert.match( error.message, @@ -478,13 +486,13 @@ describe('FilesRepository', () => { }); describe('by persistent id', () => { test('should return file when providing a valid persistent id', async () => { - const actual = await sut.getFile(testFilePersistentId, DatasetNotNumberedVersion.LATEST); + const actual = (await sut.getFile(testFilePersistentId, DatasetNotNumberedVersion.LATEST, false)) as File; assert.match(actual.name, testTextFile1Name); }); test('should return file draft when providing a valid persistent id and version is draft', async () => { - const actual = await sut.getFile(testFilePersistentId, DatasetNotNumberedVersion.DRAFT); + const actual = (await sut.getFile(testFilePersistentId, DatasetNotNumberedVersion.DRAFT, false)) as File; assert.match(actual.name, testTextFile1Name); }); @@ -493,7 +501,9 @@ describe('FilesRepository', () => { let error: ReadError = undefined; const nonExistentFiledPersistentId = 'nonExistentFiledPersistentId'; - await sut.getFile(nonExistentFiledPersistentId, DatasetNotNumberedVersion.LATEST).catch((e) => (error = e)); + await sut + .getFile(nonExistentFiledPersistentId, DatasetNotNumberedVersion.LATEST, false) + .catch((e) => (error = e)); assert.match( error.message, diff --git a/test/unit/files/FilesRepository.test.ts b/test/unit/files/FilesRepository.test.ts index 82149f03..8cc97a5e 100644 --- a/test/unit/files/FilesRepository.test.ts +++ b/test/unit/files/FilesRepository.test.ts @@ -777,37 +777,45 @@ describe('FilesRepository', () => { }); }); describe('getFile', () => { - const expectedConfigApiKey = { - ...TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, - params: { returnOwners: true }, + const expectedRequestParams = { + returnDatasetVersion: false, + returnOwners: true }; - const expectedConfigSessionCookie = { - ...TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_SESSION_COOKIE, - params: { returnOwners: true }, + + const expectedRequestConfigApiKey = { + params: expectedRequestParams, + headers: TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY.headers, + }; + + const expectedRequestConfigSessionCookie = { + params: expectedRequestParams, + headers: TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY.headers, + }; + + const testGetFileResponse = { + data: { + status: 'OK', + data: createFilePayload(), + }, }; + describe('by numeric id', () => { const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/files/${testFile.id}/versions/${DatasetNotNumberedVersion.LATEST}`; - 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); + let actual = await sut.getFile(testFile.id, DatasetNotNumberedVersion.LATEST, false); - assert.calledWithExactly(axiosGetStub, expectedApiEndpoint, expectedConfigApiKey); + assert.calledWithExactly(axiosGetStub, expectedApiEndpoint, expectedRequestConfigApiKey); assert.match(actual, createFileModel()); // Session cookie auth ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.SESSION_COOKIE); - actual = await sut.getFile(testFile.id, DatasetNotNumberedVersion.LATEST); + actual = await sut.getFile(testFile.id, DatasetNotNumberedVersion.LATEST, false); - assert.calledWithExactly(axiosGetStub, expectedApiEndpoint, expectedConfigSessionCookie); + assert.calledWithExactly(axiosGetStub, expectedApiEndpoint, expectedRequestConfigSessionCookie); assert.match(actual, createFileModel()); }); @@ -815,35 +823,29 @@ describe('FilesRepository', () => { 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)); + await sut.getFile(testFile.id, DatasetNotNumberedVersion.LATEST, false).catch((e) => (error = e)); - assert.calledWithExactly(axiosGetStub, expectedApiEndpoint, expectedConfigApiKey); + assert.calledWithExactly(axiosGetStub, expectedApiEndpoint, expectedRequestConfigApiKey); expect(error).to.be.instanceOf(Error); }); }); describe('by persistent id', () => { const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/files/:persistentId/versions/${DatasetNotNumberedVersion.LATEST}?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); + let actual = await sut.getFile(TestConstants.TEST_DUMMY_PERSISTENT_ID, DatasetNotNumberedVersion.LATEST, false); - assert.calledWithExactly(axiosGetStub, expectedApiEndpoint, expectedConfigApiKey); + assert.calledWithExactly(axiosGetStub, expectedApiEndpoint, expectedRequestConfigApiKey); 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); + actual = await sut.getFile(TestConstants.TEST_DUMMY_PERSISTENT_ID, DatasetNotNumberedVersion.LATEST, false); - assert.calledWithExactly(axiosGetStub, expectedApiEndpoint, expectedConfigSessionCookie); + assert.calledWithExactly(axiosGetStub, expectedApiEndpoint, expectedRequestConfigSessionCookie); assert.match(actual, createFileModel()); }); @@ -852,10 +854,10 @@ describe('FilesRepository', () => { let error: ReadError = undefined; await sut - .getFile(TestConstants.TEST_DUMMY_PERSISTENT_ID, DatasetNotNumberedVersion.LATEST) + .getFile(TestConstants.TEST_DUMMY_PERSISTENT_ID, DatasetNotNumberedVersion.LATEST, false) .catch((e) => (error = e)); - assert.calledWithExactly(axiosGetStub, expectedApiEndpoint, expectedConfigApiKey); + assert.calledWithExactly(axiosGetStub, expectedApiEndpoint, expectedRequestConfigApiKey); expect(error).to.be.instanceOf(Error); }); }); diff --git a/test/unit/files/GetFile.test.ts b/test/unit/files/GetFile.test.ts index 385666f8..92d67777 100644 --- a/test/unit/files/GetFile.test.ts +++ b/test/unit/files/GetFile.test.ts @@ -1,64 +1,63 @@ -import {assert, createSandbox, SinonSandbox} from "sinon"; -import {createFileModel} from "../../testHelpers/files/filesHelper"; -import {IFilesRepository} from "../../../src/files/domain/repositories/IFilesRepository"; -import {GetFile} from "../../../src/files/domain/useCases/GetFile"; -import {DatasetNotNumberedVersion, ReadError} from "../../../src"; +import { assert, createSandbox, SinonSandbox } from 'sinon'; +import { createFileModel } from '../../testHelpers/files/filesHelper'; +import { IFilesRepository } from '../../../src/files/domain/repositories/IFilesRepository'; +import { GetFile } from '../../../src/files/domain/useCases/GetFile'; +import { DatasetNotNumberedVersion, ReadError } from '../../../src'; describe('execute', () => { - const sandbox: SinonSandbox = createSandbox(); + const sandbox: SinonSandbox = createSandbox(); - afterEach(() => { - sandbox.restore(); - }); + const testFile = createFileModel(); - test('should return file on repository success when passing numeric id', async () => { - const testFile = createFileModel(); - const filesRepositoryStub = {}; - const getFileStub = sandbox.stub().returns(testFile); - filesRepositoryStub.getFile = getFileStub; - const sut = new GetFile(filesRepositoryStub); + afterEach(() => { + sandbox.restore(); + }); - const actual = await sut.execute(1); + test('should return file on repository success when passing numeric id', async () => { + const filesRepositoryStub = {}; + const getFileStub = sandbox.stub().returns(testFile); + filesRepositoryStub.getFile = getFileStub; + const sut = new GetFile(filesRepositoryStub); - assert.match(actual, testFile); - assert.calledWithExactly(getFileStub, 1, DatasetNotNumberedVersion.LATEST); - }) + const actual = await sut.execute(1); - test('should return file on repository success when passing string id', async () => { - const testFile = createFileModel(); - const filesRepositoryStub = {}; - const getFileStub = sandbox.stub().returns(testFile); - filesRepositoryStub.getFile = getFileStub; - const sut = new GetFile(filesRepositoryStub); + assert.match(actual, testFile); + assert.calledWithExactly(getFileStub, 1, DatasetNotNumberedVersion.LATEST, false); + }); - const actual = await sut.execute('doi:10.5072/FK2/J8SJZB'); + test('should return file on repository success when passing string id', async () => { + const filesRepositoryStub = {}; + const getFileStub = sandbox.stub().returns(testFile); + filesRepositoryStub.getFile = getFileStub; + const sut = new GetFile(filesRepositoryStub); - assert.match(actual, testFile); - assert.calledWithExactly(getFileStub, 'doi:10.5072/FK2/J8SJZB', DatasetNotNumberedVersion.LATEST); - }) + const actual = await sut.execute('doi:10.5072/FK2/J8SJZB'); - test('should return file on repository success when passing string id and version id', async () => { - const testFile = createFileModel(); - const filesRepositoryStub = {}; - const getFileStub = sandbox.stub().returns(testFile); - filesRepositoryStub.getFile = getFileStub; - const sut = new GetFile(filesRepositoryStub); + assert.match(actual, testFile); + assert.calledWithExactly(getFileStub, 'doi:10.5072/FK2/J8SJZB', DatasetNotNumberedVersion.LATEST, false); + }); - const actual = await sut.execute('doi:10.5072/FK2/J8SJZB', '2.0'); + test('should return file on repository success when passing string id and version id', async () => { + const filesRepositoryStub = {}; + const getFileStub = sandbox.stub().returns(testFile); + filesRepositoryStub.getFile = getFileStub; + const sut = new GetFile(filesRepositoryStub); - assert.match(actual, testFile); - assert.calledWithExactly(getFileStub, 'doi:10.5072/FK2/J8SJZB', '2.0'); - }) + const actual = await sut.execute('doi:10.5072/FK2/J8SJZB', '2.0'); - test('should return error result on repository error', async () => { - const filesRepositoryStub = {}; - const testReadError = new ReadError(); - filesRepositoryStub.getFile = sandbox.stub().throwsException(testReadError); - const sut = new GetFile(filesRepositoryStub); + assert.match(actual, testFile); + assert.calledWithExactly(getFileStub, 'doi:10.5072/FK2/J8SJZB', '2.0', false); + }); - let actualError: ReadError = undefined; - await sut.execute(1).catch((e) => (actualError = e)); + test('should return error result on repository error', async () => { + const filesRepositoryStub = {}; + const testReadError = new ReadError(); + filesRepositoryStub.getFile = sandbox.stub().throwsException(testReadError); + const sut = new GetFile(filesRepositoryStub); - assert.match(actualError, testReadError); - }) + let actualError: ReadError = undefined; + await sut.execute(1).catch((e) => (actualError = e)); + + assert.match(actualError, testReadError); + }); }); diff --git a/test/unit/files/GetFileAndDataset.test.ts b/test/unit/files/GetFileAndDataset.test.ts new file mode 100644 index 00000000..640ecc3b --- /dev/null +++ b/test/unit/files/GetFileAndDataset.test.ts @@ -0,0 +1,69 @@ +import { assert, createSandbox, SinonSandbox } from 'sinon'; +import { createFileModel } from '../../testHelpers/files/filesHelper'; +import { IFilesRepository } from '../../../src/files/domain/repositories/IFilesRepository'; +import { DatasetNotNumberedVersion, ReadError } from '../../../src'; +import { createDatasetModel } from '../../testHelpers/datasets/datasetHelper'; +import { GetFileAndDataset } from '../../../src/files/domain/useCases/GetFileAndDataset'; + +describe('execute', () => { + const sandbox: SinonSandbox = createSandbox(); + + const testFile = createFileModel(); + const testDataset = createDatasetModel(); + const testTuple = [testFile, testDataset]; + + afterEach(() => { + sandbox.restore(); + }); + + test('should return file and dataset on repository success when passing numeric id', async () => { + const filesRepositoryStub = {}; + const getFileStub = sandbox.stub().returns(testTuple); + filesRepositoryStub.getFile = getFileStub; + const sut = new GetFileAndDataset(filesRepositoryStub); + + const actual = await sut.execute(1); + + assert.match(actual[0], testFile); + assert.match(actual[1], testDataset); + assert.calledWithExactly(getFileStub, 1, DatasetNotNumberedVersion.LATEST, true); + }); + + test('should return file and dataset on repository success when passing string id', async () => { + const filesRepositoryStub = {}; + const getFileStub = sandbox.stub().returns(testTuple); + filesRepositoryStub.getFile = getFileStub; + const sut = new GetFileAndDataset(filesRepositoryStub); + + const actual = await sut.execute('doi:10.5072/FK2/J8SJZB'); + + assert.match(actual[0], testFile); + assert.match(actual[1], testDataset); + assert.calledWithExactly(getFileStub, 'doi:10.5072/FK2/J8SJZB', DatasetNotNumberedVersion.LATEST, true); + }); + + test('should return file and dataset on repository success when passing string id and version id', async () => { + const filesRepositoryStub = {}; + const getFileStub = sandbox.stub().returns(testTuple); + filesRepositoryStub.getFile = getFileStub; + const sut = new GetFileAndDataset(filesRepositoryStub); + + const actual = await sut.execute('doi:10.5072/FK2/J8SJZB', '2.0'); + + assert.match(actual[0], testFile); + assert.match(actual[1], testDataset); + assert.calledWithExactly(getFileStub, 'doi:10.5072/FK2/J8SJZB', '2.0', true); + }); + + test('should return error result on repository error', async () => { + const filesRepositoryStub = {}; + const testReadError = new ReadError(); + filesRepositoryStub.getFile = sandbox.stub().throwsException(testReadError); + const sut = new GetFileAndDataset(filesRepositoryStub); + + let actualError: ReadError = undefined; + await sut.execute(1).catch((e) => (actualError = e)); + + assert.match(actualError, testReadError); + }); +});