mirror of
https://github.com/wassname/talk.git
synced 2026-07-11 13:48:53 +08:00
Added status changing + history
- Status's for comments is now an array of objects
This commit is contained in:
@@ -95,6 +95,10 @@ function startApp() {
|
||||
server.listen(port);
|
||||
server.on('error', onError);
|
||||
server.on('listening', onListening);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
util.shutdown(1);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,21 @@ cache.get = (key) => new Promise((resolve, reject) => {
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* This invalidates a cached entry in the cache.
|
||||
* @param {Mixed} key Either an array of items composing a key or a string
|
||||
* @return {Promise}
|
||||
*/
|
||||
cache.invalidate = (key) => new Promise((resolve, reject) => {
|
||||
cache.client.del(keyfunc(key), (err) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* This sets a value on the key with the expiry and then resolves once it is
|
||||
* done.
|
||||
|
||||
+21
-5
@@ -1,6 +1,8 @@
|
||||
const mongoose = require('../mongoose');
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
const Setting = require('./setting');
|
||||
|
||||
const uuid = require('uuid');
|
||||
|
||||
const AssetSchema = new Schema({
|
||||
@@ -54,11 +56,6 @@ AssetSchema.index({
|
||||
background: true
|
||||
});
|
||||
|
||||
/**
|
||||
* Search for assets. Currently only returns all.
|
||||
*/
|
||||
AssetSchema.statics.search = (query) => Asset.find(query);
|
||||
|
||||
/**
|
||||
* Finds an asset by its id.
|
||||
* @param {String} id identifier of the asset (uuid).
|
||||
@@ -71,6 +68,25 @@ AssetSchema.statics.findById = (id) => Asset.findOne({id});
|
||||
*/
|
||||
AssetSchema.statics.findByUrl = (url) => Asset.findOne({url});
|
||||
|
||||
/**
|
||||
* Retrieves the settings given an asset query and rectifies it against the
|
||||
* global settings.
|
||||
* @param {Promise} assetQuery an asset query that returns a single asset.
|
||||
* @return {Promise}
|
||||
*/
|
||||
AssetSchema.statics.rectifySettings = (assetQuery) => Promise.all([
|
||||
Setting.retrieve(),
|
||||
assetQuery
|
||||
]).then(([settings, asset]) => {
|
||||
|
||||
// If the asset exists and has settings then return the merged object.
|
||||
if (asset && asset.settings) {
|
||||
return Object.assign({}, settings, asset.settings);
|
||||
}
|
||||
|
||||
return settings;
|
||||
});
|
||||
|
||||
/**
|
||||
* Finds a asset by its url.
|
||||
*
|
||||
|
||||
+191
-89
@@ -1,9 +1,30 @@
|
||||
const mongoose = require('../mongoose');
|
||||
const Schema = mongoose.Schema;
|
||||
const uuid = require('uuid');
|
||||
const Action = require('./action');
|
||||
|
||||
const Schema = mongoose.Schema;
|
||||
/**
|
||||
* The Mongo schema for a Comment Status.
|
||||
* @type {Schema}
|
||||
*/
|
||||
const StatusSchema = new Schema({
|
||||
type: {
|
||||
type: String,
|
||||
enum: [
|
||||
'accepted',
|
||||
'rejected',
|
||||
'premod',
|
||||
],
|
||||
},
|
||||
created_at: Date
|
||||
}, {
|
||||
_id: false
|
||||
});
|
||||
|
||||
/**
|
||||
* The Mongo schema for a Comment.
|
||||
* @type {Schema}
|
||||
*/
|
||||
const CommentSchema = new Schema({
|
||||
id: {
|
||||
type: String,
|
||||
@@ -17,11 +38,7 @@ const CommentSchema = new Schema({
|
||||
},
|
||||
asset_id: String,
|
||||
author_id: String,
|
||||
status: {
|
||||
type: String,
|
||||
enum: ['accepted', 'rejected', ''],
|
||||
default: ''
|
||||
},
|
||||
status: [StatusSchema],
|
||||
parent_id: String
|
||||
}, {
|
||||
timestamps: {
|
||||
@@ -30,90 +47,168 @@ const CommentSchema = new Schema({
|
||||
}
|
||||
});
|
||||
|
||||
//==============================================================================
|
||||
// Find Statics
|
||||
//==============================================================================
|
||||
/**
|
||||
* toJSON overrides to remove fields from the json
|
||||
* output.
|
||||
*/
|
||||
CommentSchema.options.toJSON = {};
|
||||
CommentSchema.options.toJSON.hide = '_id status';
|
||||
CommentSchema.options.toJSON.transform = (doc, ret, options) => {
|
||||
if (options.hide) {
|
||||
options.hide.split(' ').forEach((prop) => {
|
||||
delete ret[prop];
|
||||
});
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* toJSON overrides to remove fields from the json
|
||||
* output.
|
||||
*/
|
||||
CommentSchema.options.toJSON = {};
|
||||
CommentSchema.options.toJSON.hide = '_id';
|
||||
CommentSchema.options.toJSON.transform = (doc, ret, options) => {
|
||||
if (options.hide) {
|
||||
options.hide.split(' ').forEach((prop) => {
|
||||
delete ret[prop];
|
||||
});
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets up a virtual getter function on a comment such that when you try and
|
||||
* access the `comment.last_status` it returns the last status in the array
|
||||
* of status's on the comment, or `null` if there was no status.
|
||||
*/
|
||||
CommentSchema.virtual('last_status').get(function() {
|
||||
if (this.status && this.status.length > 0) {
|
||||
return this.status[this.status.length - 1].type;
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
/**
|
||||
* Creates a new Comment that came from a public source.
|
||||
* @param {Mixed} comment either a single comment or an array of comments.
|
||||
* @return {Promise}
|
||||
*/
|
||||
CommentSchema.statics.publicCreate = (comment) => {
|
||||
|
||||
// Check to see if this is an array of comments, if so map it out.
|
||||
if (Array.isArray(comment)) {
|
||||
return Promise.all(comment.map(Comment.publicCreate));
|
||||
}
|
||||
|
||||
const {
|
||||
body,
|
||||
asset_id,
|
||||
parent_id,
|
||||
status = false,
|
||||
author_id
|
||||
} = comment;
|
||||
|
||||
comment = new Comment({
|
||||
body,
|
||||
asset_id,
|
||||
parent_id,
|
||||
status: status ? [{
|
||||
type: status,
|
||||
created_at: new Date()
|
||||
}] : [],
|
||||
author_id
|
||||
});
|
||||
|
||||
return comment.save();
|
||||
};
|
||||
|
||||
/**
|
||||
* Finds a comment by the id.
|
||||
* @param {String} id identifier of comment (uuid)
|
||||
* @return {Promise}
|
||||
*/
|
||||
CommentSchema.statics.findById = function(id) {
|
||||
return Comment.findOne({'id': id});
|
||||
};
|
||||
CommentSchema.statics.findById = (id) => Comment.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}
|
||||
*/
|
||||
CommentSchema.statics.findByAssetId = function(asset_id) {
|
||||
return Comment.find({asset_id});
|
||||
};
|
||||
CommentSchema.statics.findByAssetId = (asset_id) => Comment.find({
|
||||
asset_id
|
||||
});
|
||||
|
||||
/**
|
||||
* Finds the accepted comments by the asset_id.
|
||||
* get the comments that are accepted.
|
||||
* Finds the accepted comments by the asset_id get the comments that are
|
||||
* accepted.
|
||||
* @param {String} asset_id identifier of the asset which owns the comments (uuid)
|
||||
* @return {Promise}
|
||||
*/
|
||||
CommentSchema.statics.findAcceptedByAssetId = function(asset_id) {
|
||||
return Comment.find({asset_id: asset_id, status:'accepted'});
|
||||
};
|
||||
CommentSchema.statics.findAcceptedByAssetId = (asset_id) => Comment.find({
|
||||
asset_id,
|
||||
'status.type': 'accepted'
|
||||
});
|
||||
|
||||
/**
|
||||
* Finds the new and accepted comments by the asset_id.
|
||||
* @param {String} asset_id identifier of the asset which owns the comments (uuid)
|
||||
* @return {Promise}
|
||||
*/
|
||||
CommentSchema.statics.findAcceptedAndNewByAssetId = function(asset_id) {
|
||||
return Comment.find({asset_id: asset_id, status: {'$in': ['accepted', '']}});
|
||||
};
|
||||
CommentSchema.statics.findAcceptedAndNewByAssetId = (asset_id) => Comment.find({
|
||||
asset_id,
|
||||
$or: [
|
||||
{
|
||||
'status.type': 'accepted'
|
||||
},
|
||||
{
|
||||
status: {
|
||||
$size: 0
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
/**
|
||||
* 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}
|
||||
*/
|
||||
CommentSchema.statics.findByActionType = function(action_type) {
|
||||
return Action
|
||||
.findCommentsIdByActionType(action_type, 'comment')
|
||||
.then((actions) => {
|
||||
return Comment.find({'id': {'$in': actions.map(function(a){
|
||||
return a.item_id;})}
|
||||
});
|
||||
});
|
||||
};
|
||||
CommentSchema.statics.findByActionType = (action_type) => Action
|
||||
.findCommentsIdByActionType(action_type, 'comment')
|
||||
.then((actions) => Comment.find({
|
||||
id: {
|
||||
$in: actions.map((a) => a.item_id)
|
||||
}
|
||||
}));
|
||||
|
||||
/**
|
||||
* Find not moderated comments by an action that was performed on them.
|
||||
* 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
|
||||
* @param {String} status the status of the comment to search for
|
||||
* @return {Promise}
|
||||
*/
|
||||
CommentSchema.statics.findByStatusByActionType = function(status, action_type) {
|
||||
return Action
|
||||
.findCommentsIdByActionType(action_type, 'comment')
|
||||
.then((actions) => {
|
||||
return Comment.find({
|
||||
status: status,
|
||||
id: {
|
||||
$in: actions.map(a => a.item_id)
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
CommentSchema.statics.findIdsByActionType = (action_type) => Action
|
||||
.findCommentsIdByActionType(action_type, 'comment')
|
||||
.then((actions) => actions.map(a => a.item_id));
|
||||
|
||||
/**
|
||||
* Find comments by their status.
|
||||
* @param {String} status the status of the comment to search for
|
||||
* @return {Promise}
|
||||
*/
|
||||
CommentSchema.statics.findByStatus = function(status) {
|
||||
return Comment.find({
|
||||
status: status === 'new' ? '' : status
|
||||
});
|
||||
CommentSchema.statics.findByStatus = (status = false) => {
|
||||
let q = {};
|
||||
|
||||
if (status) {
|
||||
q['status.type'] = status;
|
||||
} else {
|
||||
q.status = {$size: 0};
|
||||
}
|
||||
|
||||
return Comment.find(q);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -121,29 +216,41 @@ CommentSchema.statics.findByStatus = function(status) {
|
||||
* @param {String} moderationValue pre or post moderation setting. If it is undefined then look at the settings.
|
||||
* @return {Promise}
|
||||
*/
|
||||
CommentSchema.statics.moderationQueue = function(moderation) {
|
||||
switch(moderation){
|
||||
CommentSchema.statics.moderationQueue = (moderation, asset_id = false) => {
|
||||
|
||||
// Pre-moderation: New comments are shown in the moderator queues immediately.
|
||||
case 'pre':
|
||||
return Comment.findByStatus('').then((comments) => {
|
||||
return comments;
|
||||
});
|
||||
/**
|
||||
* This adds the asset_id requirement to the query if the asset_id is defined.
|
||||
*/
|
||||
const assetIDWrap = (query) => {
|
||||
if (asset_id) {
|
||||
query = query.where('asset_id', asset_id);
|
||||
}
|
||||
|
||||
// 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;
|
||||
});
|
||||
return query;
|
||||
};
|
||||
|
||||
default:
|
||||
return Promise.reject(Error('Moderation setting not found.'));
|
||||
// Decide on whether or not we need to load extended options for the
|
||||
// moderation based on the moderation options.
|
||||
let comments;
|
||||
|
||||
if (moderation === 'pre') {
|
||||
|
||||
// Pre-moderation: New comments are shown in the moderator queues immediately.
|
||||
comments = assetIDWrap(CommentSchema.statics.findByStatus('premod'));
|
||||
|
||||
} else {
|
||||
|
||||
// Post-moderation: New comments do not appear in moderation queues unless they are flagged by other users.
|
||||
comments = CommentSchema.statics.findIdsByActionType('flag')
|
||||
.then((ids) => assetIDWrap(Comment.find({
|
||||
id: {
|
||||
$in: ids
|
||||
}
|
||||
})));
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// Update Statics
|
||||
//==============================================================================
|
||||
return comments;
|
||||
};
|
||||
|
||||
/**
|
||||
* Change the status of a comment.
|
||||
@@ -151,9 +258,14 @@ CommentSchema.statics.moderationQueue = function(moderation) {
|
||||
* @param {String} status the new status of the comment
|
||||
* @return {Promise}
|
||||
*/
|
||||
CommentSchema.statics.changeStatus = function(id, status) {
|
||||
return Comment.findOneAndUpdate({'id': id}, {$set: {'status': status}});
|
||||
};
|
||||
CommentSchema.statics.changeStatus = (id, status) => Comment.findOneAndUpdate({id}, {
|
||||
$push: {
|
||||
status: {
|
||||
type: status,
|
||||
created_at: new Date()
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Add an action to the comment.
|
||||
@@ -169,19 +281,13 @@ CommentSchema.statics.addAction = (item_id, user_id, action_type) => Action.inse
|
||||
action_type
|
||||
});
|
||||
|
||||
//==============================================================================
|
||||
// Remove Statics
|
||||
//==============================================================================
|
||||
|
||||
/**
|
||||
* Change the status of a comment.
|
||||
* @param {String} id identifier of the comment (uuid)
|
||||
* @param {String} status the new status of the comment
|
||||
* @return {Promise}
|
||||
*/
|
||||
CommentSchema.statics.removeById = function(id) {
|
||||
return Comment.remove({'id': id});
|
||||
};
|
||||
CommentSchema.statics.removeById = (id) => Comment.remove({id});
|
||||
|
||||
/**
|
||||
* Remove an action from the comment.
|
||||
@@ -190,22 +296,18 @@ CommentSchema.statics.removeById = function(id) {
|
||||
* @param {String} user_id the id of the user performing the action
|
||||
* @return {Promise}
|
||||
*/
|
||||
CommentSchema.statics.removeAction = function(item_id, user_id, action_type) {
|
||||
return Action.remove({
|
||||
action_type,
|
||||
item_type: 'comment',
|
||||
item_id,
|
||||
user_id
|
||||
});
|
||||
};
|
||||
CommentSchema.statics.removeAction = (item_id, user_id, action_type) => Action.remove({
|
||||
action_type,
|
||||
item_type: 'comment',
|
||||
item_id,
|
||||
user_id
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns all the comments in the collection.
|
||||
* @return {Promise}
|
||||
*/
|
||||
CommentSchema.statics.all = () => {
|
||||
return Comment.find();
|
||||
};
|
||||
CommentSchema.statics.all = () => Comment.find();
|
||||
|
||||
// Comment model.
|
||||
const Comment = mongoose.model('Comment', CommentSchema);
|
||||
|
||||
+68
-40
@@ -1,18 +1,32 @@
|
||||
const mongoose = require('../mongoose');
|
||||
const Schema = mongoose.Schema;
|
||||
const cache = require('../cache');
|
||||
|
||||
/**
|
||||
* this Schema manages application settings that get used on front and backend
|
||||
* NOTE: when you set a setting here, it will not automatically be exposed to
|
||||
* the front end. You must add it to the whitelist in the settings route
|
||||
* in /routes/api/settings/index.js
|
||||
* SettingSchema manages application settings that get used on front and backend.
|
||||
* @type {Schema}
|
||||
*/
|
||||
const SettingSchema = new Schema({
|
||||
id: {type: String, default: '1'},
|
||||
moderation: {type: String, enum: ['pre', 'post'], default: 'pre'},
|
||||
infoBoxEnable: {type: Boolean, default: false},
|
||||
infoBoxContent: {type: String, default: ''},
|
||||
id: {
|
||||
type: String,
|
||||
default: '1'
|
||||
},
|
||||
moderation: {
|
||||
type: String,
|
||||
enum: [
|
||||
'pre',
|
||||
'post'
|
||||
],
|
||||
default: 'pre'
|
||||
},
|
||||
infoBoxEnable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
infoBoxContent: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
wordlist: [String]
|
||||
}, {
|
||||
timestamps: {
|
||||
@@ -22,48 +36,62 @@ const SettingSchema = new Schema({
|
||||
});
|
||||
|
||||
/**
|
||||
* this is run once when the app starts to ensure settings are populated
|
||||
* @return {Promise} null initialize the global settings object
|
||||
* The Mongo Mongoose object.
|
||||
*/
|
||||
SettingSchema.statics.init = function (defaults) {
|
||||
return this.update({id: '1'}, {$setOnInsert: defaults}, {upsert: true});
|
||||
};
|
||||
const Setting = mongoose.model('Setting', SettingSchema);
|
||||
|
||||
/**
|
||||
* The Setting Service object exposing the Setting model.
|
||||
* @type {Object}
|
||||
*/
|
||||
const SettingService = module.exports = {};
|
||||
|
||||
/**
|
||||
* The selector used to uniquely identify the settings document.
|
||||
*/
|
||||
const selector = {id: '1'};
|
||||
|
||||
/**
|
||||
* Cache expiry time in seconds for when the cached entry of the settings object
|
||||
* expires. 2 minutes.
|
||||
*/
|
||||
const EXPIRY_TIME = 60 * 2;
|
||||
|
||||
/**
|
||||
* Gets the entire settings record and sends it back
|
||||
* @return {Promise} settings the whole settings record
|
||||
*/
|
||||
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');
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the info box settings and sends it back
|
||||
* @return {Promise} content the content of the info Box
|
||||
*/
|
||||
SettingSchema.statics.getInfoBoxSetting = function () {
|
||||
return this.findOne({id: '1'}).select('infoBoxEnable', 'infoBoxContent');
|
||||
};
|
||||
SettingService.retrieve = () => cache.wrap('settings', EXPIRY_TIME, () => Setting.findOne(selector));
|
||||
|
||||
/**
|
||||
* This will update the settings object with whatever you pass in
|
||||
* @param {object} setting a hash of whatever settings you want to update
|
||||
* @return {Promise} settings Promise that resolves to the entire (updated) settings object.
|
||||
*/
|
||||
SettingSchema.statics.updateSettings = function (setting) {
|
||||
// There should only ever be one record unless something has gone wrong.
|
||||
// In the future we may have multiple records for custom settings for objects/users.
|
||||
return this.findOneAndUpdate({id: '1'}, {$set: setting}, {new: true});
|
||||
SettingService.update = (settings) => Setting.findOneAndUpdate(selector, {
|
||||
$set: settings
|
||||
}, {
|
||||
upsert: true,
|
||||
new: true,
|
||||
setDefaultsOnInsert: true
|
||||
}).then((settings) => {
|
||||
|
||||
// Invalidate the settings cache.
|
||||
return cache
|
||||
.set('settings', settings, EXPIRY_TIME)
|
||||
.then(() => settings);
|
||||
});
|
||||
|
||||
/**
|
||||
* This is run once when the app starts to ensure settings are populated.
|
||||
* @return {Promise} null initialize the global settings object
|
||||
*/
|
||||
SettingService.init = (defaults) => {
|
||||
|
||||
// Inject the defaults on top of the passed in defaults to ensure that the new
|
||||
// settings conform to the required selector.
|
||||
defaults = Object.assign({}, defaults, selector);
|
||||
|
||||
// Actually update the settings collection.
|
||||
return SettingService.update(defaults);
|
||||
};
|
||||
|
||||
const Setting = mongoose.model('Setting', SettingSchema);
|
||||
|
||||
module.exports = Setting;
|
||||
|
||||
+1
-2
@@ -9,7 +9,6 @@ const SALT_ROUNDS = 10;
|
||||
|
||||
// USER_ROLES is the array of roles that is permissible as a user role.
|
||||
const USER_ROLES = [
|
||||
'',
|
||||
'admin',
|
||||
'moderator'
|
||||
];
|
||||
@@ -98,7 +97,7 @@ UserSchema.index({
|
||||
* output.
|
||||
*/
|
||||
UserSchema.options.toJSON = {};
|
||||
UserSchema.options.toJSON.hide = 'password profiles roles disabled';
|
||||
UserSchema.options.toJSON.hide = '_id password profiles roles disabled';
|
||||
UserSchema.options.toJSON.transform = (doc, ret, options) => {
|
||||
if (options.hide) {
|
||||
options.hide.split(' ').forEach((prop) => {
|
||||
|
||||
@@ -97,6 +97,7 @@
|
||||
"eslint-config-standard": "^6.2.1",
|
||||
"eslint-plugin-flowtype": "^2.25.0",
|
||||
"eslint-plugin-import": "^2.2.0",
|
||||
"eslint-plugin-mocha": "^4.7.0",
|
||||
"eslint-plugin-promise": "^3.3.1",
|
||||
"eslint-plugin-react": "^6.6.0",
|
||||
"eslint-plugin-standard": "^2.0.1",
|
||||
|
||||
@@ -1,27 +1,53 @@
|
||||
const express = require('express');
|
||||
const Comment = require('../../../models/comment');
|
||||
const Asset = require('../../../models/asset');
|
||||
const wordlist = require('../../../services/wordlist');
|
||||
const authorization = require('../../../middleware/authorization');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', authorization.needed('admin'), (req, res, next) => {
|
||||
|
||||
const {
|
||||
status = null,
|
||||
action_type = null,
|
||||
asset_id = null
|
||||
} = req.query;
|
||||
|
||||
/**
|
||||
* This adds the asset_id requirement to the query if the asset_id is defined.
|
||||
*/
|
||||
const assetIDWrap = (query) => {
|
||||
if (asset_id) {
|
||||
query = query.where('asset_id', asset_id);
|
||||
}
|
||||
|
||||
return query;
|
||||
};
|
||||
|
||||
let query;
|
||||
|
||||
if (req.query.status) {
|
||||
query = Comment.findByStatus(req.query.status);
|
||||
} else if (req.query.action_type) {
|
||||
query = Comment.findByActionType(req.query.action_type);
|
||||
if (status) {
|
||||
query = assetIDWrap(Comment.findByStatus(status === 'new' ? null : status));
|
||||
} else if (action_type) {
|
||||
query = Comment
|
||||
.findIdsByActionType(action_type)
|
||||
.then((ids) => assetIDWrap(Comment.find({
|
||||
id: {
|
||||
$in: ids
|
||||
},
|
||||
})));
|
||||
} else {
|
||||
query = Comment.all();
|
||||
query = assetIDWrap(Comment.all());
|
||||
}
|
||||
|
||||
query.then(comments => {
|
||||
res.json(comments);
|
||||
})
|
||||
.catch((err) => {
|
||||
next(err);
|
||||
});
|
||||
query
|
||||
.then(comments => {
|
||||
res.json(comments);
|
||||
})
|
||||
.catch((err) => {
|
||||
next(err);
|
||||
});
|
||||
});
|
||||
|
||||
router.post('/', wordlist.filter('body'), (req, res, next) => {
|
||||
@@ -32,21 +58,38 @@ router.post('/', wordlist.filter('body'), (req, res, next) => {
|
||||
parent_id
|
||||
} = req.body;
|
||||
|
||||
Comment
|
||||
.create({
|
||||
body,
|
||||
asset_id,
|
||||
parent_id,
|
||||
status: req.wordlist.matched ? 'rejected' : '',
|
||||
author_id: req.user.id
|
||||
})
|
||||
.then((comment) => {
|
||||
// Decide the status based on whether or not the current asset/settings
|
||||
// has pre-mod enabled or not. If the comment was rejected based on the
|
||||
// wordlist, then reject it, otherwise if the moderation setting is
|
||||
// premod, set it to `premod`.
|
||||
let status;
|
||||
|
||||
res.status(201).send(comment);
|
||||
})
|
||||
.catch((err) => {
|
||||
next(err);
|
||||
});
|
||||
if (req.wordlist.matched) {
|
||||
status = Promise.resolve('rejected');
|
||||
} else {
|
||||
status = Asset
|
||||
.rectifySettings(Asset.findById(asset_id))
|
||||
|
||||
// Return `premod` if pre-moderation is enabled and an empty "new" status
|
||||
// in the event that it is not in pre-moderation mode.
|
||||
.then(({moderation}) => moderation === 'pre' ? 'premod' : '');
|
||||
}
|
||||
|
||||
status.then((status) => Comment.publicCreate({
|
||||
body,
|
||||
asset_id,
|
||||
parent_id,
|
||||
status,
|
||||
author_id: req.user.id
|
||||
}))
|
||||
.then((comment) => {
|
||||
|
||||
// The comment was created! Send back the created comment.
|
||||
res.status(201).send(comment);
|
||||
})
|
||||
.catch((err) => {
|
||||
next(err);
|
||||
});
|
||||
});
|
||||
|
||||
router.get('/:comment_id', authorization.needed('admin'), (req, res, next) => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
const express = require('express');
|
||||
const Comment = require('../../../models/comment');
|
||||
const Setting = require('../../../models/setting');
|
||||
const Asset = require('../../../models/asset');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
@@ -13,14 +14,39 @@ const router = express.Router();
|
||||
// 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('/comments/pending', (req, res, next) => {
|
||||
Setting.getModerationSetting().then(function({moderation}){
|
||||
Comment.moderationQueue(moderation).then((comments) => {
|
||||
res.status(200).json(comments);
|
||||
|
||||
const {
|
||||
asset_id
|
||||
} = req.query;
|
||||
|
||||
let settings = Setting.retrieve();
|
||||
|
||||
if (asset_id) {
|
||||
|
||||
// In the event that we have an asset_id, we should fetch the asset settings
|
||||
// in order to actually determine if there is additional comments to parse.
|
||||
settings = Promise.all([
|
||||
settings,
|
||||
Asset.findById(asset_id).select('settings')
|
||||
]).then(([{moderation}, asset]) => {
|
||||
if (asset.settings && asset.settings.moderation) {
|
||||
return {moderation: asset.settings.moderation};
|
||||
}
|
||||
|
||||
return {moderation};
|
||||
});
|
||||
}
|
||||
|
||||
settings
|
||||
.then(({moderation}) => {
|
||||
return Comment.moderationQueue(moderation);
|
||||
}).then((comments) => {
|
||||
|
||||
res.json(comments);
|
||||
})
|
||||
.catch(error => {
|
||||
next(error);
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
next(error);
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
@@ -4,19 +4,21 @@ const Setting = require('../../../models/setting');
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', (req, res, next) => {
|
||||
Setting
|
||||
.getSettings()
|
||||
.then(settings => {
|
||||
res.json(settings);
|
||||
})
|
||||
.catch(next);
|
||||
Setting.retrieve().then((settings) => {
|
||||
res.json(settings);
|
||||
})
|
||||
.catch((err) => {
|
||||
next(err);
|
||||
});
|
||||
});
|
||||
|
||||
router.put('/', (req, res, next) => {
|
||||
Setting
|
||||
.updateSettings(req.body)
|
||||
.then(() => res.status(204).end())
|
||||
.catch(next);
|
||||
Setting.update(req.body).then(() => {
|
||||
res.status(204).end();
|
||||
})
|
||||
.catch((err) => {
|
||||
next(err);
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
@@ -27,7 +27,7 @@ router.get('/', (req, res, next) => {
|
||||
}),
|
||||
|
||||
// Get the moderation setting from the settings.
|
||||
Setting.getModerationSetting()
|
||||
Setting.retrieve()
|
||||
])
|
||||
.then(([asset, settings]) => {
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ const wordlist = {
|
||||
*/
|
||||
wordlist.init = () => {
|
||||
return Setting
|
||||
.getSettings()
|
||||
.retrieve()
|
||||
.then((settings) => {
|
||||
|
||||
// Insert the settings wordlist.
|
||||
|
||||
@@ -4,8 +4,12 @@
|
||||
"node": true,
|
||||
"mocha": true
|
||||
},
|
||||
"plugins": [
|
||||
"mocha"
|
||||
],
|
||||
"extends": "../.eslintrc.json",
|
||||
"rules": {
|
||||
"no-undef": [0]
|
||||
"no-undef": [0],
|
||||
"mocha/no-exclusive-tests": "warn"
|
||||
}
|
||||
}
|
||||
|
||||
+23
-24
@@ -1,35 +1,34 @@
|
||||
const Action = require('../../models/action');
|
||||
const expect = require('chai').expect;
|
||||
|
||||
describe('Action: models', () => {
|
||||
let mockActions;
|
||||
describe('models.Action', () => {
|
||||
let mockActions = [];
|
||||
|
||||
beforeEach(() => {
|
||||
return Action.create([{
|
||||
action_type: 'flag',
|
||||
item_id: '123',
|
||||
item_type: 'comment',
|
||||
user_id: 'flagginguserid'
|
||||
}, {
|
||||
action_type: 'flag',
|
||||
item_id: '456',
|
||||
item_type: 'comment'
|
||||
}, {
|
||||
action_type: 'flag',
|
||||
item_id: '123',
|
||||
item_type: 'comment'
|
||||
}, {
|
||||
action_type: 'like',
|
||||
item_id: '123',
|
||||
item_type: 'comment'
|
||||
}]).then((actions) => {
|
||||
mockActions = actions;
|
||||
});
|
||||
});
|
||||
beforeEach(() => Action.create([{
|
||||
action_type: 'flag',
|
||||
item_id: '123',
|
||||
item_type: 'comment',
|
||||
user_id: 'flagginguserid'
|
||||
}, {
|
||||
action_type: 'flag',
|
||||
item_id: '456',
|
||||
item_type: 'comment'
|
||||
}, {
|
||||
action_type: 'flag',
|
||||
item_id: '123',
|
||||
item_type: 'comment'
|
||||
}, {
|
||||
action_type: 'like',
|
||||
item_id: '123',
|
||||
item_type: 'comment'
|
||||
}]).then((actions) => {
|
||||
mockActions = actions;
|
||||
}));
|
||||
|
||||
describe('#findById()', () => {
|
||||
it('should find an action by id', () => {
|
||||
return Action.findById(mockActions[0].id).then((result) => {
|
||||
expect(result).to.not.be.null;
|
||||
expect(result).to.have.property('action_type', 'flag');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,7 +6,7 @@ const expect = chai.expect;
|
||||
// Use the chai should.
|
||||
chai.should();
|
||||
|
||||
describe('Asset: model', () => {
|
||||
describe('models.Asset', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
const defaults = {url:'http://test.com'};
|
||||
|
||||
+122
-23
@@ -7,35 +7,57 @@ const settings = {id: '1', moderation: 'pre'};
|
||||
|
||||
const expect = require('chai').expect;
|
||||
|
||||
describe('Comment: models', () => {
|
||||
describe('models.Comment', () => {
|
||||
const comments = [{
|
||||
body: 'comment 10',
|
||||
asset_id: '123',
|
||||
status: '',
|
||||
status: [],
|
||||
parent_id: '',
|
||||
author_id: '123',
|
||||
id: '1'
|
||||
}, {
|
||||
body: 'comment 20',
|
||||
asset_id: '123',
|
||||
status: 'accepted',
|
||||
status: [{
|
||||
type: 'accepted'
|
||||
}],
|
||||
parent_id: '',
|
||||
author_id: '123',
|
||||
id: '2'
|
||||
}, {
|
||||
body: 'comment 30',
|
||||
asset_id: '456',
|
||||
status: '',
|
||||
status: [],
|
||||
parent_id: '',
|
||||
author_id: '456',
|
||||
id: '3'
|
||||
}, {
|
||||
body: 'comment 40',
|
||||
asset_id: '123',
|
||||
status: 'rejected',
|
||||
status: [{
|
||||
type: 'rejected'
|
||||
}],
|
||||
parent_id: '',
|
||||
author_id: '456',
|
||||
id: '4'
|
||||
}, {
|
||||
body: 'comment 50',
|
||||
asset_id: '1234',
|
||||
status: [{
|
||||
type: 'premod'
|
||||
}],
|
||||
parent_id: '',
|
||||
author_id: '456',
|
||||
id: '5'
|
||||
}, {
|
||||
body: 'comment 60',
|
||||
asset_id: '1234',
|
||||
status: [{
|
||||
type: 'premod'
|
||||
}],
|
||||
parent_id: '',
|
||||
author_id: '456',
|
||||
id: '6'
|
||||
}];
|
||||
|
||||
const users = [{
|
||||
@@ -60,25 +82,69 @@ describe('Comment: models', () => {
|
||||
user_id: '456'
|
||||
}];
|
||||
|
||||
beforeEach(() => {
|
||||
return Promise.all([
|
||||
Setting.create(settings),
|
||||
Comment.create(comments),
|
||||
User.createLocalUsers(users),
|
||||
Action.create(actions)
|
||||
]);
|
||||
beforeEach(() => Promise.all([
|
||||
Setting.init(settings),
|
||||
Comment.create(comments),
|
||||
User.createLocalUsers(users),
|
||||
Action.create(actions)
|
||||
]));
|
||||
|
||||
describe('#publicCreate()', () => {
|
||||
|
||||
it('creates a new comment', () => {
|
||||
return Comment.publicCreate({
|
||||
body: 'This is a comment!',
|
||||
status: 'accepted'
|
||||
}).then((c) => {
|
||||
expect(c).to.not.be.null;
|
||||
expect(c.id).to.not.be.null;
|
||||
expect(c.id).to.be.uuid;
|
||||
expect(c.status).to.have.length(1);
|
||||
expect(c.status[0]).to.have.property('type', 'accepted');
|
||||
});
|
||||
});
|
||||
|
||||
it('creates many new comments', () => {
|
||||
return Comment.publicCreate([{
|
||||
body: 'This is a comment!',
|
||||
status: 'accepted'
|
||||
}, {
|
||||
body: 'This is another comment!'
|
||||
}, {
|
||||
body: 'This is a rejected comment!',
|
||||
status: 'rejected'
|
||||
}]).then(([c1, c2, c3]) => {
|
||||
expect(c1).to.not.be.null;
|
||||
expect(c1.id).to.be.uuid;
|
||||
expect(c1.status).to.have.length(1);
|
||||
expect(c1.status[0]).to.have.property('type', 'accepted');
|
||||
|
||||
expect(c2).to.not.be.null;
|
||||
expect(c2.id).to.be.uuid;
|
||||
expect(c2.status).to.have.length(0);
|
||||
|
||||
expect(c3).to.not.be.null;
|
||||
expect(c3.id).to.be.uuid;
|
||||
expect(c3.status).to.have.length(1);
|
||||
expect(c3.status[0]).to.have.property('type', 'rejected');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#findById()', () => {
|
||||
|
||||
it('should find a comment by id', () => {
|
||||
return Comment.findById('1').then((result) => {
|
||||
expect(result).to.not.be.null;
|
||||
expect(result).to.have.property('body', 'comment 10');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#findByAssetId()', () => {
|
||||
|
||||
it('should find an array of all comments by asset id', () => {
|
||||
return Comment.findByAssetId('123').then((result) => {
|
||||
expect(result).to.have.length(3);
|
||||
@@ -91,6 +157,7 @@ describe('Comment: models', () => {
|
||||
expect(result[2]).to.have.property('body', 'comment 40');
|
||||
});
|
||||
});
|
||||
|
||||
it('should find an array of accepted comments by asset id', () => {
|
||||
return Comment.findAcceptedByAssetId('123').then((result) => {
|
||||
expect(result).to.have.length(1);
|
||||
@@ -101,6 +168,7 @@ describe('Comment: models', () => {
|
||||
expect(result[0]).to.have.property('body', 'comment 20');
|
||||
});
|
||||
});
|
||||
|
||||
it('should find an array of new and accepted comments by asset id', () => {
|
||||
return Comment.findAcceptedAndNewByAssetId('123').then((result) => {
|
||||
expect(result).to.have.length(2);
|
||||
@@ -112,13 +180,16 @@ describe('Comment: models', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#moderationQueue()', () => {
|
||||
|
||||
it('should find an array of new comments to moderate when pre-moderation', () => {
|
||||
return Comment.moderationQueue('pre').then((result) => {
|
||||
expect(result).to.not.be.null;
|
||||
expect(result).to.have.lengthOf(2);
|
||||
});
|
||||
});
|
||||
|
||||
it('should find an array of new comments to moderate when post-moderation', () => {
|
||||
return Comment.moderationQueue('post').then((result) => {
|
||||
expect(result).to.not.be.null;
|
||||
@@ -126,21 +197,49 @@ describe('Comment: models', () => {
|
||||
expect(result[0]).to.have.property('body', 'comment 30');
|
||||
});
|
||||
});
|
||||
// it('should fail when the moderation is not pre or post', () => {
|
||||
// return Comment.moderationQueue('any').catch(function(error) {
|
||||
// expect(error).to.not.be.null;
|
||||
// });
|
||||
// });
|
||||
|
||||
});
|
||||
|
||||
describe('#removeAction', () => {
|
||||
|
||||
it('should remove an action', () => {
|
||||
return Comment.removeAction('3', '123', 'flag').then(() => {
|
||||
return Action.findByItemIdArray(['123']);
|
||||
})
|
||||
.then((actions) => {
|
||||
expect(actions.length).to.equal(0);
|
||||
});
|
||||
return Comment.removeAction('3', '123', 'flag')
|
||||
.then(() => {
|
||||
return Action.findByItemIdArray(['123']);
|
||||
})
|
||||
.then((actions) => {
|
||||
expect(actions.length).to.equal(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#changeStatus', () => {
|
||||
|
||||
it('should change the status of a comment from no status', () => {
|
||||
return Comment.changeStatus(comments[0].id, 'rejected')
|
||||
.then(() => {
|
||||
|
||||
return Comment.findById(comments[0].id);
|
||||
})
|
||||
.then((c) => {
|
||||
expect(c).to.have.property('status');
|
||||
expect(c.status).to.have.length(1);
|
||||
expect(c.status[0]).to.have.property('type', 'rejected');
|
||||
});
|
||||
});
|
||||
|
||||
it('should change the status of a comment from accepted', () => {
|
||||
return Comment.changeStatus(comments[1].id, 'rejected')
|
||||
.then(() => {
|
||||
|
||||
return Comment.findById(comments[1].id);
|
||||
})
|
||||
.then((c) => {
|
||||
expect(c).to.have.property('status');
|
||||
expect(c.status).to.have.length(2);
|
||||
expect(c.status[1]).to.have.property('type', 'rejected');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
+9
-12
@@ -1,32 +1,29 @@
|
||||
const Setting = require('../../models/setting');
|
||||
const expect = require('chai').expect;
|
||||
|
||||
describe('Setting: model', () => {
|
||||
describe('models.Setting', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
const defaults = {id: 1};
|
||||
return Setting.update({id: '1'}, {$setOnInsert: defaults}, {upsert: true});
|
||||
});
|
||||
beforeEach(() => Setting.init({moderation: 'pre'}));
|
||||
|
||||
describe('#getSettings()', () => {
|
||||
describe('#retrieve()', () => {
|
||||
it('should have a moderation field defined', () => {
|
||||
return Setting.getSettings().then(settings => {
|
||||
return Setting.retrieve().then(settings => {
|
||||
expect(settings).to.have.property('moderation').and.to.equal('pre');
|
||||
});
|
||||
});
|
||||
|
||||
it('should have two infoBox fields defined', () => {
|
||||
return Setting.getSettings().then(settings => {
|
||||
return Setting.retrieve().then(settings => {
|
||||
expect(settings).to.have.property('infoBoxEnable').and.to.equal(false);
|
||||
expect(settings).to.have.property('infoBoxContent').and.to.equal('');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#updateSettings()', () => {
|
||||
describe('#update()', () => {
|
||||
it('should update the settings with a passed object', () => {
|
||||
const mockSettings = {moderation: 'post', infoBoxEnable: true, infoBoxContent: 'yeah'};
|
||||
return Setting.updateSettings(mockSettings).then(updatedSettings => {
|
||||
return Setting.update(mockSettings).then(updatedSettings => {
|
||||
expect(updatedSettings).to.be.an('object');
|
||||
expect(updatedSettings).to.have.property('moderation').and.to.equal('post');
|
||||
expect(updatedSettings).to.have.property('infoBoxEnable', true);
|
||||
@@ -35,9 +32,9 @@ describe('Setting: model', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getModerationSetting', () => {
|
||||
describe('#get', () => {
|
||||
it('should return the moderation settings', () => {
|
||||
return Setting.getModerationSetting().then(({moderation}) => {
|
||||
return Setting.retrieve().then(({moderation}) => {
|
||||
expect(moderation).not.to.be.null;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const User = require('../../models/user');
|
||||
const expect = require('chai').expect;
|
||||
|
||||
describe('User: models', () => {
|
||||
describe('models.User', () => {
|
||||
let mockUsers;
|
||||
beforeEach(() => {
|
||||
return User.createLocalUsers([{
|
||||
|
||||
@@ -10,6 +10,7 @@ chai.use(require('chai-http'));
|
||||
|
||||
const wordlist = require('../../../../services/wordlist');
|
||||
const Comment = require('../../../../models/comment');
|
||||
const Asset = require('../../../../models/asset');
|
||||
const Action = require('../../../../models/action');
|
||||
const User = require('../../../../models/user');
|
||||
|
||||
@@ -17,62 +18,71 @@ const Setting = require('../../../../models/setting');
|
||||
const settings = {id: '1', moderation: 'pre'};
|
||||
|
||||
describe('/api/v1/comments', () => {
|
||||
const comments = [{
|
||||
id: 'abc',
|
||||
body: 'comment 10',
|
||||
asset_id: 'asset',
|
||||
author_id: '123'
|
||||
}, {
|
||||
id: 'def',
|
||||
body: 'comment 20',
|
||||
asset_id: 'asset',
|
||||
author_id: '456'
|
||||
}, {
|
||||
id: 'def-rejected',
|
||||
body: 'comment 20',
|
||||
asset_id: 'asset',
|
||||
author_id: '456',
|
||||
status: 'rejected'
|
||||
}, {
|
||||
id: 'hij',
|
||||
body: 'comment 30',
|
||||
asset_id: '456',
|
||||
status: 'accepted'
|
||||
}];
|
||||
|
||||
const users = [{
|
||||
displayName: 'Ana',
|
||||
email: 'ana@gmail.com',
|
||||
password: '123'
|
||||
}, {
|
||||
displayName: 'Maria',
|
||||
email: 'maria@gmail.com',
|
||||
password: '123'
|
||||
}];
|
||||
|
||||
const actions = [{
|
||||
action_type: 'flag',
|
||||
item_id: 'abc',
|
||||
item_type: 'comment'
|
||||
}, {
|
||||
action_type: 'like',
|
||||
item_id: 'hij',
|
||||
item_type: 'comment'
|
||||
}];
|
||||
|
||||
beforeEach(() => {
|
||||
return Promise.all([
|
||||
Comment.create(comments),
|
||||
User.createLocalUsers(users),
|
||||
Action.create(actions),
|
||||
wordlist.insert([
|
||||
'bad words'
|
||||
]),
|
||||
Setting.create(settings)
|
||||
]);
|
||||
});
|
||||
|
||||
describe('#get', () => {
|
||||
const comments = [{
|
||||
body: 'comment 10',
|
||||
asset_id: 'asset',
|
||||
author_id: '123'
|
||||
}, {
|
||||
body: 'comment 20',
|
||||
asset_id: 'asset',
|
||||
author_id: '456'
|
||||
}, {
|
||||
body: 'comment 20',
|
||||
asset_id: 'asset',
|
||||
author_id: '456',
|
||||
status: [{
|
||||
type: 'rejected'
|
||||
}]
|
||||
}, {
|
||||
body: 'comment 30',
|
||||
asset_id: '456',
|
||||
status: [{
|
||||
type: 'accepted'
|
||||
}]
|
||||
}];
|
||||
|
||||
const users = [{
|
||||
displayName: 'Ana',
|
||||
email: 'ana@gmail.com',
|
||||
password: '123'
|
||||
}, {
|
||||
displayName: 'Maria',
|
||||
email: 'maria@gmail.com',
|
||||
password: '123'
|
||||
}];
|
||||
|
||||
const actions = [{
|
||||
action_type: 'flag',
|
||||
item_id: 'abc',
|
||||
item_type: 'comment'
|
||||
}, {
|
||||
action_type: 'like',
|
||||
item_id: 'hij',
|
||||
item_type: 'comment'
|
||||
}];
|
||||
|
||||
beforeEach(() => {
|
||||
return Promise.all([
|
||||
Comment.create(comments).then((newComments) => {
|
||||
newComments.forEach((comment, i) => {
|
||||
comments[i].id = comment.id;
|
||||
});
|
||||
|
||||
actions[0].item_id = comments[0].id;
|
||||
actions[1].item_id = comments[1].id;
|
||||
|
||||
return Action.create(actions);
|
||||
}),
|
||||
User.createLocalUsers(users),
|
||||
wordlist.insert([
|
||||
'bad words'
|
||||
]),
|
||||
Setting.init(settings)
|
||||
]);
|
||||
});
|
||||
|
||||
it('should return all the comments', () => {
|
||||
return chai.request(app)
|
||||
.get('/api/v1/comments')
|
||||
@@ -90,7 +100,8 @@ describe('/api/v1/comments', () => {
|
||||
.set(passport.inject({roles: ['admin']}))
|
||||
.then((res) => {
|
||||
expect(res).to.have.status(200);
|
||||
expect(res.body[0]).to.have.property('id', 'def-rejected');
|
||||
expect(res.body).to.have.length(1);
|
||||
expect(res.body[0]).to.have.property('id', comments[2].id);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -101,7 +112,7 @@ describe('/api/v1/comments', () => {
|
||||
.then((res) => {
|
||||
expect(res).to.have.status(200);
|
||||
expect(res.body).to.have.length(1);
|
||||
expect(res.body[0]).to.have.property('id', 'hij');
|
||||
expect(res.body[0]).to.have.property('id', comments[3].id);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -123,8 +134,7 @@ describe('/api/v1/comments', () => {
|
||||
expect(res).to.have.status(200);
|
||||
|
||||
expect(res.body).to.have.length(1);
|
||||
expect(res.body[0]).to.have.property('id', 'abc');
|
||||
|
||||
expect(res.body[0]).to.have.property('id', comments[0].id);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -150,7 +160,31 @@ describe('/api/v1/comments', () => {
|
||||
.then((res) => {
|
||||
expect(res).to.have.status(201);
|
||||
expect(res.body).to.have.property('id');
|
||||
expect(res.body).to.have.property('status', 'rejected');
|
||||
expect(res.body).to.have.property('status').and.to.have.length(1);
|
||||
expect(res.body.status[0]).to.have.property('type', 'rejected');
|
||||
});
|
||||
});
|
||||
|
||||
it('should create a comment with a premod status if it\'s asset is has pre-moderation enabled', () => {
|
||||
return Asset
|
||||
.findOrCreateByUrl('https://coralproject.net/article1')
|
||||
.then((asset) => {
|
||||
return Asset
|
||||
.overrideSettings(asset.id, {moderation: 'pre'})
|
||||
.then(() => asset);
|
||||
})
|
||||
.then((asset) => {
|
||||
return chai.request(app)
|
||||
.post('/api/v1/comments')
|
||||
.set(passport.inject({roles: []}))
|
||||
.send({'body': 'Something body.', 'author_id': '123', 'asset_id': asset.id, 'parent_id': ''});
|
||||
})
|
||||
.then((res) => {
|
||||
expect(res).to.have.status(201);
|
||||
expect(res.body).to.have.property('id');
|
||||
expect(res.body).to.have.property('asset_id');
|
||||
expect(res.body).to.have.property('status').and.to.have.length(1);
|
||||
expect(res.body.status[0]).to.have.property('type', 'premod');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -21,17 +21,24 @@ describe('/api/v1/queue', () => {
|
||||
body: 'comment 10',
|
||||
asset_id: 'asset',
|
||||
author_id: '123',
|
||||
status: 'rejected'
|
||||
status: [{
|
||||
type: 'rejected'
|
||||
}]
|
||||
}, {
|
||||
id: 'def',
|
||||
body: 'comment 20',
|
||||
asset_id: 'asset',
|
||||
author_id: '456'
|
||||
author_id: '456',
|
||||
status: [{
|
||||
type: 'premod'
|
||||
}]
|
||||
}, {
|
||||
id: 'hij',
|
||||
body: 'comment 30',
|
||||
asset_id: '456',
|
||||
status: 'accepted'
|
||||
status: [{
|
||||
type: 'accepted'
|
||||
}]
|
||||
}];
|
||||
|
||||
const users = [{
|
||||
@@ -59,7 +66,7 @@ describe('/api/v1/queue', () => {
|
||||
Comment.create(comments),
|
||||
User.createLocalUsers(users),
|
||||
Action.create(actions),
|
||||
Setting.create(settings)
|
||||
Setting.init(settings)
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ const defaults = {id: '1', moderation: 'pre'};
|
||||
|
||||
describe('/api/v1/settings', () => {
|
||||
|
||||
beforeEach(() => Setting.create(defaults));
|
||||
beforeEach(() => Setting.init(defaults));
|
||||
|
||||
describe('#get', () => {
|
||||
|
||||
@@ -40,7 +40,7 @@ describe('/api/v1/settings', () => {
|
||||
.then((res) => {
|
||||
expect(res).to.have.status(204);
|
||||
|
||||
return Setting.getSettings();
|
||||
return Setting.retrieve();
|
||||
})
|
||||
.then((settings) => {
|
||||
expect(settings).to.have.property('moderation', 'post');
|
||||
|
||||
@@ -25,25 +25,31 @@ describe('/api/v1/stream', () => {
|
||||
body: 'comment 10',
|
||||
author_id: '',
|
||||
parent_id: '',
|
||||
status: 'accepted'
|
||||
status: [{
|
||||
type: 'accepted'
|
||||
}]
|
||||
}, {
|
||||
id: 'def',
|
||||
body: 'comment 20',
|
||||
author_id: '',
|
||||
parent_id: '',
|
||||
status: ''
|
||||
status: []
|
||||
}, {
|
||||
id: 'uio',
|
||||
body: 'comment 30',
|
||||
asset_id: 'asset',
|
||||
author_id: '456',
|
||||
parent_id: '',
|
||||
status: 'accepted'
|
||||
status: [{
|
||||
type: 'accepted'
|
||||
}]
|
||||
}, {
|
||||
id: 'hij',
|
||||
body: 'comment 40',
|
||||
asset_id: '456',
|
||||
status: 'rejected'
|
||||
status: [{
|
||||
type: 'rejected'
|
||||
}]
|
||||
}];
|
||||
|
||||
const users = [{
|
||||
@@ -92,7 +98,7 @@ describe('/api/v1/stream', () => {
|
||||
return Promise.all([
|
||||
Comment.create(comments),
|
||||
Action.create(actions),
|
||||
Setting.create(settings)
|
||||
Setting.init(settings)
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user