From 0968b02c3a1859abadb4f9b828b84d314f82ae70 Mon Sep 17 00:00:00 2001 From: gaba Date: Tue, 8 Nov 2016 15:26:05 -0800 Subject: [PATCH] Moderation queue depending on moderation settings. --- models/comment.js | 41 +++++++++++++- models/setting.js | 9 +++- routes/api/comments/index.js | 8 ++- tests/models/comment.js | 87 +++++++++++++++++++++++------- tests/routes/api/comments/index.js | 7 +++ 5 files changed, 129 insertions(+), 23 deletions(-) diff --git a/models/comment.js b/models/comment.js index 3aad5d978..0edbcb34e 100644 --- a/models/comment.js +++ b/models/comment.js @@ -1,6 +1,7 @@ const mongoose = require('../mongoose'); const uuid = require('uuid'); const Action = require('./action'); +const Setting = require('./setting'); const Schema = mongoose.Schema; @@ -74,14 +75,52 @@ CommentSchema.statics.findByActionType = function(action_type) { }); }; +/** + * Find not moderated comments by an action that was performed on them. + * @param {String} action_type the type of action that was performed on the comment + * @param {String} status the status of the comment to search for +*/ +CommentSchema.statics.findByStatusByActionType = function(status, action_type) { + return Action.findCommentsIdByActionType(action_type, 'comment').then((actions) => { + return Comment.find({'status': status, 'id': {'$in': actions.map(function(a){return a.item_id;})}}); + }); +}; + /** * Find comments by their status. - * @param {String} status the status to search for + * @param {String} status the status of the comment to search for */ CommentSchema.statics.findByStatus = function(status) { return Comment.find({'status': status}); }; +/** + * Find comments that need to be moderated (aka moderation queue). + * @param {String} moderationValue pre or post moderation setting. If it is undefined then look at the settings. +*/ +CommentSchema.statics.moderationQueue = function(moderationValue) { + + return Setting.getModerationSetting().then(function({moderation}){ + if (typeof moderationValue === 'undefined' || moderationValue === undefined) { + moderationValue = moderation; + } + switch(moderationValue){ + // Pre-moderation: New comments are shown in the moderator queues immediately. + case 'pre': + return Comment.findByStatus('').then((comments) => { + return comments; + }); + // Post-moderation: New comments do not appear in moderation queues unless they are flagged by other users. + case 'post': + return Comment.findByStatusByActionType('', 'flag').then((comments) => { + return comments; + }); + default: + throw new Error('Moderation setting not found.'); + } + }); +}; + //============================================================================== // Update Statics //============================================================================== diff --git a/models/setting.js b/models/setting.js index b47b6e9e2..15c457307 100644 --- a/models/setting.js +++ b/models/setting.js @@ -5,7 +5,6 @@ const SettingSchema = new Schema({ id: {type: String, default: '1'}, moderation: {type: String, enum: ['pre', 'post'], default: 'pre'} }, { - _id: false, timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' @@ -20,6 +19,14 @@ SettingSchema.statics.getSettings = function () { return this.findOne({id: '1'}); }; +/** + * gets the moderation settings and sends it back + * @return {Promise} moderation the settings for how to moderate comments + */ +SettingSchema.statics.getModerationSetting = function () { + return this.findOne({id: '1'}).select('moderation'); +}; + /** * this will update the settings object with whatever you pass in * @param {object} setting a hash of whatever settings you want to update diff --git a/routes/api/comments/index.js b/routes/api/comments/index.js index b3e2bdee7..c51db9f26 100644 --- a/routes/api/comments/index.js +++ b/routes/api/comments/index.js @@ -27,6 +27,7 @@ router.get('/:comment_id', (req, res, next) => { // Moderation Queues Routes //============================================================================== +// Get all the comments that have that action_type over them. router.get('/action/:action_type', (req, res, next) => { Comment.findByActionType(req.params.action_type).then((comments) => { res.status(200).json(comments); @@ -35,6 +36,7 @@ router.get('/action/:action_type', (req, res, next) => { }); }); +// Get all the comments that were rejected. router.get('/status/rejected', (req, res, next) => { Comment.findByStatus('rejected').then((comments) => { res.status(200).json(comments); @@ -43,8 +45,12 @@ router.get('/status/rejected', (req, res, next) => { }); }); +// Returns back all the comments that are in the moderation queue. The moderation queue is pre or post moderated, +// depending on the settings. The :moderation overwrites this settings. +// Pre-moderation: New comments are shown in the moderator queues immediately. +// Post-moderation: New comments do not appear in moderation queues unless they are flagged by other users. router.get('/status/pending', (req, res, next) => { - Comment.findByStatus('').then((comments) => { + Comment.moderationQueue(req.query.moderation).then((comments) => { res.status(200).json(comments); }).catch(error => { next(error); diff --git a/tests/models/comment.js b/tests/models/comment.js index b3f0c0f30..20f501da1 100644 --- a/tests/models/comment.js +++ b/tests/models/comment.js @@ -1,30 +1,73 @@ require('../utils/mongoose'); const Comment = require('../../models/comment'); +const User = require('../../models/user'); +const Action = require('../../models/action'); +const Setting = require('../../models/setting'); + +const settings = {id: '1', moderation: 'pre'}; + const expect = require('chai').expect; describe('Comment: models', () => { - let mockComments; + const comments = [{ + body: 'comment 10', + asset_id: '123', + status: '', + parent_id: '', + author_id: '123', + id: '1' + }, { + body: 'comment 20', + asset_id: '123', + status: 'accepted', + parent_id: '', + author_id: '123', + id: '2' + }, { + body: 'comment 30', + asset_id: '456', + status: 'rejected', + parent_id: '', + author_id: '456', + id: '3' + }]; + + const users = [{ + id: '123', + display_name: 'Ana', + }, { + id: '456', + display_name: 'Maria', + }]; + + const actions = [{ + action_type: 'flag', + item_id: comments[0].id, + item_type: 'comment', + user_id: '123' + }, { + action_type: 'like', + item_id: comments[1].id, + item_type: 'comment', + user_id: '456' + }]; + beforeEach(() => { - return Comment.create([{ - body: 'comment 10', - asset_id: '123' - }, { - body: 'comment 20', - asset_id: '123' - }, { - body: 'comment 30', - asset_id: '456' - }]).then((comments) => { - mockComments = comments; + return Setting.create(settings).then(() => { + return Comment.create(comments); + }).then(() => { + return User.create(users); + }).then(() => { + return Action.create(actions); }); }); describe('#findById()', () => { it('should find a comment by id', () => { - return Comment.findById(mockComments[0].id).then((result) => { - expect(result).to.have.property('body') - .and.to.equal('comment 10'); + return Comment.findById('1').then((result) => { + expect(result).to.not.be.null; + expect(result).to.have.property('body', 'comment 10'); }); }); }); @@ -37,13 +80,17 @@ describe('Comment: models', () => { if (a.body < b.body) {return -1;} else {return 1;} }); - expect(result[0]).to.have.property('body') - .and.to.equal('comment 10'); - expect(result[1]).to.have.property('body') - .and.to.equal('comment 20'); + expect(result[0]).to.have.property('body', 'comment 10'); + expect(result[1]).to.have.property('body', 'comment 20'); }); }); }); - // }); + describe('#moderationQueue()', () => { + it('should find an array of new comments to moderate when pre-moderation'); + it('should find an array of new comments to moderate when post-moderation'); + it('should find an array of new comments to moderate when pre-moderation in settings'); + it('should find an array of new comments to moderate when post-moderation in settings'); + it('should fail when the moderation is not pre or post'); + }); }); diff --git a/tests/routes/api/comments/index.js b/tests/routes/api/comments/index.js index 378860bcb..5dc6d2d0b 100644 --- a/tests/routes/api/comments/index.js +++ b/tests/routes/api/comments/index.js @@ -14,6 +14,13 @@ const Comment = require('../../../../models/comment'); const Action = require('../../../../models/action'); const User = require('../../../../models/user'); +const Setting = require('../../../../models/setting'); +const settings = {id: '1', moderation: 'pre'}; + +beforeEach(() => { + return Setting.create(settings); +}); + describe('Get /comments', () => { const comments = [{ id: 'abc',