From e189bbe3c2534659e743388a54d096bdcd1c2440 Mon Sep 17 00:00:00 2001 From: Maksym Mykhailenko Date: Fri, 1 Nov 2019 18:43:49 +0800 Subject: [PATCH 1/4] fix: "Cannot read property 'hits' of undefined" in Project Service Project Service expects Milestone Templates to be stored inside "milestoneTemplates" so "milestoneTemplate" has been renamed to be plural. --- .../ProcessorServiceMilestoneTemplate.js | 18 +++++++++--------- test/e2e/processor.metadata.index.test.js | 10 +++++----- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/services/ProcessorServiceMilestoneTemplate.js b/src/services/ProcessorServiceMilestoneTemplate.js index 57fe085..c7adeeb 100644 --- a/src/services/ProcessorServiceMilestoneTemplate.js +++ b/src/services/ProcessorServiceMilestoneTemplate.js @@ -68,17 +68,17 @@ function createSchema () { async function create (message) { // handle ES Update async function updateDocPromise (doc) { - const milestoneTemplate = _.isArray(doc._source.milestoneTemplate) ? doc._source.milestoneTemplate : [] + const milestoneTemplates = _.isArray(doc._source.milestoneTemplates) ? doc._source.milestoneTemplates : [] - const existingMilestoneTemplateIndex = _.findIndex(milestoneTemplate, p => p.id === message.id)// if milestone template does not exists already + const existingMilestoneTemplateIndex = _.findIndex(milestoneTemplates, p => p.id === message.id)// if milestone template does not exists already if (existingMilestoneTemplateIndex === -1) { - milestoneTemplate.push(message) + milestoneTemplates.push(message) } else { // if milestone template already exists, ideally we should never land here, but code handles the buggy indexing // replaces the old inconsistent index where previously milestone template was not removed from the index but deleted // from the database - milestoneTemplate.splice(existingMilestoneTemplateIndex, 1, message) + milestoneTemplates.splice(existingMilestoneTemplateIndex, 1, message) } - return _.assign(doc._source, { milestoneTemplate }) + return _.assign(doc._source, { milestoneTemplates }) } await helper.updateMetadadaESPromise(updateDocPromise) @@ -97,14 +97,14 @@ create.schema = { async function update (message) { // handle ES Update async function updateDocPromise (doc) { - const milestoneTemplate = _.map(doc._source.milestoneTemplate, (single) => { + const milestoneTemplates = _.map(doc._source.milestoneTemplates, (single) => { if (single.id === message.id) { return _.assign(single, message) } return single }) - return _.assign(doc._source, { milestoneTemplate }) + return _.assign(doc._source, { milestoneTemplates }) } await helper.updateMetadadaESPromise(updateDocPromise) @@ -123,8 +123,8 @@ update.schema = { async function deleteMessage (message) { // handle ES Update async function updateDocPromise (doc) { - const milestoneTemplate = _.filter(doc._source.milestoneTemplate, single => single.id !== message.id) - return _.assign(doc._source, { milestoneTemplate }) + const milestoneTemplates = _.filter(doc._source.milestoneTemplates, single => single.id !== message.id) + return _.assign(doc._source, { milestoneTemplates }) } await helper.updateMetadadaESPromise(updateDocPromise) diff --git a/test/e2e/processor.metadata.index.test.js b/test/e2e/processor.metadata.index.test.js index f8e4b13..ea47583 100644 --- a/test/e2e/processor.metadata.index.test.js +++ b/test/e2e/processor.metadata.index.test.js @@ -66,7 +66,7 @@ describe('TC Milestone Template Topic Tests', () => { it('create milestone template message', async () => { await ProcessorService.create(milestoneTemplateCreatedMessage) const data = await testHelper.getMetadataESData(metadataId) - testHelper.expectObj(_.find(data.milestoneTemplate, { id: milestoneTemplateId }), + testHelper.expectObj(_.find(data.milestoneTemplates, { id: milestoneTemplateId }), milestoneTemplateCreatedMessage.payload, _.keys(_.omit(milestoneTemplateCreatedMessage.payload, ['resource']))) }) @@ -74,7 +74,7 @@ describe('TC Milestone Template Topic Tests', () => { it('create milestone template message - already exists', async () => { await ProcessorService.create(milestoneTemplateCreatedMessage) const data = await testHelper.getMetadataESData(metadataId) - testHelper.expectObj(_.find(data.milestoneTemplate, { id: milestoneTemplateId }), + testHelper.expectObj(_.find(data.milestoneTemplates, { id: milestoneTemplateId }), milestoneTemplateCreatedMessage.payload, _.keys(_.omit(milestoneTemplateCreatedMessage.payload, ['resource']))) }) @@ -82,7 +82,7 @@ describe('TC Milestone Template Topic Tests', () => { it('update milestone template message', async () => { await ProcessorService.update(milestoneTemplateUpdatedMessage) const data = await testHelper.getMetadataESData(metadataId) - testHelper.expectObj(_.find(data.milestoneTemplate, { id: milestoneTemplateId }), + testHelper.expectObj(_.find(data.milestoneTemplates, { id: milestoneTemplateId }), milestoneTemplateUpdatedMessage.payload, _.keys(_.omit(milestoneTemplateUpdatedMessage.payload, ['resource']))) }) @@ -92,13 +92,13 @@ describe('TC Milestone Template Topic Tests', () => { message.payload.id = notFoundId await ProcessorService.update(message) const data = await testHelper.getMetadataESData(metadataId) - expect(_.find(data.milestoneTemplate, { id: notFoundId })).to.be.an('undefined') + expect(_.find(data.milestoneTemplates, { id: notFoundId })).to.be.an('undefined') }) it('delete milestone template message', async () => { await ProcessorService.deleteMessage(milestoneTemplateDeletedMessage) const data = await testHelper.getMetadataESData(metadataId) - expect(_.find(data.milestoneTemplate, { id: milestoneTemplateId })).to.be.an('undefined') + expect(_.find(data.milestoneTemplates, { id: milestoneTemplateId })).to.be.an('undefined') }) }) From b96030642a0be9a41d8f039a168cea72268f6ec3 Mon Sep 17 00:00:00 2001 From: Maksym Mykhailenko Date: Mon, 4 Nov 2019 13:29:18 +0800 Subject: [PATCH 2/4] fix: member role validation on create and update - Unlike in Project Service endpoints, in this processor we should let create members with any roles because Project Service may create members with any roles implicitly, when accepting invitations. - Also, updated the list of possible user roles, with recently added new roles. --- src/constants.js | 6 +++++- src/services/ProcessorServiceProjectMember.js | 8 ++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/constants.js b/src/constants.js index 8625842..7dc2778 100644 --- a/src/constants.js +++ b/src/constants.js @@ -56,7 +56,11 @@ const PROJECT_MEMBER_ROLE = { OBSERVER: 'observer', CUSTOMER: 'customer', COPILOT: 'copilot', - ACCOUNT_MANAGER: 'account_manager' + ACCOUNT_MANAGER: 'account_manager', + PROGRAM_MANAGER: 'program_manager', + ACCOUNT_EXECUTIVE: 'account_executive', + SOLUTION_ARCHITECT: 'solution_architect', + PROJECT_MANAGER: 'project_manager' } const MILESTONE_TEMPLATE_REFERENCES = { diff --git a/src/services/ProcessorServiceProjectMember.js b/src/services/ProcessorServiceProjectMember.js index 03ff309..4fddeea 100644 --- a/src/services/ProcessorServiceProjectMember.js +++ b/src/services/ProcessorServiceProjectMember.js @@ -27,8 +27,9 @@ function createIdSchema () { function updateSchema () { return createIdSchema().keys({ isPrimary: Joi.boolean(), - role: Joi.any().valid(PROJECT_MEMBER_ROLE.CUSTOMER, PROJECT_MEMBER_ROLE.MANAGER, - PROJECT_MEMBER_ROLE.ACCOUNT_MANAGER, PROJECT_MEMBER_ROLE.COPILOT, PROJECT_MEMBER_ROLE.OBSERVER).required() + // unlike in Project Service endpoints, in this processor we should let create members with any roles + // because Project Service may create members with any roles implicitly, when accepting invitations + role: Joi.string().valid(_.values(PROJECT_MEMBER_ROLE)).required() }) } @@ -38,8 +39,7 @@ function updateSchema () { */ function createSchema () { return createIdSchema().keys({ - role: Joi.any() - .valid(PROJECT_MEMBER_ROLE.MANAGER, PROJECT_MEMBER_ROLE.ACCOUNT_MANAGER, PROJECT_MEMBER_ROLE.COPILOT) + role: Joi.string().valid(_.values(PROJECT_MEMBER_ROLE)) }) } From 141e6da1c0d77ad83fc193d960513a9b7bffceb7 Mon Sep 17 00:00:00 2001 From: Maksym Mykhailenko Date: Mon, 4 Nov 2019 17:59:06 +0800 Subject: [PATCH 3/4] fix: create productCategory validation --- src/services/ProcessorServiceProductCategory.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/services/ProcessorServiceProductCategory.js b/src/services/ProcessorServiceProductCategory.js index ee712f3..5f66073 100644 --- a/src/services/ProcessorServiceProductCategory.js +++ b/src/services/ProcessorServiceProductCategory.js @@ -81,7 +81,6 @@ async function create (message) { create.schema = { message: createSchema() - .xor('form', 'template') } /** From 436b9009a5de8fe64698387ef8e1a13d48ff9228 Mon Sep 17 00:00:00 2001 From: Maksym Mykhailenko Date: Tue, 5 Nov 2019 12:59:20 +0800 Subject: [PATCH 4/4] fix: resource names match ones in "project-service" --- src/constants.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/constants.js b/src/constants.js index 7dc2778..bdcac61 100644 --- a/src/constants.js +++ b/src/constants.js @@ -16,6 +16,8 @@ const RESOURCES = { PROJECT: 'project', PROJECT_TEMPLATE: 'project.template', PROJECT_TYPE: 'project.type', + PROJECT_MEMBER: 'project.member', + PROJECT_MEMBER_INVITE: 'project.member.invite', ORG_CONFIG: 'project.orgConfig', FORM_VERSION: 'project.form.version', FORM_REVISION: 'project.form.revision', @@ -25,14 +27,12 @@ const RESOURCES = { PLAN_CONFIG_REVISION: 'project.planConfig.revision', PRODUCT_TEMPLATE: 'product.template', PRODUCT_CATEGORY: 'product.category', - ATTACHMENT: 'attachment', - PHASE: 'phase', - PROJECT_MEMBER: 'project.member', - PHASE_PRODUCT: 'phase.product', + PHASE: 'project.phase', + PHASE_PRODUCT: 'project.phase.product', TIMELINE: 'timeline', MILESTONE: 'milestone', MILESTONE_TEMPLATE: 'milestone.template', - PROJECT_MEMBER_INVITE: 'project.member.invite' + ATTACHMENT: 'attachment' } const TIMELINE_REFERENCES = {