From 97c47fdbad01efb1a0aa83aa0334de3acc55c6f3 Mon Sep 17 00:00:00 2001 From: GPortas Date: Fri, 19 Jan 2024 16:40:49 +0000 Subject: [PATCH] Changed: returning ids when the dataset is created --- .../models/CreatedDatasetIdentifiers.ts | 4 + .../repositories/IDatasetsRepository.ts | 2 +- src/datasets/domain/useCases/CreateDataset.ts | 5 +- .../infra/repositories/DatasetsRepository.ts | 11 +- .../datasets/DatasetsRepository.test.ts | 106 +++++++++++------- test/integration/environment/setup.js | 5 +- test/unit/datasets/CreateDataset.test.ts | 16 ++- test/unit/datasets/DatasetsRepository.test.ts | 25 ++++- 8 files changed, 118 insertions(+), 56 deletions(-) create mode 100644 src/datasets/domain/models/CreatedDatasetIdentifiers.ts diff --git a/src/datasets/domain/models/CreatedDatasetIdentifiers.ts b/src/datasets/domain/models/CreatedDatasetIdentifiers.ts new file mode 100644 index 00000000..c4dc825a --- /dev/null +++ b/src/datasets/domain/models/CreatedDatasetIdentifiers.ts @@ -0,0 +1,4 @@ +export interface CreatedDatasetIdentifiers { + persistentId: string; + numericId: number; +} diff --git a/src/datasets/domain/repositories/IDatasetsRepository.ts b/src/datasets/domain/repositories/IDatasetsRepository.ts index 2540cc9e..929e8f54 100644 --- a/src/datasets/domain/repositories/IDatasetsRepository.ts +++ b/src/datasets/domain/repositories/IDatasetsRepository.ts @@ -14,5 +14,5 @@ export interface IDatasetsRepository { getDatasetUserPermissions(datasetId: number | string): Promise; getDatasetLocks(datasetId: number | string): Promise; getAllDatasetPreviews(limit?: number, offset?: number): Promise; - createDataset(newDataset: NewDataset, datasetMetadataBlocks: MetadataBlock[], collectionId: string): Promise; + createDataset(newDataset: NewDataset, datasetMetadataBlocks: MetadataBlock[], collectionId: string): Promise; } diff --git a/src/datasets/domain/useCases/CreateDataset.ts b/src/datasets/domain/useCases/CreateDataset.ts index fd51289f..7840446c 100644 --- a/src/datasets/domain/useCases/CreateDataset.ts +++ b/src/datasets/domain/useCases/CreateDataset.ts @@ -4,8 +4,9 @@ import { NewDataset, NewDatasetMetadataBlockValues } from '../models/NewDataset' import { NewResourceValidator } from '../../../core/domain/useCases/validators/NewResourceValidator'; import { IMetadataBlocksRepository } from '../../../metadataBlocks/domain/repositories/IMetadataBlocksRepository'; import { MetadataBlock } from '../../../metadataBlocks'; +import { CreatedDatasetIdentifiers } from '../models/CreatedDatasetIdentifiers'; -export class CreateDataset implements UseCase { +export class CreateDataset implements UseCase { private datasetsRepository: IDatasetsRepository; private metadataBlocksRepository: IMetadataBlocksRepository; private newDatasetValidator: NewResourceValidator; @@ -20,7 +21,7 @@ export class CreateDataset implements UseCase { this.newDatasetValidator = newDatasetValidator; } - async execute(newDataset: NewDataset, collectionId: string = 'root'): Promise { + async execute(newDataset: NewDataset, 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); diff --git a/src/datasets/infra/repositories/DatasetsRepository.ts b/src/datasets/infra/repositories/DatasetsRepository.ts index f33b381e..ba0dfd75 100644 --- a/src/datasets/infra/repositories/DatasetsRepository.ts +++ b/src/datasets/infra/repositories/DatasetsRepository.ts @@ -11,6 +11,7 @@ import { DatasetPreviewSubset } from '../../domain/models/DatasetPreviewSubset'; import { NewDataset } from '../../domain/models/NewDataset'; import { MetadataBlock } from '../../../metadataBlocks'; import { transformNewDatasetModelToRequestPayload } from './transformers/newDatasetTransformers'; +import { CreatedDatasetIdentifiers } from '../../domain/models/CreatedDatasetIdentifiers'; export interface GetAllDatasetPreviewsQueryParams { per_page?: number; @@ -114,12 +115,18 @@ export class DatasetsRepository extends ApiRepository implements IDatasetsReposi newDataset: NewDataset, datasetMetadataBlocks: MetadataBlock[], collectionId: string, - ): Promise { + ): Promise { return this.doPost( `/dataverses/${collectionId}/datasets`, transformNewDatasetModelToRequestPayload(newDataset, datasetMetadataBlocks), ) - .then(() => {}) + .then((response) => { + const responseData = response.data.data; + return { + persistentId: responseData.persistentId, + numericId: responseData.id, + }; + }) .catch((error) => { throw error; }); diff --git a/test/integration/datasets/DatasetsRepository.test.ts b/test/integration/datasets/DatasetsRepository.test.ts index a9c7eaa4..d6003261 100644 --- a/test/integration/datasets/DatasetsRepository.test.ts +++ b/test/integration/datasets/DatasetsRepository.test.ts @@ -14,6 +14,7 @@ import { ApiConfig } from '../../../src'; import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig'; import { NewDataset } from '../../../src/datasets/domain/models/NewDataset'; import { MetadataBlocksRepository } from '../../../src/metadataBlocks/infra/repositories/MetadataBlocksRepository'; +import { Author, DatasetContact, DatasetDescription } from '../../../src/datasets/domain/models/Dataset'; describe('DatasetsRepository', () => { const sut: DatasetsRepository = new DatasetsRepository(); @@ -247,52 +248,75 @@ describe('DatasetsRepository', () => { }); describe('createDataset', () => { - const testNewDatasetTitle = 'Dataset created using the createDataset use case'; - const testNewDataset: NewDataset = { - metadataBlockValues: [ - { - name: 'citation', - fields: { - title: testNewDatasetTitle, - author: [ - { - authorName: 'Admin, Dataverse', - authorAffiliation: 'Dataverse.org', - }, - { - authorName: 'Owner, Dataverse', - authorAffiliation: 'Dataverse.org', - }, - ], - datasetContact: [ - { - datasetContactEmail: 'finch@mailinator.com', - datasetContactName: 'Finch, Fiona', - }, - ], - dsDescription: [ - { - dsDescriptionValue: 'This is the description of the dataset.', - }, - ], - subject: ['Medicine, Health and Life Sciences'], + test('should create a dataset with the provided dataset citation fields', async () => { + const testTitle = 'Dataset created using the createDataset use case'; + const testAuthorName1 = 'Admin, Dataverse'; + const testAuthorName2 = 'Owner, Dataverse'; + const testAuthorAffiliation1 = 'Dataverse.org'; + const testAuthorAffiliation2 = 'Dataversedemo.org'; + const testContactEmail = 'finch@mailinator.com'; + const testContactName = 'Finch, Fiona'; + const testDescription = 'This is the description of the dataset.'; + const testSubject = ['Medicine, Health and Life Sciences']; + + const testNewDataset: NewDataset = { + metadataBlockValues: [ + { + name: 'citation', + fields: { + title: testTitle, + author: [ + { + authorName: testAuthorName1, + authorAffiliation: testAuthorAffiliation1, + }, + { + authorName: testAuthorName2, + authorAffiliation: testAuthorAffiliation2, + }, + ], + datasetContact: [ + { + datasetContactEmail: testContactEmail, + datasetContactName: testContactName, + }, + ], + dsDescription: [ + { + dsDescriptionValue: testDescription, + }, + ], + subject: testSubject, + }, }, - }, - ], - }; + ], + }; - test('should create a dataset', async () => { const metadataBlocksRepository = new MetadataBlocksRepository(); const citationMetadataBlock = await metadataBlocksRepository.getMetadataBlockByName('citation'); + const createdDataset = await sut.createDataset(testNewDataset, [citationMetadataBlock], 'root'); + const actualCreatedDataset = await sut.getDataset(createdDataset.numericId, latestVersionId, false); - await sut.createDataset(testNewDataset, [citationMetadataBlock], 'root').catch(() => { - assert.fail('Error while creating the Dataset'); - }); - - await new Promise((resolve) => setTimeout(resolve, 2000)); - - const actualCreatedDataset = await sut.getDataset(4, latestVersionId, false); - expect(actualCreatedDataset.metadataBlocks[0].fields.title).toBe(testNewDatasetTitle); + expect(actualCreatedDataset.metadataBlocks[0].fields.title).toBe(testTitle); + expect((actualCreatedDataset.metadataBlocks[0].fields.author[0] as Author).authorName).toBe(testAuthorName1); + expect((actualCreatedDataset.metadataBlocks[0].fields.author[0] as Author).authorAffiliation).toBe( + testAuthorAffiliation1, + ); + expect((actualCreatedDataset.metadataBlocks[0].fields.author[1] as Author).authorName).toBe(testAuthorName2); + expect((actualCreatedDataset.metadataBlocks[0].fields.author[1] as Author).authorAffiliation).toBe( + testAuthorAffiliation2, + ); + expect( + (actualCreatedDataset.metadataBlocks[0].fields.datasetContact[0] as DatasetContact).datasetContactEmail, + ).toBe(testContactEmail); + expect( + (actualCreatedDataset.metadataBlocks[0].fields.datasetContact[0] as DatasetContact).datasetContactName, + ).toBe(testContactName); + expect( + (actualCreatedDataset.metadataBlocks[0].fields.dsDescription[0] as DatasetDescription).dsDescriptionValue, + ).toBe(testDescription); + expect(actualCreatedDataset.metadataBlocks[0].fields.subject[0]).toBe(testSubject[0]); + expect(actualCreatedDataset.metadataBlocks[0].fields.subject[1]).toBe(testSubject[1]); }); }); }); diff --git a/test/integration/environment/setup.js b/test/integration/environment/setup.js index 57cf5c06..c618ce63 100644 --- a/test/integration/environment/setup.js +++ b/test/integration/environment/setup.js @@ -51,12 +51,11 @@ async function setupTestFixtures() { console.log('Creating test datasets...'); await createDatasetViaApi(datasetJson1) .then() - .catch((error) => { + .catch(() => { console.error('Tests setup: Error while creating test Dataset 1'); }); await createDatasetViaApi(datasetJson2) - .then() - .catch((error) => { + .catch(() => { console.error('Tests setup: Error while creating test Dataset 2'); }); console.log('Test datasets created'); diff --git a/test/unit/datasets/CreateDataset.test.ts b/test/unit/datasets/CreateDataset.test.ts index 6b626a78..88977a77 100644 --- a/test/unit/datasets/CreateDataset.test.ts +++ b/test/unit/datasets/CreateDataset.test.ts @@ -1,4 +1,5 @@ import { CreateDataset } from '../../../src/datasets/domain/useCases/CreateDataset'; +import { CreatedDatasetIdentifiers } from '../../../src/datasets/domain/models/CreatedDatasetIdentifiers'; import { IDatasetsRepository } from '../../../src/datasets/domain/repositories/IDatasetsRepository'; import { assert, createSandbox, SinonSandbox } from 'sinon'; import { NewResourceValidator } from '../../../src/core/domain/useCases/validators/NewResourceValidator'; @@ -23,9 +24,14 @@ describe('execute', () => { return metadataBlocksRepositoryStub; } - test('should call repository when validation is successful', async () => { + test('should return new dataset identifiers when validation is successful and repository call is successful', async () => { + const testCreatedDatasetIdentifiers: CreatedDatasetIdentifiers = { + persistentId: 'test', + numericId: 1, + }; + const datasetsRepositoryStub = {}; - const createDatasetStub = sandbox.stub(); + const createDatasetStub = sandbox.stub().returns(testCreatedDatasetIdentifiers); datasetsRepositoryStub.createDataset = createDatasetStub; const newDatasetValidatorStub = {}; @@ -34,10 +40,12 @@ describe('execute', () => { const sut = new CreateDataset(datasetsRepositoryStub, setupMetadataBlocksRepositoryStub(), newDatasetValidatorStub); - await sut.execute(testDataset); + const actual = await sut.execute(testDataset); + + assert.match(actual, testCreatedDatasetIdentifiers); assert.calledWithExactly(validateStub, testDataset, testMetadataBlocks); - assert.calledWithExactly(createDatasetStub, testDataset, testMetadataBlocks, 'root') + assert.calledWithExactly(createDatasetStub, testDataset, testMetadataBlocks, 'root'); assert.callOrder(validateStub, createDatasetStub); }); diff --git a/test/unit/datasets/DatasetsRepository.test.ts b/test/unit/datasets/DatasetsRepository.test.ts index d581d38e..eba9f682 100644 --- a/test/unit/datasets/DatasetsRepository.test.ts +++ b/test/unit/datasets/DatasetsRepository.test.ts @@ -613,13 +613,28 @@ describe('DatasetsRepository', () => { const testCollectionName = 'test'; const expectedNewDatasetRequestPayloadJson = JSON.stringify(createNewDatasetRequestPayload()); + const testCreatedDatasetIdentifiers = { + persistentId: 'test', + numericId: 1, + }; + + const testCreateDatasetResponse = { + data: { + status: 'OK', + data: { + id: testCreatedDatasetIdentifiers.numericId, + persistentId: testCreatedDatasetIdentifiers.persistentId, + }, + }, + }; + const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/dataverses/${testCollectionName}/datasets`; test('should call the API with a correct request payload', async () => { - const axiosPostStub = sandbox.stub(axios, 'post').resolves(); + const axiosPostStub = sandbox.stub(axios, 'post').resolves(testCreateDatasetResponse); // API Key auth - await sut.createDataset(testNewDataset, testMetadataBlocks, testCollectionName); + let actual = await sut.createDataset(testNewDataset, testMetadataBlocks, testCollectionName); assert.calledWithExactly( axiosPostStub, @@ -628,10 +643,12 @@ describe('DatasetsRepository', () => { TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY, ); + assert.match(actual, testCreatedDatasetIdentifiers); + // Session cookie auth ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.SESSION_COOKIE); - await sut.createDataset(testNewDataset, testMetadataBlocks, testCollectionName); + actual = await sut.createDataset(testNewDataset, testMetadataBlocks, testCollectionName); assert.calledWithExactly( axiosPostStub, @@ -639,6 +656,8 @@ describe('DatasetsRepository', () => { expectedNewDatasetRequestPayloadJson, TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_SESSION_COOKIE, ); + + assert.match(actual, testCreatedDatasetIdentifiers); }); test('should return error result on error response', async () => {