-
Tania Fecheta authored
test(fragmentRecommendation/post): add test for case HE makes another recommendation after eic decid
08883898
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
process.env.SUPPRESS_NO_CONFIG_WARNING = true
const Chance = require('chance')
const cloneDeep = require('lodash/cloneDeep')
const fixturesService = require('pubsweet-component-fixture-service')
const requests = require('../requests')
const { Model, fixtures } = fixturesService
const chance = new Chance()
jest.mock('@pubsweet/component-send-email', () => ({
send: jest.fn(),
}))
jest.mock('pubsweet-component-mts-package')
const reqBody = {
recommendation: 'publish',
comments: [
{
content: chance.paragraph(),
public: chance.bool(),
files: [
{
id: chance.guid(),
name: 'file.pdf',
size: chance.natural(),
},
],
},
],
recommendationType: 'editorRecommendation',
}
const path = '../routes/fragmentsRecommendations/post'
const route = {
path: '/api/collections/:collectionId/fragments/:fragmentId/recommendations',
}
describe('Post fragments recommendations route handler', () => {
let testFixtures = {}
let body = {}
let models
beforeEach(() => {
testFixtures = cloneDeep(fixtures)
body = cloneDeep(reqBody)
models = Model.build(testFixtures)
})
it('should return an error when params are missing', async () => {
const { reviewer } = testFixtures.users
delete body.recommendationType
const res = await requests.sendRequest({
body,
userId: reviewer.id,
route,
models,
path,
})
expect(res.statusCode).toBe(400)
const data = JSON.parse(res._getData())
expect(data.error).toEqual('Recommendation type is required.')
})
it('should return success when creating a recommendation as a reviewer', async () => {
const { reviewer } = testFixtures.users
const { collection } = testFixtures.collections
const { fragment } = testFixtures.fragments
const res = await requests.sendRequest({
body,
userId: reviewer.id,
models,
route,
path,
params: {
collectionId: collection.id,
fragmentId: fragment.id,
},
})
expect(res.statusCode).toBe(200)
const data = JSON.parse(res._getData())
expect(data.userId).toEqual(reviewer.id)
})
it('should return success when creating a recommendation as a HE when there is a single version with at least one review.', async () => {
const { noRecommendationHE } = testFixtures.users
const { noEditorRecomedationCollection } = testFixtures.collections
const { noEditorRecomedationFragment } = testFixtures.fragments
const res = await requests.sendRequest({
body,
userId: noRecommendationHE.id,
models,
route,
path,
params: {
collectionId: noEditorRecomedationCollection.id,
fragmentId: noEditorRecomedationFragment.id,
},
})
expect(res.statusCode).toBe(200)
const data = JSON.parse(res._getData())
expect(data.userId).toEqual(noRecommendationHE.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 { collection } = testFixtures.collections
const {
minorRevisionWithReview,
noInvitesFragment1,
} = testFixtures.fragments
collection.fragments = [minorRevisionWithReview.id, noInvitesFragment1.id]
const res = await requests.sendRequest({
body,
userId: handlingEditor.id,
models,
route,
path,
params: {
collectionId: collection.id,
fragmentId: noInvitesFragment1.id,
},
})
expect(res.statusCode).toBe(200)
const data = JSON.parse(res._getData())
expect(data.userId).toEqual(handlingEditor.id)
})
it('should return error when creating a recommendation as a HE after minor revision and there are no reviews.', async () => {
const { handlingEditor } = testFixtures.users
const { collection } = testFixtures.collections
const {
minorRevisionWithoutReview,
noInvitesFragment1,
} = testFixtures.fragments
collection.fragments = [
minorRevisionWithoutReview.id,
noInvitesFragment1.id,
]
const res = await requests.sendRequest({
body,
userId: handlingEditor.id,
models,
route,
path,
params: {
collectionId: collection.id,
fragmentId: noInvitesFragment1.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 major revision and there are least one review on fragment.', async () => {
const { handlingEditor } = testFixtures.users
const { collection } = testFixtures.collections
const {
majorRevisionWithReview,
reviewCompletedFragment,
} = testFixtures.fragments
reviewCompletedFragment.collectionId = collection.id
collection.fragments = [
majorRevisionWithReview.id,
reviewCompletedFragment.id,
]
const res = await requests.sendRequest({
body,
userId: handlingEditor.id,
models,
route,
path,
params: {
collectionId: collection.id,
fragmentId: reviewCompletedFragment.id,
},
})
expect(res.statusCode).toBe(200)
const data = JSON.parse(res._getData())
expect(data.userId).toEqual(handlingEditor.id)
})
it('should return error when creating a recommendation as a HE after major revision there are no reviews on fragment.', async () => {
const { handlingEditor } = testFixtures.users
const { collection } = testFixtures.collections
const {
majorRevisionWithReview,
noInvitesFragment1,
} = testFixtures.fragments
collection.fragments = [majorRevisionWithReview.id, noInvitesFragment1.id]
const res = await requests.sendRequest({
body,
userId: handlingEditor.id,
models,
route,
path,
params: {
collectionId: collection.id,
fragmentId: noInvitesFragment1.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 an error when the fragmentId does not match the collectionId', async () => {
const { reviewer } = testFixtures.users
const { collection } = testFixtures.collections
const { fragment } = testFixtures.fragments
collection.fragments.length = 0
const res = await requests.sendRequest({
body,
userId: reviewer.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('Collection and fragment do not match.')
})
it('should return an error when the collection does not exist', async () => {
const { reviewer } = testFixtures.users
const { fragment } = testFixtures.fragments
const res = await requests.sendRequest({
body,
userId: reviewer.id,
models,
route,
path,
params: {
collectionId: 'invalid-id',
fragmentId: fragment.id,
},
})
expect(res.statusCode).toBe(404)
const data = JSON.parse(res._getData())
expect(data.error).toEqual('Item not found')
})
it('should return an error when the request user is not a reviewer', async () => {
const { author } = testFixtures.users
const { collection } = testFixtures.collections
const { fragment } = testFixtures.fragments
const res = await requests.sendRequest({
body,
userId: author.id,
models,
route,
path,
params: {
collectionId: collection.id,
fragmentId: fragment.id,
},
})
expect(res.statusCode).toBe(403)
const data = JSON.parse(res._getData())
expect(data.error).toEqual('Unauthorized.')
})
it('should return success when a HE recommends to reject', async () => {
const { noRecommendationHE } = testFixtures.users
const { noEditorRecomedationCollection } = testFixtures.collections
const { noEditorRecomedationFragment } = testFixtures.fragments
body.recommendation = 'reject'
body.recommendationType = 'editorRecommendation'
const res = await requests.sendRequest({
body,
userId: noRecommendationHE.id,
models,
route,
path,
params: {
collectionId: noEditorRecomedationCollection.id,
fragmentId: noEditorRecomedationFragment.id,
},
})
expect(res.statusCode).toBe(200)
const data = JSON.parse(res._getData())
expect(data.userId).toEqual(noRecommendationHE.id)
expect(data.recommendation).toBe('reject')
})
it('should return an error when the user is inactive', async () => {
const { inactiveUser } = testFixtures.users
const { collection } = testFixtures.collections
const { fragment } = testFixtures.fragments
const res = await requests.sendRequest({
body,
userId: inactiveUser.id,
models,
route,
path,
params: {
collectionId: collection.id,
fragmentId: fragment.id,
},
})
expect(res.statusCode).toBe(403)
const data = JSON.parse(res._getData())
expect(data.error).toEqual('Unauthorized.')
})
it('should return success when the EiC recommends to reject without peer review', async () => {
const { editorInChief } = testFixtures.users
const { collection } = testFixtures.collections
const { fragment } = testFixtures.fragments
body.recommendation = 'reject'
body.recommendationType = 'editorRecommendation'
delete fragment.recommendations
delete fragment.revision
delete fragment.invitations
delete collection.invitations
delete collection.handlingEditor
const res = await requests.sendRequest({
body,
userId: editorInChief.id,
models,
route,
path,
params: {
collectionId: collection.id,
fragmentId: fragment.id,
},
})
expect(res.statusCode).toBe(200)
const data = JSON.parse(res._getData())
expect(data.userId).toEqual(editorInChief.id)
expect(data.recommendation).toBe('reject')
})
it('should return success when the EiC recommends to publish without EQA', async () => {
const { editorInChief } = testFixtures.users
const { collection } = testFixtures.collections
const { fragment } = testFixtures.fragments
body.recommendation = 'publish'
body.recommendationType = 'editorRecommendation'
delete collection.technicalChecks
const res = await requests.sendRequest({
body,
userId: editorInChief.id,
models,
route,
path,
params: {
collectionId: collection.id,
fragmentId: fragment.id,
},
})
expect(res.statusCode).toBe(200)
const data = JSON.parse(res._getData())
expect(collection.status).toBe('inQA')
expect(collection.technicalChecks).toHaveProperty('eqa')
expect(collection.technicalChecks.eqa).toBeFalsy()
expect(data.userId).toEqual(editorInChief.id)
expect(data.recommendation).toBe('publish')
})
it('should return success when the EiC recommends to publish with EQA accepted', async () => {
const { editorInChief } = testFixtures.users
const { collection } = testFixtures.collections
const { fragment } = testFixtures.fragments
body.recommendation = 'publish'
body.recommendationType = 'editorRecommendation'
collection.technicalChecks.eqa = true
const res = await requests.sendRequest({
body,
userId: editorInChief.id,
models,
route,
path,
params: {
collectionId: collection.id,
fragmentId: fragment.id,
},
})
expect(res.statusCode).toBe(200)
const data = JSON.parse(res._getData())
expect(collection.status).toBe('accepted')
expect(data.userId).toEqual(editorInChief.id)
expect(data.recommendation).toBe('publish')
})
it('should return success when the EiC returns the manuscript to HE with comments after EQA returned to EiC', async () => {
const { editorInChief } = testFixtures.users
const { collection } = testFixtures.collections
const { fragment } = testFixtures.fragments
body.recommendation = 'return-to-handling-editor'
body.recommendationType = 'editorRecommendation'
body.comments = 'This needs more work'
delete fragment.recommendations
delete fragment.revision
delete fragment.invitations
collection.technicalChecks.eqa = false
const res = await requests.sendRequest({
body,
userId: editorInChief.id,
models,
route,
path,
params: {
collectionId: collection.id,
fragmentId: fragment.id,
},
})
expect(res.statusCode).toBe(200)
const data = JSON.parse(res._getData())
expect(collection.status).toBe('reviewCompleted')
expect(collection.technicalChecks).not.toHaveProperty('token')
expect(collection.technicalChecks).not.toHaveProperty('eqa')
expect(data.userId).toEqual(editorInChief.id)
expect(data.recommendation).toBe('return-to-handling-editor')
})
it('should return an error when a HE recommends to publish without a reviewer report', async () => {
const { handlingEditor } = testFixtures.users
const { collection } = testFixtures.collections
const { fragment } = testFixtures.fragments
body.recommendation = 'publish'
body.recommendationType = 'editorRecommendation'
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 an error when a HE makes a recommendation on an older version of a manuscript', async () => {
const { handlingEditor } = testFixtures.users
const { twoVersionsCollection } = testFixtures.collections
const { fragment } = testFixtures.fragments
body.recommendation = 'publish'
body.recommendationType = 'editorRecommendation'
const res = await requests.sendRequest({
body,
userId: handlingEditor.id,
models,
route,
path,
params: {
collectionId: twoVersionsCollection.id,
fragmentId: fragment.id,
},
})
expect(res.statusCode).toBe(400)
const data = JSON.parse(res._getData())
expect(data.error).toEqual(
'Cannot make a recommendation on an older version.',
)
})
it('should return an error when a reviewer writes a review on an older version of a manuscript', async () => {
const { reviewer } = testFixtures.users
const { twoVersionsCollection } = testFixtures.collections
const { fragment } = testFixtures.fragments
body.recommendationType = 'review'
const res = await requests.sendRequest({
body,
userId: reviewer.id,
models,
route,
path,
params: {
collectionId: twoVersionsCollection.id,
fragmentId: fragment.id,
},
})
expect(res.statusCode).toBe(400)
const data = JSON.parse(res._getData())
expect(data.error).toEqual('Cannot write a review on an older version.')
})
it('should return an error when a reviewer writes another review on the current version of a manuscript', async () => {
const { newReviewer } = testFixtures.users
const { noEditorRecomedationCollection } = testFixtures.collections
const { noEditorRecomedationFragment } = testFixtures.fragments
body.recommendationType = 'review'
const res = await requests.sendRequest({
body,
userId: newReviewer.id,
models,
route,
path,
params: {
collectionId: noEditorRecomedationCollection.id,
fragmentId: noEditorRecomedationFragment.id,
},
})
expect(res.statusCode).toBe(400)
const data = JSON.parse(res._getData())
expect(data.error).toEqual('Cannot write another review on this version.')
})
it('should return success when creating another recommendation as a HE on the same version when EiC returned manuscript to He ', async () => {
const { noRecommendationHE } = testFixtures.users
const { noEditorRecomedationCollection } = testFixtures.collections
const { noEditorRecomedationFragment } = testFixtures.fragments
const res = await requests.sendRequest({
body,
userId: noRecommendationHE.id,
models,
route,
path,
params: {
collectionId: noEditorRecomedationCollection.id,
fragmentId: noEditorRecomedationFragment.id,
},
})
expect(res.statusCode).toBe(200)
const data = JSON.parse(res._getData())
expect(data.userId).toEqual(noRecommendationHE.id)
})
it('should return an error when creating another recommendation as a HE on the same version after EiC made decision to publish', async () => {
const { handlingEditor } = testFixtures.users
const { collection } = testFixtures.collections
const { fragment } = testFixtures.fragments
body.recommendation = 'publish'
body.recommendationType = 'editorRecommendation'
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 make another recommendation on this version.',
)
})
it('should return an error when an EiC makes a decision on an older version of a manuscript', async () => {
const { editorInChief } = testFixtures.users
const { twoVersionsCollection } = testFixtures.collections
const { fragment } = testFixtures.fragments
body.recommendation = 'publish'
body.recommendationType = 'editorRecommendation'
const res = await requests.sendRequest({
body,
userId: editorInChief.id,
models,
route,
path,
params: {
collectionId: twoVersionsCollection.id,
fragmentId: fragment.id,
},
})
expect(res.statusCode).toBe(400)
const data = JSON.parse(res._getData())
expect(data.error).toEqual(
'Cannot make a recommendation on an older version.',
)
})
})