diff --git a/services/comments.js b/services/comments.js index 91bd814e1..7820106ed 100644 --- a/services/comments.js +++ b/services/comments.js @@ -45,6 +45,8 @@ module.exports = class CommentsService { /** * Adds a tag if it doesn't already exist on the comment. + * @throws if tag is already added to the comment + * @throws if tag name is not in ALLOWED_TAGS * @param {String} id the id of the comment to tag * @param {String} name the name of the tag to add * @param {String} assigned_by the user id for the user who added the tag @@ -85,7 +87,43 @@ module.exports = class CommentsService { return; default: console.warn('CommentsService#addTag modified multiple comments, but it should only have modified 1. ' - + `You may have bad data. Check for multiple comments with id=${id}`); + + `You may have bad data. Check for multiple comments with id=${id}`); + } + }); + } + + /** + * Removes a tag from a comment + * @throws if the tag is not on the comment + * @param {String} id the id of the comment to tag + * @param {String} name the name of the tag to add + */ + static removeTag(id, name) { + const filter = { + id, + tags: {$elemMatch: {name}} + }; + const update = {$pull: {tags: {name}}}; + return CommentModel.update(filter, update) + .then(({nModified}) => { + switch (nModified) { + case 0: + + // either the tag was already there, or the comment doesn't exist with that id... + return this.findById(id) + .then(result => { + if ( ! result) { + throw new Error(`Can't remove tag from comment. There is no comment with id ${id}`); + } + throw new Error(`Can't remove tag ${name} from comment. Comment doesn't have that tag.`); + }); + case 1: + + // tag removed + return; + default: + console.warn('CommentsService#removeTag modified multiple comments, but it should only have modified 1. ' + + `You may have bad data. Check for multiple comments with id=${id}`); } }); } diff --git a/test/services/comments.js b/test/services/comments.js index 525b70c06..782c00560 100644 --- a/test/services/comments.js +++ b/test/services/comments.js @@ -251,15 +251,29 @@ describe('services.CommentsService', () => { }); describe('#removeTag', () => { - it.skip('removes a tag', async () => { + it('removes a tag', async () => { const commentId = comments[0].id; const tagName = 'BEST'; await CommentsService.addTag(commentId, tagName, users[0].id); - let updatedComment = await CommentsService.findById(commentId); + const updatedComment = await CommentsService.findById(commentId); expect(updatedComment.tags.length).to.equal(1); // ok now to remove it await CommentsService.removeTag(commentId, tagName); + const updatedComment2 = await CommentsService.findById(commentId); + expect(updatedComment2.tags.length).to.equal(0); + }); + it('throws if removing a tag that isn\'t there', async () => { + const commentId = comments[0].id; + + // just make sure it has no tags to start + const updatedComment2 = await CommentsService.findById(commentId); + expect(updatedComment2.tags.length).to.equal(0); + + const tagName = 'BEST'; + + // ok now to remove it + await expect(CommentsService.removeTag(commentId, tagName)).to.be.rejected; }); });