From a06f76fd4c1f84d862b829d35e82885073512f3a Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Mon, 29 Jan 2018 16:36:54 -0700 Subject: [PATCH 01/56] removed events --- services/actions.js | 156 +++---------- services/comments.js | 218 +++---------------- services/events/constants.js | 10 - services/events/index.js | 36 --- services/users.js | 87 ++------ test/server/graph/mutations/addTag.js | 3 +- test/server/graph/mutations/createComment.js | 12 +- test/server/graph/mutations/editComment.js | 17 +- test/server/graph/mutations/removeTag.js | 5 +- test/server/services/actions.js | 47 ---- test/server/services/comments.js | 46 +--- test/server/services/tags.js | 15 +- 12 files changed, 121 insertions(+), 531 deletions(-) delete mode 100644 services/events/constants.js delete mode 100644 services/events/index.js diff --git a/services/actions.js b/services/actions.js index a1cef9ff6..856e67482 100644 --- a/services/actions.js +++ b/services/actions.js @@ -3,8 +3,34 @@ const CommentModel = require('../models/comment'); const UserModel = require('../models/user'); const _ = require('lodash'); const errors = require('../errors'); -const events = require('./events'); -const { ACTIONS_NEW, ACTIONS_DELETE } = require('./events/constants'); + +const incrActionCounts = async (action, value) => { + const ACTION_TYPE = action.action_type.toLowerCase(); + + const query = { id: action.item_id }; + const update = { + [`action_counts.${ACTION_TYPE}`]: value, + }; + + if (action.group_id && action.group_id.length > 0) { + const GROUP_ID = action.group_id.toLowerCase(); + + update[`action_counts.${ACTION_TYPE}_${GROUP_ID}`] = value; + } + + switch (action.item_type) { + case 'USERS': + return UserModel.update(query, { + $inc: update, + }); + case 'COMMENTS': + return CommentModel.update(query, { + $inc: update, + }); + default: + return; + } +}; /** * findOnlyOneAndUpdate will perform a fondOneAndUpdate on the mongo collection @@ -58,14 +84,12 @@ module.exports = class ActionsService { /** * Inserts an action. * - * @param {String} item_id identifier of the item (uuid) - * @param {String} user_id user id of the action (uuid) * @param {String} action the new action to the item * @return {Promise} */ static async create(action) { - // Actions are made unique by using a query that can be reproducable, i.e., - // not containing user inputable values. + // Actions are made unique by using a query that can be reproducible, i.e., + // not containing user modifiable values. let foundAction = await findOnlyOneAndUpdate( { action_type: action.action_type, @@ -80,8 +104,7 @@ module.exports = class ActionsService { } ); - // Emit that there was a new action created. - await events.emitAsync(ACTIONS_NEW, foundAction); + await incrActionCounts(action, 1); return foundAction; } @@ -103,42 +126,6 @@ module.exports = class ActionsService { return actions; } - /** - * Fetches the action summaries for the given asset, and comments around the - * given user id. - * - * @param {[type]} asset_id [description] - * @param {[type]} comments [description] - * @param {String} [current_user_id=''] [description] - * @return {[type]} [description] - */ - static getActionSummariesFromComments( - asset_id = '', - comments, - current_user_id = '' - ) { - // Get the user id's from the author id's as a unique array that gets - // sorted. - let userIDs = _.uniq(comments.map(comment => comment.author_id)).sort(); - - // Fetch the actions for pretty much everything at this point. - return ActionsService.getActionSummaries( - _.uniq( - [ - // Actions can be on assets... - asset_id, - - // Comments... - ...comments.map(comment => comment.id), - - // Or Authors... - ...userIDs, - ].filter(e => e) - ), - current_user_id - ); - } - /** * Returns summaries of actions for an array of ids. * @@ -210,19 +197,6 @@ module.exports = class ActionsService { ]); } - /** - * Finds all comments for a specific action. - * - * @param {String} action_type type of action - * @param {String} item_type type of item the action is on - */ - static findByType(action_type, item_type) { - return ActionModel.find({ - action_type: action_type, - item_type: item_type, - }); - } - /** * delete will remove the record from the collection if it exists. Otherwise * it will do nothing. This will then return the deleted action. @@ -239,8 +213,7 @@ module.exports = class ActionsService { return; } - // Emit that the action was deleted. - await events.emitAsync(ACTIONS_DELETE, action); + await incrActionCounts(action, -1); return action; } @@ -261,68 +234,3 @@ module.exports = class ActionsService { ); } }; - -const incrActionCounts = async (action, value) => { - const ACTION_TYPE = action.action_type.toLowerCase(); - - const update = { - [`action_counts.${ACTION_TYPE}`]: value, - }; - - if (action.group_id && action.group_id.length > 0) { - const GROUP_ID = action.group_id.toLowerCase(); - - update[`action_counts.${ACTION_TYPE}_${GROUP_ID}`] = value; - } - - try { - switch (action.item_type) { - case 'USERS': - return UserModel.update( - { - id: action.item_id, - }, - { - $inc: update, - } - ); - case 'COMMENTS': - return CommentModel.update( - { - id: action.item_id, - }, - { - $inc: update, - } - ); - default: - throw new Error('Invalid item type for action summary monitoring'); - } - } catch (err) { - console.error(`Can't mutate the action_counts.${ACTION_TYPE}:`, err); - } -}; - -// When a new action is created, modify the comment. -events.on(ACTIONS_NEW, async action => { - if ( - !action || - (action.item_type !== 'COMMENTS' && action.item_type !== 'USERS') - ) { - return; - } - - return incrActionCounts(action, 1); -}); - -// When an action is deleted, remove the action count on the comment. -events.on(ACTIONS_DELETE, async action => { - if ( - !action || - (action.item_type !== 'COMMENTS' && action.item_type !== 'USERS') - ) { - return; - } - - return incrActionCounts(action, -1); -}); diff --git a/services/comments.js b/services/comments.js index 68f991324..fd6f2282d 100644 --- a/services/comments.js +++ b/services/comments.js @@ -1,22 +1,36 @@ const CommentModel = require('../models/comment'); const debug = require('debug')('talk:services:comments'); -const ActionsService = require('./actions'); const SettingsService = require('./settings'); const cloneDeep = require('lodash/cloneDeep'); const errors = require('../errors'); -const events = require('./events'); const merge = require('lodash/merge'); -const { COMMENTS_NEW, COMMENTS_EDIT } = require('./events/constants'); -module.exports = class CommentsService { +const incrReplyCount = async (comment, value) => { + try { + await CommentModel.update( + { + id: comment.parent_id, + }, + { + $inc: { + reply_count: value, + }, + } + ); + } catch (err) { + console.error("Can't mutate the reply count:", err); + } +}; + +module.exports = { /** * Creates a new Comment that came from a public source. * @param {Object} input either a single comment or an array of comments. * @return {Promise} */ - static async publicCreate(input) { + publicCreate: async input => { // Extract the parent_id from the comment, if there is one. const { status = 'NONE', parent_id = null } = input; const created_at = new Date(); @@ -54,27 +68,10 @@ module.exports = class CommentsService { ); // Emit that the comment was created! - await events.emitAsync(COMMENTS_NEW, comment); + await incrReplyCount(comment, 1); return comment; - } - - /** - * lastUnmoderatedStatus will retrieve the last status before this one. - * - * @param {Object} comment the comment to get the last status of - */ - static lastUnmoderatedStatus(comment) { - const UNMODERATED_STATUSES = ['NONE', 'PREMOD']; - - for (let i = comment.status_history.length - 1; i >= 0; i--) { - const { type } = comment.status_history[i]; - - if (UNMODERATED_STATUSES.includes(type)) { - return type; - } - } - } + }, /** * Edit a Comment. @@ -84,7 +81,7 @@ module.exports = class CommentsService { * @param {String} body the new Comment body * @param {String} status the new Comment status */ - static async edit({ id, author_id, body, status }) { + edit: async ({ id, author_id, body, status }) => { const EDITABLE_STATUSES = ['NONE', 'PREMOD', 'ACCEPTED']; const created_at = new Date(); @@ -125,7 +122,7 @@ module.exports = class CommentsService { if (originalComment == null) { // Try to get the comment. - const comment = await CommentsService.findById(id); + const comment = await CommentModel.findOne({ id }); if (comment == null) { debug('rejecting comment edit because comment was not found'); throw errors.ErrNotFound; @@ -169,86 +166,8 @@ module.exports = class CommentsService { created_at, }); - await events.emitAsync(COMMENTS_EDIT, originalComment, editedComment); - return editedComment; - } - - /** - * Finds a comment by the id. - * @param {String} id identifier of comment (uuid) - * @return {Promise} - */ - static findById(id) { - return CommentModel.findOne({ id }); - } - - /** - * Finds ALL the comments by the asset_id. - * @param {String} asset_id identifier of the asset which owns this comment (uuid) - * @return {Promise} - */ - static findByAssetId(asset_id) { - return CommentModel.find({ - asset_id, - }); - } - - /** - * findByAssetIdWithStatuses finds all the comments where the asset id matches - * what's provided and the status is one of the ones listed in the statuses - * array. - * @param {String} asset_id the asset id to search by - * @param {Array} [statuses=[]] the array of statuses to search by - * @return {Promise} resolves to an array of comments - */ - static findByAssetIdWithStatuses(asset_id, statuses = []) { - return CommentModel.find({ - asset_id, - status: { - $in: statuses, - }, - }); - } - - /** - * Find comments by an action that was performed on them. - * @param {String} action_type the type of action that was performed on the comment - * @return {Promise} - */ - static findByActionType(action_type) { - return ActionsService.findCommentsIdByActionType( - action_type, - 'COMMENTS' - ).then(actions => - CommentModel.find({ - id: { - $in: actions.map(a => a.item_id), - }, - }) - ); - } - - /** - * Find comment id's where the action type matches the argument. - * @param {String} action_type the type of action that was performed on the comment - * @return {Promise} - */ - static findIdsByActionType(action_type) { - return ActionsService.findCommentsIdByActionType( - action_type, - 'COMMENTS' - ).then(actions => actions.map(a => a.item_id)); - } - - /** - * Find comments by current status - * @param {String} status status of the comment to search for - * @return {Promise} resovles to comment array - */ - static findByStatus(status = 'NONE') { - return CommentModel.find({ status }); - } + }, /** * Pushes a new status in for the user. @@ -258,7 +177,7 @@ module.exports = class CommentsService { * moderation action * @return {Promise} */ - static async pushStatus(id, status, assigned_by = null) { + pushStatus: async (id, status, assigned_by = null) => { const created_at = new Date(); const originalComment = await CommentModel.findOneAndUpdate( { id }, @@ -286,83 +205,16 @@ module.exports = class CommentsService { }); editedComment.status = status; - // Emit that the comment was edited, and pass the original comment and the - // edited comment. - await events.emitAsync(COMMENTS_EDIT, originalComment, editedComment); + // If the comment was visible before, and now it isn't, decrement the count; + if (originalComment.visible && !editedComment.visible) { + await incrReplyCount(editedComment, -1); + } + + // If the comment was not visible before, and now it is, increment the count. + if (!originalComment.visible && editedComment.visible) { + await incrReplyCount(editedComment, 1); + } return editedComment; - } - - /** - * Add an action to the comment. - * @param {String} item_id identifier of the comment (uuid) - * @param {String} user_id user id of the action (uuid) - * @param {String} action the new action to the comment - * @return {Promise} - */ - static addAction(item_id, user_id, action_type, metadata = {}) { - return ActionsService.create({ - item_id, - item_type: 'COMMENTS', - user_id, - action_type, - metadata, - }); - } + }, }; - -//============================================================================== -// Event Hooks -//============================================================================== - -const incrReplyCount = async (comment, value) => { - try { - await CommentModel.update( - { - id: comment.parent_id, - }, - { - $inc: { - reply_count: value, - }, - } - ); - } catch (err) { - console.error("Can't mutate the reply count:", err); - } -}; - -// When a comment is created, if it is a reply, increment the reply count on the -// parent's document. -events.on(COMMENTS_NEW, async comment => { - if ( - !comment || // Check that the comment is defined. - (!comment.parent_id || comment.parent_id.length === 0) || // Check that the comment has a parent (is a reply). - !(comment.status === 'NONE' || comment.status === 'ACCEPTED') // Check that the comment is visible. - ) { - return; - } - - return incrReplyCount(comment, 1); -}); - -// When a comment is edited, if the visability changed publicly, then modify the -// comment. -events.on(COMMENTS_EDIT, async (originalComment, editedComment) => { - if ( - !editedComment || // Check that the comment is defined. - (!editedComment.parent_id || editedComment.parent_id.length === 0) // Check that the comment has a parent (is a reply). - ) { - return; - } - - // If the comment was visible before, and now it isn't, decrement the count; - if (originalComment.visible && !editedComment.visible) { - return incrReplyCount(editedComment, -1); - } - - // If the comment was not visible before, and now it is, increment the count. - if (!originalComment.visible && editedComment.visible) { - return incrReplyCount(editedComment, 1); - } -}); diff --git a/services/events/constants.js b/services/events/constants.js deleted file mode 100644 index f3aa84d62..000000000 --- a/services/events/constants.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - USERS_NEW: 'USERS_NEW', - ACTIONS_DELETE: 'ACTIONS_DELETE', - ACTIONS_NEW: 'ACTIONS_NEW', - COMMENTS_NEW: 'COMMENTS_NEW', - COMMENTS_EDIT: 'COMMENTS_EDIT', - USERS_SUSPENSION_CHANGE: 'USERS_SUSPENSION_CHANGE', - USERS_BAN_CHANGE: 'USERS_BAN_CHANGE', - USERS_USERNAME_STATUS_CHANGE: 'USERS_USERNAME_STATUS_CHANGE', -}; diff --git a/services/events/index.js b/services/events/index.js deleted file mode 100644 index 2698df653..000000000 --- a/services/events/index.js +++ /dev/null @@ -1,36 +0,0 @@ -const { EventEmitter2 } = require('eventemitter2'); -const constants = require('./constants'); -const debug = require('debug')('talk:services:events'); -const enabled = require('debug').enabled('talk:services:events'); - -const emitter = new EventEmitter2({ - wildcard: true, -}); - -// If event debugging is enabled, bind the debugger to all events being emitted -// and log a debug message. -if (enabled) { - emitter.onAny(function(event) { - debug( - `[${event}] ${arguments.length - 1} argument${ - arguments.length - 1 === 1 ? '' : 's' - }` - ); - }); -} - -// Allow any number of listeners to attach to this. -emitter.setMaxListeners(0); - -// The default error handler. -emitter.on('error', err => { - console.error('events error:', err); -}); - -emitter.on('newListener', event => { - if (!(event in constants)) { - throw new Error(`Event[${event}] not a valid event name`); - } -}); - -module.exports = emitter; diff --git a/services/users.js b/services/users.js index 96386108f..cfbbaf822 100644 --- a/services/users.js +++ b/services/users.js @@ -4,14 +4,6 @@ const errors = require('../errors'); const some = require('lodash/some'); const merge = require('lodash/merge'); -const { - USERS_NEW, - USERS_SUSPENSION_CHANGE, - USERS_BAN_CHANGE, - USERS_USERNAME_STATUS_CHANGE, -} = require('./events/constants'); -const events = require('./events'); - const { ROOT_URL } = require('../config'); const { jwt: JWT_SECRET } = require('../secrets'); @@ -125,12 +117,16 @@ class UsersService { ); } - // Emit that the user username status was changed. - await events.emitAsync(USERS_SUSPENSION_CHANGE, user, { - until, - message, - assignedBy, - }); + // Check to see if the user was suspended now and is currently suspended. + if (user.suspended && message && message.length > 0) { + await UsersService.sendEmail(user, { + template: 'plain', + locals: { + body: message, + }, + subject: 'Your account has been suspended', + }); + } return user; } @@ -174,12 +170,16 @@ class UsersService { throw new Error('ban status change edit failed for an unknown reason'); } - // Emit that the user ban status was changed. - await events.emitAsync(USERS_BAN_CHANGE, user, { - status, - assignedBy, - message, - }); + // Check to see if the user was banned now and is currently banned. + if (user.banned && status && message && message.length > 0) { + await UsersService.sendEmail(user, { + template: 'plain', + locals: { + body: message, + }, + subject: 'Your account has been banned', + }); + } return user; } @@ -223,12 +223,6 @@ class UsersService { ); } - // Emit that the user username status was changed. - await events.emitAsync(USERS_USERNAME_STATUS_CHANGE, user, { - status, - assignedBy, - }); - return user; } @@ -286,9 +280,6 @@ class UsersService { throw new Error('edit username failed for an unexpected reason'); } - // Emit that the user username status was changed. - await events.emitAsync(USERS_USERNAME_STATUS_CHANGE, user, toStatus); - return user; } catch (err) { if (err.code === 11000) { @@ -404,9 +395,6 @@ class UsersService { // Save the user in the database. await user.save(); - // Emit that the user was created. - await events.emitAsync(USERS_NEW, user); - return user; } @@ -578,9 +566,6 @@ class UsersService { throw err; } - // Emit that the user was created. - await events.emitAsync(USERS_NEW, user); - return user; } @@ -952,38 +937,6 @@ class UsersService { module.exports = UsersService; -events.on(USERS_BAN_CHANGE, async (user, { status, message }) => { - // Check to see if the user was banned now and is currently banned. - if (user.banned && status && message && message.length > 0) { - await UsersService.sendEmail(user, { - template: 'plain', - locals: { - body: message, - }, - subject: 'Your account has been banned', - }); - } -}); - -events.on(USERS_SUSPENSION_CHANGE, async (user, { until, message }) => { - // Check to see if the user was suspended now and is currently suspended. - if ( - user.suspended && - until !== null && - until > Date.now() && - message && - message.length > 0 - ) { - await UsersService.sendEmail(user, { - template: 'plain', - locals: { - body: message, - }, - subject: 'Your account has been suspended', - }); - } -}); - // Extract all the tokenUserNotFound plugins so we can integrate with other // providers. let tokenUserNotFoundHooks = null; diff --git a/test/server/graph/mutations/addTag.js b/test/server/graph/mutations/addTag.js index d93c7fa44..fe22c498f 100644 --- a/test/server/graph/mutations/addTag.js +++ b/test/server/graph/mutations/addTag.js @@ -3,6 +3,7 @@ const { graphql } = require('graphql'); const schema = require('../../../../graph/schema'); const Context = require('../../../../graph/context'); const AssetModel = require('../../../../models/asset'); +const CommentModel = require('../../../../models/comment'); const UserModel = require('../../../../models/user'); const SettingsService = require('../../../../services/settings'); const CommentsService = require('../../../../services/comments'); @@ -50,7 +51,7 @@ describe('graph.mutations.addTag', () => { expect(res.errors).to.be.empty; - let { tags } = await CommentsService.findById(comment.id); + let { tags } = await CommentModel.findOne({ id: comment.id }); expect(tags).to.have.length(1); }); diff --git a/test/server/graph/mutations/createComment.js b/test/server/graph/mutations/createComment.js index 720297e12..ffac0f510 100644 --- a/test/server/graph/mutations/createComment.js +++ b/test/server/graph/mutations/createComment.js @@ -3,12 +3,12 @@ const { graphql } = require('graphql'); const schema = require('../../../../graph/schema'); const Context = require('../../../../graph/context'); -const UserModel = require('../../../../models/user'); -const AssetModel = require('../../../../models/asset'); const ActionModel = require('../../../../models/action'); +const AssetModel = require('../../../../models/asset'); +const CommentModel = require('../../../../models/comment'); +const UserModel = require('../../../../models/user'); const SettingsService = require('../../../../services/settings'); -const CommentsService = require('../../../../services/comments'); const { expect } = require('chai'); @@ -293,9 +293,9 @@ describe('graph.mutations.createComment', () => { expect(data.createComment).to.have.property('comment').not.null; expect(data.createComment).to.have.property('errors').null; - const { tags } = await CommentsService.findById( - data.createComment.comment.id - ); + const { tags } = await CommentModel.findOne({ + id: data.createComment.comment.id, + }); if (tag) { expect(tags).to.have.length(1); expect(tags[0].tag.name).to.have.equal(tag); diff --git a/test/server/graph/mutations/editComment.js b/test/server/graph/mutations/editComment.js index 67c81a5d5..476279ae8 100644 --- a/test/server/graph/mutations/editComment.js +++ b/test/server/graph/mutations/editComment.js @@ -1,12 +1,13 @@ const { graphql } = require('graphql'); const timekeeper = require('timekeeper'); -const schema = require('../../../../graph/schema'); -const Context = require('../../../../graph/context'); -const UsersService = require('../../../../services/users'); const AssetModel = require('../../../../models/asset'); -const SettingsService = require('../../../../services/settings'); +const CommentModel = require('../../../../models/comment'); const CommentsService = require('../../../../services/comments'); +const Context = require('../../../../graph/context'); +const schema = require('../../../../graph/schema'); +const SettingsService = require('../../../../services/settings'); +const UsersService = require('../../../../services/users'); const { expect } = require('chai'); @@ -70,7 +71,7 @@ describe('graph.mutations.editComment', () => { expect(response.data.editComment.errors).to.be.null; // assert body has changed - const commentAfterEdit = await CommentsService.findById(comment.id); + const commentAfterEdit = await CommentModel.findOne({ id: comment.id }); expect(commentAfterEdit.body).to.equal(newBody); expect(commentAfterEdit.body_history).to.be.instanceOf(Array); expect(commentAfterEdit.body_history.length).to.equal(2); @@ -110,7 +111,7 @@ describe('graph.mutations.editComment', () => { expect(response.data.editComment.errors[0].translation_key).to.equal( 'EDIT_WINDOW_ENDED' ); - const commentAfterEdit = await CommentsService.findById(comment.id); + const commentAfterEdit = await CommentModel.findOne({ id: comment.id }); // it *hasn't* changed from the original expect(commentAfterEdit.body).to.equal(comment.body); @@ -142,7 +143,7 @@ describe('graph.mutations.editComment', () => { expect(response.data.editComment.errors[0].translation_key).to.equal( 'NOT_AUTHORIZED' ); - const commentAfterEdit = await CommentsService.findById(comment.id); + const commentAfterEdit = await CommentModel.findOne({ id: comment.id }); // it *hasn't* changed from the original expect(commentAfterEdit.body).to.equal(comment.body); @@ -274,7 +275,7 @@ describe('graph.mutations.editComment', () => { console.error(response.data.editComment.errors); } expect(response.data.editComment.errors).to.be.null; - const commentAfterEdit = await CommentsService.findById(comment.id); + const commentAfterEdit = await CommentModel.findOne({ id: comment.id }); expect(commentAfterEdit.body).to.equal(newBody); expect(commentAfterEdit.status).to.equal(afterEdit.status); } diff --git a/test/server/graph/mutations/removeTag.js b/test/server/graph/mutations/removeTag.js index f1de90f5c..ccd5e95f5 100644 --- a/test/server/graph/mutations/removeTag.js +++ b/test/server/graph/mutations/removeTag.js @@ -6,8 +6,9 @@ const UserModel = require('../../../../models/user'); const SettingModel = require('../../../../models/setting'); const AssetModel = require('../../../../models/asset'); -const SettingsService = require('../../../../services/settings'); +const CommentModel = require('../../../../models/comment'); const CommentsService = require('../../../../services/comments'); +const SettingsService = require('../../../../services/settings'); const TagsService = require('../../../../services/tags'); const { expect } = require('chai'); @@ -59,7 +60,7 @@ describe('graph.mutations.removeTag', () => { expect(response.errors).to.be.empty; expect(response.data.removeTag).to.be.null; - let retrievedComment = await CommentsService.findById(comment.id); + let retrievedComment = await CommentModel.findOne({ id: comment.id }); expect(retrievedComment.tags).to.have.length(0); }); diff --git a/test/server/services/actions.js b/test/server/services/actions.js index d1cab11bd..670bcf4d3 100644 --- a/test/server/services/actions.js +++ b/test/server/services/actions.js @@ -6,14 +6,6 @@ const chai = require('chai'); chai.use(require('chai-as-promised')); const expect = chai.expect; -const events = require('../../../services/events'); -const { - ACTIONS_NEW, - ACTIONS_DELETE, -} = require('../../../services/events/constants'); - -const sinon = require('sinon'); - describe('services.ActionsService', () => { let mockActions = []; let comment; @@ -78,30 +70,6 @@ describe('services.ActionsService', () => { expect(retrievedAction).has.property('id', createdAction.id); expect(retrievedAction).has.property('item_id', comment.id); }); - - it('fires the callback successfully', async () => { - const srcAction = { - action_type: 'LIKE', - item_type: 'COMMENTS', - item_id: comment.id, - }; - - const spy = sinon.spy(); - events.once(ACTIONS_NEW, spy); - - const createdAction = await ActionsService.create(srcAction); - - expect(createdAction).is.not.null; - expect(createdAction).has.property('id'); - expect(createdAction).has.property('item_id', comment.id); - - expect(spy).to.have.been.calledWith(createdAction); - - const retrievedComment = await CommentModel.findOne({ id: comment.id }); - - expect(retrievedComment).to.have.property('action_counts'); - expect(retrievedComment.action_counts).to.have.property('like', 1); - }); }); describe('#delete', () => { @@ -116,21 +84,6 @@ describe('services.ActionsService', () => { expect(retrievedAction).is.null; }); - - it('fires the callback successfully', async () => { - const spy = sinon.spy(); - events.once(ACTIONS_DELETE, spy); - - const deletedAction = await ActionsService.delete(mockActions[0]); - - expect(deletedAction).has.property('id', mockActions[0].id); - expect(spy).to.have.been.calledWith(deletedAction); - - const retrievedComment = await CommentModel.findOne({ id: comment.id }); - - expect(retrievedComment).to.have.property('action_counts'); - expect(retrievedComment.action_counts).to.have.property('flag', -1); - }); }); describe('#findById()', () => { diff --git a/test/server/services/comments.js b/test/server/services/comments.js index e0fc6da67..0c1a72ab7 100644 --- a/test/server/services/comments.js +++ b/test/server/services/comments.js @@ -1,8 +1,6 @@ const CommentModel = require('../../../models/comment'); const ActionModel = require('../../../models/action'); -const events = require('../../../services/events'); -const { COMMENTS_EDIT } = require('../../../services/events/constants'); const UsersService = require('../../../services/users'); const SettingsService = require('../../../services/settings'); const CommentsService = require('../../../services/comments'); @@ -17,8 +15,6 @@ const chai = require('chai'); chai.use(require('sinon-chai')); const expect = chai.expect; -const sinon = require('sinon'); - describe('services.CommentsService', () => { const comments = [ { @@ -214,7 +210,9 @@ describe('services.CommentsService', () => { await CommentsService.pushStatus(originalComment.id, 'ACCEPTED'); - let retrivedComment = await CommentsService.findById(originalComment.id); + let retrivedComment = await CommentModel.findOne({ + id: originalComment.id, + }); expect(retrivedComment).to.have.property('status', 'ACCEPTED'); expect(retrivedComment.status_history).to.have.length(2); @@ -237,7 +235,7 @@ describe('services.CommentsService', () => { 'PREMOD' ); - retrivedComment = await CommentsService.findById(originalComment.id); + retrivedComment = await CommentModel.findOne({ id: originalComment.id }); expect(retrivedComment).to.have.property('status', 'PREMOD'); expect(retrivedComment.status_history).to.have.length(3); @@ -248,41 +246,13 @@ describe('services.CommentsService', () => { }); }); - describe('#findById()', () => { - it('should find a comment by id', async () => { - const comment = await CommentsService.findById('1'); - expect(comment).to.not.be.null; - expect(comment).to.have.property('body', 'comment 10'); - }); - }); - - describe('#findByAssetId()', () => { - it('should find an array of all comments by asset id', async () => { - const comments = await CommentsService.findByAssetId('123'); - expect(comments).to.have.length(3); - comments.sort((a, b) => { - if (a.body < b.body) { - return -1; - } else { - return 1; - } - }); - expect(comments[0]).to.have.property('body', 'comment 10'); - expect(comments[1]).to.have.property('body', 'comment 20'); - expect(comments[2]).to.have.property('body', 'comment 40'); - }); - }); - describe('#changeStatus', () => { it('should change the status of a comment from no status', async () => { let comment_id = comments[0].id; - let c = await CommentsService.findById(comment_id); + let c = await CommentModel.findOne({ id: comment_id }); expect(c.status).to.be.equal('NONE'); - const spy = sinon.spy(); - events.once(COMMENTS_EDIT, spy); - let c2 = await CommentsService.pushStatus(comment_id, 'REJECTED', '123'); expect(c2).to.have.property('status'); expect(c2.status).to.equal('REJECTED'); @@ -290,9 +260,7 @@ describe('services.CommentsService', () => { expect(c2.status_history[0]).to.have.property('type', 'REJECTED'); expect(c2.status_history[0]).to.have.property('assigned_by', '123'); - expect(spy).to.have.been.called; - - let c3 = await CommentsService.findById(comment_id); + let c3 = await CommentModel.findOne({ id: comment_id }); expect(c3).to.have.property('status'); expect(c3.status).to.equal('REJECTED'); expect(c3.status_history).to.have.length(1); @@ -302,7 +270,7 @@ describe('services.CommentsService', () => { it('should change the status of a comment from accepted', async () => { await CommentsService.pushStatus(comments[1].id, 'REJECTED', '123'); - const c = await CommentsService.findById(comments[1].id); + const c = await CommentModel.findOne({ id: comments[1].id }); expect(c).to.have.property('status_history'); expect(c).to.have.property('status'); expect(c.status).to.equal('REJECTED'); diff --git a/test/server/services/tags.js b/test/server/services/tags.js index eb3144114..92e566f7c 100644 --- a/test/server/services/tags.js +++ b/test/server/services/tags.js @@ -1,4 +1,3 @@ -const CommentsService = require('../../../services/comments'); const TagsService = require('../../../services/tags'); const UsersService = require('../../../services/users'); const SettingsService = require('../../../services/settings'); @@ -40,7 +39,7 @@ describe('services.TagsService', () => { assigned_by, }); - const { tags } = await CommentsService.findById(id); + const { tags } = await CommentModel.findOne({ id }); expect(tags.length).to.equal(1); expect(tags[0].tag.name).to.equal(name); expect(tags[0].assigned_by).to.equal(assigned_by); @@ -59,7 +58,7 @@ describe('services.TagsService', () => { }); { - let { tags } = await CommentsService.findById(id); + let { tags } = await CommentModel.findOne({ id }); expect(tags.length).to.equal(1); } @@ -71,7 +70,7 @@ describe('services.TagsService', () => { }); { - let { tags } = await CommentsService.findById(id); + let { tags } = await CommentModel.findOne({ id }); expect(tags.length).to.equal(1); } }); @@ -91,7 +90,7 @@ describe('services.TagsService', () => { }); { - const { tags } = await CommentsService.findById(id); + const { tags } = await CommentModel.findOne({ id }); expect(tags.length).to.equal(1); } @@ -104,7 +103,7 @@ describe('services.TagsService', () => { }); { - const { tags } = await CommentsService.findById(id); + const { tags } = await CommentModel.findOne({ id }); expect(tags.length).to.equal(0); } }); @@ -128,7 +127,7 @@ describe('services.TagsService', () => { }); { - const { tags } = await CommentsService.findById(id); + const { tags } = await CommentModel.findOne({ id }); expect(tags.length).to.equal(2); } @@ -141,7 +140,7 @@ describe('services.TagsService', () => { }); { - const { tags } = await CommentsService.findById(id); + const { tags } = await CommentModel.findOne({ id }); expect(tags.length).to.equal(1); expect(tags[0].tag.name).to.equal('ANOTHER'); } From 931fb81aa8062d089eaf28b71fb3fb74189fafcf Mon Sep 17 00:00:00 2001 From: Kim Gardner Date: Tue, 30 Jan 2018 12:21:10 -0500 Subject: [PATCH 02/56] Update version to 4.1.0 and update LICENSE --- LICENSE | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE b/LICENSE index e0a687532..5beee04b4 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 Mozilla Foundation +Copyright 2018 Mozilla Foundation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/package.json b/package.json index b3afdc9b6..6a3b1b447 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "talk", - "version": "4.0.0", + "version": "4.1.0", "description": "A better commenting experience from Mozilla, The New York Times, and the Washington Post. https://coralproject.net", "main": "app.js", "private": true, From f8f882fbfd2372fde4253756955a37c90eb50953 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Tue, 30 Jan 2018 11:00:48 -0700 Subject: [PATCH 03/56] blocked user actions in username change process --- .../src/components/CommentLabels.js | 3 ++- .../src/routes/Community/components/People.js | 14 +++++++---- .../coral-embed-stream/src/graphql/index.js | 3 ++- .../src/tabs/stream/components/Comment.js | 5 ++-- client/coral-framework/constants/roles.js | 4 ++++ .../constants/usernameStatus.js | 22 +++++++++++++++++ client/coral-framework/services/perms.js | 24 ++++++++++++------- 7 files changed, 58 insertions(+), 17 deletions(-) create mode 100644 client/coral-framework/constants/roles.js create mode 100644 client/coral-framework/constants/usernameStatus.js diff --git a/client/coral-admin/src/components/CommentLabels.js b/client/coral-admin/src/components/CommentLabels.js index e50d53632..8eac152bd 100644 --- a/client/coral-admin/src/components/CommentLabels.js +++ b/client/coral-admin/src/components/CommentLabels.js @@ -5,8 +5,9 @@ import Slot from 'coral-framework/components/Slot'; import FlagLabel from 'coral-ui/components/FlagLabel'; import cn from 'classnames'; import styles from './CommentLabels.css'; +import { ADMIN, MODERATOR, STAFF } from 'coral-framework/constants/roles'; -const staffRoles = ['ADMIN', 'STAFF', 'MODERATOR']; +const staffRoles = [ADMIN, MODERATOR, STAFF]; function isUserFlagged(actions) { return actions.some( diff --git a/client/coral-admin/src/routes/Community/components/People.js b/client/coral-admin/src/routes/Community/components/People.js index 0328d148b..1f5e4bab8 100644 --- a/client/coral-admin/src/routes/Community/components/People.js +++ b/client/coral-admin/src/routes/Community/components/People.js @@ -10,6 +10,12 @@ import ActionsMenu from 'coral-admin/src/components/ActionsMenu'; import ActionsMenuItem from 'coral-admin/src/components/ActionsMenuItem'; import { isSuspended, isBanned } from 'coral-framework/utils/user'; import moment from 'moment'; +import { + ADMIN, + COMMENTER, + MODERATOR, + STAFF, +} from 'coral-framework/constants/roles'; const headers = [ { @@ -200,19 +206,19 @@ class People extends React.Component { onChange={role => setUserRole(user.id, role)} >