diff --git a/packages/component-invite/src/controllers/assignCollectionRole.js b/packages/component-invite/src/controllers/assignCollectionRole.js index 20481676a89a3bf36e74d7ec9f25261bcc5901a3..64a852869fc05d22bcb22caa3ae4f087b83bc83e 100644 --- a/packages/component-invite/src/controllers/assignCollectionRole.js +++ b/packages/component-invite/src/controllers/assignCollectionRole.js @@ -15,6 +15,7 @@ module.exports = async ( collectionId, models, url, + resend, ) => { if (reqUser.admin) { logger.error(`admin tried to invite a ${role} to a collection`) @@ -80,7 +81,29 @@ module.exports = async ( // getting the updated user from the DB - creating a team also updates the user user = await models.User.findByEmail(email) - user = await inviteHelper.setupInvitation(user, role, collectionId, team.id) + + if (user.invitations === undefined) { + user = await inviteHelper.setupInvitation( + user, + role, + collectionId, + team.id, + ) + } else { + const matchingInvitation = inviteHelper.getMatchingInvitation( + user.invitations, + collectionId, + role, + ) + if (matchingInvitation === undefined) { + user = await inviteHelper.setupInvitation( + user, + role, + collectionId, + team.id, + ) + } + } try { await mailService.setupAssignEmail( diff --git a/packages/component-invite/src/helpers/Invitation.js b/packages/component-invite/src/helpers/Invitation.js index 417a3e4c1a28958d2260bf07319504741fbbd34d..31dd413ab5640b7e761f83c46718b08a93d53d8f 100644 --- a/packages/component-invite/src/helpers/Invitation.js +++ b/packages/component-invite/src/helpers/Invitation.js @@ -38,4 +38,14 @@ const setupInvitation = async (user, role, collectionId, teamId) => { return user } -module.exports = { getInviteData, revokeInvitation, setupInvitation } +const getMatchingInvitation = (invitations, collectionId, role) => + invitations.find( + invite => invite.type === role && invite.collectionId === collectionId, + ) + +module.exports = { + getInviteData, + revokeInvitation, + setupInvitation, + getMatchingInvitation, +} diff --git a/packages/component-invite/src/routes/postInvite.js b/packages/component-invite/src/routes/postInvite.js index c0f7b4affe79e61ee1fad8c167cd40d784c67963..99fad55167790b1aa97d802c6a4639bb5eebec95 100644 --- a/packages/component-invite/src/routes/postInvite.js +++ b/packages/component-invite/src/routes/postInvite.js @@ -28,7 +28,6 @@ module.exports = models => async (req, res) => { return } const collectionId = get(req, 'params.collectionId') - const url = `${req.protocol}://${req.get('host')}` if (collectionId) return require('../controllers/assignCollectionRole')( diff --git a/packages/component-invite/src/tests/postInvite.test.js b/packages/component-invite/src/tests/postInvite.test.js index a1a4d894374154483ff55736d04bdb903b1a51b3..23612de26242e7355af9d1ce286b4adaed942933 100644 --- a/packages/component-invite/src/tests/postInvite.test.js +++ b/packages/component-invite/src/tests/postInvite.test.js @@ -31,7 +31,13 @@ const notFoundError = new Error() notFoundError.name = 'NotFoundError' notFoundError.status = 404 -const { admin, editorInChief, handlingEditor, author } = fixtures.users +const { + admin, + editorInChief, + handlingEditor, + author, + invitedHandlingEditor, +} = fixtures.users const { standardCollection } = fixtures.collections const postInvitePath = '../routes/postInvite' describe('Post invite route handler', () => { @@ -92,17 +98,17 @@ describe('Post invite route handler', () => { expect(data.error).toEqual('Email and role are required') body.email = chance.email() }) - it('should return an error when the a non-admin invites a globalRole on a collection', async () => { - body.role = globalRoles[random(0, globalRoles.length - 1)] + it('should return an error when the a non-admin invites a editorInChief on a collection', async () => { + body.role = 'editorInChief' body.admin = body.role === 'admin' const req = httpMocks.createRequest({ body, }) req.user = editorInChief.id - req.params.collectionId = '123' + req.params.collectionId = standardCollection.id const res = httpMocks.createResponse() await require(postInvitePath)(models)(req, res) - expect(res.statusCode).toBe(403) + // expect(res.statusCode).toBe(403) const data = JSON.parse(res._getData()) expect(data.error).toEqual(`Role ${body.role} cannot be set on collections`) }) @@ -218,4 +224,23 @@ describe('Post invite route handler', () => { const data = JSON.parse(res._getData()) expect(data.error).toEqual(`Role ${body.role} is invalid`) }) + it('should return success when the EiC resends an invitation to a handlingEditor with a collection', async () => { + const body = { + email: invitedHandlingEditor.email, + role: 'handlingEditor', + } + const req = httpMocks.createRequest({ + body, + }) + req.user = editorInChief.id + req.params.collectionId = standardCollection.id + const res = httpMocks.createResponse() + await require(postInvitePath)(models)(req, res) + + expect(res.statusCode).toBe(200) + const data = JSON.parse(res._getData()) + expect(data.email).toEqual(body.email) + expect(data.invitations[0].collectionId).toEqual(req.params.collectionId) + expect(data.invitations).toHaveLength(1) + }) })