From 8bec0b2a54e3616b6e9ed6eff2c9ef07d9b9da21 Mon Sep 17 00:00:00 2001 From: Anissa Agahchen Date: Mon, 13 Mar 2023 19:18:44 -0700 Subject: [PATCH 1/5] decouple upload to Biohub from create/update project/survey --- api/src/paths/project/create.ts | 2 +- .../project/{projectId}/survey/create.ts | 2 +- .../{projectId}/survey/{surveyId}/update.ts | 2 +- api/src/paths/project/{projectId}/update.ts | 2 +- api/src/services/project-service.ts | 23 +++++++--- api/src/services/survey-service.test.ts | 4 +- api/src/services/survey-service.ts | 42 +++++++++++++++---- 7 files changed, 57 insertions(+), 20 deletions(-) diff --git a/api/src/paths/project/create.ts b/api/src/paths/project/create.ts index c0f00174d2..252af6464f 100644 --- a/api/src/paths/project/create.ts +++ b/api/src/paths/project/create.ts @@ -87,7 +87,7 @@ export function createProject(): RequestHandler { const projectService = new ProjectService(connection); - const projectId = await projectService.createProject(sanitizedProjectPostData); + const projectId = await projectService.createProjectAndUploadToBiohub(sanitizedProjectPostData); await connection.commit(); diff --git a/api/src/paths/project/{projectId}/survey/create.ts b/api/src/paths/project/{projectId}/survey/create.ts index 24950c3753..3db38c6a62 100644 --- a/api/src/paths/project/{projectId}/survey/create.ts +++ b/api/src/paths/project/{projectId}/survey/create.ts @@ -248,7 +248,7 @@ export function createSurvey(): RequestHandler { const surveyService = new SurveyService(connection); - const surveyId = await surveyService.createSurvey(projectId, sanitizedPostSurveyData); + const surveyId = await surveyService.createSurveyAndUploadToBiohub(projectId, sanitizedPostSurveyData); await connection.commit(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/update.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/update.ts index e1a4f942d0..31012c520c 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/update.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/update.ts @@ -285,7 +285,7 @@ export function updateSurvey(): RequestHandler { const surveyService = new SurveyService(connection); - await surveyService.updateSurvey(surveyId, sanitizedPutSurveyData); + await surveyService.updateSurveyAndUploadToBiohub(surveyId, sanitizedPutSurveyData); await connection.commit(); diff --git a/api/src/paths/project/{projectId}/update.ts b/api/src/paths/project/{projectId}/update.ts index ef723398fe..c90b39f38c 100644 --- a/api/src/paths/project/{projectId}/update.ts +++ b/api/src/paths/project/{projectId}/update.ts @@ -436,7 +436,7 @@ export function updateProject(): RequestHandler { const projectService = new ProjectService(connection); - await projectService.updateProject(projectId, entities); + await projectService.updateProjectAndUploadToBiohub(projectId, entities); await connection.commit(); diff --git a/api/src/services/project-service.ts b/api/src/services/project-service.ts index 498b416f2a..25f670ad2c 100644 --- a/api/src/services/project-service.ts +++ b/api/src/services/project-service.ts @@ -286,6 +286,15 @@ export class ProjectService extends DBService { return this.projectRepository.getReportAttachmentsData(projectId); } + async createProjectAndUploadToBiohub(postProjectData: PostProjectObject): Promise { + const projectId = await this.createProject(postProjectData); + + //Submit Eml to biohub and publish record + await this.platformService.submitAndPublishDwcAMetadata(projectId); + + return projectId; + } + async createProject(postProjectData: PostProjectObject): Promise { const projectId = await this.insertProject(postProjectData); @@ -341,9 +350,6 @@ export class ProjectService extends DBService { // The user that creates a project is automatically assigned a project lead role, for this project await this.insertParticipantRole(projectId, PROJECT_ROLE.PROJECT_LEAD); - //Submit Eml to biohub and publish record - await this.platformService.submitAndPublishDwcAMetadata(projectId); - return projectId; } @@ -375,6 +381,14 @@ export class ProjectService extends DBService { return this.projectRepository.insertParticipantRole(projectId, projectParticipantRole); } + async updateProjectAndUploadToBiohub(projectId: number, entities: IUpdateProject) { + await this.updateProject(projectId, entities); + + // Update Eml to biohub and publish record + return this.platformService.submitAndPublishDwcAMetadata(projectId); + + return projectId; + } async updateProject(projectId: number, entities: IUpdateProject) { const promises: Promise[] = []; @@ -395,9 +409,6 @@ export class ProjectService extends DBService { } await Promise.all(promises); - - // Update Eml to biohub and publish record - return this.platformService.submitAndPublishDwcAMetadata(projectId); } async updateIUCNData(projectId: number, entities: IUpdateProject): Promise { diff --git a/api/src/services/survey-service.test.ts b/api/src/services/survey-service.test.ts index b725e72f51..a4fe2c42cf 100644 --- a/api/src/services/survey-service.test.ts +++ b/api/src/services/survey-service.test.ts @@ -122,7 +122,7 @@ describe('SurveyService', () => { const surveyId = 2; const putSurveyData = new PutSurveyObject(null); - await surveyService.updateSurvey(surveyId, putSurveyData); + await surveyService.updateSurveyAndUploadToBiohub(surveyId, putSurveyData); expect(updateSurveyDetailsDataStub).not.to.have.been.called; expect(updateSurveyVantageCodesDataStub).not.to.have.been.called; @@ -166,7 +166,7 @@ describe('SurveyService', () => { location: {} }); - await surveyService.updateSurvey(surveyId, putSurveyData); + await surveyService.updateSurveyAndUploadToBiohub(surveyId, putSurveyData); expect(updateSurveyDetailsDataStub).to.have.been.calledOnce; expect(updateSurveyVantageCodesDataStub).to.have.been.calledOnce; diff --git a/api/src/services/survey-service.ts b/api/src/services/survey-service.ts index c0b4c6189c..5c352ec06c 100644 --- a/api/src/services/survey-service.ts +++ b/api/src/services/survey-service.ts @@ -294,6 +294,23 @@ export class SurveyService extends DBService { return Promise.all(surveyIds.map(async (surveyId) => this.getSurveyById(surveyId))); } + /** + * Creates a new survey for a project and returns survey ID + * + * @param {number} projectId + * @param {PostSurveyObject} postSurveyData + * @returns {*} {Promise} + * @memberof SurveyService + */ + async createSurveyAndUploadToBiohub(projectId: number, postSurveyData: PostSurveyObject): Promise { + const surveyId = await this.createSurvey(projectId, postSurveyData); + + //Update Eml to biohub and publish record + await this.platformService.submitAndPublishDwcAMetadata(projectId, surveyId); + + return surveyId; + } + /** * Creates a new survey for a project and returns survey ID * @@ -354,9 +371,6 @@ export class SurveyService extends DBService { await Promise.all(promises); - //Update Eml to biohub and publish record - await this.platformService.submitAndPublishDwcAMetadata(projectId, surveyId); - return surveyId; } @@ -487,7 +501,22 @@ export class SurveyService extends DBService { * @returns {*} {Promise} * @memberof SurveyService */ - async updateSurvey(surveyId: number, putSurveyData: PutSurveyObject): Promise { + async updateSurveyAndUploadToBiohub(surveyId: number, putSurveyData: PutSurveyObject): Promise { + const surveyData = await this.updateSurvey(surveyId, putSurveyData); + + // Update Eml to biohub and publish record + return this.platformService.submitAndPublishDwcAMetadata(surveyData.survey_details.project_id, surveyId); + } + + /** + * Updates provided survey information and submits to BioHub + * + * @param {number} surveyId + * @param {PutSurveyObject} putSurveyData + * @returns {*} {Promise} + * @memberof SurveyService + */ + async updateSurvey(surveyId: number, putSurveyData: PutSurveyObject): Promise { const promises: Promise[] = []; if (putSurveyData?.survey_details || putSurveyData?.purpose_and_methodology || putSurveyData?.location) { @@ -516,10 +545,7 @@ export class SurveyService extends DBService { await Promise.all(promises); - const surveyData = await this.getSurveyById(surveyId); - - // Update Eml to biohub and publish record - return this.platformService.submitAndPublishDwcAMetadata(surveyData.survey_details.project_id, surveyId); + return await this.getSurveyById(surveyId); } /** From 43a0717d2afdf67abc5dc352386292f0840a4006 Mon Sep 17 00:00:00 2001 From: Anissa Agahchen Date: Tue, 14 Mar 2023 10:28:04 -0700 Subject: [PATCH 2/5] update function names on create/update tests --- api/src/paths/project/create.test.ts | 4 ++-- api/src/paths/project/{projectId}/survey/create.test.ts | 4 ++-- .../project/{projectId}/survey/{surveyId}/update.test.ts | 4 ++-- api/src/paths/project/{projectId}/update.test.ts | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/api/src/paths/project/create.test.ts b/api/src/paths/project/create.test.ts index 61e75615c3..75fd185988 100644 --- a/api/src/paths/project/create.test.ts +++ b/api/src/paths/project/create.test.ts @@ -30,7 +30,7 @@ describe('create', () => { sinon.stub(db, 'getDBConnection').returns(dbConnectionObj); - sinon.stub(ProjectService.prototype, 'createProject').resolves(1); + sinon.stub(ProjectService.prototype, 'createProjectAndUploadToBiohub').resolves(1); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); @@ -51,7 +51,7 @@ describe('create', () => { sinon.stub(db, 'getDBConnection').returns(dbConnectionObj); - sinon.stub(ProjectService.prototype, 'createProject').rejects(new Error('a test error')); + sinon.stub(ProjectService.prototype, 'createProjectAndUploadToBiohub').rejects(new Error('a test error')); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); diff --git a/api/src/paths/project/{projectId}/survey/create.test.ts b/api/src/paths/project/{projectId}/survey/create.test.ts index 9db1df370d..3ee6c7371e 100644 --- a/api/src/paths/project/{projectId}/survey/create.test.ts +++ b/api/src/paths/project/{projectId}/survey/create.test.ts @@ -21,7 +21,7 @@ describe('survey/create', () => { sinon.stub(db, 'getDBConnection').returns(dbConnectionObj); - sinon.stub(SurveyService.prototype, 'createSurvey').resolves(2); + sinon.stub(SurveyService.prototype, 'createSurveyAndUploadToBiohub').resolves(2); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); @@ -45,7 +45,7 @@ describe('survey/create', () => { sinon.stub(db, 'getDBConnection').returns(dbConnectionObj); - sinon.stub(SurveyService.prototype, 'createSurvey').rejects(new Error('a test error')); + sinon.stub(SurveyService.prototype, 'createSurveyAndUploadToBiohub').rejects(new Error('a test error')); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); diff --git a/api/src/paths/project/{projectId}/survey/{surveyId}/update.test.ts b/api/src/paths/project/{projectId}/survey/{surveyId}/update.test.ts index fc80acd387..99d55e9c7c 100644 --- a/api/src/paths/project/{projectId}/survey/{surveyId}/update.test.ts +++ b/api/src/paths/project/{projectId}/survey/{surveyId}/update.test.ts @@ -20,7 +20,7 @@ describe('updateSurvey', () => { sinon.stub(db, 'getDBConnection').returns(dbConnectionObj); - sinon.stub(SurveyService.prototype, 'updateSurvey').resolves(); + sinon.stub(SurveyService.prototype, 'updateSurveyAndUploadToBiohub').resolves(); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); @@ -48,7 +48,7 @@ describe('updateSurvey', () => { sinon.stub(db, 'getDBConnection').returns(dbConnectionObj); - sinon.stub(SurveyService.prototype, 'updateSurvey').rejects(new Error('a test error')); + sinon.stub(SurveyService.prototype, 'updateSurveyAndUploadToBiohub').rejects(new Error('a test error')); const { mockReq, mockRes, mockNext } = getRequestHandlerMocks(); diff --git a/api/src/paths/project/{projectId}/update.test.ts b/api/src/paths/project/{projectId}/update.test.ts index 69f50c069f..009ce0aaea 100644 --- a/api/src/paths/project/{projectId}/update.test.ts +++ b/api/src/paths/project/{projectId}/update.test.ts @@ -154,7 +154,7 @@ describe('update', () => { sinon.stub(db, 'getDBConnection').returns(dbConnectionObj); - sinon.stub(ProjectService.prototype, 'updateProject').resolves(); + sinon.stub(ProjectService.prototype, 'updateProjectAndUploadToBiohub').resolves(); const requestHandler = update.updateProject(); From 214e0575777411c0f8e67a12d81eafb4e40756d5 Mon Sep 17 00:00:00 2001 From: Anissa Agahchen Date: Tue, 14 Mar 2023 10:34:19 -0700 Subject: [PATCH 3/5] fix unreachable code --- api/src/services/project-service.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/api/src/services/project-service.ts b/api/src/services/project-service.ts index 25f670ad2c..4c2f93e188 100644 --- a/api/src/services/project-service.ts +++ b/api/src/services/project-service.ts @@ -385,9 +385,7 @@ export class ProjectService extends DBService { await this.updateProject(projectId, entities); // Update Eml to biohub and publish record - return this.platformService.submitAndPublishDwcAMetadata(projectId); - - return projectId; + return await this.platformService.submitAndPublishDwcAMetadata(projectId); } async updateProject(projectId: number, entities: IUpdateProject) { const promises: Promise[] = []; From c6136f3ace2505e77e250af4137e451bad0e298a Mon Sep 17 00:00:00 2001 From: Anissa Agahchen Date: Tue, 14 Mar 2023 12:50:14 -0700 Subject: [PATCH 4/5] updated tests --- api/src/services/project-service.test.ts | 37 +++++++++++++++++++++ api/src/services/survey-service.test.ts | 41 ++++++++++++++++++++++++ api/src/services/survey-service.ts | 2 +- 3 files changed, 79 insertions(+), 1 deletion(-) diff --git a/api/src/services/project-service.test.ts b/api/src/services/project-service.test.ts index a440d6d4a9..6ee2e64693 100644 --- a/api/src/services/project-service.test.ts +++ b/api/src/services/project-service.test.ts @@ -2,6 +2,7 @@ import chai, { expect } from 'chai'; import { describe } from 'mocha'; import sinon from 'sinon'; import sinonChai from 'sinon-chai'; +import { PostProjectObject } from '../models/project-create'; import { GetCoordinatorData, GetFundingData, @@ -13,11 +14,15 @@ import { } from '../models/project-view'; import { ProjectRepository } from '../repositories/project-repository'; import { getMockDBConnection } from '../__mocks__/db'; +import { PlatformService } from './platform-service'; import { ProjectService } from './project-service'; chai.use(sinonChai); describe('ProjectService', () => { + afterEach(() => { + sinon.restore(); + }); describe('ensureProjectParticipant', () => { afterEach(() => { sinon.restore(); @@ -116,6 +121,38 @@ describe('ProjectService', () => { expect(repoStub).to.be.calledOnce; expect(response).to.eql(undefined); }); + + describe('createProjectAndUploadToBiohub', () => { + it('returns projectId on success', async () => { + const dbConnection = getMockDBConnection(); + const service = new ProjectService(dbConnection); + + const repoStub1 = sinon.stub(ProjectService.prototype, 'createProject').resolves(1); + const repoStub2 = sinon.stub(PlatformService.prototype, 'submitAndPublishDwcAMetadata').resolves(); + + const response = await service.createProjectAndUploadToBiohub((null as unknown) as PostProjectObject); + + expect(repoStub1).to.be.calledOnce; + expect(repoStub2).to.be.calledOnce; + expect(response).to.eql(1); + }); + }); + + describe('updateProjectAndUploadToBiohub', () => { + it('successfully updates project', async () => { + const dbConnection = getMockDBConnection(); + const service = new ProjectService(dbConnection); + + const repoStub1 = sinon.stub(ProjectService.prototype, 'updateProject').resolves(); + const repoStub2 = sinon.stub(PlatformService.prototype, 'submitAndPublishDwcAMetadata').resolves(); + + const response = await service.updateProjectAndUploadToBiohub(1, (null as unknown) as PostProjectObject); + + expect(repoStub1).to.be.calledOnce; + expect(repoStub2).to.be.calledOnce; + expect(response).to.eql(undefined); + }); + }); }); describe('getProjectList', () => { diff --git a/api/src/services/survey-service.test.ts b/api/src/services/survey-service.test.ts index a4fe2c42cf..4d0ca15dcb 100644 --- a/api/src/services/survey-service.test.ts +++ b/api/src/services/survey-service.test.ts @@ -1080,4 +1080,45 @@ describe('SurveyService', () => { } }); }); + + describe('createSurveyAndUploadToBiohub', () => { + it('returns projectId on success', async () => { + const dbConnection = getMockDBConnection(); + const service = new SurveyService(dbConnection); + + const repoStub1 = sinon.stub(SurveyService.prototype, 'createSurvey').resolves(1); + const repoStub2 = sinon.stub(PlatformService.prototype, 'submitAndPublishDwcAMetadata').resolves(); + + const response = await service.createSurveyAndUploadToBiohub(1, (null as unknown) as PostSurveyObject); + + expect(repoStub1).to.be.calledOnce; + expect(repoStub2).to.be.calledOnce; + expect(response).to.eql(1); + }); + }); + + describe('updateProjectAndUploadToBiohub', () => { + it('successfully updates project', async () => { + const dbConnection = getMockDBConnection(); + const service = new SurveyService(dbConnection); + + const repoStub1 = sinon.stub(SurveyService.prototype, 'updateSurvey').resolves(({ + survey_details: { + survey_name: 'my survey', + start_date: '2020-10-10', + end_date: '2021-10-10', + biologist_last_name: 'henry', + biologist_first_name: 'erin', + revision_count: 1 + } + } as unknown) as SurveyObject); + const repoStub2 = sinon.stub(PlatformService.prototype, 'submitAndPublishDwcAMetadata').resolves(); + + const response = await service.updateSurveyAndUploadToBiohub(1, (null as unknown) as PutSurveyObject); + + expect(repoStub1).to.be.calledOnce; + expect(repoStub2).to.be.calledOnce; + expect(response).to.eql(undefined); + }); + }); }); diff --git a/api/src/services/survey-service.ts b/api/src/services/survey-service.ts index 5c352ec06c..284e8849e1 100644 --- a/api/src/services/survey-service.ts +++ b/api/src/services/survey-service.ts @@ -505,7 +505,7 @@ export class SurveyService extends DBService { const surveyData = await this.updateSurvey(surveyId, putSurveyData); // Update Eml to biohub and publish record - return this.platformService.submitAndPublishDwcAMetadata(surveyData.survey_details.project_id, surveyId); + return await this.platformService.submitAndPublishDwcAMetadata(surveyData.survey_details.project_id, surveyId); } /** From 54fd48eea88f0c6ae3cef74584f3eac8ba6fbf68 Mon Sep 17 00:00:00 2001 From: Anissa Agahchen Date: Tue, 14 Mar 2023 13:28:54 -0700 Subject: [PATCH 5/5] clean up jsdoc --- api/src/services/project-service.ts | 30 +++++++++++++++++++++++++++++ api/src/services/survey-service.ts | 8 ++++---- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/api/src/services/project-service.ts b/api/src/services/project-service.ts index 4c2f93e188..2bb6e4f9de 100644 --- a/api/src/services/project-service.ts +++ b/api/src/services/project-service.ts @@ -286,6 +286,13 @@ export class ProjectService extends DBService { return this.projectRepository.getReportAttachmentsData(projectId); } + /** + * + * + * @param {PostProjectObject} postProjectData + * @return {*} {Promise} + * @memberof ProjectService + */ async createProjectAndUploadToBiohub(postProjectData: PostProjectObject): Promise { const projectId = await this.createProject(postProjectData); @@ -295,6 +302,13 @@ export class ProjectService extends DBService { return projectId; } + /** + * + * + * @param {PostProjectObject} postProjectData + * @return {*} {Promise} + * @memberof ProjectService + */ async createProject(postProjectData: PostProjectObject): Promise { const projectId = await this.insertProject(postProjectData); @@ -381,12 +395,28 @@ export class ProjectService extends DBService { return this.projectRepository.insertParticipantRole(projectId, projectParticipantRole); } + /** + * Updates the project and uploads to Biohub + * + * @param {number} projectId + * @param {IUpdateProject} entities + * @return {*} + * @memberof ProjectService + */ async updateProjectAndUploadToBiohub(projectId: number, entities: IUpdateProject) { await this.updateProject(projectId, entities); // Update Eml to biohub and publish record return await this.platformService.submitAndPublishDwcAMetadata(projectId); } + + /** + * Updates the project + * + * @param {number} projectId + * @param {IUpdateProject} entities + * @memberof ProjectService + */ async updateProject(projectId: number, entities: IUpdateProject) { const promises: Promise[] = []; diff --git a/api/src/services/survey-service.ts b/api/src/services/survey-service.ts index 284e8849e1..cca6ba8a54 100644 --- a/api/src/services/survey-service.ts +++ b/api/src/services/survey-service.ts @@ -295,11 +295,11 @@ export class SurveyService extends DBService { } /** - * Creates a new survey for a project and returns survey ID + * Creates a survey and uploads the metadata to Biohub * * @param {number} projectId * @param {PostSurveyObject} postSurveyData - * @returns {*} {Promise} + * @return {*} {Promise} * @memberof SurveyService */ async createSurveyAndUploadToBiohub(projectId: number, postSurveyData: PostSurveyObject): Promise { @@ -312,11 +312,11 @@ export class SurveyService extends DBService { } /** - * Creates a new survey for a project and returns survey ID + * Creates the survey * * @param {number} projectId * @param {PostSurveyObject} postSurveyData - * @returns {*} {Promise} + * @return {*} {Promise} * @memberof SurveyService */ async createSurvey(projectId: number, postSurveyData: PostSurveyObject): Promise {