diff --git a/packages/component-fixture-manager/src/fixtures/fragments.js b/packages/component-fixture-manager/src/fixtures/fragments.js index 4efbe9b38ed5e07754ecb38fe86f277cb73744d5..4c1e617cb00aea8f7f25d27924bf780e431af189 100644 --- a/packages/component-fixture-manager/src/fixtures/fragments.js +++ b/packages/component-fixture-manager/src/fixtures/fragments.js @@ -41,6 +41,7 @@ const fragments = { userId: recReviewer.id, createdOn: chance.timestamp(), updatedOn: chance.timestamp(), + submittedOn: chance.timestamp(), }, { recommendation: 'minor', diff --git a/packages/component-helper-service/config/authsome-mode.js b/packages/component-helper-service/config/authsome-mode.js new file mode 100644 index 0000000000000000000000000000000000000000..9c663beae1962d9fc13141f8439dc0a84214ae08 --- /dev/null +++ b/packages/component-helper-service/config/authsome-mode.js @@ -0,0 +1,3 @@ +const authsomeMode = require('xpub-faraday/config/authsome-mode') + +module.exports = authsomeMode diff --git a/packages/component-helper-service/config/default.js b/packages/component-helper-service/config/default.js new file mode 100644 index 0000000000000000000000000000000000000000..9950c9b354fa8710a4f043a07ac2b86a3cf6bd2f --- /dev/null +++ b/packages/component-helper-service/config/default.js @@ -0,0 +1,3 @@ +const defaultConfig = require('xpub-faraday/config/default') + +module.exports = defaultConfig diff --git a/packages/component-helper-service/config/test.js b/packages/component-helper-service/config/test.js new file mode 100644 index 0000000000000000000000000000000000000000..9950c9b354fa8710a4f043a07ac2b86a3cf6bd2f --- /dev/null +++ b/packages/component-helper-service/config/test.js @@ -0,0 +1,3 @@ +const defaultConfig = require('xpub-faraday/config/default') + +module.exports = defaultConfig diff --git a/packages/component-helper-service/package.json b/packages/component-helper-service/package.json index 5764bac137e9af7f48e1736f819e2497d3bd8d62..6c707d470181361319f2e2ead30675bc8967562d 100644 --- a/packages/component-helper-service/package.json +++ b/packages/component-helper-service/package.json @@ -22,5 +22,12 @@ }, "publishConfig": { "access": "public" + }, + "scripts": { + "test": "jest" + }, + "jest": { + "verbose": true, + "testRegex": "/src/.*.test.js$" } } diff --git a/packages/component-helper-service/src/Helper.js b/packages/component-helper-service/src/Helper.js index b47dc41778f2baec3e50de9a08d72f1b5b4ffc4b..44d3ef6c44ee6711e0b384f08329e85535c59251 100644 --- a/packages/component-helper-service/src/Helper.js +++ b/packages/component-helper-service/src/Helper.js @@ -1,4 +1,3 @@ -const Email = require('./services/email/Email') const Collection = require('./services/Collection') const Fragment = require('./services/Fragment') const services = require('./services/services') @@ -8,7 +7,6 @@ const Team = require('./services/Team') const Invitation = require('./services/Invitation') module.exports = { - Email, Collection, Fragment, services, diff --git a/packages/component-helper-service/src/services/Fragment.js b/packages/component-helper-service/src/services/Fragment.js index bf7013772455b040774f5eb3eab97f3a468f8e22..3abcbd805d87a0c911076df40015710eee429e9e 100644 --- a/packages/component-helper-service/src/services/Fragment.js +++ b/packages/component-helper-service/src/services/Fragment.js @@ -142,6 +142,13 @@ class Fragment { .filter(rev => rev.isActive) .filter(rev => get(rev, 'notifications.email.user')) } + + hasReviewReport() { + const { fragment: { recommendations = [] } } = this + return recommendations.find( + rec => rec.recommendationType === 'review' && rec.submittedOn, + ) + } } module.exports = Fragment diff --git a/packages/component-helper-service/src/services/email/Email.js b/packages/component-helper-service/src/services/email/Email.js deleted file mode 100644 index 5b422bd5a7718a7bd5b898b3497803877f78c38c..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/Email.js +++ /dev/null @@ -1,95 +0,0 @@ -const config = require('config') - -const helpers = require('./helpers') -const SendEmail = require('@pubsweet/component-send-email') -const logger = require('@pubsweet/logger') - -const mainFromEmail = config.get('journal.staffEmail') -class Email { - constructor({ - type = 'system', - fromEmail = mainFromEmail, - toUser = { - id: '', - email: '', - name: '', - }, - content = { - subject: '', - ctaLink: '', - ctaText: '', - signatureName: '', - unsubscribeLink: '', - signatureJournal: '', - }, - }) { - this.type = type - this.toUser = toUser - this.content = content - this.fromEmail = fromEmail - } - - set _toUser(newToUser) { - this.toUser = newToUser - } - - set _subject(newSubject) { - this.subject = newSubject - } - - set _content(newContent) { - this.content = newContent - } - - getBody({ body = {}, isReviewerInvitation = false }) { - if (isReviewerInvitation) { - return { - html: helpers.getInvitationBody({ - replacements: { - ...body, - ...this.content, - toEmail: this.toUser.email, - toUserName: this.toUser.name, - }, - }), - text: `${this.content.signatureName}`, - } - } - - return { - html: helpers.getNotificationBody({ - replacements: { - ...body, - ...this.content, - toEmail: this.toUser.email, - toUserName: this.toUser.name, - }, - }), - text: `${body.paragraph} ${this.content.ctaLink} ${ - this.content.ctaText - } ${this.content.signatureName}`, - } - } - - sendEmail({ text, html }) { - const { fromEmail: from } = this - const { email: to } = this.toUser - const { subject } = this.content - - const mailData = { - to, - text, - html, - from, - subject, - } - - logger.info( - `EMAIL: Sent email from ${from} to ${to} with subject '${subject}'`, - ) - - SendEmail.send(mailData) - } -} - -module.exports = Email diff --git a/packages/component-helper-service/src/services/email/helpers.js b/packages/component-helper-service/src/services/email/helpers.js deleted file mode 100644 index f704b8d6656364b5069e9f99481dafc5045927ea..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/helpers.js +++ /dev/null @@ -1,53 +0,0 @@ -const fs = require('fs') -const handlebars = require('handlebars') - -const getNotificationBody = ({ replacements }) => { - handlePartial('header', replacements) - if (replacements.hasIntro) handlePartial('intro', replacements) - handlePartial('footer', replacements) - if (replacements.hasSignature) handlePartial('signature', replacements) - if (replacements.hasLink) handlePartial('button', replacements) - handlePartial('body', replacements) - - return getMainTemplate({ fileName: 'notification', context: replacements }) -} - -const getInvitationBody = ({ replacements }) => { - handlePartial('invHeader', replacements) - handlePartial('footer', replacements) - handlePartial('invUpperContent', replacements) - handlePartial('invButtons', replacements) - handlePartial('invManuscriptData', replacements) - handlePartial('signature', replacements) - handlePartial('invLowerContent', replacements) - - return getMainTemplate({ fileName: 'invitation', context: replacements }) -} - -const readFile = path => - fs.readFileSync(path, { encoding: 'utf-8' }, (err, file) => { - if (err) { - throw err - } else { - return file - } - }) - -const handlePartial = (partialName = 'signature', context = {}) => { - let partial = readFile(`${__dirname}/templates/partials/${partialName}.hbs`) - const template = handlebars.compile(partial) - partial = template(context) - handlebars.registerPartial(partialName, partial) -} - -const getMainTemplate = ({ fileName, context }) => { - const htmlFile = readFile(`${__dirname}/templates/${fileName}.html`) - const htmlTemplate = handlebars.compile(htmlFile) - const htmlBody = htmlTemplate(context) - return htmlBody -} - -module.exports = { - getNotificationBody, - getInvitationBody, -} diff --git a/packages/component-helper-service/src/services/email/templates/invitation.html b/packages/component-helper-service/src/services/email/templates/invitation.html deleted file mode 100644 index f9d5ed18cfa96454ba3454e9555e6144a6411467..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/invitation.html +++ /dev/null @@ -1,5 +0,0 @@ -{{> invHeader }} -{{> invUpperContent }} -{{> invButtons }} -{{> invLowerContent }} -{{> footer }} \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/notification.html b/packages/component-helper-service/src/services/email/templates/notification.html deleted file mode 100644 index 02cbf2a6e9c1b383534faf9358c0df3cd078c534..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/notification.html +++ /dev/null @@ -1,3 +0,0 @@ -{{> header }} -{{> body }} -{{> footer}} \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/body.hbs b/packages/component-helper-service/src/services/email/templates/partials/body.hbs deleted file mode 100644 index 59e1230635ab84764ca255052c0952cebf6df56e..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/partials/body.hbs +++ /dev/null @@ -1,25 +0,0 @@ -<table class="module" role="module" data-type="text" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;"> - <tr> - <td style="padding:30px 23px 0px 23px;background-color:#ffffff;" height="100%" valign="top" bgcolor="#ffffff"> - <div> - {{#if hasIntro}} - {{> intro}} - {{/if}} - <p> </p> - <p> - {{{paragraph}}} - </p> - <p> </p> - <p> - {{#if hasLink }} - {{> button }} - {{/if}} - </p> - {{#if hasSignature }} - {{> signature}} - {{/if}} - <p> </p> - </div> - </td> - </tr> -</table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/button.hbs b/packages/component-helper-service/src/services/email/templates/partials/button.hbs deleted file mode 100644 index 5b8b0493173d905c8a8a98322e4da5b0173a7302..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/partials/button.hbs +++ /dev/null @@ -1,19 +0,0 @@ -<table border="0" cellPadding="0" cellSpacing="0" class="module" data-role="module-button" data-type="button" role="module" - style="table-layout:fixed" width="100%"> - <tbody> - <tr> - <td align="center" bgcolor="#FFFFFF" class="outer-td" style="padding:0px 0px 30px 0px;background-color:#FFFFFF"> - <table border="0" cellPadding="0" cellSpacing="0" class="button-css__deep-table___2OZyb wrapper-mobile" style="text-align:center"> - <tbody> - <tr> - <td align="center" bgcolor="#63a945" class="inner-td" style="border-radius:6px;font-size:16px;text-align:center;background-color:inherit"> - <a href="{{ ctaLink }}" style="background-color:#63a945;border:1px solid #333333;border-color:#63a945;border-radius:0px;border-width:1px;color:#ffffff;display:inline-block;font-family:arial,helvetica,sans-serif;font-size:16px;font-weight:normal;letter-spacing:0px;line-height:16px;padding:12px 18px 12px 18px;text-align:center;text-decoration:none" - target="_blank">{{ ctaText }}</a> - </td> - </tr> - </tbody> - </table> - </td> - </tr> - </tbody> -</table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/footer.hbs b/packages/component-helper-service/src/services/email/templates/partials/footer.hbs deleted file mode 100644 index 5a98112919505d7caf577129073b5f5e72585921..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/partials/footer.hbs +++ /dev/null @@ -1,40 +0,0 @@ -<div data-role="module-unsubscribe" class="module unsubscribe-css__unsubscribe___2CDlR" role="module" data-type="unsubscribe" - style="color:#444444;font-size:12px;line-height:20px;padding:16px 16px 16px 16px;text-align:center"> - <p style="font-family:Arial, Helvetica, sans-serif;font-size:11px;line-height:20px;text-align:left"> - This email was sent to {{toEmail}}. You have received this email in regards to the account creation, submission, or peer review process of a paper submitted to a journal published by Hindawi Limited. - </p> - <div class="Unsubscribe--addressLine"> - <p style="font-family:Arial, Helvetica, sans-serif;font-size:11px;line-height:20px;text-align:left"> - Hindawi Limited, 3rd Floor, Adam House, 1 Fitzroy Square, London, W1T 5HF, United Kingdom - </p> - </div> - <p style="font-family:Arial, Helvetica, sans-serif;font-size:11px;line-height:20px;text-align:left"> - </p> - <p style="font-family:Arial, Helvetica, sans-serif;font-size:11px;line-height:20px;text-align:left"> - Hindawi respects your right to privacy. Please see our <a href="https://www.hindawi.com/privacy/">privacy policy</a> for information on how we store, process, and safeguard your data. - </p> - <p style="font-family:Arial, Helvetica, sans-serif;font-size:12px;line-height:20px"> - <a class="Unsubscribe--unsubscribeLink" href="{{ unsubscribeLink }}">Unsubscribe</a> - </p> -</div> -</td> -</tr> -</table> -<!--[if mso]> - </td></tr></table> - </center> - <![endif]--> -</td> -</tr> -</table> -</td> -</tr> -</table> -</td> -</tr> -</table> -</div> -</center> -</body> - -</html> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/header.hbs b/packages/component-helper-service/src/services/email/templates/partials/header.hbs deleted file mode 100644 index aef79db924cb4ea509dda88e4bcf63e2c02e4f75..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/partials/header.hbs +++ /dev/null @@ -1,163 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html data-editor-version="2" class="sg-campaigns" xmlns="http://www.w3.org/1999/xhtml"> - -<head> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1" /> - <!--[if !mso]><!--> - <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> - <!--<![endif]--> - <!--[if (gte mso 9)|(IE)]> - <xml> - <o:OfficeDocumentSettings> - <o:AllowPNG/> - <o:PixelsPerInch>96</o:PixelsPerInch> - </o:OfficeDocumentSettings> - </xml> - <![endif]--> - <!--[if (gte mso 9)|(IE)]> - <style type="text/css"> - body {width: 600px;margin: 0 auto;} - table {border-collapse: collapse;} - table, td {mso-table-lspace: 0pt;mso-table-rspace: 0pt;} - img {-ms-interpolation-mode: bicubic;} - </style> - <![endif]--> - - <style type="text/css"> - body, - p, - div { - font-family: helvetica, arial, sans-serif; - font-size: 14px; - } - - body { - color: #626262; - } - - body a { - color: #0D78F2; - text-decoration: none; - } - - p { - margin: 0; - padding: 0; - } - - table.wrapper { - width: 100% !important; - table-layout: fixed; - -webkit-font-smoothing: antialiased; - -webkit-text-size-adjust: 100%; - -moz-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; - } - - img.max-width { - max-width: 100% !important; - } - - .column.of-2 { - width: 50%; - } - - .column.of-3 { - width: 33.333%; - } - - .column.of-4 { - width: 25%; - } - - @media screen and (max-width:480px) { - .preheader .rightColumnContent, - .footer .rightColumnContent { - text-align: left !important; - } - .preheader .rightColumnContent div, - .preheader .rightColumnContent span, - .footer .rightColumnContent div, - .footer .rightColumnContent span { - text-align: left !important; - } - .preheader .rightColumnContent, - .preheader .leftColumnContent { - font-size: 80% !important; - padding: 5px 0; - } - table.wrapper-mobile { - width: 100% !important; - table-layout: fixed; - } - img.max-width { - height: auto !important; - max-width: 480px !important; - } - a.bulletproof-button { - display: block !important; - width: auto !important; - font-size: 80%; - padding-left: 0 !important; - padding-right: 0 !important; - } - .columns { - width: 100% !important; - } - .column { - display: block !important; - width: 100% !important; - padding-left: 0 !important; - padding-right: 0 !important; - margin-left: 0 !important; - margin-right: 0 !important; - } - } - </style> - <!--user entered Head Start--> - - <!--End Head user entered--> -</head> - -<body> - <center class="wrapper" data-link-color="#0D78F2" data-body-style="font-size: 14px; font-family: helvetica,arial,sans-serif; color: #626262; background-color: #F4F4F4;"> - <div class="webkit"> - <table cellpadding="0" cellspacing="0" border="0" width="100%" class="wrapper" bgcolor="#F4F4F4"> - <tr> - <td valign="top" bgcolor="#F4F4F4" width="100%"> - <table width="100%" role="content-container" class="outer" align="center" cellpadding="0" cellspacing="0" border="0"> - <tr> - <td width="100%"> - <table width="100%" cellpadding="0" cellspacing="0" border="0"> - <tr> - <td> - <!--[if mso]> - <center> - <table><tr><td width="600"> - <![endif]--> - <table width="100%" cellpadding="0" cellspacing="0" border="0" style="width: 100%; max-width:600px;" align="center"> - <tr> - <td role="modules-container" style="padding: 0px 0px 0px 0px; color: #626262; text-align: left;" bgcolor="#F4F4F4" width="100%" - align="left"> - - <table class="module preheader preheader-hide" role="module" data-type="preheader" border="0" cellpadding="0" cellspacing="0" - width="100%" style="display: none !important; mso-hide: all; visibility: hidden; opacity: 0; color: transparent; height: 0; width: 0;"> - <tr> - <td role="module-content"> - <p>you have a new notification</p> - </td> - </tr> - </table> - - <table class="wrapper" role="module" data-type="image" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;"> - <tr> - <td style="font-size:6px;line-height:10px;padding:20px 0px 20px 0px;" valign="top" align="center"> - <a href="https://hindawi.com"> - <img class="max-width" border="0" style="display:block;color:#000000;text-decoration:none;font-family:Helvetica, arial, sans-serif;font-size:16px;max-width:10% !important;width:10%;height:auto !important;" - src="https://marketing-image-production.s3.amazonaws.com/uploads/bb39b20cf15e52c1c0933676e25f2b2402737c6560b8098c204ad6932b84eb2058804376dbc4db138c7a21dcaed9325bde36185648afac5bc97e3d73d4e12718.png" - alt="" width="60"> - </a> - </td> - </tr> - </table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/intro.hbs b/packages/component-helper-service/src/services/email/templates/partials/intro.hbs deleted file mode 100644 index 0ce780b6d9e09ac62aecd9ec48ef287f92184e30..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/partials/intro.hbs +++ /dev/null @@ -1 +0,0 @@ -<p data-pm-slice="1 1 []">Dear Dr. {{toUserName}},</p> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/invButtons.hbs b/packages/component-helper-service/src/services/email/templates/partials/invButtons.hbs deleted file mode 100644 index 5c5041dec3a973c019e5743106826fa11137c14e..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/partials/invButtons.hbs +++ /dev/null @@ -1,88 +0,0 @@ -<table border="0" cellpadding="0" cellspacing="0" align="center" width="100%" role="module" data-type="columns" data-version="2" - style="padding:20px 0px 20px 0px;background-color:#ffffff;box-sizing:border-box;" bgcolor="#ffffff"> - <tr role='module-content'> - <td height="100%" valign="top"> - <!--[if (gte mso 9)|(IE)]> - <center> - <table cellpadding="0" cellspacing="0" border="0" width="100%" style="border-spacing:0;border-collapse:collapse;table-layout: fixed;" > - <tr> - <![endif]--> - - <!--[if (gte mso 9)|(IE)]> - <td width="300.000px" valign="top" style="padding: 0px 0px 0px 0px;border-collapse: collapse;" > - <![endif]--> - - <table width="300.000" style="width:300.000px;border-spacing:0;border-collapse:collapse;margin:0px 0px 0px 0px;" cellpadding="0" - cellspacing="0" align="left" border="0" bgcolor="#ffffff" class="column column-0 of-2 - empty"> - <tr> - <td style="padding:0px;margin:0px;border-spacing:0;"> - <table border="0" cellPadding="0" cellSpacing="0" class="module" data-role="module-button" data-type="button" role="module" - style="table-layout:fixed" width="100%"> - <tbody> - <tr> - <td align="center" class="outer-td" style="padding:0px 0px 0px 0px"> - <table border="0" cellPadding="0" cellSpacing="0" class="button-css__deep-table___2OZyb wrapper-mobile" style="text-align:center"> - <tbody> - <tr> - <td align="center" bgcolor="#0d78f2" class="inner-td" style="border-radius:6px;font-size:16px;text-align:center;background-color:inherit"> - <a style="background-color:#0d78f2;border:1px solid #333333;border-color:#0d78f2;border-radius:0px;border-width:1px;color:#ffffff;display:inline-block;font-family:arial,helvetica,sans-serif;font-size:16px;font-weight:normal;letter-spacing:0px;line-height:16px;padding:12px 18px 12px 18px;text-align:center;text-decoration:none" - href="{{ agreeLink }}" target="_blank">AGREE</a> - </td> - </tr> - </tbody> - </table> - </td> - </tr> - </tbody> - </table> - </td> - </tr> - </table> - - <!--[if (gte mso 9)|(IE)]> - </td> - <![endif]--> - <!--[if (gte mso 9)|(IE)]> - <td width="300.000px" valign="top" style="padding: 0px 0px 0px 0px;border-collapse: collapse;" > - <![endif]--> - - <table width="300.000" style="width:300.000px;border-spacing:0;border-collapse:collapse;margin:0px 0px 0px 0px;" cellpadding="0" - cellspacing="0" align="left" border="0" bgcolor="#ffffff" class="column column-1 of-2 - empty"> - <tr> - <td style="padding:0px;margin:0px;border-spacing:0;"> - <table border="0" cellPadding="0" cellSpacing="0" class="module" data-role="module-button" data-type="button" role="module" - style="table-layout:fixed" width="100%"> - <tbody> - <tr> - <td align="center" class="outer-td" style="padding:0px 0px 0px 0px"> - <table border="0" cellPadding="0" cellSpacing="0" class="button-css__deep-table___2OZyb wrapper-mobile" style="text-align:center"> - <tbody> - <tr> - <td align="center" bgcolor="#e4dfdf" class="inner-td" style="border-radius:6px;font-size:16px;text-align:center;background-color:inherit"> - <a style="background-color:#e4dfdf;border:1px solid #333333;border-color:#E4DFDF;border-radius:0px;border-width:1px;color:#302e2e;display:inline-block;font-family:arial,helvetica,sans-serif;font-size:16px;font-weight:normal;letter-spacing:0px;line-height:16px;padding:12px 18px 12px 18px;text-align:center;text-decoration:none" - href="{{ declineLink }}" target="_blank">DECLINE</a> - </td> - </tr> - </tbody> - </table> - </td> - </tr> - </tbody> - </table> - </td> - </tr> - </table> - - <!--[if (gte mso 9)|(IE)]> - </td> - <![endif]--> - <!--[if (gte mso 9)|(IE)]> - <tr> - </table> - </center> - <![endif]--> - </td> - </tr> -</table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/invHeader.hbs b/packages/component-helper-service/src/services/email/templates/partials/invHeader.hbs deleted file mode 100644 index a8390f81f0389272c8824e79e17fda96b444748d..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/partials/invHeader.hbs +++ /dev/null @@ -1,161 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html data-editor-version="2" class="sg-campaigns" xmlns="http://www.w3.org/1999/xhtml"> - -<head> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1" /> - <!--[if !mso]><!--> - <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> - <!--<![endif]--> - <!--[if (gte mso 9)|(IE)]> - <xml> - <o:OfficeDocumentSettings> - <o:AllowPNG/> - <o:PixelsPerInch>96</o:PixelsPerInch> - </o:OfficeDocumentSettings> - </xml> - <![endif]--> - <!--[if (gte mso 9)|(IE)]> - <style type="text/css"> - body {width: 600px;margin: 0 auto;} - table {border-collapse: collapse;} - table, td {mso-table-lspace: 0pt;mso-table-rspace: 0pt;} - img {-ms-interpolation-mode: bicubic;} - </style> - <![endif]--> - - <style type="text/css"> - body, - p, - div { - font-family: helvetica, arial, sans-serif; - font-size: 14px; - } - - body { - color: #626262; - } - - body a { - color: #0D78F2; - text-decoration: none; - } - - p { - margin: 0; - padding: 0; - } - - table.wrapper { - width: 100% !important; - table-layout: fixed; - -webkit-font-smoothing: antialiased; - -webkit-text-size-adjust: 100%; - -moz-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; - } - - img.max-width { - max-width: 100% !important; - } - - .column.of-2 { - width: 50%; - } - - .column.of-3 { - width: 33.333%; - } - - .column.of-4 { - width: 25%; - } - - @media screen and (max-width:480px) { - .preheader .rightColumnContent, - .footer .rightColumnContent { - text-align: left !important; - } - .preheader .rightColumnContent div, - .preheader .rightColumnContent span, - .footer .rightColumnContent div, - .footer .rightColumnContent span { - text-align: left !important; - } - .preheader .rightColumnContent, - .preheader .leftColumnContent { - font-size: 80% !important; - padding: 5px 0; - } - table.wrapper-mobile { - width: 100% !important; - table-layout: fixed; - } - img.max-width { - height: auto !important; - max-width: 480px !important; - } - a.bulletproof-button { - display: block !important; - width: auto !important; - font-size: 80%; - padding-left: 0 !important; - padding-right: 0 !important; - } - .columns { - width: 100% !important; - } - .column { - display: block !important; - width: 100% !important; - padding-left: 0 !important; - padding-right: 0 !important; - margin-left: 0 !important; - margin-right: 0 !important; - } - } - </style> - <!--user entered Head Start--> - - <!--End Head user entered--> -</head> - -<body> - <center class="wrapper" data-link-color="#0D78F2" data-body-style="font-size: 14px; font-family: helvetica,arial,sans-serif; color: #626262; background-color: #F4F4F4;"> - <div class="webkit"> - <table cellpadding="0" cellspacing="0" border="0" width="100%" class="wrapper" bgcolor="#F4F4F4"> - <tr> - <td valign="top" bgcolor="#F4F4F4" width="100%"> - <table width="100%" role="content-container" class="outer" align="center" cellpadding="0" cellspacing="0" border="0"> - <tr> - <td width="100%"> - <table width="100%" cellpadding="0" cellspacing="0" border="0"> - <tr> - <td> - <!--[if mso]> - <center> - <table><tr><td width="600"> - <![endif]--> - <table width="100%" cellpadding="0" cellspacing="0" border="0" style="width: 100%; max-width:600px;" align="center"> - <tr> - <td role="modules-container" style="padding: 0px 0px 0px 0px; color: #626262; text-align: left;" bgcolor="#F4F4F4" width="100%" - align="left"> - - <table class="module preheader preheader-hide" role="module" data-type="preheader" border="0" cellpadding="0" cellspacing="0" - width="100%" style="display: none !important; mso-hide: all; visibility: hidden; opacity: 0; color: transparent; height: 0; width: 0;"> - <tr> - <td role="module-content"> - <p>new invitation</p> - </td> - </tr> - </table> - - <table class="wrapper" role="module" data-type="image" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;"> - <tr> - <td style="font-size:6px;line-height:10px;padding:20px 0px 20px 0px;" valign="top" align="center"> - <img class="max-width" border="0" style="display:block;color:#000000;text-decoration:none;font-family:Helvetica, arial, sans-serif;font-size:16px;max-width:10% !important;width:10%;height:auto !important;" - src="https://marketing-image-production.s3.amazonaws.com/uploads/bb39b20cf15e52c1c0933676e25f2b2402737c6560b8098c204ad6932b84eb2058804376dbc4db138c7a21dcaed9325bde36185648afac5bc97e3d73d4e12718.png" - alt="" width="60"> - </td> - </tr> - </table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/invLowerContent.hbs b/packages/component-helper-service/src/services/email/templates/partials/invLowerContent.hbs deleted file mode 100644 index 2e391bc6b161adfc49bee25dd7db227001cab266..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/partials/invLowerContent.hbs +++ /dev/null @@ -1,20 +0,0 @@ -<table class="module" role="module" data-type="text" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;"> - <tr> - <td style="padding:30px 23px 0px 23px;background-color:#ffffff;" height="100%" valign="top" bgcolor="#ffffff"> - <p data-pm-slice="1 1 []"> - <a href="{{ detailsLink }}">See more information</a> - </p> - - <p data-pm-slice="1 1 []"> </p> - - {{#unless resend }} - {{> invManuscriptData }} - {{/unless}} - <p data-pm-slice="1 1 []">{{{ lowerContent }}}</p> - - <p> </p> - {{> signature }} - <div style="text-align: center;"> </div> - </td> - </tr> -</table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/invManuscriptData.hbs b/packages/component-helper-service/src/services/email/templates/partials/invManuscriptData.hbs deleted file mode 100644 index 36d60dbe2943b37e8ef7ba15031256728b8f409b..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/partials/invManuscriptData.hbs +++ /dev/null @@ -1,15 +0,0 @@ -<p data-pm-slice="1 1 []">{{ manuscriptText }}</p> -<p> </p> -<h2>{{ title }}</h2> -<p> </p> -<h4> - <span style="font-family:arial,helvetica,sans-serif;">{{ authorsList }}</span> -</h4> -<p> - <br /> - <em> - <span style="font-family:arial,helvetica,sans-serif;">{{{abstract}}}</span> - </em> -</p> - -<p> </p> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/invUpperContent.hbs b/packages/component-helper-service/src/services/email/templates/partials/invUpperContent.hbs deleted file mode 100644 index 2b9dc858cbc000c6aff38dc4905fe8eb40474101..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/partials/invUpperContent.hbs +++ /dev/null @@ -1,13 +0,0 @@ -<table class="module" role="module" data-type="text" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;"> - <tr> - <td style="padding:30px 23px 20px 23px;background-color:#ffffff;" height="100%" valign="top" bgcolor="#ffffff"> - <div> - <p data-pm-slice="1 1 []">Dear Dr. {{ toUserName }},</p> - - <p> </p> - <p>{{{ upperContent }}}</p> - </div> - - </td> - </tr> -</table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/signature.hbs b/packages/component-helper-service/src/services/email/templates/partials/signature.hbs deleted file mode 100644 index eec0831b8cdc1d3835c9852b1d79c04a8dcce891..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/partials/signature.hbs +++ /dev/null @@ -1,4 +0,0 @@ -<p>Kind regards, - <br /> {{ signatureName }} - <br /> {{ signatureJournal }} -</p> \ No newline at end of file diff --git a/packages/component-helper-service/src/tests/fragment.test.js b/packages/component-helper-service/src/tests/fragment.test.js new file mode 100644 index 0000000000000000000000000000000000000000..3b5875eaf284e315ce1e3dd8a8792769e545e9c4 --- /dev/null +++ b/packages/component-helper-service/src/tests/fragment.test.js @@ -0,0 +1,29 @@ +process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0' +process.env.SUPPRESS_NO_CONFIG_WARNING = true + +const { cloneDeep } = require('lodash') +const fixturesService = require('pubsweet-component-fixture-service') + +const { fixtures } = fixturesService +const { Fragment } = require('../Helper') + +describe('Fragment helper', () => { + let testFixtures = {} + beforeEach(() => { + testFixtures = cloneDeep(fixtures) + }) + + it('hasReviewReport - should return true if the fragment has a review report', () => { + const { fragment } = testFixtures.fragments + const fragmentHelper = new Fragment({ fragment }) + + expect(fragmentHelper.hasReviewReport()).toBeTruthy() + }) + it('hasReviewReport - should return false if the fragment does not have a review report', () => { + const { fragment } = testFixtures.fragments + fragment.recommendations = [] + const fragmentHelper = new Fragment({ fragment }) + + expect(fragmentHelper.hasReviewReport()).toBeFalsy() + }) +}) diff --git a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js index ee36ebb094a75bd91e694ad027c0d7b6c6bac745..4cbdb582680e110dc4d067474dfa4cc3e0c3e913 100644 --- a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js +++ b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js @@ -5,11 +5,12 @@ const { v4 } = require('uuid') const { services, - authsome: authsomeHelper, + Fragment, Collection, + authsome: authsomeHelper, } = require('pubsweet-component-helper-service') -const { features = {} } = config +const { features = {}, recommendations } = config const sendMTSPackage = async (collection, fragment) => { const s3Config = get(config, 'pubsweet-component-aws-s3', {}) @@ -68,6 +69,20 @@ module.exports = models => async (req, res) => { error: 'Unauthorized.', }) + if ( + recommendation === recommendations.publish && + recommendationType === recommendations.type.editor && + collection.handlingEditor && + collection.handlingEditor.id === req.user + ) { + const fragmentHelper = new Fragment({ fragment }) + if (!fragmentHelper.hasReviewReport()) { + return res + .status(400) + .json({ error: 'Cannot publish without at least one reviewer report.' }) + } + } + fragment.recommendations = fragment.recommendations || [] const newRecommendation = { id: uuid.v4(), diff --git a/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/post.test.js b/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/post.test.js index 5489b35a75f8d70fba86992ab2369029248cd2e7..e86097c9abb9defbad77862f1826360d5edef8fa 100644 --- a/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/post.test.js +++ b/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/post.test.js @@ -332,4 +332,31 @@ describe('Post fragments recommendations route handler', () => { expect(data.userId).toEqual(editorInChief.id) expect(data.recommendation).toBe('return-to-handling-editor') }) + it('should return an error when a HE recommends to publish without a reviewer report', async () => { + const { handlingEditor } = testFixtures.users + const { collection } = testFixtures.collections + const { fragment } = testFixtures.fragments + body.recommendation = 'publish' + body.recommendationType = 'editorRecommendation' + fragment.recommendations = [] + + const res = await requests.sendRequest({ + body, + userId: handlingEditor.id, + models, + route, + path, + params: { + collectionId: collection.id, + fragmentId: fragment.id, + }, + }) + + expect(res.statusCode).toBe(400) + const data = JSON.parse(res._getData()) + + expect(data.error).toEqual( + 'Cannot publish without at least one reviewer report.', + ) + }) }) diff --git a/packages/xpub-faraday/config/default.js b/packages/xpub-faraday/config/default.js index 737efe3bd3b91372aff2a608b6a712f30a25dbda..7cd9de3dbaab836663730ca2ed9942712d2d237b 100644 --- a/packages/xpub-faraday/config/default.js +++ b/packages/xpub-faraday/config/default.js @@ -129,4 +129,14 @@ module.exports = { features: { mts: JSON.parse(get(process, 'env.FEATURE_MTS', true)), }, + recommendations: { + minor: 'minor', + major: 'major', + reject: 'reject', + publish: 'publish', + type: { + review: 'review', + editor: 'editorRecommendation', + }, + }, }