From 36b704a58a1602fcca855646848359bfa8500b7d Mon Sep 17 00:00:00 2001
From: Sebastian Mihalache <sebastian.mihalache@gmail.con>
Date: Fri, 4 May 2018 17:11:51 +0300
Subject: [PATCH] feat(component-invite): add invitedOn and respondedOn to
 invitations, fix API tests

---
 .../src/CollectionsInvitations.js             | 47 +++++++------------
 .../src/helpers/Collection.js                 |  5 +-
 .../src/helpers/Invitation.js                 |  7 +--
 .../routes/collectionsInvitations/decline.js  |  2 +-
 .../src/routes/collectionsInvitations/get.js  | 11 +++--
 .../routes/collectionsInvitations/patch.js    |  6 +--
 .../src/routes/collectionsInvitations/post.js |  8 ++--
 .../src/tests/fixtures/collections.js         | 12 +++--
 packages/xpub-faraday/config/authsome-mode.js |  6 +--
 9 files changed, 52 insertions(+), 52 deletions(-)

diff --git a/packages/component-invite/src/CollectionsInvitations.js b/packages/component-invite/src/CollectionsInvitations.js
index e9c0f3aa5..ba6fa2d85 100644
--- a/packages/component-invite/src/CollectionsInvitations.js
+++ b/packages/component-invite/src/CollectionsInvitations.js
@@ -18,21 +18,14 @@ const CollectionsInvitations = app => {
    *    }
    * @apiSuccessExample {json} Success
    *    HTTP/1.1 200 OK
-   *    {
-   *      "id": "a6184463-b17a-42f8-b02b-ae1d755cdc6b",
-   *      "type": "user",
-   *      "admin": false,
-   *      "email": "email@example.com",
-   *      "teams": [
-   *        "c576695a-7cda-4e27-8e9c-31f3a0e9d592"
-   *      ],
-   *      "username": "email@example.com",
-   *      "fragments": [],
-   *      "collections": [],
-   *      "isConfirmed": false,
-   *      "editorInChief": false,
-   *      "handlingEditor": true,
-   *      "passwordResetToken": "04590a2b7f6c1f37cb84881d529e516fa6fc309c205a07f1341b2bfaa6f2b46c"
+   *   {
+   *     "id": "7b2431af-210c-49f9-a69a-e19271066ebd",
+   *     "role": "reviewer",
+   *     "userId": "4c3f8ee1-785b-4adb-87b4-407a27f652c6",
+   *     "hasAnswer": false,
+   *     "invitedOn": 1525428890167,
+   *     "isAccepted": false,
+   *     "respondedOn": null
    *    }
    * @apiErrorExample {json} Invite user errors
    *    HTTP/1.1 403 Forbidden
@@ -55,7 +48,8 @@ const CollectionsInvitations = app => {
    *    HTTP/1.1 200 OK
    *    [{
    *      "name": "John Smith",
-   *      "timestamp": "123223121",
+   *     "invitedOn": 1525428890167,
+   *     "respondedOn": 1525428890299,
    *      "email": "email@example.com",
    *      "status": "pending",
    *      "invitationId": "1990881"
@@ -99,19 +93,14 @@ const CollectionsInvitations = app => {
    *    }
    * @apiSuccessExample {json} Success
    *    HTTP/1.1 200 OK
-   *    {
-   *      "id": "a6184463-b17a-42f8-b02b-ae1d755cdc6b",
-   *      "type": "user",
-   *      "admin": false,
-   *      "email": "email@example.com",
-   *      "teams": [],
-   *      "username": "email@example.com",
-   *      "fragments": [],
-   *      "collections": [],
-   *      "isConfirmed": false,
-   *      "editorInChief": false,
-   *      "handlingEditor": true,
-   *      "passwordResetToken": "04590a2b7f6c1f37cb84881d529e516fa6fc309c205a07f1341b2bfaa6f2b46c"
+   *   {
+   *     "id": "7b2431af-210c-49f9-a69a-e19271066ebd",
+   *     "role": "reviewer",
+   *     "userId": "4c3f8ee1-785b-4adb-87b4-407a27f652c6",
+   *     "hasAnswer": true,
+   *     "invitedOn": 1525428890167,
+   *     "isAccepted": false,
+   *     "respondedOn": 1525428890299
    *    }
    * @apiErrorExample {json} Update invitations errors
    *    HTTP/1.1 403 Forbidden
diff --git a/packages/component-invite/src/helpers/Collection.js b/packages/component-invite/src/helpers/Collection.js
index d56784679..0fdd02e43 100644
--- a/packages/component-invite/src/helpers/Collection.js
+++ b/packages/component-invite/src/helpers/Collection.js
@@ -7,7 +7,8 @@ const addHandlingEditor = async (collection, user, invitation) => {
   collection.handlingEditor = {
     id: user.id,
     name: `${user.firstName} ${user.lastName}`,
-    timestamp: invitation.timestamp,
+    invitedOn: invitation.invitedOn,
+    respondedOn: invitation.respondedOn,
     email: user.email,
     hasAnswer: invitation.hasAnswer,
     isAccepted: invitation.isAccepted,
@@ -18,7 +19,7 @@ const addHandlingEditor = async (collection, user, invitation) => {
 const updateHandlingEditor = async (collection, isAccepted) => {
   collection.handlingEditor.hasAnswer = true
   collection.handlingEditor.isAccepted = isAccepted
-  collection.handlingEditor.timestamp = Date.now()
+  collection.handlingEditor.respondedOn = Date.now()
   let status
   isAccepted ? (status = 'heAssigned') : (status = 'submitted')
   await updateStatus(collection, status)
diff --git a/packages/component-invite/src/helpers/Invitation.js b/packages/component-invite/src/helpers/Invitation.js
index 9b08c227e..00b39f0cb 100644
--- a/packages/component-invite/src/helpers/Invitation.js
+++ b/packages/component-invite/src/helpers/Invitation.js
@@ -12,8 +12,8 @@ const getInvitationData = (invitations, userId, role) => {
     status = 'declined'
   }
 
-  const { timestamp, id } = matchingInvitation
-  return { timestamp, status, id }
+  const { invitedOn, respondedOn, id } = matchingInvitation
+  return { invitedOn, respondedOn, status, id }
 }
 
 const setupInvitation = async (userId, role, collection) => {
@@ -21,9 +21,10 @@ const setupInvitation = async (userId, role, collection) => {
     role,
     hasAnswer: false,
     isAccepted: false,
-    timestamp: Date.now(),
+    invitedOn: Date.now(),
     id: uuid.v4(),
     userId,
+    respondedOn: null,
   }
   collection.invitations = collection.invitations || []
   collection.invitations.push(invitation)
diff --git a/packages/component-invite/src/routes/collectionsInvitations/decline.js b/packages/component-invite/src/routes/collectionsInvitations/decline.js
index edb84f8ae..2143b943b 100644
--- a/packages/component-invite/src/routes/collectionsInvitations/decline.js
+++ b/packages/component-invite/src/routes/collectionsInvitations/decline.js
@@ -33,7 +33,7 @@ module.exports = models => async (req, res) => {
         }`,
       })
 
-    invitation.timestamp = Date.now()
+    invitation.respondedOn = Date.now()
     invitation.hasAnswer = true
     invitation.isAccepted = false
     await collection.save()
diff --git a/packages/component-invite/src/routes/collectionsInvitations/get.js b/packages/component-invite/src/routes/collectionsInvitations/get.js
index 2a2148198..d40c94ed1 100644
--- a/packages/component-invite/src/routes/collectionsInvitations/get.js
+++ b/packages/component-invite/src/routes/collectionsInvitations/get.js
@@ -7,7 +7,6 @@ const authsomeHelper = require('../../helpers/authsome')
 const configRoles = config.get('roles')
 module.exports = models => async (req, res) => {
   const { role } = req.query
-  // TO DO: authsome
   if (!helpers.checkForUndefinedParams(role)) {
     res.status(400).json({ error: 'Role is required' })
     return
@@ -41,14 +40,20 @@ module.exports = models => async (req, res) => {
     // TO DO: handle case for when the invitationID is provided
     const membersData = members.map(async member => {
       const user = await models.User.find(member)
-      const { timestamp, status, id } = invitationHelper.getInvitationData(
+      const {
+        invitedOn,
+        respondedOn,
+        status,
+        id,
+      } = invitationHelper.getInvitationData(
         collection.invitations,
         user.id,
         role,
       )
       return {
         name: `${user.firstName} ${user.lastName}`,
-        timestamp,
+        invitedOn,
+        respondedOn,
         email: user.email,
         status,
         invitationId: id,
diff --git a/packages/component-invite/src/routes/collectionsInvitations/patch.js b/packages/component-invite/src/routes/collectionsInvitations/patch.js
index 88a00ace9..90de7caa8 100644
--- a/packages/component-invite/src/routes/collectionsInvitations/patch.js
+++ b/packages/component-invite/src/routes/collectionsInvitations/patch.js
@@ -43,7 +43,7 @@ module.exports = models => async (req, res) => {
     }
     if (invitation.role === 'handlingEditor')
       await collectionHelper.updateHandlingEditor(collection, isAccepted)
-    invitation.timestamp = Date.now()
+    invitation.respondedOn = Date.now()
     invitation.hasAnswer = true
     const eic = await userHelper.getEditorInChief(models.User)
     const toEmail = eic.email
@@ -69,9 +69,9 @@ module.exports = models => async (req, res) => {
           await userHelper.setupReviewerDecisionEmailData({
             ...params,
             agree: true,
-            timestamp: invitation.timestamp,
+            timestamp: invitation.respondedOn,
           })
-        res.status(200).json(invitation)
+        return res.status(200).json(invitation)
       } catch (e) {
         logger.error(e)
         return res.status(500).json({ error: 'Email could not be sent.' })
diff --git a/packages/component-invite/src/routes/collectionsInvitations/post.js b/packages/component-invite/src/routes/collectionsInvitations/post.js
index d22a23e62..29aac5780 100644
--- a/packages/component-invite/src/routes/collectionsInvitations/post.js
+++ b/packages/component-invite/src/routes/collectionsInvitations/post.js
@@ -79,7 +79,7 @@ module.exports = models => async (req, res) => {
         return res
           .status(400)
           .json({ error: 'User has already replied to a previous invitation.' })
-      invitation.timestamp = Date.now()
+      invitation.invitedOn = Date.now()
       await collection.save()
       resend = true
     } else {
@@ -99,13 +99,13 @@ module.exports = models => async (req, res) => {
           ...params,
           user,
           invitationId: invitation.id,
-          timestamp: invitation.timestamp,
+          timestamp: invitation.invitedOn,
           resend,
         })
       }
 
       if (role === 'handlingEditor') {
-        invitation.timestamp = Date.now()
+        invitation.invitedOn = Date.now()
         await collection.save()
         await collectionHelper.addHandlingEditor(collection, user, invitation)
         await mailService.setupAssignEmail(
@@ -148,7 +148,7 @@ module.exports = models => async (req, res) => {
         ...params,
         user: newUser,
         invitationId: invitation.id,
-        timestamp: invitation.timestamp,
+        timestamp: invitation.invitedOn,
       })
       return res.status(200).json(invitation)
     }
diff --git a/packages/component-invite/src/tests/fixtures/collections.js b/packages/component-invite/src/tests/fixtures/collections.js
index 66e4e0f60..bef613219 100644
--- a/packages/component-invite/src/tests/fixtures/collections.js
+++ b/packages/component-invite/src/tests/fixtures/collections.js
@@ -31,7 +31,8 @@ const collections = {
         hasAnswer: false,
         isAccepted: false,
         userId: handlingEditor.id,
-        timestamp: chance.timestamp(),
+        invitedOn: chance.timestamp(),
+        respondedOn: null,
       },
       {
         id: chance.guid(),
@@ -39,7 +40,8 @@ const collections = {
         hasAnswer: false,
         isAccepted: false,
         userId: reviewer.id,
-        timestamp: chance.timestamp(),
+        invitedOn: chance.timestamp(),
+        respondedOn: null,
       },
       {
         id: chance.guid(),
@@ -47,7 +49,8 @@ const collections = {
         hasAnswer: true,
         isAccepted: false,
         userId: answerReviewer.id,
-        timestamp: chance.timestamp(),
+        invitedOn: chance.timestamp(),
+        respondedOn: chance.timestamp(),
       },
     ],
     handlingEditor: {
@@ -55,7 +58,8 @@ const collections = {
       hasAnswer: false,
       isAccepted: false,
       email: handlingEditor.email,
-      timestamp: chance.timestamp(),
+      invitedOn: chance.timestamp(),
+      respondedOn: null,
       name: `${handlingEditor.firstName} ${handlingEditor.lastName}`,
     },
   },
diff --git a/packages/xpub-faraday/config/authsome-mode.js b/packages/xpub-faraday/config/authsome-mode.js
index 364f8242e..866460db7 100644
--- a/packages/xpub-faraday/config/authsome-mode.js
+++ b/packages/xpub-faraday/config/authsome-mode.js
@@ -162,9 +162,9 @@ async function authenticatedUser(user, operation, object, context) {
     const collection = await context.models.Collection.find(
       get(object.collection, 'id'),
     )
-    if (collection.handlingEditor.id === user.id) {
-      return true
-    }
+    const handlingEditor = get(collection, 'handlingEditor')
+    if (!handlingEditor) return false
+    if (handlingEditor.id === user.id) return true
     return false
   }
 
-- 
GitLab