Skip to content
Snippets Groups Projects
Commit dd83efc3 authored by Sebastian Mihalache's avatar Sebastian Mihalache :hammer_pick:
Browse files

feat(reviewer-reminders): cancel reminders

parent c16165d7
No related branches found
No related tags found
3 merge requests!233S26 updates,!230S26 Updates,!214Hin 1170 automatic reminders
Showing
with 74 additions and 34 deletions
...@@ -6,6 +6,7 @@ const { ...@@ -6,6 +6,7 @@ const {
} = require('pubsweet-component-helper-service') } = require('pubsweet-component-helper-service')
const notifications = require('./emails/notifications') const notifications = require('./emails/notifications')
const { cancelReviewerJobs } = require('./jobs/cancelReviewerJobs')
module.exports = models => async (req, res) => { module.exports = models => async (req, res) => {
const { collectionId, invitationId, fragmentId } = req.params const { collectionId, invitationId, fragmentId } = req.params
...@@ -67,6 +68,8 @@ module.exports = models => async (req, res) => { ...@@ -67,6 +68,8 @@ module.exports = models => async (req, res) => {
error: 'Unauthorized.', error: 'Unauthorized.',
}) })
await cancelReviewerJobs(user.id)
invitation.respondedOn = Date.now() invitation.respondedOn = Date.now()
invitation.hasAnswer = true invitation.hasAnswer = true
invitation.isAccepted = false invitation.isAccepted = false
......
...@@ -6,6 +6,7 @@ const { ...@@ -6,6 +6,7 @@ const {
} = require('pubsweet-component-helper-service') } = require('pubsweet-component-helper-service')
const notifications = require('./emails/notifications') const notifications = require('./emails/notifications')
const { cancelReviewerJobs } = require('./jobs/cancelReviewerJobs')
module.exports = models => async (req, res) => { module.exports = models => async (req, res) => {
const { collectionId, invitationId, fragmentId } = req.params const { collectionId, invitationId, fragmentId } = req.params
...@@ -79,6 +80,8 @@ module.exports = models => async (req, res) => { ...@@ -79,6 +80,8 @@ module.exports = models => async (req, res) => {
UserModel: models.User, UserModel: models.User,
}) })
await cancelReviewerJobs(user.id)
return res.status(200).json({ fragment }) return res.status(200).json({ fragment })
} catch (e) { } catch (e) {
const notFoundError = await services.handleNotFoundError(e, 'collection') const notFoundError = await services.handleNotFoundError(e, 'collection')
......
...@@ -26,7 +26,6 @@ module.exports = { ...@@ -26,7 +26,6 @@ module.exports = {
baseUrl, baseUrl,
fragment, fragment,
UserModel, UserModel,
TeamModel,
timestamp, timestamp,
collection, collection,
invitation, invitation,
...@@ -124,6 +123,7 @@ module.exports = { ...@@ -124,6 +123,7 @@ module.exports = {
scheduleReminderJob({ scheduleReminderJob({
days, days,
email, email,
userId: invitedUser.id,
timeUnit, timeUnit,
subject: `${subjectBaseText} reminder`, subject: `${subjectBaseText} reminder`,
titleText: `the manuscript titled "${title}" by ${authorName}`, titleText: `the manuscript titled "${title}" by ${authorName}`,
...@@ -135,6 +135,7 @@ module.exports = { ...@@ -135,6 +135,7 @@ module.exports = {
timeUnit, timeUnit,
invitation, invitation,
days: removalDays, days: removalDays,
userId: invitedUser.id,
fragmentId: fragment.id, fragmentId: fragment.id,
collectionId: collection.id, collectionId: collection.id,
}) })
......
const moment = require('moment')
const logger = require('@pubsweet/logger')
const { Team, Collection } = require('pubsweet-component-helper-service')
const {
Team: TeamModel,
User: UserModel,
Fragment: FragmentModel,
Collection: CollectionModel,
} = require('pubsweet-server')
const { jobs: { connectToJobQueue } } = require('pubsweet-server/src')
const cancelJob = async ({ name }) => {
const queue = `reviewer-removal`
const jobQueue = await connectToJobQueue()
// Subscribe to the job queue with an async handler
await jobQueue.subscribe(queue, jobHandler)
await jobQueue.onComplete(queue, job => {
console.log(job.data.response.value)
logger.info(job.data.response.value)
})
}
const logger = require('@pubsweet/logger')
const { jobs: { connectToJobQueue } } = require('pubsweet-server/src')
const cancelReviewerJobs = async userId => {
const removalQueue = `reviewer-removal-${userId}`
const remindersQueue = `reviewer-reminders-${userId}`
const jobQueue = await connectToJobQueue()
await jobQueue.unsubscribe(remindersQueue)
await jobQueue.unsubscribe(removalQueue)
logger.info(`Canceled queue for reviewer ${userId}`)
}
module.exports = { cancelReviewerJobs }
...@@ -9,6 +9,7 @@ const Email = require('@pubsweet/component-email-templating') ...@@ -9,6 +9,7 @@ const Email = require('@pubsweet/component-email-templating')
const scheduleReminderJob = async ({ const scheduleReminderJob = async ({
days, days,
email, email,
userId,
subject, subject,
timeUnit, timeUnit,
titleText, titleText,
...@@ -18,7 +19,7 @@ const scheduleReminderJob = async ({ ...@@ -18,7 +19,7 @@ const scheduleReminderJob = async ({
.add(days, timeUnit) .add(days, timeUnit)
.toISOString() .toISOString()
const queue = `reviewer-reminders-${days}-${executionDate}` const queue = `reviewer-reminders-${userId}`
const jobQueue = await connectToJobQueue() const jobQueue = await connectToJobQueue()
...@@ -32,7 +33,7 @@ const scheduleReminderJob = async ({ ...@@ -32,7 +33,7 @@ const scheduleReminderJob = async ({
email.content.subject = subject email.content.subject = subject
// Add job to the queue // Add job to the queue
const jobId = await jobQueue.publishAfter( await jobQueue.publishAfter(
queue, queue,
{ {
days, days,
...@@ -43,13 +44,11 @@ const scheduleReminderJob = async ({ ...@@ -43,13 +44,11 @@ const scheduleReminderJob = async ({
{}, {},
executionDate, executionDate,
) )
console.log(`published job ${jobId} for the ${days} ${timeUnit} reminder`)
// Subscribe to the job queue with an async handler // Subscribe to the job queue with an async handler
await jobQueue.subscribe(queue, jobHandler) await jobQueue.subscribe(queue, jobHandler)
await jobQueue.onComplete(queue, job => { await jobQueue.onComplete(queue, job => {
console.log(job.data.response.value)
logger.info(job.data.response.value) logger.info(job.data.response.value)
}) })
} }
......
...@@ -12,6 +12,7 @@ const { jobs: { connectToJobQueue } } = require('pubsweet-server/src') ...@@ -12,6 +12,7 @@ const { jobs: { connectToJobQueue } } = require('pubsweet-server/src')
const scheduleRemovalJob = async ({ const scheduleRemovalJob = async ({
days, days,
userId,
timeUnit, timeUnit,
invitation, invitation,
fragmentId, fragmentId,
...@@ -21,7 +22,7 @@ const scheduleRemovalJob = async ({ ...@@ -21,7 +22,7 @@ const scheduleRemovalJob = async ({
.add(days, timeUnit) .add(days, timeUnit)
.toISOString() .toISOString()
const queue = `reviewer-removal` const queue = `reviewer-removal-${userId}`
const jobQueue = await connectToJobQueue() const jobQueue = await connectToJobQueue()
...@@ -44,7 +45,6 @@ const scheduleRemovalJob = async ({ ...@@ -44,7 +45,6 @@ const scheduleRemovalJob = async ({
await jobQueue.subscribe(queue, jobHandler) await jobQueue.subscribe(queue, jobHandler)
await jobQueue.onComplete(queue, job => { await jobQueue.onComplete(queue, job => {
console.log(job.data.response.value)
logger.info(job.data.response.value) logger.info(job.data.response.value)
}) })
} }
......
...@@ -6,6 +6,7 @@ const { ...@@ -6,6 +6,7 @@ const {
authsome: authsomeHelper, authsome: authsomeHelper,
} = require('pubsweet-component-helper-service') } = require('pubsweet-component-helper-service')
const { cancelReviewerJobs } = require('./jobs/cancelReviewerJobs')
const notifications = require('./emails/notifications') const notifications = require('./emails/notifications')
module.exports = models => async (req, res) => { module.exports = models => async (req, res) => {
...@@ -48,6 +49,8 @@ module.exports = models => async (req, res) => { ...@@ -48,6 +49,8 @@ module.exports = models => async (req, res) => {
error: 'Unauthorized.', error: 'Unauthorized.',
}) })
await cancelReviewerJobs(user.id)
const collectionHelper = new Collection({ collection }) const collectionHelper = new Collection({ collection })
const baseUrl = services.getBaseUrl(req) const baseUrl = services.getBaseUrl(req)
......
...@@ -123,7 +123,6 @@ module.exports = models => async (req, res) => { ...@@ -123,7 +123,6 @@ module.exports = models => async (req, res) => {
invitation, invitation,
invitedUser: user, invitedUser: user,
UserModel: models.User, UserModel: models.User,
TeamModel: models.Team,
timestamp: invitation.invitedOn, timestamp: invitation.invitedOn,
}) })
} }
...@@ -187,7 +186,6 @@ module.exports = models => async (req, res) => { ...@@ -187,7 +186,6 @@ module.exports = models => async (req, res) => {
invitation, invitation,
invitedUser: newUser, invitedUser: newUser,
UserModel: models.User, UserModel: models.User,
TeamModel: models.Team,
timestamp: invitation.invitedOn, timestamp: invitation.invitedOn,
}) })
......
...@@ -10,6 +10,16 @@ const cloneDeep = require('lodash/cloneDeep') ...@@ -10,6 +10,16 @@ const cloneDeep = require('lodash/cloneDeep')
jest.mock('@pubsweet/component-send-email', () => ({ jest.mock('@pubsweet/component-send-email', () => ({
send: jest.fn(), send: jest.fn(),
})) }))
jest.mock('pubsweet-server/src', () => ({
jobs: {
connectToJobQueue: () => ({
unsubscribe: jest.fn(),
publishAfter: jest.fn(),
subscribe: jest.fn(),
onComplete: jest.fn(),
}),
},
}))
const reqBody = { const reqBody = {
invitationToken: fixtures.users.reviewer.accessTokens.invitation, invitationToken: fixtures.users.reviewer.accessTokens.invitation,
......
...@@ -9,6 +9,16 @@ const { Model, fixtures } = fixturesService ...@@ -9,6 +9,16 @@ const { Model, fixtures } = fixturesService
jest.mock('@pubsweet/component-send-email', () => ({ jest.mock('@pubsweet/component-send-email', () => ({
send: jest.fn(), send: jest.fn(),
})) }))
jest.mock('pubsweet-server/src', () => ({
jobs: {
connectToJobQueue: () => ({
unsubscribe: jest.fn(),
publishAfter: jest.fn(),
subscribe: jest.fn(),
onComplete: jest.fn(),
}),
},
}))
const path = '../routes/fragmentsInvitations/delete' const path = '../routes/fragmentsInvitations/delete'
const route = { const route = {
......
...@@ -10,6 +10,17 @@ jest.mock('@pubsweet/component-send-email', () => ({ ...@@ -10,6 +10,17 @@ jest.mock('@pubsweet/component-send-email', () => ({
send: jest.fn(), send: jest.fn(),
})) }))
jest.mock('pubsweet-server/src', () => ({
jobs: {
connectToJobQueue: () => ({
unsubscribe: jest.fn(),
publishAfter: jest.fn(),
subscribe: jest.fn(),
onComplete: jest.fn(),
}),
},
}))
const reqBody = { const reqBody = {
isAccepted: true, isAccepted: true,
} }
......
...@@ -11,6 +11,16 @@ const { Model, fixtures } = fixturesService ...@@ -11,6 +11,16 @@ const { Model, fixtures } = fixturesService
jest.mock('@pubsweet/component-send-email', () => ({ jest.mock('@pubsweet/component-send-email', () => ({
send: jest.fn(), send: jest.fn(),
})) }))
jest.mock('pubsweet-server/src', () => ({
jobs: {
connectToJobQueue: () => ({
unsubscribe: jest.fn(),
publishAfter: jest.fn(),
subscribe: jest.fn(),
onComplete: jest.fn(),
}),
},
}))
const chance = new Chance() const chance = new Chance()
const reqBody = { const reqBody = {
......
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