Saturday, 16 November 2019

How would you refactor this service layer method into smaller testable chunks?

exports.sendFeedbackServiceProviderMethod = function(req, res, next) { var articleId = req.body.articleId var commentId = req.body.commentId var action = req.body.action var meta = req.body.meta var Target var targetId if (articleId) { Target = Article targetId = articleId } else if (commentId) { Target = Comment targetId = commentId } //1. find the target //Note: will refetch when need to send json, since feedback has been changed Target.findById(targetId).exec(function(err, target) { if (err) return next(err) if (!target) return next(helper.getGeneralError('target does not exist')) //2. find the feedback var criteria = {} criteria['statusMeta.createdBy'] = req.user if (action === 'like' || action === 'dislike' || action === 'unlike' || action === 'undislike') criteria['type'] = {$in: ['like', 'dislike']} else if (action === 'share' || action === 'unshare') criteria['type'] = 'share' if (articleId) criteria['target.article'] = articleId else if (commentId) criteria['target.comment'] = commentId Feedback.find(criteria).exec(function(err, feedbacks) { if (err) next(err) if (feedbacks.length === 0) { //3. Feedback does not exist, create it var newFeedback = new Feedback() if (action === 'like' || action === 'dislike' || action === 'share') { newFeedback.type = action newFeedback.status = 'normal' newFeedback.statusMeta.createdBy = req.user if (articleId) newFeedback.target.article = targetId else if (commentId) newFeedback.target.comment = targetId if (meta) newFeedback.meta= meta } newFeedback.save(function(err) { if (err) return next(err) //4. save to target feedbacks list target.feedbacks.push(newFeedback) target.save(function(err) { if (err) return next(err) //5. save to user feedbacks list req.user.feedbacks.push(newFeedback) req.user.save(function(err) { if (err) return next(err) //6. done //Note: send the target! //Note: refetch target and populate, since its feedbacks have been changed var query = Target.findById(targetId) populateUsersForQuery(query) populateFeedbacksForQuery(query) query.exec(function(err, target) { if (err) return next(err) return res.json(target) }) }) }) }) } else { //3x. Found the feedback, update it var feedback = feedbacks[0] //must be length 1 if (action === 'like' || action === 'dislike' || action === 'share') { feedback.type = action feedback.status = 'normal' feedback.statusMeta.updatedBy = req.user feedback.statusMeta.updatedDate = new Date } else if (action === 'unlike' || action === 'undislike' || action === 'unshare') { feedback.status = 'deleted' feedback.statusMeta.deletedBy = req.user feedback.statusMeta.deletedDate = new Date } if (meta) feedback.meta= meta feedback.save(function(err) { if (err) return next(err) //4x. done //Note: send the target! //Note: refetch target and populate, since its feedbacks have been changed var query = Target.findById(targetId) populateUsersForQuery(query) populateFeedbacksForQuery(query) query.exec(function(err, target) { if (err) return next(err) return res.json(target) }) }) } }) }) } Let's say you have this method inside the service layer called feedbackProvider, how would you refactor the method into smaller chunks and where would you put the methods? Would you create an util class called feedbackUtils or would you put them inside feedbackProvider?

Submitted November 16, 2019 at 02:06PM by jesusscript

No comments:

Post a Comment