Skip to content
Snippets Groups Projects
Commit 8ca32a11 authored by Andrei Cioromila's avatar Andrei Cioromila
Browse files

bug(HIN-1022): display manuscript status based on invitation status for reviewer

parent f98b731a
No related branches found
No related tags found
2 merge requests!110Sprint 21 Features,!72bug(HIN-1022): display manuscript status based on invitation status for reviewer
const Chance = require('chance') const Chance = require('chance')
const { user, handlingEditor, answerHE } = require('./userData') const {
const { fragment } = require('./fragments') user,
handlingEditor,
answerHE,
reviewer,
answerReviewer,
recReviewer,
} = require('./userData')
const { fragment, reviewCompletedFragment } = require('./fragments')
const { standardCollID } = require('./collectionIDs') const { standardCollID } = require('./collectionIDs')
const chance = new Chance() const chance = new Chance()
...@@ -89,6 +96,36 @@ const collections = { ...@@ -89,6 +96,36 @@ const collections = {
}, },
status: 'pendingApproval', status: 'pendingApproval',
}, },
collectionReviewCompleted: {
type: 'collection',
owners: [user.id],
status: 'reviewCompleted',
created: chance.timestamp(),
customId: '0000001',
fragments: [reviewCompletedFragment.id],
invitations: [
{
id: chance.guid(),
role: 'handlingEditor',
type: 'invitation',
userId: handlingEditor.id,
hasAnswer: true,
invitedOn: chance.timestamp(),
isAccepted: true,
respondedOn: chance.timestamp(),
},
],
handlingEditor: {
id: handlingEditor.id,
name: handlingEditor.name,
email: handlingEditor.email,
hasAnswer: true,
invitedOn: chance.timestamp(),
isAccepted: true,
respondedOn: chance.timestamp(),
},
technicalChecks: {},
},
} }
module.exports = collections module.exports = collections
...@@ -171,6 +171,112 @@ const fragments = { ...@@ -171,6 +171,112 @@ const fragments = {
owners: [user.id], owners: [user.id],
type: 'fragment', type: 'fragment',
}, },
reviewCompletedFragment: {
id: chance.guid(),
type: 'fragment',
files: {
coverLetter: [],
manuscripts: [
{
id:
'28ca8f73-2dcb-4a93-97c9-24d474d54691/a1107517-1d19-445d-90ee-315a026469c4',
name: 'LinkedInProfileDemystified.pdf',
size: 804871,
originalName: 'LinkedInProfileDemystified.pdf',
},
],
supplementary: [],
},
owners: [user.id],
authors: [
{
id: user.id,
email: user.email,
title: user.title,
lastName: user.lastName,
firstName: user.firstName,
affiliation: user.affiliation,
isSubmitting: true,
isCorresponding: true,
},
],
created: '2018-10-08T12:01:46.384Z',
version: 1,
metadata: {
type: 'research',
title: chance.sentence(),
journal: 'Bioinorganic Chemistry and Applications',
abstract: chance.paragraph(),
},
conflicts: {
hasFunding: 'yes',
hasConflicts: 'no',
hasDataAvailability: 'yes',
},
submitted: 1539000486993,
invitations: [
{
id: chance.guid(),
role: 'reviewer',
type: 'invitation',
userId: answerReviewer.id,
hasAnswer: true,
invitedOn: chance.timestamp(),
isAccepted: true,
respondedOn: chance.timestamp(),
},
{
id: chance.guid(),
role: 'reviewer',
type: 'invitation',
userId: recReviewer.id,
hasAnswer: false,
invitedOn: chance.timestamp(),
isAccepted: false,
respondedOn: null,
},
{
id: chance.guid(),
role: 'reviewer',
type: 'invitation',
userId: reviewer.id,
hasAnswer: true,
invitedOn: chance.timestamp(),
isAccepted: true,
respondedOn: chance.timestamp(),
},
],
collectionId: standardCollID,
declarations: {
agree: true,
},
fragmentType: 'version',
recommendations: [
{
id: chance.guid(),
userId: answerReviewer.id,
comments: [
{
files: [
{
id: chance.guid(),
name: 'file.pdf',
size: chance.natural(),
},
],
public: true,
content: 'A not so nice manuscript',
},
],
createdOn: chance.timestamp(),
updatedOn: chance.timestamp(),
submittedOn: chance.timestamp(),
recommendation: 'publish',
recommendationType: 'review',
},
],
save: jest.fn(() => fragments.fragment),
},
} }
module.exports = fragments module.exports = fragments
...@@ -237,6 +237,30 @@ const getCollections = async ({ user, models }) => { ...@@ -237,6 +237,30 @@ const getCollections = async ({ user, models }) => {
) )
} }
async function updateReviewerVisibleStatusByInvitation({
collection,
FragmentModel,
user,
}) {
const fragmentId = last(collection.fragments)
const fragment = await FragmentModel.find(fragmentId)
const invitation = fragment.invitations.find(inv => inv.userId === user.id)
const recommendationDone = fragment.recommendations.some(
rec =>
rec.recommendationType === 'review' &&
rec.userId === user.id &&
rec.submittedOn,
)
if (recommendationDone) {
return get(statuses, `${collection.status}.reviewer.label`)
}
return invitation.hasAnswer && invitation.isAccepted
? get(statuses, `underReview.reviewer.label`)
: get(statuses, `reviewersInvited.reviewer.label`)
}
module.exports = { module.exports = {
filterObjectData, filterObjectData,
parseAuthorsData, parseAuthorsData,
...@@ -255,4 +279,5 @@ module.exports = { ...@@ -255,4 +279,5 @@ module.exports = {
getUsersList, getUsersList,
parseUser, parseUser,
getCollections, getCollections,
updateReviewerVisibleStatusByInvitation,
} }
...@@ -78,13 +78,9 @@ async function applyAuthenticatedUserPolicy(user, operation, object, context) { ...@@ -78,13 +78,9 @@ async function applyAuthenticatedUserPolicy(user, operation, object, context) {
return true return true
} }
const fragmentPermission = userPermissions.find(p => return userPermissions.find(p =>
collection.fragments.includes(p.objectId), collection.fragments.includes(p.objectId),
) )
if (fragmentPermission) {
return true
}
return false
}) })
}, },
} }
...@@ -113,7 +109,19 @@ async function applyAuthenticatedUserPolicy(user, operation, object, context) { ...@@ -113,7 +109,19 @@ async function applyAuthenticatedUserPolicy(user, operation, object, context) {
collection.fragments.includes(p.objectId), collection.fragments.includes(p.objectId),
) )
const role = get(collPermission, 'role', 'author') const role = get(collPermission, 'role', 'author')
const visibleStatus = get(statuses, `${status}.${role}.label`)
let visibleStatus = get(statuses, `${status}.${role}.label`)
if (role === 'reviewer' && status !== 'reviewersInvited') {
visibleStatus = await helpers.updateReviewerVisibleStatusByInvitation(
{
collection,
FragmentModel: context.models.Fragment,
user,
},
)
}
const parsedCollection = helpers.stripeCollectionByRole( const parsedCollection = helpers.stripeCollectionByRole(
collection, collection,
role, role,
......
...@@ -208,4 +208,42 @@ describe('Authsome Helpers', () => { ...@@ -208,4 +208,42 @@ describe('Authsome Helpers', () => {
expect(parsedUser).toHaveProperty('email') expect(parsedUser).toHaveProperty('email')
expect(parsedUser).toHaveProperty('username') expect(parsedUser).toHaveProperty('username')
}) })
describe('updateReviewerVisibleStatusByInvitation', () => {
it('should return the fragment status for reviewer when they have done the review', async () => {
const { answerReviewer } = testFixtures.users
const { collectionReviewCompleted } = testFixtures.collections
const visibleStatus = await ah.updateReviewerVisibleStatusByInvitation({
collection: collectionReviewCompleted,
FragmentModel: models.Fragment,
user: answerReviewer,
})
expect(visibleStatus).toEqual('Review Completed')
})
it('should return the underReview status for reviewer when they have accepted the review', async () => {
const { reviewer } = testFixtures.users
const { collectionReviewCompleted } = testFixtures.collections
const visibleStatus = await ah.updateReviewerVisibleStatusByInvitation({
collection: collectionReviewCompleted,
FragmentModel: models.Fragment,
user: reviewer,
})
expect(visibleStatus).toEqual('Complete Review')
})
it('should return the reviewersInvited status for reviewer when they have to accept the review', async () => {
const { recReviewer } = testFixtures.users
const { collectionReviewCompleted } = testFixtures.collections
const visibleStatus = await ah.updateReviewerVisibleStatusByInvitation({
collection: collectionReviewCompleted,
FragmentModel: models.Fragment,
user: recReviewer,
})
expect(visibleStatus).toEqual('Respond to Invite')
})
})
}) })
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment