From 620afea56e1a252032a71f589fc48c08406a6c78 Mon Sep 17 00:00:00 2001
From: Sebastian <sebastian.mihalache@thinslices.com>
Date: Thu, 19 Apr 2018 14:35:43 +0300
Subject: [PATCH] feat(component-invite): fix test fixtures and add data to
 mail

---
 .../routes/collectionsInvitations/patch.js    | 17 +++++------
 .../collectionsInvitations/delete.test.js     |  3 +-
 .../tests/collectionsInvitations/get.test.js  |  7 ++---
 .../collectionsInvitations/patch.test.js      | 28 ++++++++++++++++---
 .../tests/collectionsInvitations/post.test.js |  3 +-
 .../src/tests/fixtures/collections.js         |  8 ++++++
 .../src/tests/helpers/Model.js                | 22 +++++++--------
 packages/component-mail-service/src/Mail.js   |  2 ++
 8 files changed, 60 insertions(+), 30 deletions(-)

diff --git a/packages/component-invite/src/routes/collectionsInvitations/patch.js b/packages/component-invite/src/routes/collectionsInvitations/patch.js
index 19e95891c..dcfde76b4 100644
--- a/packages/component-invite/src/routes/collectionsInvitations/patch.js
+++ b/packages/component-invite/src/routes/collectionsInvitations/patch.js
@@ -21,20 +21,21 @@ module.exports = models => async (req, res) => {
     const invitation = await collection.invitations.find(
       invitation => invitation.id === invitationId,
     )
-    if (invitation === undefined) {
-      res.status(404).json({
+    if (invitation === undefined)
+      return res.status(404).json({
         error: `Invitation ${invitationId} not found`,
       })
-      return
-    }
-    if (invitation.userId !== user.id) {
-      res.status(403).json({
+    if (invitation.hasAnswer)
+      return res
+        .status(400)
+        .json({ error: `${invitation.id} has already been answered` })
+    if (invitation.userId !== user.id)
+      return 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()
diff --git a/packages/component-invite/src/tests/collectionsInvitations/delete.test.js b/packages/component-invite/src/tests/collectionsInvitations/delete.test.js
index 8b8b78eaa..38ca5f0f2 100644
--- a/packages/component-invite/src/tests/collectionsInvitations/delete.test.js
+++ b/packages/component-invite/src/tests/collectionsInvitations/delete.test.js
@@ -11,12 +11,13 @@ jest.mock('pubsweet-component-mail-service', () => ({
 }))
 
 const deletePath = '../../routes/collectionsInvitations/delete'
-const models = Model.build()
 
 describe('Delete Collections Invitations route handler', () => {
   let testFixtures = {}
+  let models
   beforeEach(() => {
     testFixtures = cloneDeep(fixtures)
+    models = Model.build(testFixtures)
   })
   it('should return an error when the collection does not exist', async () => {
     const { editorInChief } = testFixtures.users
diff --git a/packages/component-invite/src/tests/collectionsInvitations/get.test.js b/packages/component-invite/src/tests/collectionsInvitations/get.test.js
index b594ef526..7d64dcf8b 100644
--- a/packages/component-invite/src/tests/collectionsInvitations/get.test.js
+++ b/packages/component-invite/src/tests/collectionsInvitations/get.test.js
@@ -9,8 +9,10 @@ const cloneDeep = require('lodash/cloneDeep')
 const getPath = '../../routes/collectionsInvitations/get'
 describe('Get collection invitations route handler', () => {
   let testFixtures = {}
+  let models
   beforeEach(() => {
     testFixtures = cloneDeep(fixtures)
+    models = Model.build(testFixtures)
   })
   it('should return success when the request data is correct', async () => {
     const { editorInChief, handlingEditor } = testFixtures.users
@@ -23,7 +25,6 @@ describe('Get collection invitations route handler', () => {
     req.params.collectionId = collection.id
     req.user = editorInChief.id
     const res = httpMocks.createResponse()
-    const models = Model.build()
     await require(getPath)(models)(req, res)
 
     expect(res.statusCode).toBe(200)
@@ -36,7 +37,6 @@ describe('Get collection invitations route handler', () => {
     req.query = {}
     req.user = editorInChief.id
     const res = httpMocks.createResponse()
-    const models = Model.build()
     await require(getPath)(models)(req, res)
     expect(res.statusCode).toBe(400)
     const data = JSON.parse(res._getData())
@@ -53,7 +53,6 @@ describe('Get collection invitations route handler', () => {
     req.params.collectionId = 'invalid-id'
     req.user = editorInChief.id
     const res = httpMocks.createResponse()
-    const models = Model.build()
     await require(getPath)(models)(req, res)
     expect(res.statusCode).toBe(404)
     const data = JSON.parse(res._getData())
@@ -70,7 +69,6 @@ describe('Get collection invitations route handler', () => {
     req.params.collectionId = collection.id
     req.user = editorInChief.id
     const res = httpMocks.createResponse()
-    const models = Model.build()
     await require(getPath)(models)(req, res)
     expect(res.statusCode).toBe(400)
     const data = JSON.parse(res._getData())
@@ -88,7 +86,6 @@ describe('Get collection invitations route handler', () => {
     req.params.collectionId = collection.id
     req.user = editorInChief.id
     const res = httpMocks.createResponse()
-    const models = Model.build()
     await require(getPath)(models)(req, res)
     expect(res.statusCode).toBe(400)
     const data = JSON.parse(res._getData())
diff --git a/packages/component-invite/src/tests/collectionsInvitations/patch.test.js b/packages/component-invite/src/tests/collectionsInvitations/patch.test.js
index 62c4332bd..5bd244209 100644
--- a/packages/component-invite/src/tests/collectionsInvitations/patch.test.js
+++ b/packages/component-invite/src/tests/collectionsInvitations/patch.test.js
@@ -6,7 +6,6 @@ const fixtures = require('./../fixtures/fixtures')
 const Model = require('./../helpers/Model')
 const cloneDeep = require('lodash/cloneDeep')
 
-const models = Model.build()
 jest.mock('pubsweet-component-mail-service', () => ({
   setupAssignEmail: jest.fn(),
   setupAgreeEmail: jest.fn(),
@@ -20,9 +19,11 @@ const patchPath = '../../routes/collectionsInvitations/patch'
 describe('Patch collections invitations route handler', () => {
   let testFixtures = {}
   let body = {}
+  let models
   beforeEach(() => {
     testFixtures = cloneDeep(fixtures)
     body = cloneDeep(reqBody)
+    models = Model.build(testFixtures)
   })
   it('should return success when the handling editor accepts work on a collection', async () => {
     const { handlingEditor } = testFixtures.users
@@ -33,7 +34,7 @@ describe('Patch collections invitations route handler', () => {
     req.user = handlingEditor.id
     req.params.collectionId = collection.id
     const heInv = collection.invitations.find(
-      inv => inv.role === 'handlingEditor',
+      inv => inv.role === 'handlingEditor' && inv.hasAnswer === false,
     )
     req.params.invitationId = heInv.id
     const res = httpMocks.createResponse()
@@ -65,7 +66,10 @@ describe('Patch collections invitations route handler', () => {
     })
     req.user = handlingEditor.id
     req.params.collectionId = collection.id
-    req.params.invitationId = collection.invitations[0].id
+    const heInv = collection.invitations.find(
+      inv => inv.role === 'handlingEditor' && inv.hasAnswer == false,
+    )
+    req.params.invitationId = heInv.id
     const res = httpMocks.createResponse()
     await require(patchPath)(models)(req, res)
 
@@ -127,7 +131,7 @@ describe('Patch collections invitations route handler', () => {
     req.user = reviewer.id
     req.params.collectionId = collection.id
     const inv = collection.invitations.find(
-      inv => inv.role === 'handlingEditor',
+      inv => inv.role === 'handlingEditor' && inv.hasAnswer === false,
     )
     req.params.invitationId = inv.id
     const res = httpMocks.createResponse()
@@ -138,4 +142,20 @@ describe('Patch collections invitations route handler', () => {
       `User ${reviewer.email} is not allowed to modify invitation ${inv.id}`,
     )
   })
+  it('should return an error when the invitation is already answered', async () => {
+    const { handlingEditor } = testFixtures.users
+    const { collection } = testFixtures.collections
+    const req = httpMocks.createRequest({
+      body,
+    })
+    req.user = handlingEditor.id
+    req.params.collectionId = collection.id
+    const inv = collection.invitations.find(inv => inv.hasAnswer)
+    req.params.invitationId = inv.id
+    const res = httpMocks.createResponse()
+    await require(patchPath)(models)(req, res)
+    expect(res.statusCode).toBe(400)
+    const data = JSON.parse(res._getData())
+    expect(data.error).toEqual(`${inv.id} has already been answered`)
+  })
 })
diff --git a/packages/component-invite/src/tests/collectionsInvitations/post.test.js b/packages/component-invite/src/tests/collectionsInvitations/post.test.js
index 14573ae73..5378ad0e6 100644
--- a/packages/component-invite/src/tests/collectionsInvitations/post.test.js
+++ b/packages/component-invite/src/tests/collectionsInvitations/post.test.js
@@ -11,7 +11,6 @@ const cloneDeep = require('lodash/cloneDeep')
 
 const configRoles = config.get('roles')
 
-const models = Model.build()
 jest.mock('pubsweet-component-mail-service', () => ({
   setupInviteEmail: jest.fn(),
   setupAssignEmail: jest.fn(),
@@ -34,9 +33,11 @@ const postPath = '../../routes/collectionsInvitations/post'
 describe('Post collections invitations route handler', () => {
   let testFixtures = {}
   let body = {}
+  let models
   beforeEach(() => {
     testFixtures = cloneDeep(fixtures)
     body = cloneDeep(reqBody)
+    models = Model.build(testFixtures)
   })
   it('should return an error params are missing', async () => {
     const { admin } = testFixtures.users
diff --git a/packages/component-invite/src/tests/fixtures/collections.js b/packages/component-invite/src/tests/fixtures/collections.js
index 78920b4aa..9331af1e1 100644
--- a/packages/component-invite/src/tests/fixtures/collections.js
+++ b/packages/component-invite/src/tests/fixtures/collections.js
@@ -35,6 +35,14 @@ const collections = {
         userId: reviewer.id,
         timestamp: chance.timestamp(),
       },
+      {
+        id: chance.guid(),
+        role: 'handlingEditor',
+        hasAnswer: true,
+        isAccepted: false,
+        userId: handlingEditor.id,
+        timestamp: chance.timestamp(),
+      },
     ],
     handlingEditor: {
       id: handlingEditor.id,
diff --git a/packages/component-invite/src/tests/helpers/Model.js b/packages/component-invite/src/tests/helpers/Model.js
index c1ded2c8e..7337e1aa6 100644
--- a/packages/component-invite/src/tests/helpers/Model.js
+++ b/packages/component-invite/src/tests/helpers/Model.js
@@ -1,4 +1,4 @@
-const fixtures = require('../fixtures/fixtures')
+// const fixtures = require('../fixtures/fixtures')
 
 const UserMock = require('../mocks/User')
 const TeamMock = require('../mocks/Team')
@@ -7,23 +7,23 @@ const notFoundError = new Error()
 notFoundError.name = 'NotFoundError'
 notFoundError.status = 404
 
-const build = () => {
+const build = fixtures => {
   const models = {
     User: {},
     Collection: {
-      find: jest.fn(id => findMock(id, 'collections')),
+      find: jest.fn(id => findMock(id, 'collections', fixtures)),
     },
     Team: {},
     Fragment: {
-      find: jest.fn(id => findMock(id, 'fragments')),
+      find: jest.fn(id => findMock(id, 'fragments', fixtures)),
     },
   }
-  UserMock.find = jest.fn(id => findMock(id, 'users'))
-  UserMock.findByEmail = jest.fn(email => findByEmailMock(email))
+  UserMock.find = jest.fn(id => findMock(id, 'users', fixtures))
+  UserMock.findByEmail = jest.fn(email => findByEmailMock(email, fixtures))
   UserMock.all = jest.fn(() => Object.values(fixtures.users))
-  TeamMock.find = jest.fn(id => findMock(id, 'teams'))
+  TeamMock.find = jest.fn(id => findMock(id, 'teams', fixtures))
   TeamMock.updateProperties = jest.fn(team =>
-    updatePropertiesMock(team, 'teams'),
+    updatePropertiesMock(team, 'teams', fixtures),
   )
   TeamMock.all = jest.fn(() => Object.values(fixtures.teams))
 
@@ -32,7 +32,7 @@ const build = () => {
   return models
 }
 
-const findMock = (id, type) => {
+const findMock = (id, type, fixtures) => {
   const foundObj = Object.values(fixtures[type]).find(
     fixtureObj => fixtureObj.id === id,
   )
@@ -41,7 +41,7 @@ const findMock = (id, type) => {
   return Promise.resolve(foundObj)
 }
 
-const findByEmailMock = email => {
+const findByEmailMock = (email, fixtures) => {
   const foundUser = Object.values(fixtures.users).find(
     fixtureUser => fixtureUser.email === email,
   )
@@ -50,7 +50,7 @@ const findByEmailMock = email => {
   return Promise.resolve(foundUser)
 }
 
-const updatePropertiesMock = (obj, type) => {
+const updatePropertiesMock = (obj, type, fixtures) => {
   const foundObj = Object.values(fixtures[type]).find(
     fixtureObj => fixtureObj === obj,
   )
diff --git a/packages/component-mail-service/src/Mail.js b/packages/component-mail-service/src/Mail.js
index e153a5bd6..7c2fe121f 100644
--- a/packages/component-mail-service/src/Mail.js
+++ b/packages/component-mail-service/src/Mail.js
@@ -160,7 +160,9 @@ module.exports = {
         email: invitedUser.email,
         token: invitedUser.passwordResetToken,
         collectionId: collection.id,
+        fragmentId,
         agree: true,
+        invitationId,
       })}`
     }
 
-- 
GitLab