Skip to content
Snippets Groups Projects
Commit 925267ec authored by Sebastian's avatar Sebastian
Browse files

feat(component-invite): add agree logic for a reviewer

parent c8c01455
No related branches found
No related tags found
1 merge request!6Agree/Decline to work on a manuscript
...@@ -27,19 +27,30 @@ module.exports = models => async (req, res) => { ...@@ -27,19 +27,30 @@ module.exports = models => async (req, res) => {
}) })
return return
} }
if (invitation.userId !== user.id) {
await collectionHelper.updateHandlingEditor(collection, isAccepted) res.status(403).json({
error: `User ${user.email} is not allowed to modify invitation ${
invitation.id
}`,
})
return
}
if (invitation.role === 'handlingEditor')
await collectionHelper.updateHandlingEditor(collection, isAccepted)
invitation.timestamp = Date.now() invitation.timestamp = Date.now()
invitation.hasAnswer = true invitation.hasAnswer = true
const eic = await userHelper.getEditorInChief(models.User) const eic = await userHelper.getEditorInChief(models.User)
if (isAccepted === true) { if (isAccepted === true) {
invitation.isAccepted = true invitation.isAccepted = true
let toEmail = eic.email
if (invitation.role === 'reviewer')
toEmail = collection.handlingEditor.email
await collection.save() await collection.save()
try { try {
await mailService.setupHandlingEditorAgreedEmail( await mailService.setupAgreeEmail(
eic.email, toEmail,
user, user,
'handling-editor-agreed', invitation.role,
`${req.protocol}://${req.get('host')}`, `${req.protocol}://${req.get('host')}`,
collection.customId, collection.customId,
) )
......
...@@ -9,7 +9,7 @@ const cloneDeep = require('lodash/cloneDeep') ...@@ -9,7 +9,7 @@ const cloneDeep = require('lodash/cloneDeep')
const models = Model.build() const models = Model.build()
jest.mock('pubsweet-component-mail-service', () => ({ jest.mock('pubsweet-component-mail-service', () => ({
setupAssignEmail: jest.fn(), setupAssignEmail: jest.fn(),
setupHandlingEditorAgreedEmail: jest.fn(), setupAgreeEmail: jest.fn(),
setupDeclineEmail: jest.fn(), setupDeclineEmail: jest.fn(),
})) }))
...@@ -32,7 +32,26 @@ describe('Patch collections invitations route handler', () => { ...@@ -32,7 +32,26 @@ describe('Patch collections invitations route handler', () => {
}) })
req.user = handlingEditor.id req.user = handlingEditor.id
req.params.collectionId = collection.id req.params.collectionId = collection.id
req.params.invitationId = collection.invitations[0].id const heInv = collection.invitations.find(
inv => inv.role === 'handlingEditor',
)
req.params.invitationId = heInv.id
const res = httpMocks.createResponse()
await require(patchPath)(models)(req, res)
expect(res.statusCode).toBe(200)
})
it('should return success when the reviewer agrees work on a collection', async () => {
const { reviewer } = testFixtures.users
const { collection } = testFixtures.collections
const req = httpMocks.createRequest({
body,
})
req.user = reviewer.id
req.params.collectionId = collection.id
const reviewerInv = collection.invitations.find(
inv => inv.role === 'reviewer',
)
req.params.invitationId = reviewerInv.id
const res = httpMocks.createResponse() const res = httpMocks.createResponse()
await require(patchPath)(models)(req, res) await require(patchPath)(models)(req, res)
expect(res.statusCode).toBe(200) expect(res.statusCode).toBe(200)
...@@ -99,4 +118,24 @@ describe('Patch collections invitations route handler', () => { ...@@ -99,4 +118,24 @@ describe('Patch collections invitations route handler', () => {
const data = JSON.parse(res._getData()) const data = JSON.parse(res._getData())
expect(data.error).toEqual('Invitation invalid-id not found') expect(data.error).toEqual('Invitation invalid-id not found')
}) })
it("should return an error when a user tries to patch another user's invitation", async () => {
const { reviewer } = testFixtures.users
const { collection } = testFixtures.collections
const req = httpMocks.createRequest({
body,
})
req.user = reviewer.id
req.params.collectionId = collection.id
const inv = collection.invitations.find(
inv => inv.role === 'handlingEditor',
)
req.params.invitationId = inv.id
const res = httpMocks.createResponse()
await require(patchPath)(models)(req, res)
expect(res.statusCode).toBe(403)
const data = JSON.parse(res._getData())
expect(data.error).toEqual(
`User ${reviewer.email} is not allowed to modify invitation ${inv.id}`,
)
})
}) })
const Chance = require('chance') const Chance = require('chance')
const { user, handlingEditor, author } = require('./userData') const { user, handlingEditor, author, reviewer } = require('./userData')
const { fragment } = require('./fragments') const { fragment } = require('./fragments')
const chance = new Chance() const chance = new Chance()
...@@ -27,6 +27,14 @@ const collections = { ...@@ -27,6 +27,14 @@ const collections = {
userId: handlingEditor.id, userId: handlingEditor.id,
timestamp: chance.timestamp(), timestamp: chance.timestamp(),
}, },
{
id: chance.guid(),
role: 'reviewer',
hasAnswer: false,
isAccepted: false,
userId: reviewer.id,
timestamp: chance.timestamp(),
},
], ],
handlingEditor: { handlingEditor: {
id: handlingEditor.id, id: handlingEditor.id,
......
const Chance = require('chance') const Chance = require('chance')
const chance = new Chance() const chance = new Chance()
const generateUserData = () => ({
id: chance.guid(),
email: chance.email(),
firstName: chance.first(),
lastName: chance.last(),
})
module.exports = { module.exports = {
handlingEditor: { handlingEditor: generateUserData(),
id: chance.guid(), user: generateUserData(),
email: chance.email(), admin: generateUserData(),
firstName: chance.first(), author: generateUserData(),
lastName: chance.last(), reviewer: generateUserData(),
},
user: {
id: chance.guid(),
email: chance.email(),
firstName: chance.first(),
lastName: chance.last(),
},
admin: {
id: chance.guid(),
email: chance.email(),
},
author: {
id: chance.guid(),
email: chance.email(),
firstName: chance.first(),
lastName: chance.last(),
},
} }
const { heTeamID } = require('./teamIDs') const { heTeamID } = require('./teamIDs')
const { handlingEditor, user, admin, author } = require('./userData') const { handlingEditor, user, admin, author, reviewer } = require('./userData')
const Chance = require('chance') const Chance = require('chance')
const chance = new Chance() const chance = new Chance()
...@@ -8,6 +8,8 @@ const users = { ...@@ -8,6 +8,8 @@ const users = {
type: 'user', type: 'user',
username: 'admin', username: 'admin',
email: admin.email, email: admin.email,
firstName: admin.firstName,
lastName: admin.lastName,
password: 'test', password: 'test',
admin: true, admin: true,
id: admin.id, id: admin.id,
...@@ -71,6 +73,20 @@ const users = { ...@@ -71,6 +73,20 @@ const users = {
save: jest.fn(() => users.author), save: jest.fn(() => users.author),
isConfirmed: true, isConfirmed: true,
}, },
reviewer: {
type: 'user',
username: chance.word(),
email: reviewer.email,
password: 'password',
admin: false,
id: reviewer.id,
firstName: reviewer.firstName,
lastName: reviewer.lastName,
affiliation: chance.company(),
title: 'Mr',
save: jest.fn(() => users.reviewer),
isConfirmed: true,
},
} }
module.exports = users module.exports = users
...@@ -91,22 +91,24 @@ module.exports = { ...@@ -91,22 +91,24 @@ module.exports = {
} }
return Email.send(mailData) return Email.send(mailData)
}, },
setupHandlingEditorAgreedEmail: async ( setupAgreeEmail: async (toEmail, user, invRole, url, collectionId) => {
toEmail, let role = 'Handling Editor'
user, let subject = 'Handling Editor Agreed'
emailType, if (invRole === 'reviewer') {
url, subject = 'Reviewer Agreed'
collectionId, role = 'Reviewer'
) => { }
const { htmlBody, textBody } = getEmailBody(emailType, { const { htmlBody, textBody } = getEmailBody('agree', {
url, url,
role,
name: `${user.firstName} ${user.lastName}`, name: `${user.firstName} ${user.lastName}`,
collectionId, collectionId,
}) })
const mailData = { const mailData = {
from: config.get('mailer.from'), from: config.get('mailer.from'),
to: toEmail, to: toEmail,
subject: 'Handling Editor Agreed', subject,
text: textBody, text: textBody,
html: htmlBody, html: htmlBody,
} }
...@@ -152,6 +154,8 @@ module.exports = { ...@@ -152,6 +154,8 @@ module.exports = {
agreeUrl = `${baseUrl}${resetPath}?${querystring.encode({ agreeUrl = `${baseUrl}${resetPath}?${querystring.encode({
email: invitedUser.email, email: invitedUser.email,
token: invitedUser.passwordResetToken, token: invitedUser.passwordResetToken,
collectionId: collection.id,
agree: true,
})}` })}`
} }
......
...@@ -145,7 +145,7 @@ ...@@ -145,7 +145,7 @@
width="100%" style="display: none !important; mso-hide: all; visibility: hidden; opacity: 0; color: transparent; height: 0; width: 0;"> width="100%" style="display: none !important; mso-hide: all; visibility: hidden; opacity: 0; color: transparent; height: 0; width: 0;">
<tr> <tr>
<td role="module-content"> <td role="module-content">
<p>handling editor agreed</p> <p>a user has agreed</p>
</td> </td>
</tr> </tr>
</table> </table>
...@@ -163,7 +163,7 @@ ...@@ -163,7 +163,7 @@
<table class="module" role="module" data-type="text" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;"> <table class="module" role="module" data-type="text" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;">
<tr> <tr>
<td style="padding:30px 23px 0px 23px;background-color:#ffffff;" height="100%" valign="top" bgcolor="#ffffff"> <td style="padding:30px 23px 0px 23px;background-color:#ffffff;" height="100%" valign="top" bgcolor="#ffffff">
<h1 style="text-align: center;">{{ name }} has agreed to be Handling Editor on manuscript {{ collectionId }}</h1> <h1 style="text-align: center;">{{ name }} has agreed to be a {{ role }} on manuscript {{ collectionId }}.</h1>
<div style="text-align: center;">Please click on the link below to access your dashboard.</div> <div style="text-align: center;">Please click on the link below to access your dashboard.</div>
......
{{ name }} has agreed to be Handling Editor on manuscript {{ collectionId }} {{ name }} has agreed to be a {{ role }} on manuscript {{ collectionId }}
Please click on the link below to access your dashboard Please click on the link below to access your dashboard
{{ url }} VIEW DASHBOARD {{ url }} VIEW DASHBOARD
Hindawi Publishing Corporation Hindawi Publishing Corporation
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment