From 85feffbb2e19885e33ec2f4f1e6dac83a25dd649 Mon Sep 17 00:00:00 2001 From: Sebastian <sebastian.mihalache@thinslices.com> Date: Wed, 25 Apr 2018 13:45:35 +0300 Subject: [PATCH] feat(component-invite): send email to HE when reviewer agrees --- .../src/helpers/Collection.js | 63 +++++-------------- .../src/helpers/Invitation.js | 29 +++++---- packages/component-invite/src/helpers/User.js | 51 ++++++++------- .../component-invite/src/helpers/helpers.js | 3 + .../routes/collectionsInvitations/decline.js | 13 ++-- .../routes/collectionsInvitations/patch.js | 50 ++++++++------- .../collectionsInvitations/decline.test.js | 2 +- .../collectionsInvitations/patch.test.js | 2 +- 8 files changed, 96 insertions(+), 117 deletions(-) diff --git a/packages/component-invite/src/helpers/Collection.js b/packages/component-invite/src/helpers/Collection.js index c1a4c3a33..9da0b0d10 100644 --- a/packages/component-invite/src/helpers/Collection.js +++ b/packages/component-invite/src/helpers/Collection.js @@ -1,47 +1,8 @@ -const invitationHelper = require('./Invitation') -const mailService = require('pubsweet-component-mail-service') -const logger = require('@pubsweet/logger') const config = require('config') const last = require('lodash/last') const statuses = config.get('statuses') -const addInvitation = async (collection, userId, role) => { - collection.invitations = collection.invitations || [] - let matchingInvitation = collection.invitations.find( - invitation => - invitation.userId === userId && - invitation.role === role && - invitation.hasAnswer === false, - ) - if (matchingInvitation === undefined) { - matchingInvitation = await invitationHelper.setupInvitation( - userId, - role, - collection, - ) - } else { - matchingInvitation.timestamp = Date.now() - } - - await collection.save() - return matchingInvitation -} - -const addAuthor = async (collection, user, res, url) => { - if (collection.owners.includes(user.id)) { - return res.status(200).json(user) - } - try { - await mailService.setupAssignEmail(user.email, 'assign-author', url) - - return res.status(200).json(user) - } catch (e) { - logger.error(e) - return res.status(500).json({ error: 'Email could not be sent.' }) - } -} - const addHandlingEditor = async (collection, user, invitation) => { collection.handlingEditor = { id: user.id, @@ -63,18 +24,28 @@ const updateHandlingEditor = async (collection, isAccepted) => { await updateStatus(collection, status) } -const getFragmentAndAuthorData = async (models, collection) => { - const fragment = await models.Fragment.find(last(collection.fragments)) - let { title } = fragment.metadata +const getFragmentAndAuthorData = async ({ + UserModel, + FragmentModel, + collection: { fragments, authors }, +}) => { + const fragment = await FragmentModel.find(last(fragments)) + let { title, abstract } = fragment.metadata title = title.replace(/<(.|\n)*?>/g, '') + abstract = abstract ? abstract.replace(/<(.|\n)*?>/g, '') : '' - const submittingAuthorData = collection.authors.find( + const submittingAuthorData = authors.find( author => author.isSubmitting === true, ) - const author = await models.User.find(submittingAuthorData.userId) + const author = await UserModel.find(submittingAuthorData.userId) const authorName = `${author.firstName} ${author.lastName}` + const authorsPromises = authors.map(async author => { + const user = await UserModel.find(author.userId) + return `${user.firstName} ${user.lastName}` + }) + const authorsList = await Promise.all(authorsPromises) const { id } = fragment - return { title, authorName, id } + return { title, authorName, id, abstract, authorsList } } const updateReviewerCollectionStatus = async collection => { @@ -92,8 +63,6 @@ const updateStatus = async (collection, newStatus) => { } module.exports = { - addInvitation, - addAuthor, addHandlingEditor, updateHandlingEditor, getFragmentAndAuthorData, diff --git a/packages/component-invite/src/helpers/Invitation.js b/packages/component-invite/src/helpers/Invitation.js index b95bfb071..b7ae10f4f 100644 --- a/packages/component-invite/src/helpers/Invitation.js +++ b/packages/component-invite/src/helpers/Invitation.js @@ -1,4 +1,5 @@ const uuid = require('uuid') +const collectionHelper = require('./Collection') const getInvitationData = (invitations, userId, role) => { const matchingInvitation = invitations.find( @@ -41,34 +42,32 @@ const setupReviewerInvitation = async ({ timestamp, resend = false, }) => { - const fragment = await FragmentModel.find(collection.fragments[0]) - const submittingAuthorData = collection.authors.find( - author => author.isSubmitting === true, - ) - const submittingAuthor = await UserModel.find(submittingAuthorData.userId) - const authorsPromises = collection.authors.map(async author => { - const user = await UserModel.find(author.userId) - return `${user.firstName} ${user.lastName}` + const { + title, + authorName, + id, + abstract, + authrosList, + } = await collectionHelper.getFragmentAndAuthorData({ + UserModel, + FragmentModel, + collection, }) - const authors = await Promise.all(authorsPromises) - let { abstract, title } = fragment.metadata - title = title.replace(/<(.|\n)*?>/g, '') - abstract = abstract ? abstract.replace(/<(.|\n)*?>/g, '') : '' const params = { invitedUser: user, baseUrl, collection: { id: collection.id, - authorName: `${submittingAuthor.firstName} ${submittingAuthor.lastName}`, + authorName, handlingEditor: collection.handlingEditor, }, subject: `${collection.customId}: Review Requested`, fragment: { - id: fragment.id, + id, title, abstract, - authors, + authrosList, }, invitation: { id: invitationId, diff --git a/packages/component-invite/src/helpers/User.js b/packages/component-invite/src/helpers/User.js index 05adf5362..ebcd946ff 100644 --- a/packages/component-invite/src/helpers/User.js +++ b/packages/component-invite/src/helpers/User.js @@ -41,38 +41,37 @@ const getEditorInChief = async UserModel => { return eic } -const setupReviewerDeclinedEmailData = async ( - models, +const setupReviewerDecisionEmailData = async ({ + baseUrl, + UserModel, + FragmentModel, collection, - req, - res, - user, + reviewerName, mailService, -) => { + agree, + timestamp = Date.now(), +}) => { const { title, authorName, id, - } = await collectionHelper.getFragmentAndAuthorData(models, collection) - const eic = await getEditorInChief(models.User) + } = await collectionHelper.getFragmentAndAuthorData({ + UserModel, + FragmentModel, + collection, + }) + const eic = await getEditorInChief(UserModel) const toEmail = collection.handlingEditor.email - try { - await mailService.setupReviewerDeclinedEmail( - toEmail, - user, - collection, - title, - authorName, - id, - `${eic.firstName} ${eic.lastName}`, - `${req.protocol}://${req.get('host')}`, - ) - await user.save() - res.status(200).json({}) - } catch (e) { - logger.error(e) - return res.status(500).json({ error: 'Email could not be sent.' }) - } + await mailService.setupReviewerDecisionEmail({ + toEmail, + reviewerName, + collection, + eicName: `${eic.firstName} ${eic.lastName}`, + baseUrl, + fragment: { id, title, authorName }, + agree, + timestamp, + }) } const setupReviewerUnassignEmail = async ( @@ -97,6 +96,6 @@ const setupReviewerUnassignEmail = async ( module.exports = { setupNewUser, getEditorInChief, - setupReviewerDeclinedEmailData, + setupReviewerDecisionEmailData, setupReviewerUnassignEmail, } diff --git a/packages/component-invite/src/helpers/helpers.js b/packages/component-invite/src/helpers/helpers.js index 429c91f29..b48472146 100644 --- a/packages/component-invite/src/helpers/helpers.js +++ b/packages/component-invite/src/helpers/helpers.js @@ -112,9 +112,12 @@ const createNewUser = async ( } } +const getBaseUrl = req => `${req.protocol}://${req.get('host')}` + module.exports = { checkForUndefinedParams, validateEmailAndToken, handleNotFoundError, createNewUser, + getBaseUrl, } diff --git a/packages/component-invite/src/routes/collectionsInvitations/decline.js b/packages/component-invite/src/routes/collectionsInvitations/decline.js index 97714177f..64daa1e63 100644 --- a/packages/component-invite/src/routes/collectionsInvitations/decline.js +++ b/packages/component-invite/src/routes/collectionsInvitations/decline.js @@ -37,14 +37,15 @@ module.exports = models => async (req, res) => { invitation.hasAnswer = true invitation.isAccepted = false await collection.save() - return await userHelper.setupReviewerDeclinedEmailData( - models, + return await userHelper.setupReviewerDecisionEmailData({ + baseUrl: helpers.getBaseUrl(req), + UserModel: models.User, + FragmentModel: models.Fragment, collection, - req, - res, - user, + reviewerName: `${user.firstName} ${user.lastName}`, mailService, - ) + agree: false, + }) } catch (e) { const notFoundError = await helpers.handleNotFoundError(e, 'item') return res.status(notFoundError.status).json({ diff --git a/packages/component-invite/src/routes/collectionsInvitations/patch.js b/packages/component-invite/src/routes/collectionsInvitations/patch.js index da754a1fc..03dada906 100644 --- a/packages/component-invite/src/routes/collectionsInvitations/patch.js +++ b/packages/component-invite/src/routes/collectionsInvitations/patch.js @@ -4,9 +4,7 @@ const teamHelper = require('../../helpers/Team') const mailService = require('pubsweet-component-mail-service') const userHelper = require('../../helpers/User') const collectionHelper = require('../../helpers/Collection') -const config = require('config') -const statuses = config.get('statuses') module.exports = models => async (req, res) => { const { collectionId, invitationId } = req.params const { isAccepted, reason } = req.body @@ -38,6 +36,14 @@ module.exports = models => async (req, res) => { }`, }) + const params = { + baseUrl: helpers.getBaseUrl(req), + UserModel: models.User, + FragmentModel: models.Fragment, + collection, + reviewerName: `${user.firstName} ${user.lastName}`, + mailService, + } if (invitation.role === 'handlingEditor') await collectionHelper.updateHandlingEditor(collection, isAccepted) invitation.timestamp = Date.now() @@ -51,19 +57,25 @@ module.exports = models => async (req, res) => { if ( invitation.role === 'reviewer' && collection.status === 'reviewersInvited' - ) { - collection.status = 'underReview' - collection.visibleStatus = statuses[collection.status].private - } + ) + await collectionHelper.updateStatus(collection, 'underReview') + await collection.save() try { - await mailService.setupAgreeEmail( - toEmail, - user, - invitation.role, - `${req.protocol}://${req.get('host')}`, - collection.customId, - ) + if (invitation.role === 'handlingEditor') + await mailService.setupAgreeEmail( + toEmail, + user, + invitation.role, + `${req.protocol}://${req.get('host')}`, + collection.customId, + ) + if (invitation.role === 'reviewer') + await userHelper.setupReviewerDecisionEmailData({ + ...params, + agree: true, + timestamp: invitation.timestamp, + }) } catch (e) { logger.error(e) return res.status(500).json({ error: 'Email could not be sent.' }) @@ -93,14 +105,10 @@ module.exports = models => async (req, res) => { ) } else if (invitation.role === 'reviewer') { await collectionHelper.updateReviewerCollectionStatus(collection) - return await userHelper.setupReviewerDeclinedEmailData( - models, - collection, - req, - res, - user, - mailService, - ) + return await userHelper.setupReviewerDecisionEmailData({ + ...params, + agree: false, + }) } } catch (e) { logger.error(e) diff --git a/packages/component-invite/src/tests/collectionsInvitations/decline.test.js b/packages/component-invite/src/tests/collectionsInvitations/decline.test.js index 2d9941282..9da12457d 100644 --- a/packages/component-invite/src/tests/collectionsInvitations/decline.test.js +++ b/packages/component-invite/src/tests/collectionsInvitations/decline.test.js @@ -7,7 +7,7 @@ const Model = require('./../helpers/Model') const cloneDeep = require('lodash/cloneDeep') jest.mock('pubsweet-component-mail-service', () => ({ - setupReviewerDeclinedEmail: jest.fn(), + setupReviewerDecisionEmail: jest.fn(), })) const reqBody = { diff --git a/packages/component-invite/src/tests/collectionsInvitations/patch.test.js b/packages/component-invite/src/tests/collectionsInvitations/patch.test.js index c03b6779d..fba9ffbe3 100644 --- a/packages/component-invite/src/tests/collectionsInvitations/patch.test.js +++ b/packages/component-invite/src/tests/collectionsInvitations/patch.test.js @@ -10,7 +10,7 @@ jest.mock('pubsweet-component-mail-service', () => ({ setupAssignEmail: jest.fn(), setupAgreeEmail: jest.fn(), setupDeclineEmail: jest.fn(), - setupReviewerDeclinedEmail: jest.fn(), + setupReviewerDecisionEmail: jest.fn(), })) const reqBody = { -- GitLab