Adds Tag Model that will be apply to different models.

This commit is contained in:
gaba
2017-04-18 14:03:26 -07:00
parent fa944927e4
commit 1137fca3b4
8 changed files with 162 additions and 78 deletions
View File
-22
View File
@@ -30,27 +30,6 @@ const StatusSchema = new Schema({
_id: false
});
/**
* The Mongo schema for a Comment Tag.
* @type {Schema}
*/
const TagSchema = new Schema({
name: String,
// The User ID of the user that assigned the status.
assigned_by: {
type: String,
default: null
},
created_at: {
type: Date,
default: Date
}
}, {
_id: false
});
/**
* The Mongo schema for a Comment.
* @type {Schema}
@@ -74,7 +53,6 @@ const CommentSchema = new Schema({
enum: STATUSES,
default: 'NONE'
},
tags: [TagSchema],
parent_id: String,
// Additional metadata stored on the field.
+64
View File
@@ -0,0 +1,64 @@
const mongoose = require('../services/mongoose');
const uuid = require('uuid');
const Schema = mongoose.Schema;
// in settings
// --> decide who can apply them (self, role, anyone) and
// Who can see the tag (self, by role, anyone)
const PRIVACY_TYPES = [
'ADMIN',
'SELF',
'PUBLIC'
];
// The type of item that the tag is apply on.
const ITEM_TYPES = [
'ASSETS',
'COMMENTS',
'USERS'
];
/**
* The Mongo schema for a Comment Tag.
* @type {Schema}
*/
const TagSchema = new Schema({
id: {
type: String,
default: uuid.v4,
unique: true
},
name: {
type: String,
unique: true
},
item_type: {
type: String,
enum: ITEM_TYPES
},
item_id: String,
// The User ID of the user that assigned the status.
assigned_by: {
type: String,
default: null
},
privacy_type: {
type: String,
enum: PRIVACY_TYPES
},
// Additional metadata stored on the field.
metadata: Schema.Types.Mixed
}, {
_id: false
});
const Tag = mongoose.model('Tag', TagSchema);
module.exports = Tag;
+4 -2
View File
@@ -185,7 +185,9 @@ const USER_GRAPH_OPERATIONS = [
'mutation:suspendUser',
'mutation:setCommentStatus',
'mutation:addCommentTag',
'mutation:removeCommentTag'
'mutation:removeCommentTag',
'mutation:addUserTag',
'mutation:removeUserTag'
];
/**
@@ -207,7 +209,7 @@ UserSchema.method('can', function(...actions) {
// {add,remove}CommentTag - requires admin and/or moderator role
const userCanModifyTags = user => ['ADMIN', 'MODERATOR'].some(r => user.hasRoles(r));
if (actions.some(a => ['mutation:removeCommentTag', 'mutation:addCommentTag'].includes(a)) && ! userCanModifyTags(this)) {
if (actions.some(a => ['mutation:removeCommentTag', 'mutation:addCommentTag', 'mutation:removeUserTag', 'mutation: addUserTag'].includes(a)) && ! userCanModifyTags(this)) {
return false;
}
+14 -53
View File
@@ -3,10 +3,8 @@ const CommentModel = require('../models/comment');
const ActionModel = require('../models/action');
const ActionsService = require('./actions');
const ALLOWED_TAGS = [
{name: 'STAFF'},
{name: 'BEST'},
];
const TagModel = require('../models/tag');
const TagsService = require('./tags');
const STATUSES = [
'ACCEPTED',
@@ -53,37 +51,14 @@ module.exports = class CommentsService {
*/
static addTag(id, name, assigned_by) {
if (ALLOWED_TAGS.find((t) => t.name === name) == null) {
return Promise.reject(new Error('tag not allowed'));
}
return TagsService.insertCommentTag({
name,
item_id: id,
item_type: 'COMMENTS',
user_id: assigned_by,
});
const filter = {
id,
'tags.name': {$ne: name},
};
const update = {
$push: {tags: {
name,
assigned_by,
created_at: new Date()
}}
};
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...
throw new Error('Could not add tag to comment. Either the comment doesn\'t exist or the tag is already present.');
case 1:
// tag added
return;
default:
// this should never happen because no multi parameter and unique index on id
}
});
// Add the ID to the comment
}
/**
@@ -93,25 +68,11 @@ module.exports = class CommentsService {
* @param {String} name the name of the tag to add
*/
static removeTag(id, name) {
const filter = {
id,
'tags.name': name,
};
const update = {$pull: {tags: {name}}};
return CommentModel.update(filter, update)
.then(({nModified}) => {
switch (nModified) {
case 0:
throw new Error('Could not remove tag from comment. Either the comment doesn\'t exist or the tag is not present');
case 1:
// tag removed
return;
default:
// this should never happen because no multi parameter and unique index on id
}
});
return TagModel.remove({
item_type: 'COMMENTS',
item_id: id,
name
});
}
/**
+1
View File
@@ -65,4 +65,5 @@ require('../models/action');
require('../models/asset');
require('../models/comment');
require('../models/setting');
require('../models/tag');
require('../models/user');
+72
View File
@@ -0,0 +1,72 @@
const TagModel = require('../models/tag');
const ALLOWED_COMMENT_TAGS = [
{name: 'STAFF'},
{name: 'BEST'},
];
module.exports = class TagsService {
/**
* Finds an action by the id.
* @param {String} id identifier of the tag (uuid)
*/
static findById(id) {
return TagModel.findOne({id});
}
/**
* Add a tag.
* @param {string} name the actual tag
* @param {String} item_id identifier of the comment (uuid)
* @param {String} item_type type of the object being tag (COMMENTS)
* @param {String} user_id user id that assigned the tag (uuid)
* @param {String} privacy_type visibility of the tag on the comment
* @return {Promise}
*/
static insertCommentTag(tag) {
if (ALLOWED_COMMENT_TAGS.find((t) => t.name === tag.name) == null) {
return Promise.reject(new Error('tag not allowed'));
}
// Tags are made unique by using a query that can be reproducable, i.e.,
// not containing user inputable values.
let query = {
name: tag.name,
item_id: tag.item_id,
item_type: tag.item_type,
assigned_by: tag.user_id,
privacy_type: tag.privacy_type
};
// Create/Update the tag.
return TagModel.findOneAndUpdate(query, tag, {
// Ensure that if it's new, we return the new object created.
new: true,
// Perform an upsert in the event that this doesn't exist.
upsert: true,
// Set the default values if not provided based on the mongoose models.
setDefaultsOnInsert: true
})
.then(({nModified}) => {
switch (nModified) {
case 0:
// either the tag was already there, or the comment doesn't exist with that id...
throw new Error('Could not add tag to comment. Either the comment doesn\'t exist or the tag is already present.');
case 1:
// tag added
return;
default:
// this should never happen because no multi parameter and unique index on id
}
});
}
};
+7 -1
View File
@@ -4,6 +4,7 @@ const {graphql} = require('graphql');
const schema = require('../../../../graph/schema');
const Context = require('../../../../graph/context');
const UserModel = require('../../../../models/user');
const TagModel = require('../../../../models/tag');
const SettingsService = require('../../../../services/settings');
const CommentsService = require('../../../../services/comments');
@@ -37,7 +38,12 @@ describe('graph.mutations.addCommentTag', () => {
console.error(response.errors);
}
expect(response.errors).to.be.empty;
expect(response.data.addCommentTag.comment.tags).to.deep.equal([{name: 'BEST'}]);
TagModel.find({
item_id: response.data.addCommentTag.comment.id,
name: 'BEST'
}).then((tags) => {
expect(tags).to.have.length(1);
});
});
describe('users who cant add tags', () => {