Skip to content

Commit 9f8ac02

Browse files
authored
Merge pull request #34 from topcoder-platform/hotfix/remove-invite-on-member-create-dev
[HOTIFX] [DEV] Remove not removed invite for added member
2 parents ca2f4be + 779fa56 commit 9f8ac02

File tree

5 files changed

+65
-15
lines changed

5 files changed

+65
-15
lines changed

src/common/helper.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,11 +188,27 @@ async function populateMemberWithUserDetails (member) {
188188
}
189189
}
190190

191+
/**
192+
* Reusable method to generate a function which would remove invite from the project ES document.
193+
*
194+
* @param {Object} message invite update or delete message
195+
*/
196+
const removeInvitePromise = message => async (doc) => {
197+
// now merge the updated changes and re-index the document
198+
const invites = _.isArray(doc._source.invites) ? doc._source.invites : []
199+
const removedInvites = _.remove(invites, { id: message.id })
200+
if (!removedInvites.length) {
201+
throw new Error(`Invite with id "${message.id}" is not found and not removed.`)
202+
}
203+
return _.assign(doc._source, { invites })
204+
}
205+
191206
module.exports = {
192207
getESClient,
193208
updateProjectESPromise,
194209
updateTimelineESPromise,
195210
updateMetadadaESPromise,
196211
getMemberDetailsByUserIds,
197-
populateMemberWithUserDetails
212+
populateMemberWithUserDetails,
213+
removeInvitePromise
198214
}

src/services/ProcessorServiceProjectMember.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,32 @@ async function create (message) {
6262
// from the database
6363
members.splice(existingMemberIndex, 1, member)
6464
}
65+
66+
// sometimes we have issue that when member accepts invitation the invitation is somehow
67+
// is not removed from the ES, so here we are making sure that invite is removed when we are adding member
68+
const addedMember = members[existingMemberIndex]
69+
const addedMemberInvites = _.filter(doc._source.invites, (invite) => (
70+
invite.email === addedMember.email || invite.userId === addedMember.userId
71+
))
72+
73+
if (addedMemberInvites.length > 0) {
74+
logger.warn(`There are ${addedMemberInvites.length} invite(s) are not yet removed` +
75+
` for member.id: ${addedMember.id} member.userId: ${addedMember.userId}.`)
76+
77+
for (let i = 0; i < addedMemberInvites.length; i++) {
78+
const invite = addedMemberInvites[i]
79+
logger.debug(`Removing invite.id: ${invite.id} for member.id: ${addedMember.id} member.userId: ${addedMember.userId}.`)
80+
try {
81+
const message = { id: invite.id }
82+
const updateDocHandler = helper.removeInvitePromise(message)
83+
await updateDocHandler(doc)
84+
logger.debug(`Successfully removed invite.id: ${invite.id}.`)
85+
} catch (err) {
86+
logger.error(`Failed removing invite.id: ${invite.id}. ${err}`)
87+
}
88+
}
89+
}
90+
6591
return _.assign(doc._source, { members })
6692
}
6793

src/services/ProcessorServiceProjectMemberInvite.js

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,24 +53,13 @@ create.schema = {
5353
message: createSchema()
5454
}
5555

56-
// handle ES Update or Delete on invites
57-
const updateInvitesPromise = message => async (doc) => {
58-
// now merge the updated changes and re-index the document
59-
const invites = _.isArray(doc._source.invites) ? doc._source.invites : []
60-
const removedInvites = _.remove(invites, invite => message.id === invite.id)
61-
if (!removedInvites.length) {
62-
throw new Error(`Invite with id "${message.id}" is not found and not removed.`)
63-
}
64-
return _.assign(doc._source, { invites })
65-
}
66-
6756
/**
6857
* Update message in Elasticsearch.
6958
* @param {Object} message the challenge updated message
7059
* @return {Promise} promise result
7160
*/
7261
async function update (message) {
73-
await helper.updateProjectESPromise(message.projectId, updateInvitesPromise(message))
62+
await helper.updateProjectESPromise(message.projectId, helper.removeInvitePromise(message))
7463
logger.debug(`Member invite updated successfully in elasticsearch index, (memberInviteId: ${message.id})`)
7564
}
7665

@@ -84,7 +73,7 @@ update.schema = {
8473
* @return {Promise} promise result
8574
*/
8675
async function deleteMessage (message) {
87-
await helper.updateProjectESPromise(message.projectId, updateInvitesPromise(message))
76+
await helper.updateProjectESPromise(message.projectId, helper.removeInvitePromise(message))
8877
logger.debug(`Member invite deleted successfully in elasticsearch index, (memberInviteId: ${message.id})`)
8978
}
9079

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"topic":"project.action.create","originator":"project-api","timestamp":"2019-06-21T04:45:18.165Z","mime-type":"application/json","payload":{"resource":"project.member","createdAt":"2019-06-21T04:45:18.036Z","updatedAt":"2019-06-21T04:45:18.038Z","isPrimary":false,"id":1,"projectId":1,"role":"manager","userId":40051334,"createdBy":40051334,"updatedBy":40051334,"deletedAt":null,"deletedBy":null}}
1+
{"topic":"project.action.create","originator":"project-api","timestamp":"2019-06-21T04:45:18.165Z","mime-type":"application/json","payload":{"resource":"project.member","createdAt":"2019-06-21T04:45:18.036Z","updatedAt":"2019-06-21T04:45:18.038Z","isPrimary":false,"id":1,"projectId":1,"role":"manager","userId":40051331,"createdBy":40051334,"updatedBy":40051334,"deletedAt":null,"deletedBy":null}}

test/e2e/processor.project.index.test.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,25 @@ describe('TC Project Member Topic Tests', () => {
832832
_.keys(_.omit(projectMemberCreatedMessage.payload, ['resource'])))
833833
})
834834

835+
it('create project member message and remove not removed invite', async () => {
836+
// let's say we still have invite
837+
await ProcessorService.create(projectMemberInviteCreatedMessage)
838+
let data = await testHelper.getProjectESData(projectId)
839+
// make sure that invite is there
840+
testHelper.expectObj(_.find(data.invites, { id: projectMemberInviteId }), projectMemberInviteCreatedMessage.payload,
841+
_.keys(_.omit(projectMemberInviteCreatedMessage.payload, ['resource'])))
842+
843+
// and we are adding a member (but invite is still there as we created above)
844+
await ProcessorService.create(projectMemberCreatedMessage)
845+
data = await testHelper.getProjectESData(projectId)
846+
847+
// check that member has been added
848+
testHelper.expectObj(_.find(data.members, { id: projectMemberId }), projectMemberCreatedMessage.payload,
849+
_.keys(_.omit(projectMemberCreatedMessage.payload, ['resource'])))
850+
// and at the same time the invite for the member has been removed
851+
expect(_.find(data.invites, { id: projectMemberInviteId })).to.be.an('undefined')
852+
})
853+
835854
it('update project member message', async () => {
836855
await ProcessorService.update(projectMemberUpdatedMessage)
837856
const data = await testHelper.getProjectESData(projectId)

0 commit comments

Comments
 (0)