diff --git a/packages/component-fixture-manager/src/fixtures/fragments.js b/packages/component-fixture-manager/src/fixtures/fragments.js index 9fca41e0ffba404be7fd612dd6feb483e6a23763..a9717e4cde3a81240bcdf334ca4cccc09e76c52e 100644 --- a/packages/component-fixture-manager/src/fixtures/fragments.js +++ b/packages/component-fixture-manager/src/fixtures/fragments.js @@ -413,14 +413,13 @@ const fragments = { isCorresponding: false, }, ], - owners: [user.id], - type: 'fragment', }, }, } fragments.noInvitesFragment = { ...fragments.fragment1, + recommendations: [], invites: [], id: chance.guid(), } diff --git a/packages/component-fixture-manager/src/fixtures/teamIDs.js b/packages/component-fixture-manager/src/fixtures/teamIDs.js index ab1eae10948701757d3d0e745a307204a14b7f4e..506ba0160c31924e674b48ece9fd5a4be53ffa2f 100644 --- a/packages/component-fixture-manager/src/fixtures/teamIDs.js +++ b/packages/component-fixture-manager/src/fixtures/teamIDs.js @@ -8,4 +8,5 @@ module.exports = { authorTeamID: chance.guid(), revRecommendationTeamID: chance.guid(), rev1TeamID: chance.guid(), + heTeamMinorRevisionCollectionTeamID: chance.guid(), } diff --git a/packages/component-fixture-manager/src/fixtures/teams.js b/packages/component-fixture-manager/src/fixtures/teams.js index 370a9c0e988c6c886454314b76173613d898bf25..8cdf3c1d8bccb0b112e31c105e11bf040e592630 100644 --- a/packages/component-fixture-manager/src/fixtures/teams.js +++ b/packages/component-fixture-manager/src/fixtures/teams.js @@ -8,10 +8,11 @@ const { authorTeamID, revRecommendationTeamID, rev1TeamID, + heTeamMinorRevisionCollectionTeamID, } = require('./teamIDs') const { submittingAuthor } = require('./userData') -const { collection } = collections +const { collection, collection2 } = collections const { fragment, reviewCompletedFragment, fragment1 } = fragments const { handlingEditor, @@ -39,6 +40,23 @@ const teams = { updateProperties: jest.fn(() => teams.heTeam), id: heTeamID, }, + heTeamMinorRevisionCollection: { + teamType: { + name: 'handlingEditor', + permissions: 'handlingEditor', + }, + group: 'handlingEditor', + name: 'HandlingEditor', + object: { + type: 'collection', + id: collection2.id, + }, + members: [handlingEditor.id], + save: jest.fn(() => teams.heTeam), + delete: jest.fn(), + updateProperties: jest.fn(() => teams.heTeam), + id: heTeamMinorRevisionCollectionTeamID, + }, revTeam: { teamType: { name: 'reviewer', diff --git a/packages/component-fixture-manager/src/fixtures/users.js b/packages/component-fixture-manager/src/fixtures/users.js index f0a6737c38eb46d4990c4131828b75e7af74ee4b..11dfb44381d2f8e89baba9f38faaeeb1562a6bae 100644 --- a/packages/component-fixture-manager/src/fixtures/users.js +++ b/packages/component-fixture-manager/src/fixtures/users.js @@ -8,6 +8,7 @@ const { authorTeamID, revRecommendationTeamID, rev1TeamID, + heTeamMinorRevisionCollectionTeamID, } = require('./teamIDs') const keys = Object.keys(usersData) @@ -18,7 +19,7 @@ users = keys.reduce((obj, item) => { let teams = [] if (isHE) { - teams = [heTeamID] + teams = [heTeamID, heTeamMinorRevisionCollectionTeamID] } if (item === 'author') { teams = [authorTeamID] diff --git a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js index c2a2d99bdd590cafe9895440156803dcec6f3fb8..0da41adaa75e0e17174f1a277d71f482af29c2f4 100644 --- a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js +++ b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js @@ -1,6 +1,6 @@ /* eslint-disable no-return-await */ const uuid = require('uuid') -const { pick, get, set, has, isEmpty, last } = require('lodash') +const { pick, get, set, has, isEmpty, last, findLast } = require('lodash') const config = require('config') const { v4 } = require('uuid') @@ -100,14 +100,6 @@ module.exports = models => async (req, res) => { .status(400) .json({ error: 'Cannot write a review on an older version.' }) } - - const lastRecommendationByHE = last( - get(fragments[fragments.length - 2], 'recommendations', []) || - [].find( - recommendation => - recommendation.recommendationType === 'editorRecommendation', - ), - ) if ( recommendation === recommendations.publish && recommendationType === recommendations.type.editor && @@ -115,24 +107,38 @@ module.exports = models => async (req, res) => { collection.handlingEditor.id === req.user ) { const fragmentHelper = new Fragment({ fragment }) - const canHeMakeRecommendationAfterMajor = - fragmentHelper.hasReviewReport() && - lastRecommendationByHE.recommendation === 'major' - - const collectionHasReview = fragments.find(fragment => - new Fragment({ fragment }).hasReviewReport(), - ) - const canHeMakeRecommendationAfterMinor = - collectionHasReview && lastRecommendationByHE.recommendation !== 'major' - if ( - !(canHeMakeRecommendationAfterMajor || canHeMakeRecommendationAfterMinor) - ) { + if (!canHEMakeRecommendation(fragmentHelper)) { return res.status(400).json({ error: 'Cannot publish without at least one reviewer report.', }) } } + function canHEMakeRecommendation(fragmentHelper) { + if (collection.fragments.length === 1) { + return fragmentHelper.hasReviewReport() + } + const previousVersionRecommendations = get( + fragments[fragments.length - 2], + 'recommendations', + [], + ) + + const lastRecommendationByHE = findLast( + previousVersionRecommendations, + recommendation => + recommendation.userId === collection.handlingEditor.id && + recommendation.recommendationType === 'editorRecommendation', + ) + if (lastRecommendationByHE.recommendation === 'minor') { + return fragments.find(fragment => + new Fragment({ fragment }).hasReviewReport(), + ) + } else if (lastRecommendationByHE.recommendation === 'major') { + return fragmentHelper.hasReviewReport() + } + } + 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 05ae4193c249185b9c160ed1a1c74cbba2fbbf72..71d3e562a0dfc097f24630c8e90fa9c5d2e48327 100644 --- a/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/post.test.js +++ b/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/post.test.js @@ -28,7 +28,7 @@ const reqBody = { ], }, ], - recommendationType: 'review', + recommendationType: 'editorRecommendation', } const path = '../routes/fragmentsRecommendations/post' @@ -80,7 +80,7 @@ describe('Post fragments recommendations route handler', () => { const data = JSON.parse(res._getData()) expect(data.userId).toEqual(reviewer.id) }) - it('should return success when creating a recommendation as a HE', async () => { + it('should return success when creating a recommendation as a HE when there is a single version with at least one review.', async () => { const { handlingEditor } = testFixtures.users const { collection } = testFixtures.collections const { fragment } = testFixtures.fragments @@ -101,6 +101,55 @@ describe('Post fragments recommendations route handler', () => { const data = JSON.parse(res._getData()) expect(data.userId).toEqual(handlingEditor.id) }) + + it('should return an error when creating a recommendation with publish as a HE when there is a single version and there are no reviews.', async () => { + const { handlingEditor } = testFixtures.users + const { collection } = testFixtures.collections + const { fragment } = testFixtures.fragments + + 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.', + ) + }) + + it('should return success when creating a recommendation as a HE after minor revision and we have at least one review on collection.', async () => { + const { handlingEditor } = testFixtures.users + const { collection2 } = testFixtures.collections + const { noInvitesFragment } = testFixtures.fragments + + const res = await requests.sendRequest({ + body, + userId: handlingEditor.id, + models, + route, + path, + params: { + collectionId: collection2.id, + fragmentId: noInvitesFragment.id, + }, + }) + + expect(res.statusCode).toBe(200) + const data = JSON.parse(res._getData()) + expect(data.userId).toEqual(handlingEditor.id) + }) + it('should return an error when the fragmentId does not match the collectionId', async () => { const { reviewer } = testFixtures.users const { collection } = testFixtures.collections