From 1668a5833d4d53c7c040c6655b02c1fbd10a88e1 Mon Sep 17 00:00:00 2001
From: Bogdan Cochior <bogdan.cochior@thinslices.com>
Date: Thu, 28 Jun 2018 16:04:08 +0300
Subject: [PATCH] feat(manuscript-details): update authsome by filtering
 authors coll, fragment data

---
 .../src/fixtures/fragments.js                 |   3 +
 .../xpub-faraday/config/authsome-helpers.js   |  53 ++++++++
 packages/xpub-faraday/config/authsome-mode.js |  29 ++---
 packages/xpub-faraday/config/test.js          |   3 +
 packages/xpub-faraday/package.json            |   9 +-
 .../tests/authsome-helpers.test.js            | 117 ++++++++++++++++++
 6 files changed, 194 insertions(+), 20 deletions(-)
 create mode 100644 packages/xpub-faraday/config/test.js
 create mode 100644 packages/xpub-faraday/tests/authsome-helpers.test.js

diff --git a/packages/component-fixture-manager/src/fixtures/fragments.js b/packages/component-fixture-manager/src/fixtures/fragments.js
index 2ee8c78db..10fcf908e 100644
--- a/packages/component-fixture-manager/src/fixtures/fragments.js
+++ b/packages/component-fixture-manager/src/fixtures/fragments.js
@@ -86,6 +86,7 @@ const fragments = {
     ],
     authors: [
       {
+        email: chance.email(),
         id: submittingAuthor.id,
         isSubmitting: true,
         isCorresponding: false,
@@ -124,6 +125,7 @@ const fragments = {
     },
     authors: [
       {
+        email: chance.email(),
         id: submittingAuthor.id,
         isSubmitting: true,
         isCorresponding: false,
@@ -162,6 +164,7 @@ const fragments = {
     },
     authors: [
       {
+        email: chance.email(),
         id: submittingAuthor.id,
         isSubmitting: true,
         isCorresponding: false,
diff --git a/packages/xpub-faraday/config/authsome-helpers.js b/packages/xpub-faraday/config/authsome-helpers.js
index ad75355dd..8b5a135a3 100644
--- a/packages/xpub-faraday/config/authsome-helpers.js
+++ b/packages/xpub-faraday/config/authsome-helpers.js
@@ -4,7 +4,9 @@ const config = require('config')
 
 const statuses = config.get('statuses')
 
+const keysToOmit = ['email', 'id']
 const publicStatusesPermissions = ['author', 'reviewer']
+const authorAllowedStatuses = ['revisionRequested', 'rejected', 'accepted']
 
 const parseAuthorsData = (coll, matchingCollPerm) => {
   if (['reviewer'].includes(matchingCollPerm.permission)) {
@@ -124,6 +126,55 @@ const hasFragmentInDraft = async ({ object, Fragment }) => {
   return isInDraft(fragment)
 }
 
+const filterAuthorRecommendationData = recommendation => {
+  const { comments } = recommendation
+  return {
+    ...recommendation,
+    comments: comments ? comments.filter(c => c.public) : [],
+  }
+}
+
+const stripeCollectionByRole = (coll = {}, role = '') => {
+  if (role === 'author') {
+    const { handlingEditor } = coll
+
+    if (!authorAllowedStatuses.includes(coll.status)) {
+      coll = {
+        ...coll,
+        handlingEditor: handlingEditor && {
+          ...omit(handlingEditor, keysToOmit),
+          name: 'Assigned',
+        },
+      }
+    }
+  }
+  return coll
+}
+
+const stripeFragmentByRole = (fragment = {}, role = '', user = {}) => {
+  const { recommendations, files, authors } = fragment
+  switch (role) {
+    case 'author':
+      return {
+        ...fragment,
+        recommendations: recommendations
+          ? recommendations.map(filterAuthorRecommendationData)
+          : [],
+      }
+    case 'reviewer':
+      return {
+        ...fragment,
+        files: omit(files, ['coverLetter']),
+        authors: authors.map(a => omit(a, ['email'])),
+        recommendations: recommendations
+          ? recommendations.filter(r => r.userId === user.id)
+          : [],
+      }
+    default:
+      return fragment
+  }
+}
+
 module.exports = {
   filterObjectData,
   parseAuthorsData,
@@ -137,4 +188,6 @@ module.exports = {
   hasPermissionForObject,
   isInDraft,
   hasFragmentInDraft,
+  stripeCollectionByRole,
+  stripeFragmentByRole,
 }
diff --git a/packages/xpub-faraday/config/authsome-mode.js b/packages/xpub-faraday/config/authsome-mode.js
index 960e0bede..49e34f158 100644
--- a/packages/xpub-faraday/config/authsome-mode.js
+++ b/packages/xpub-faraday/config/authsome-mode.js
@@ -1,5 +1,5 @@
 const config = require('config')
-const { get, pickBy, omit } = require('lodash')
+const { get, pickBy } = require('lodash')
 
 const statuses = config.get('statuses')
 const helpers = require('./authsome-helpers')
@@ -103,9 +103,13 @@ async function applyAuthenticatedUserPolicy(user, operation, object, context) {
               collection.fragments.includes(p.objectId),
           )
           const visibleStatus = get(statuses, `${status}.${role}.label`)
+          const parsedCollection = helpers.stripeCollectionByRole(
+            collection,
+            role,
+          )
 
           return {
-            ...collection,
+            ...parsedCollection,
             visibleStatus,
           }
         },
@@ -113,11 +117,7 @@ async function applyAuthenticatedUserPolicy(user, operation, object, context) {
     }
 
     if (get(object, 'type') === 'fragment') {
-      if (helpers.isOwner({ user, object })) {
-        return true
-      }
-
-      if (helpers.isInDraft(object)) {
+      if (helpers.isInDraft(object) && !helpers.isOwner({ user, object })) {
         return false
       }
 
@@ -133,17 +133,8 @@ async function applyAuthenticatedUserPolicy(user, operation, object, context) {
       if (!permission) return false
 
       return {
-        filter: fragment => {
-          // handle other roles
-          if (permission.role === 'reviewer') {
-            fragment.files = omit(fragment.files, ['coverLetter'])
-            fragment.authors = fragment.authors.map(a => omit(a, ['email']))
-            fragment.recommendations = fragment.recommendations
-              ? fragment.recommendations.filter(r => r.userId === user.id)
-              : []
-          }
-          return fragment
-        },
+        filter: fragment =>
+          helpers.stripeFragmentByRole(fragment, permission.role, user),
       }
     }
 
@@ -167,7 +158,7 @@ async function applyAuthenticatedUserPolicy(user, operation, object, context) {
   }
 
   if (operation === 'POST') {
-    // allow everytone to create manuscripts and versions
+    // allow everyone to create manuscripts and versions
     if (createPaths.includes(object.path)) {
       return true
     }
diff --git a/packages/xpub-faraday/config/test.js b/packages/xpub-faraday/config/test.js
new file mode 100644
index 000000000..9950c9b35
--- /dev/null
+++ b/packages/xpub-faraday/config/test.js
@@ -0,0 +1,3 @@
+const defaultConfig = require('xpub-faraday/config/default')
+
+module.exports = defaultConfig
diff --git a/packages/xpub-faraday/package.json b/packages/xpub-faraday/package.json
index 246048289..e4e829dea 100644
--- a/packages/xpub-faraday/package.json
+++ b/packages/xpub-faraday/package.json
@@ -63,6 +63,7 @@
     "file-loader": "^1.1.5",
     "html-webpack-plugin": "^2.24.0",
     "joi-browser": "^10.0.6",
+    "jest": "^22.1.1",
     "react-hot-loader": "^3.1.1",
     "string-replace-loader": "^1.3.0",
     "style-loader": "^0.19.0",
@@ -71,6 +72,10 @@
     "webpack-dev-middleware": "^1.12.0",
     "webpack-hot-middleware": "^2.20.0"
   },
+  "jest": {
+    "verbose": true,
+    "testRegex": "/tests/.*.test.js$"
+  },
   "scripts": {
     "setupdb": "pubsweet setupdb ./",
     "start": "pubsweet start",
@@ -79,6 +84,8 @@
     "start-now":
       "echo $secret > config/local-development.json && npm run server",
     "build": "NODE_ENV=production pubsweet build",
-    "clean": "rm -rf node_modules"
+    "clean": "rm -rf node_modules",
+    "debug": "pgrep -f startup/start.js | xargs kill -sigusr1",
+    "test": "jest"
   }
 }
diff --git a/packages/xpub-faraday/tests/authsome-helpers.test.js b/packages/xpub-faraday/tests/authsome-helpers.test.js
new file mode 100644
index 000000000..8999b892b
--- /dev/null
+++ b/packages/xpub-faraday/tests/authsome-helpers.test.js
@@ -0,0 +1,117 @@
+const { cloneDeep, get } = require('lodash')
+const fixturesService = require('pubsweet-component-fixture-service')
+const ah = require('../config/authsome-helpers')
+
+describe('Authsome Helpers', () => {
+  let testFixtures = {}
+  beforeEach(() => {
+    testFixtures = cloneDeep(fixturesService.fixtures)
+  })
+  it('stripeCollection - should return collection', () => {
+    const { collection } = testFixtures.collections
+    const result = ah.stripeCollectionByRole(collection)
+    expect(result).toBeTruthy()
+  })
+  it('stripeFragment - should return fragment', () => {
+    const { fragment } = testFixtures.fragments
+    const result = ah.stripeFragmentByRole(fragment)
+    expect(result).toBeTruthy()
+  })
+
+  it('stripeCollection - author should not see HE name before recommendation made', () => {
+    const { collection } = testFixtures.collections
+    collection.status = 'underReview'
+
+    const result = ah.stripeCollectionByRole(collection, 'author')
+    const { handlingEditor = {} } = result
+
+    expect(handlingEditor.email).toBeFalsy()
+    expect(handlingEditor.name).toEqual('Assigned')
+  })
+
+  it('stripeCollection - author should see HE name after recommendation made', () => {
+    const { collection } = testFixtures.collections
+    collection.status = 'revisionRequested'
+
+    const result = ah.stripeCollectionByRole(collection, 'author')
+    const { handlingEditor = {} } = result
+
+    expect(handlingEditor.name).not.toEqual('Assigned')
+  })
+
+  it('stripeCollection - other user than author should see HE name before recommendation made', () => {
+    const { collection } = testFixtures.collections
+    collection.status = 'underReview'
+
+    const result = ah.stripeCollectionByRole(collection, 'admin')
+    const { handlingEditor = {} } = result
+
+    expect(handlingEditor.name).not.toEqual('Assigned')
+  })
+
+  it('stripeCollection - other user than author should see HE name after recommendation made', () => {
+    const { collection } = testFixtures.collections
+    collection.status = 'revisionRequested'
+
+    const result = ah.stripeCollectionByRole(collection, 'admin')
+    const { handlingEditor = {} } = result
+
+    expect(handlingEditor.name).not.toEqual('Assigned')
+  })
+
+  it('stripeCollection - returns if collection does not have HE', () => {
+    const { collection } = testFixtures.collections
+    delete collection.handlingEditor
+
+    const result = ah.stripeCollectionByRole(collection, 'admin')
+    expect(result.handlingEditor).toBeFalsy()
+  })
+
+  it('stripeFragment - reviewer should not see authors email', () => {
+    const { fragment } = testFixtures.fragments
+    const result = ah.stripeFragmentByRole(fragment, 'reviewer')
+    const { authors = [] } = result
+    expect(authors[0].email).toBeFalsy()
+  })
+  it('stripeFragment - other roles than reviewer should see authors emails', () => {
+    const { fragment } = testFixtures.fragments
+    const result = ah.stripeFragmentByRole(fragment, 'author')
+    const { authors = [] } = result
+
+    expect(authors[0].email).toBeTruthy()
+  })
+
+  it('stripeFragment - reviewer should not see cover letter', () => {
+    const { fragment } = testFixtures.fragments
+    const result = ah.stripeFragmentByRole(fragment, 'reviewer')
+    const { files = {} } = result
+    expect(files.coverLetter).toBeFalsy()
+  })
+  it('stripeFragment - reviewer should not see others reviews', () => {
+    const { fragment } = testFixtures.fragments
+    const result = ah.stripeFragmentByRole(fragment, 'reviewer')
+    const { recommendations } = result
+    expect(recommendations).toEqual([])
+  })
+
+  it('stripeFragment - author should not see private recommendations comments', () => {
+    const { fragment } = testFixtures.fragments
+    fragment.recommendations = [
+      {
+        comments: [
+          {
+            content: 'private',
+            public: false,
+          },
+          {
+            content: 'public',
+            public: true,
+          },
+        ],
+      },
+    ]
+    const result = ah.stripeFragmentByRole(fragment, 'author')
+    const privateComments = get(result, 'recommendations[0].comments')
+    expect(privateComments).toHaveLength(1)
+  })
+})
-- 
GitLab