diff --git a/src/datasets/domain/repositories/IDatasetsRepository.ts b/src/datasets/domain/repositories/IDatasetsRepository.ts index 41c7ca78..fa3c697d 100644 --- a/src/datasets/domain/repositories/IDatasetsRepository.ts +++ b/src/datasets/domain/repositories/IDatasetsRepository.ts @@ -15,5 +15,9 @@ export interface IDatasetsRepository { getDatasetUserPermissions(datasetId: number | string): Promise; getDatasetLocks(datasetId: number | string): Promise; getAllDatasetPreviews(limit?: number, offset?: number): Promise; - createDataset(newDataset: NewDatasetDTO, datasetMetadataBlocks: MetadataBlock[], collectionId: string): Promise; + createDataset( + newDataset: NewDatasetDTO, + datasetMetadataBlocks: MetadataBlock[], + collectionId: string, + ): Promise; } diff --git a/src/datasets/domain/useCases/CreateDataset.ts b/src/datasets/domain/useCases/CreateDataset.ts index da73e517..ca352d82 100644 --- a/src/datasets/domain/useCases/CreateDataset.ts +++ b/src/datasets/domain/useCases/CreateDataset.ts @@ -23,20 +23,17 @@ export class CreateDataset implements UseCase { async execute(newDataset: NewDatasetDTO, collectionId: string = 'root'): Promise { const metadataBlocks = await this.getNewDatasetMetadataBlocks(newDataset); - return await this.newDatasetValidator.validate(newDataset, metadataBlocks).then(async () => { - return await this.datasetsRepository.createDataset(newDataset, metadataBlocks, collectionId); - }); + this.newDatasetValidator.validate(newDataset, metadataBlocks); + return this.datasetsRepository.createDataset(newDataset, metadataBlocks, collectionId); } async getNewDatasetMetadataBlocks(newDataset: NewDatasetDTO): Promise { let metadataBlocks: MetadataBlock[] = []; - for (const metadataBlockValue in newDataset.metadataBlockValues) { - metadataBlocks.push( - await this.metadataBlocksRepository.getMetadataBlockByName( - (metadataBlockValue as unknown as NewDatasetMetadataBlockValuesDTO).name, - ), - ); - } + await Promise.all( + newDataset.metadataBlockValues.map(async (metadataBlockValue: NewDatasetMetadataBlockValuesDTO) => { + metadataBlocks.push(await this.metadataBlocksRepository.getMetadataBlockByName(metadataBlockValue.name)); + }), + ); return metadataBlocks; } } diff --git a/src/datasets/domain/useCases/validators/NewDatasetValidator.ts b/src/datasets/domain/useCases/validators/NewDatasetValidator.ts index d5f63692..6c969610 100644 --- a/src/datasets/domain/useCases/validators/NewDatasetValidator.ts +++ b/src/datasets/domain/useCases/validators/NewDatasetValidator.ts @@ -203,7 +203,9 @@ export class NewDatasetValidator implements NewResourceValidator { } private isEmptyArray(metadataFieldValue: NewDatasetMetadataFieldValueDTO): boolean { - return Array.isArray(metadataFieldValue) && (metadataFieldValue as Array).length == 0; + return ( + Array.isArray(metadataFieldValue) && (metadataFieldValue as Array).length == 0 + ); } private isValidArrayType( diff --git a/src/datasets/infra/repositories/transformers/newDatasetTransformers.ts b/src/datasets/infra/repositories/transformers/newDatasetTransformers.ts index b4ff1f37..5ae104b5 100644 --- a/src/datasets/infra/repositories/transformers/newDatasetTransformers.ts +++ b/src/datasets/infra/repositories/transformers/newDatasetTransformers.ts @@ -71,7 +71,8 @@ export const transformMetadataFieldModelsToRequestPayload = ( ): MetadataFieldRequestPayload[] => { let metadataFieldsRequestPayload: MetadataFieldRequestPayload[] = []; for (const metadataFieldKey of Object.keys(newDatasetMetadataFields)) { - const newDatasetMetadataChildFieldValue: NewDatasetMetadataFieldValueDTO = newDatasetMetadataFields[metadataFieldKey]; + const newDatasetMetadataChildFieldValue: NewDatasetMetadataFieldValueDTO = + newDatasetMetadataFields[metadataFieldKey]; metadataFieldsRequestPayload.push({ value: transformMetadataFieldValueToRequestPayload( newDatasetMetadataChildFieldValue, diff --git a/test/unit/datasets/CreateDataset.test.ts b/test/unit/datasets/CreateDataset.test.ts index 6cfd4544..f3f91388 100644 --- a/test/unit/datasets/CreateDataset.test.ts +++ b/test/unit/datasets/CreateDataset.test.ts @@ -5,7 +5,7 @@ import { assert, createSandbox, SinonSandbox } from 'sinon'; import { NewResourceValidator } from '../../../src/core/domain/useCases/validators/NewResourceValidator'; import { createNewDatasetDTO, createNewDatasetMetadataBlockModel } from '../../testHelpers/datasets/newDatasetHelper'; import { ResourceValidationError } from '../../../src/core/domain/useCases/validators/errors/ResourceValidationError'; -import { WriteError } from '../../../src'; +import { WriteError, ReadError } from '../../../src'; import { IMetadataBlocksRepository } from '../../../src/metadataBlocks/domain/repositories/IMetadataBlocksRepository'; describe('execute', () => { @@ -17,13 +17,6 @@ describe('execute', () => { sandbox.restore(); }); - function setupMetadataBlocksRepositoryStub(): IMetadataBlocksRepository { - const metadataBlocksRepositoryStub = {}; - const getMetadataBlockByNameStub = sandbox.stub().resolves(testMetadataBlocks[0]); - metadataBlocksRepositoryStub.getMetadataBlockByName = getMetadataBlockByNameStub; - return metadataBlocksRepositoryStub; - } - test('should return new dataset identifiers when validation is successful and repository call is successful', async () => { const testCreatedDatasetIdentifiers: CreatedDatasetIdentifiers = { persistentId: 'test', @@ -38,12 +31,17 @@ describe('execute', () => { const validateStub = sandbox.stub().resolves(); newDatasetValidatorStub.validate = validateStub; - const sut = new CreateDataset(datasetsRepositoryStub, setupMetadataBlocksRepositoryStub(), newDatasetValidatorStub); + const metadataBlocksRepositoryStub = {}; + const getMetadataBlockByNameStub = sandbox.stub().resolves(testMetadataBlocks[0]); + metadataBlocksRepositoryStub.getMetadataBlockByName = getMetadataBlockByNameStub; + + const sut = new CreateDataset(datasetsRepositoryStub, metadataBlocksRepositoryStub, newDatasetValidatorStub); const actual = await sut.execute(testDataset); assert.match(actual, testCreatedDatasetIdentifiers); + assert.calledWithExactly(getMetadataBlockByNameStub, testMetadataBlocks[0].name); assert.calledWithExactly(validateStub, testDataset, testMetadataBlocks); assert.calledWithExactly(createDatasetStub, testDataset, testMetadataBlocks, 'root'); @@ -51,22 +49,27 @@ describe('execute', () => { }); test('should throw ResourceValidationError and not call repository when validation is unsuccessful', async () => { - const datasetsRepositoryStub = {}; - const createDatasetStub = sandbox.stub(); - datasetsRepositoryStub.createDataset = createDatasetStub; + const datasetsRepositoryMock = {}; + const createDatasetMock = sandbox.stub(); + datasetsRepositoryMock.createDataset = createDatasetMock; const newDatasetValidatorStub = {}; const testValidationError = new ResourceValidationError('Test error'); const validateStub = sandbox.stub().throwsException(testValidationError); newDatasetValidatorStub.validate = validateStub; - const sut = new CreateDataset(datasetsRepositoryStub, setupMetadataBlocksRepositoryStub(), newDatasetValidatorStub); + const metadataBlocksRepositoryStub = {}; + const getMetadataBlockByNameStub = sandbox.stub().resolves(testMetadataBlocks[0]); + metadataBlocksRepositoryStub.getMetadataBlockByName = getMetadataBlockByNameStub; + + const sut = new CreateDataset(datasetsRepositoryMock, metadataBlocksRepositoryStub, newDatasetValidatorStub); let actualError: ResourceValidationError = undefined; await sut.execute(testDataset).catch((e) => (actualError = e)); assert.match(actualError, testValidationError); + assert.calledWithExactly(getMetadataBlockByNameStub, testMetadataBlocks[0].name); assert.calledWithExactly(validateStub, testDataset, testMetadataBlocks); - assert.notCalled(createDatasetStub); + assert.notCalled(createDatasetMock); }); test('should throw WriteError when validation is successful and repository raises an error', async () => { @@ -79,14 +82,44 @@ describe('execute', () => { const validateMock = sandbox.stub().resolves(); newDatasetValidatorStub.validate = validateMock; - const sut = new CreateDataset(datasetsRepositoryStub, setupMetadataBlocksRepositoryStub(), newDatasetValidatorStub); - let actualError: ResourceValidationError = undefined; + const metadataBlocksRepositoryStub = {}; + const getMetadataBlockByNameStub = sandbox.stub().resolves(testMetadataBlocks[0]); + metadataBlocksRepositoryStub.getMetadataBlockByName = getMetadataBlockByNameStub; + + const sut = new CreateDataset(datasetsRepositoryStub, metadataBlocksRepositoryStub, newDatasetValidatorStub); + let actualError: WriteError = undefined; await sut.execute(testDataset).catch((e) => (actualError = e)); assert.match(actualError, testWriteError); + assert.calledWithExactly(getMetadataBlockByNameStub, testMetadataBlocks[0].name); assert.calledWithExactly(validateMock, testDataset, testMetadataBlocks); assert.calledWithExactly(createDatasetStub, testDataset, testMetadataBlocks, 'root'); assert.callOrder(validateMock, createDatasetStub); }); + + test('should throw ReadError when metadata blocks repository raises an error', async () => { + const datasetsRepositoryMock = {}; + const createDatasetMock = sandbox.stub(); + datasetsRepositoryMock.createDataset = createDatasetMock; + + const newDatasetValidatorMock = {}; + const validateMock = sandbox.stub().resolves(); + newDatasetValidatorMock.validate = validateMock; + + const metadataBlocksRepositoryStub = {}; + const testReadError = new ReadError('Test error'); + const getMetadataBlockByNameStub = sandbox.stub().throwsException(testReadError); + metadataBlocksRepositoryStub.getMetadataBlockByName = getMetadataBlockByNameStub; + + const sut = new CreateDataset(datasetsRepositoryMock, metadataBlocksRepositoryStub, newDatasetValidatorMock); + let actualError: ReadError = undefined; + await sut.execute(testDataset).catch((e) => (actualError = e)); + assert.match(actualError, testReadError); + + assert.notCalled(validateMock); + assert.notCalled(createDatasetMock); + + assert.calledWithExactly(getMetadataBlockByNameStub, testMetadataBlocks[0].name); + }); });