mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-07 22:45:46 +01:00
Merge branch 'master' into categories_revamp
Conflicts: src/views/admin/partials/menu.tpl
This commit is contained in:
11
app.js
11
app.js
@@ -328,14 +328,9 @@ function resetThemes(callback) {
|
||||
|
||||
function resetPlugin(pluginId) {
|
||||
var db = require('./src/database');
|
||||
db.setRemove('plugins:active', pluginId, function(err, result) {
|
||||
if (err || result !== 1) {
|
||||
winston.error('[reset] Could not disable plugin: %s', pluginId);
|
||||
if (err) {
|
||||
winston.error('[reset] Encountered error: %s', err.message);
|
||||
} else {
|
||||
winston.info('[reset] Perhaps it has already been disabled?');
|
||||
}
|
||||
db.setRemove('plugins:active', pluginId, function(err) {
|
||||
if (err) {
|
||||
winston.error('[reset] Could not disable plugin: %s encountered error %s', pluginId, err.message);
|
||||
} else {
|
||||
winston.info('[reset] Plugin `%s` disabled', pluginId);
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@
|
||||
"fork_success": "Successfully forked topic! Click here to go to the forked topic.",
|
||||
|
||||
"composer.title_placeholder": "Enter your topic title here...",
|
||||
"composer.handle_placeholder": "Name",
|
||||
"composer.discard": "Discard",
|
||||
"composer.submit": "Submit",
|
||||
"composer.replying_to": "Replying to %1",
|
||||
|
||||
@@ -267,14 +267,21 @@ define('admin/manage/users', ['admin/modules/selectable'], function(selectable)
|
||||
|
||||
handleUserCreate();
|
||||
|
||||
function onUsersLoaded(users) {
|
||||
templates.parse('admin/manage/users', 'users', {users: users, requireEmailConfirmation: config.requireEmailConfirmation}, function(html) {
|
||||
$('#users-container').append($(html));
|
||||
selectable.enable('#users-container', '.user-selectable');
|
||||
});
|
||||
}
|
||||
$('#load-more-users-btn').on('click', loadMoreUsers);
|
||||
|
||||
$(window).off('scroll').on('scroll', function() {
|
||||
var bottom = ($(document).height() - $(window).height()) * 0.9;
|
||||
|
||||
if ($(window).scrollTop() > bottom && !loadingMoreUsers) {
|
||||
loadMoreUsers();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function loadMoreUsers() {
|
||||
if (active === 'search') {
|
||||
return;
|
||||
}
|
||||
var set = 'users:joindate';
|
||||
if (active === 'sort-posts') {
|
||||
set = 'users:postcount';
|
||||
@@ -284,7 +291,6 @@ define('admin/manage/users', ['admin/modules/selectable'], function(selectable)
|
||||
set = 'users:banned';
|
||||
}
|
||||
|
||||
|
||||
loadingMoreUsers = true;
|
||||
socket.emit('user.loadMore', {
|
||||
set: set,
|
||||
@@ -297,15 +303,12 @@ define('admin/manage/users', ['admin/modules/selectable'], function(selectable)
|
||||
});
|
||||
}
|
||||
|
||||
$('#load-more-users-btn').on('click', loadMoreUsers);
|
||||
|
||||
$(window).off('scroll').on('scroll', function() {
|
||||
var bottom = ($(document).height() - $(window).height()) * 0.9;
|
||||
|
||||
if ($(window).scrollTop() > bottom && !loadingMoreUsers) {
|
||||
loadMoreUsers();
|
||||
}
|
||||
});
|
||||
function onUsersLoaded(users) {
|
||||
templates.parse('admin/manage/users', 'users', {users: users, requireEmailConfirmation: config.requireEmailConfirmation}, function(html) {
|
||||
$('#users-container').append($(html));
|
||||
selectable.enable('#users-container', '.user-selectable');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -154,6 +154,8 @@ define('composer', [
|
||||
|
||||
push({
|
||||
pid: pid,
|
||||
uid: threadData.uid,
|
||||
handle: threadData.handle,
|
||||
title: $('<div/>').html(threadData.title).text(),
|
||||
body: threadData.body,
|
||||
modified: false,
|
||||
@@ -213,9 +215,11 @@ define('composer', [
|
||||
}
|
||||
|
||||
function createNewComposer(post_uuid) {
|
||||
var allowTopicsThumbnail = config.allowTopicsThumbnail && composer.posts[post_uuid].isMain && (config.hasImageUploadPlugin || config.allowFileUploads);
|
||||
var isTopic = composer.posts[post_uuid] ? !!composer.posts[post_uuid].cid : false;
|
||||
var isMain = composer.posts[post_uuid] ? !!composer.posts[post_uuid].isMain : false;
|
||||
var allowTopicsThumbnail = config.allowTopicsThumbnail && composer.posts[post_uuid].isMain && (config.hasImageUploadPlugin || config.allowFileUploads),
|
||||
isTopic = composer.posts[post_uuid] ? !!composer.posts[post_uuid].cid : false,
|
||||
isMain = composer.posts[post_uuid] ? !!composer.posts[post_uuid].isMain : false,
|
||||
isEditing = composer.posts[post_uuid] ? !!composer.posts[post_uuid].pid : false,
|
||||
isGuestPost = composer.posts[post_uuid] ? composer.posts[post_uuid].uid === '0' : null;
|
||||
|
||||
composer.bsEnvironment = utils.findBootstrapEnvironment();
|
||||
|
||||
@@ -224,7 +228,9 @@ define('composer', [
|
||||
var data = {
|
||||
allowTopicsThumbnail: allowTopicsThumbnail,
|
||||
showTags: isTopic || isMain,
|
||||
isTopic: isTopic
|
||||
isTopic: isTopic,
|
||||
showHandleInput: (app.user.uid === 0 || (isEditing && isGuestPost && app.user.isAdmin)) && config.allowGuestHandles,
|
||||
handle: composer.posts[post_uuid] ? composer.posts[post_uuid].handle || '' : undefined
|
||||
};
|
||||
|
||||
parseAndTranslate(template, data, function(composerTemplate) {
|
||||
@@ -377,6 +383,7 @@ define('composer', [
|
||||
function post(post_uuid) {
|
||||
var postData = composer.posts[post_uuid],
|
||||
postContainer = $('#cmp-uuid-' + post_uuid),
|
||||
handleEl = postContainer.find('.handle'),
|
||||
titleEl = postContainer.find('.title'),
|
||||
bodyEl = postContainer.find('textarea'),
|
||||
thumbEl = postContainer.find('input#topic-thumb-url');
|
||||
@@ -405,6 +412,7 @@ define('composer', [
|
||||
|
||||
if (parseInt(postData.cid, 10) > 0) {
|
||||
composerData = {
|
||||
handle: handleEl ? handleEl.val() : undefined,
|
||||
title: titleEl.val(),
|
||||
content: bodyEl.val(),
|
||||
topic_thumb: thumbEl.val() || '',
|
||||
@@ -423,6 +431,7 @@ define('composer', [
|
||||
} else if (parseInt(postData.tid, 10) > 0) {
|
||||
composerData = {
|
||||
tid: postData.tid,
|
||||
handle: handleEl ? handleEl.val() : undefined,
|
||||
content: bodyEl.val(),
|
||||
toPid: postData.toPid
|
||||
};
|
||||
@@ -432,6 +441,7 @@ define('composer', [
|
||||
} else if (parseInt(postData.pid, 10) > 0) {
|
||||
composerData = {
|
||||
pid: postData.pid,
|
||||
handle: handleEl ? handleEl.val() : undefined,
|
||||
content: bodyEl.val(),
|
||||
title: titleEl.val(),
|
||||
topic_thumb: thumbEl.val() || '',
|
||||
|
||||
@@ -9,7 +9,7 @@ var usersController = {};
|
||||
usersController.search = function(req, res, next) {
|
||||
res.render('admin/manage/users', {
|
||||
search_display: '',
|
||||
loadmore_display: 'none',
|
||||
loadmore_display: 'hide',
|
||||
users: []
|
||||
});
|
||||
};
|
||||
@@ -52,6 +52,9 @@ function getUsers(set, req, res, next) {
|
||||
|
||||
usersController.getCSV = function(req, res, next) {
|
||||
user.getUsersCSV(function(err, data) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
res.attachment('users.csv');
|
||||
res.setHeader('Content-Type', 'text/csv');
|
||||
res.end(data);
|
||||
|
||||
@@ -30,6 +30,7 @@ apiController.getConfig = function(req, res, next) {
|
||||
config.maximumSignatureLength = meta.config.maximumSignatureLength;
|
||||
config.useOutgoingLinksPage = parseInt(meta.config.useOutgoingLinksPage, 10) === 1;
|
||||
config.allowGuestSearching = parseInt(meta.config.allowGuestSearching, 10) === 1;
|
||||
config.allowGuestHandles = parseInt(meta.config.allowGuestHandles, 10) === 1;
|
||||
config.allowFileUploads = parseInt(meta.config.allowFileUploads, 10) === 1;
|
||||
config.allowTopicsThumbnail = parseInt(meta.config.allowTopicsThumbnail, 10) === 1;
|
||||
config.allowAccountDelete = parseInt(meta.config.allowAccountDelete, 10) === 1;
|
||||
|
||||
@@ -182,7 +182,9 @@ module.exports = function(db, module) {
|
||||
var data = {};
|
||||
field = helpers.fieldToString(field);
|
||||
data[field] = '';
|
||||
db.collection('objects').update({_key: key}, {$unset : data}, callback);
|
||||
db.collection('objects').update({_key: key}, {$unset : data}, function(err, res) {
|
||||
callback(err);
|
||||
});
|
||||
};
|
||||
|
||||
module.incrObjectField = function(key, field, callback) {
|
||||
|
||||
@@ -100,6 +100,22 @@ module.exports = function(db, module) {
|
||||
});
|
||||
};
|
||||
|
||||
module.getSortedSetRange = function(key, start, stop, callback) {
|
||||
getSortedSetRange(key, start, stop, 1, false, callback);
|
||||
};
|
||||
|
||||
module.getSortedSetRevRange = function(key, start, stop, callback) {
|
||||
getSortedSetRange(key, start, stop, -1, false, callback);
|
||||
};
|
||||
|
||||
module.getSortedSetRangeWithScores = function(key, start, stop, callback) {
|
||||
getSortedSetRange(key, start, stop, 1, true, callback);
|
||||
};
|
||||
|
||||
module.getSortedSetRevRangeWithScores = function(key, start, stop, callback) {
|
||||
getSortedSetRange(key, start, stop, -1, true, callback);
|
||||
};
|
||||
|
||||
function getSortedSetRange(key, start, stop, sort, withScores, callback) {
|
||||
if (!key) {
|
||||
return callback();
|
||||
@@ -128,22 +144,6 @@ module.exports = function(db, module) {
|
||||
});
|
||||
}
|
||||
|
||||
module.getSortedSetRange = function(key, start, stop, callback) {
|
||||
getSortedSetRange(key, start, stop, 1, false, callback);
|
||||
};
|
||||
|
||||
module.getSortedSetRevRange = function(key, start, stop, callback) {
|
||||
getSortedSetRange(key, start, stop, -1, false, callback);
|
||||
};
|
||||
|
||||
module.getSortedSetRangeWithScores = function(key, start, stop, callback) {
|
||||
getSortedSetRange(key, start, stop, 1, true, callback);
|
||||
};
|
||||
|
||||
module.getSortedSetRevRangeWithScores = function(key, start, stop, callback) {
|
||||
getSortedSetRange(key, start, stop, -1, true, callback);
|
||||
};
|
||||
|
||||
module.getSortedSetRangeByScore = function(key, start, count, min, max, callback) {
|
||||
getSortedSetRangeByScore(key, start, count, min, max, 1, false, callback);
|
||||
};
|
||||
@@ -153,7 +153,7 @@ module.exports = function(db, module) {
|
||||
};
|
||||
|
||||
module.getSortedSetRangeByScoreWithScores = function(key, start, count, min, max, callback) {
|
||||
getSortedSetRangeByScore(key, start, count, min, max, -1, true, callback);
|
||||
getSortedSetRangeByScore(key, start, count, min, max, 1, true, callback);
|
||||
};
|
||||
|
||||
module.getSortedSetRevRangeByScoreWithScores = function(key, start, count, max, min, callback) {
|
||||
@@ -204,7 +204,14 @@ module.exports = function(db, module) {
|
||||
if (!key) {
|
||||
return callback();
|
||||
}
|
||||
db.collection('objects').count({_key: key, score: {$gte: min, $lte: max}}, function(err, count) {
|
||||
var scoreQuery = {};
|
||||
if (min !== '-inf') {
|
||||
scoreQuery.$gte = min;
|
||||
}
|
||||
if (max !== '+inf') {
|
||||
scoreQuery.$lte = max;
|
||||
}
|
||||
db.collection('objects').count({_key: key, score: scoreQuery}, function(err, count) {
|
||||
callback(err, count ? count : 0);
|
||||
});
|
||||
};
|
||||
@@ -447,8 +454,8 @@ module.exports = function(db, module) {
|
||||
value = helpers.fieldToString(value);
|
||||
data.score = parseInt(increment, 10);
|
||||
|
||||
db.collection('objects').findAndModify({_key: key, value: value}, {}, {$inc: data}, {new:true, upsert:true}, function(err, result) {
|
||||
callback(err, result ? result[value] : null);
|
||||
db.collection('objects').findAndModify({_key: key, value: value}, {}, {$inc: data}, {new: true, upsert: true}, function(err, result) {
|
||||
callback(err, result ? result.score : null);
|
||||
});
|
||||
};
|
||||
};
|
||||
@@ -89,7 +89,9 @@ module.exports = function(redisClient, module) {
|
||||
};
|
||||
|
||||
module.deleteObjectField = function(key, field, callback) {
|
||||
redisClient.hdel(key, field, callback);
|
||||
redisClient.hdel(key, field, function(err, res) {
|
||||
callback(err);
|
||||
});
|
||||
};
|
||||
|
||||
module.incrObjectField = function(key, field, callback) {
|
||||
|
||||
@@ -78,7 +78,7 @@ var db = require('./database'),
|
||||
if (!messages || !messages[0]) {
|
||||
return next(null, null);
|
||||
}
|
||||
|
||||
|
||||
messages[0].newSet = isNewSet;
|
||||
messages[0].mid = mid;
|
||||
next(null, messages[0]);
|
||||
@@ -341,7 +341,8 @@ var db = require('./database'),
|
||||
summary: '[[notifications:new_message_from, ' + messageObj.fromUser.username + ']]',
|
||||
message: messageObj,
|
||||
site_title: meta.config.title || 'NodeBB',
|
||||
url: nconf.get('url') + '/chats/' + utils.slugify(messageObj.fromUser.username)
|
||||
url: nconf.get('url'),
|
||||
fromUserslug: utils.slugify(messageObj.fromUser.username)
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -18,21 +18,22 @@ var winston = require('winston'),
|
||||
|
||||
(function(PostTools) {
|
||||
|
||||
PostTools.edit = function(uid, pid, title, content, options, callback) {
|
||||
options = options || {};
|
||||
PostTools.edit = function(data, callback) {
|
||||
var options = data.options || {},
|
||||
title = data.title.trim();
|
||||
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
privileges.posts.canEdit(pid, uid, next);
|
||||
privileges.posts.canEdit(data.pid, data.uid, next);
|
||||
},
|
||||
function(canEdit, next) {
|
||||
if (!canEdit) {
|
||||
return next(new Error('[[error:no-privileges]]'));
|
||||
}
|
||||
posts.getPostData(pid, next);
|
||||
posts.getPostData(data.pid, next);
|
||||
},
|
||||
function(postData, next) {
|
||||
postData.content = content;
|
||||
postData.content = data.content;
|
||||
plugins.fireHook('filter:post.save', postData, next);
|
||||
}
|
||||
], function(err, postData) {
|
||||
@@ -42,15 +43,19 @@ var winston = require('winston'),
|
||||
|
||||
async.parallel({
|
||||
post: function(next) {
|
||||
posts.setPostFields(pid, {
|
||||
var d = {
|
||||
edited: Date.now(),
|
||||
editor: uid,
|
||||
editor: data.uid,
|
||||
content: postData.content
|
||||
}, next);
|
||||
};
|
||||
if (data.handle) {
|
||||
d.handle = data.handle;
|
||||
}
|
||||
posts.setPostFields(data.pid, d, next);
|
||||
},
|
||||
topic: function(next) {
|
||||
var tid = postData.tid;
|
||||
posts.isMain(pid, function(err, isMainPost) {
|
||||
posts.isMain(data.pid, function(err, isMainPost) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
@@ -64,11 +69,9 @@ var winston = require('winston'),
|
||||
});
|
||||
}
|
||||
|
||||
title = title.trim();
|
||||
|
||||
var topicData = {
|
||||
tid: tid,
|
||||
mainPid: pid,
|
||||
mainPid: data.pid,
|
||||
title: title,
|
||||
slug: tid + '/' + utils.slugify(title)
|
||||
};
|
||||
@@ -96,7 +99,7 @@ var winston = require('winston'),
|
||||
});
|
||||
},
|
||||
postData: function(next) {
|
||||
PostTools.parsePost(postData, uid, next);
|
||||
PostTools.parsePost(postData, data.uid, next);
|
||||
}
|
||||
}, function(err, results) {
|
||||
if (err) {
|
||||
|
||||
@@ -17,7 +17,6 @@ module.exports = function(Posts) {
|
||||
content = data.content,
|
||||
timestamp = data.timestamp || Date.now();
|
||||
|
||||
|
||||
if (!uid && parseInt(uid, 10) !== 0) {
|
||||
return callback(new Error('[[error:invalid-uid]]'));
|
||||
}
|
||||
@@ -51,6 +50,10 @@ module.exports = function(Posts) {
|
||||
postData.ip = data.ip;
|
||||
}
|
||||
|
||||
if (parseInt(uid, 10) === 0 && data.handle) {
|
||||
postData.handle = data.handle;
|
||||
}
|
||||
|
||||
plugins.fireHook('filter:post.save', postData, next);
|
||||
},
|
||||
function(postData, next) {
|
||||
|
||||
@@ -169,12 +169,11 @@ function getTemplatesListing(req, res, next) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
var data = [];
|
||||
data = results.views.filter(function(value, index, self) {
|
||||
return self.indexOf(value) === index;
|
||||
}).map(function(el) {
|
||||
return el.replace(nconf.get('views_dir') + '/', '');
|
||||
});
|
||||
var data = results.views.filter(function(value, index, self) {
|
||||
return value && self.indexOf(value) === index;
|
||||
}).map(function(el) {
|
||||
return el && el.replace(nconf.get('views_dir') + '/', '');
|
||||
});
|
||||
|
||||
data = data.concat(results.extended);
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ Categories.search = function(socket, data, callback) {
|
||||
var username = data.username,
|
||||
cid = data.cid;
|
||||
|
||||
user.search(username, 'username', function(err, data) {
|
||||
user.search({query: username}, function(err, data) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ User.deleteUsers = function(socket, uids, callback) {
|
||||
};
|
||||
|
||||
User.search = function(socket, data, callback) {
|
||||
user.search(data.query, data.type, function(err, searchData) {
|
||||
user.search({query: data.query, by: data.type, startsWith: false}, function(err, searchData) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ SocketModules.composer.push = function(socket, pid, callback) {
|
||||
if (err || !canRead) {
|
||||
return callback(err || new Error('[[error:no-privileges]]'));
|
||||
}
|
||||
posts.getPostFields(pid, ['content', 'tid'], function(err, postData) {
|
||||
posts.getPostFields(pid, ['content', 'tid', 'uid', 'handle'], function(err, postData) {
|
||||
if(err || (!postData && !postData.content)) {
|
||||
return callback(err || new Error('[[error:invalid-pid]]'));
|
||||
}
|
||||
@@ -61,6 +61,8 @@ SocketModules.composer.push = function(socket, pid, callback) {
|
||||
|
||||
callback(null, {
|
||||
pid: pid,
|
||||
uid: postData.uid,
|
||||
handle: parseInt(meta.config.allowGuestHandles, 10) ? postData.handle : undefined,
|
||||
body: postData.content,
|
||||
title: results.topic.title,
|
||||
topic_thumb: results.topic.thumb,
|
||||
|
||||
@@ -257,13 +257,25 @@ SocketPosts.edit = function(socket, data, callback) {
|
||||
return callback(new Error('[[error:content-too-short, ' + meta.config.minimumPostLength + ']]'));
|
||||
}
|
||||
|
||||
postTools.edit(socket.uid, data.pid, data.title, data.content, {topic_thumb: data.topic_thumb, tags: data.tags}, function(err, results) {
|
||||
// uid, pid, title, content, options
|
||||
postTools.edit({
|
||||
uid: socket.uid,
|
||||
handle: data.handle,
|
||||
pid: data.pid,
|
||||
title: data.title,
|
||||
content: data.content,
|
||||
options: {
|
||||
topic_thumb: data.topic_thumb,
|
||||
tags: data.tags
|
||||
}
|
||||
}, function(err, results) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
websockets.in('topic_' + results.topic.tid).emit('event:post_edited', {
|
||||
pid: data.pid,
|
||||
handle: data.handle,
|
||||
title: results.topic.title,
|
||||
isMainPost: results.topic.isMainPost,
|
||||
tags: results.topic.tags,
|
||||
|
||||
@@ -27,6 +27,7 @@ SocketTopics.post = function(socket, data, callback) {
|
||||
|
||||
topics.post({
|
||||
uid: socket.uid,
|
||||
handle: data.handle,
|
||||
title: data.title,
|
||||
content: data.content,
|
||||
cid: data.category_id,
|
||||
|
||||
@@ -66,7 +66,7 @@ SocketUser.search = function(socket, username, callback) {
|
||||
if (!socket.uid) {
|
||||
return callback(new Error('[[error:not-logged-in]]'));
|
||||
}
|
||||
user.search(username, 'username', callback);
|
||||
user.search({query: username}, callback);
|
||||
};
|
||||
|
||||
// Password Reset
|
||||
|
||||
@@ -93,6 +93,7 @@ module.exports = function(Topics) {
|
||||
|
||||
Topics.post = function(data, callback) {
|
||||
var uid = data.uid,
|
||||
handle = data.handle,
|
||||
title = data.title,
|
||||
content = data.content,
|
||||
cid = data.cid;
|
||||
@@ -134,7 +135,7 @@ module.exports = function(Topics) {
|
||||
Topics.create({uid: uid, title: title, cid: cid, thumb: data.thumb, tags: data.tags}, next);
|
||||
},
|
||||
function(tid, next) {
|
||||
Topics.reply({uid:uid, tid:tid, content:content, req: data.req}, next);
|
||||
Topics.reply({uid:uid, tid:tid, handle: handle, content:content, req: data.req}, next);
|
||||
},
|
||||
function(postData, next) {
|
||||
async.parallel({
|
||||
@@ -154,7 +155,7 @@ module.exports = function(Topics) {
|
||||
});
|
||||
},
|
||||
topicData: function(next) {
|
||||
Topics.getTopicsByTids([postData.tid], 0, next);
|
||||
Topics.getTopicsByTids([postData.tid], uid, next);
|
||||
}
|
||||
}, next);
|
||||
},
|
||||
@@ -184,6 +185,7 @@ module.exports = function(Topics) {
|
||||
var tid = data.tid,
|
||||
uid = data.uid,
|
||||
toPid = data.toPid,
|
||||
handle = data.handle,
|
||||
content = data.content,
|
||||
postData;
|
||||
|
||||
@@ -226,7 +228,7 @@ module.exports = function(Topics) {
|
||||
checkContentLength(content, next);
|
||||
},
|
||||
function(next) {
|
||||
posts.create({uid: uid, tid: tid, content: content, toPid: toPid, ip: data.req ? data.req.ip : null}, next);
|
||||
posts.create({uid: uid, tid: tid, handle: handle, content: content, toPid: toPid, ip: data.req ? data.req.ip : null}, next);
|
||||
},
|
||||
function(data, next) {
|
||||
postData = data;
|
||||
@@ -258,6 +260,11 @@ module.exports = function(Topics) {
|
||||
postData.user = results.userInfo[0];
|
||||
postData.topic = results.topicInfo;
|
||||
|
||||
// Username override for guests, if enabled
|
||||
if (parseInt(meta.config.allowGuestHandles, 10) === 1 && parseInt(postData.uid, 10) === 0 && data.handle) {
|
||||
postData.user.username = data.handle;
|
||||
}
|
||||
|
||||
if (results.settings.followTopicsOnReply) {
|
||||
threadTools.follow(postData.tid, uid);
|
||||
}
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
|
||||
var async = require('async'),
|
||||
winston = require('winston'),
|
||||
_ = require('underscore'),
|
||||
|
||||
db = require('../database'),
|
||||
user = require('../user'),
|
||||
favourites = require('../favourites'),
|
||||
posts = require('../posts'),
|
||||
privileges = require('../privileges');
|
||||
privileges = require('../privileges'),
|
||||
meta = require('../meta');
|
||||
|
||||
module.exports = function(Topics) {
|
||||
|
||||
@@ -106,29 +108,34 @@ module.exports = function(Topics) {
|
||||
posts.getPostIndices(postData, uid, next);
|
||||
}
|
||||
}, function(err, results) {
|
||||
if(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
for (var i = 0; i < postData.length; ++i) {
|
||||
if (postData[i]) {
|
||||
postData[i].index = results.indices[i];
|
||||
postData[i].deleted = parseInt(postData[i].deleted, 10) === 1;
|
||||
postData[i].user = results.userData[postData[i].uid];
|
||||
postData[i].editor = postData[i].editor ? results.editors[postData[i].editor] : null;
|
||||
postData[i].favourited = results.favourites[i];
|
||||
postData[i].upvoted = results.voteData.upvotes[i];
|
||||
postData[i].downvoted = results.voteData.downvotes[i];
|
||||
postData[i].votes = postData[i].votes || 0;
|
||||
postData[i].display_moderator_tools = results.privileges[i].editable;
|
||||
postData[i].display_move_tools = results.privileges[i].move && postData[i].index !== 0;
|
||||
postData[i].selfPost = parseInt(uid, 10) === parseInt(postData[i].uid, 10);
|
||||
postData.forEach(function(postObj, i) {
|
||||
if (postObj) {
|
||||
postObj.index = results.indices[i];
|
||||
postObj.deleted = parseInt(postObj.deleted, 10) === 1;
|
||||
postObj.user = parseInt(postObj.uid, 10) ? results.userData[postObj.uid] : _.clone(results.userData[postObj.uid]);
|
||||
postObj.editor = postObj.editor ? results.editors[postObj.editor] : null;
|
||||
postObj.favourited = results.favourites[i];
|
||||
postObj.upvoted = results.voteData.upvotes[i];
|
||||
postObj.downvoted = results.voteData.downvotes[i];
|
||||
postObj.votes = postObj.votes || 0;
|
||||
postObj.display_moderator_tools = results.privileges[i].editable;
|
||||
postObj.display_move_tools = results.privileges[i].move && postObj.index !== 0;
|
||||
postObj.selfPost = parseInt(uid, 10) === parseInt(postObj.uid, 10);
|
||||
|
||||
if(postData[i].deleted && !results.privileges[i].view_deleted) {
|
||||
postData[i].content = '[[topic:post_is_deleted]]';
|
||||
if(postObj.deleted && !results.privileges[i].view_deleted) {
|
||||
postObj.content = '[[topic:post_is_deleted]]';
|
||||
}
|
||||
|
||||
// Username override for guests, if enabled
|
||||
if (parseInt(meta.config.allowGuestHandles, 10) === 1 && parseInt(postObj.uid, 10) === 0 && postObj.handle) {
|
||||
postObj.user.username = postObj.handle;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
callback(null, postData);
|
||||
});
|
||||
|
||||
@@ -6,18 +6,22 @@ var async = require('async'),
|
||||
|
||||
module.exports = function(User) {
|
||||
|
||||
User.search = function(query, type, callback) {
|
||||
User.search = function(data, callback) {
|
||||
var query = data.query;
|
||||
var by = data.by || 'username';
|
||||
var startsWith = data.hasOwnProperty('startsWith') ? data.startsWith : true;
|
||||
|
||||
if (!query || query.length === 0) {
|
||||
return callback(null, {timing:0, users:[]});
|
||||
}
|
||||
|
||||
if (type === 'ip') {
|
||||
if (by === 'ip') {
|
||||
return searchByIP(query, callback);
|
||||
}
|
||||
|
||||
var start = process.hrtime();
|
||||
var key = 'username:uid';
|
||||
if (type === 'email') {
|
||||
if (by === 'email') {
|
||||
key = 'email:uid';
|
||||
}
|
||||
|
||||
@@ -32,7 +36,11 @@ module.exports = function(User) {
|
||||
var uids = [];
|
||||
|
||||
for(var i=0; i<values.length; ++i) {
|
||||
if (values[i].toLowerCase().indexOf(query) === 0) {
|
||||
if (startsWith) {
|
||||
if (values[i].toLowerCase().indexOf(query) === 0) {
|
||||
uids.push(values[i]);
|
||||
}
|
||||
} else if (values[i].toLowerCase().indexOf(query) !== -1) {
|
||||
uids.push(values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
<li><a href="{relative_path}/admin/settings/reputation">Reputation</a></li>
|
||||
<li><a href="{relative_path}/admin/settings/email">Email</a></li>
|
||||
<li><a href="{relative_path}/admin/settings/user">User</a></li>
|
||||
<li><a href="{relative_path}/admin/settings/guest">Guest</a></li>
|
||||
<li><a href="{relative_path}/admin/settings/post">Post</a></li>
|
||||
<li><a href="{relative_path}/admin/settings/pagination">Pagination</a></li>
|
||||
<li><a href="{relative_path}/admin/settings/tags">Tags</a></li>
|
||||
|
||||
25
src/views/admin/settings/guest.tpl
Normal file
25
src/views/admin/settings/guest.tpl
Normal file
@@ -0,0 +1,25 @@
|
||||
<!-- IMPORT admin/settings/header.tpl -->
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Guests</div>
|
||||
<div class="panel-body">
|
||||
<p class="alert alert-info">
|
||||
These options affect guest users as a whole. Control over which categories a guest can see or post to is handled in
|
||||
the categories themselves
|
||||
</p>
|
||||
|
||||
<form role="form">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" data-field="allowGuestHandles"> <strong>Allow guest handles</strong>
|
||||
<p class="help-block">
|
||||
This option exposes a new field that allows guests to pick a name to associate with each post they make. If disabled,
|
||||
the will simply be called "Guest" (or the equivalent in the forum's selected language)
|
||||
</p>
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- IMPORT admin/settings/footer.tpl -->
|
||||
@@ -3,7 +3,7 @@
|
||||
<p>{summary}:</p>
|
||||
<blockquote>{message.content}</blockquote>
|
||||
|
||||
<a href="{url}">[[email:notif.chat.cta]]</a>
|
||||
<a href="{url}/chats/{fromUserslug}">[[email:notif.chat.cta]]</a>
|
||||
|
||||
<p>
|
||||
[[email:closing]]<br />
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
{message.content}
|
||||
|
||||
[[email:notif.chat.cta]]: {url}
|
||||
[[email:notif.chat.cta]]: {url}/chats/{fromUserslug}
|
||||
|
||||
|
||||
[[email:closing]]
|
||||
|
||||
@@ -13,199 +13,7 @@ describe('Test database', function() {
|
||||
require('./database/keys');
|
||||
require('./database/list');
|
||||
require('./database/sets');
|
||||
require('./database/hash');
|
||||
require('./database/sorted');
|
||||
|
||||
it('should not throw err', function(done) {
|
||||
var objectKey = 'testObj';
|
||||
|
||||
function setObject(callback) {
|
||||
db.setObject(objectKey, {name:'baris', 'lastname':'usakli', age:3}, function(err, result) {
|
||||
callback(err, {'setObject':result});
|
||||
});
|
||||
}
|
||||
|
||||
function getObject(callback) {
|
||||
db.getObject(objectKey, function(err, data) {
|
||||
callback(err, {'getObject':data});
|
||||
});
|
||||
}
|
||||
|
||||
function getObjects(callback) {
|
||||
db.getObjects(['testing1', objectKey, 'doesntexist', 'user:1'], function(err, data) {
|
||||
callback(err, {'getObjects':data});
|
||||
});
|
||||
}
|
||||
|
||||
function setObjectField(callback) {
|
||||
db.setObjectField(objectKey, 'reputation', 5, function(err, result) {
|
||||
callback(err, {'setObjectField': result});
|
||||
});
|
||||
}
|
||||
|
||||
function getObjectField(callback) {
|
||||
db.getObjectField(objectKey, 'age', function(err, age) {
|
||||
callback(err, {'getObjectField' : age});
|
||||
});
|
||||
}
|
||||
|
||||
function getObjectFields(callback) {
|
||||
db.getObjectFields(objectKey, ['name', 'lastname'], function(err, data) {
|
||||
callback(err, {'getObjectFields':data});
|
||||
});
|
||||
}
|
||||
|
||||
function getObjectValues(callback) {
|
||||
db.getObjectValues(objectKey, function(err, data) {
|
||||
callback(err, {'getObjectValues':data});
|
||||
});
|
||||
}
|
||||
|
||||
function isObjectField(callback) {
|
||||
db.isObjectField(objectKey, 'age', function(err, data) {
|
||||
callback(err, {'isObjectField':data});
|
||||
});
|
||||
}
|
||||
|
||||
function deleteObjectField(callback) {
|
||||
db.deleteObjectField(objectKey, 'reputation', function(err, data) {
|
||||
callback(err, {'deleteObjectField':data});
|
||||
});
|
||||
}
|
||||
|
||||
function incrObjectFieldBy(callback) {
|
||||
db.incrObjectFieldBy(objectKey, 'age', 3, function(err, data) {
|
||||
callback(err, {'incrObjectFieldBy':data});
|
||||
});
|
||||
}
|
||||
|
||||
function getObjectKeys(callback) {
|
||||
db.getObjectKeys(objectKey, function(err, data) {
|
||||
callback(err, {'getObjectKeys':data});
|
||||
});
|
||||
}
|
||||
|
||||
var objectTasks = [
|
||||
setObject,
|
||||
getObject,
|
||||
deleteObjectField,
|
||||
getObject,
|
||||
setObjectField,
|
||||
getObject,
|
||||
deleteObjectField,
|
||||
getObject,
|
||||
getObjectField,
|
||||
getObjectFields,
|
||||
getObjectValues,
|
||||
isObjectField,
|
||||
incrObjectFieldBy,
|
||||
getObject,
|
||||
getObjects,
|
||||
getObjectKeys
|
||||
];
|
||||
|
||||
async.series(objectTasks, function(err, results) {
|
||||
assert.equal(err, null, 'error in object methods');
|
||||
assert.ok(results);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should not throw err', function(done) {
|
||||
function sortedSetAdd(callback) {
|
||||
db.sortedSetAdd('sortedSet3', 12, 5, function(err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
function sortedSetRemove(callback) {
|
||||
db.sortedSetRemove('sortedSet3', 12, function(err, data) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
function getSortedSetRange(callback) {
|
||||
db.getSortedSetRange('sortedSet3', 0, -1, function(err, data) {
|
||||
callback(err, {'getSortedSetRange': data});
|
||||
});
|
||||
}
|
||||
|
||||
function getSortedSetRevRange(callback) {
|
||||
db.getSortedSetRevRange('sortedSet3', 0, -1, function(err, data) {
|
||||
callback(err, {'getSortedSetRevRange': data});
|
||||
});
|
||||
}
|
||||
|
||||
function getSortedSetRevRangeByScore(callback) {
|
||||
db.getSortedSetRevRangeByScore('sortedSet3', 0, 10, Infinity, 100, function(err, data) {
|
||||
callback(err, {'getSortedSetRevRangeByScore': data});
|
||||
});
|
||||
}
|
||||
|
||||
function sortedSetCount(callback) {
|
||||
db.sortedSetCount('sortedSet3', -Infinity, Infinity, function(err, data) {
|
||||
callback(err, {'sortedSetCount': data});
|
||||
});
|
||||
}
|
||||
|
||||
function sortedSetScore(callback) {
|
||||
db.sortedSetScore('users:joindate', 1, function(err, data) {
|
||||
callback(err, {'sortedSetScore': data});
|
||||
});
|
||||
}
|
||||
|
||||
function sortedSetsScore(callback) {
|
||||
db.sortedSetsScore(['users:joindate', 'users:derp', 'users:postcount'], 1, function(err, data) {
|
||||
callback(err, {'sortedSetsScore': data});
|
||||
});
|
||||
}
|
||||
|
||||
function isSortedSetMember(callback) {
|
||||
db.isSortedSetMember('sortedSet3', 5, function(err, data) {
|
||||
callback(err, {'sortedSetMember': data});
|
||||
});
|
||||
}
|
||||
|
||||
function getSortedSetUnion(callback) {
|
||||
db.getSortedSetUnion(['users:joindate', 'users:derp', 'users:postcount'], 0, -1, function(err, data) {
|
||||
callback(err, {'sortedSetUnion': data});
|
||||
});
|
||||
}
|
||||
|
||||
function getSortedSetRevUnion(callback) {
|
||||
db.getSortedSetRevUnion(['users:joindate', 'users:derp', 'users:postcount'], 0, -1, function(err, data) {
|
||||
callback(err, {'sortedSetUnion': data});
|
||||
});
|
||||
}
|
||||
|
||||
var sortedSetTasks = [
|
||||
sortedSetAdd,
|
||||
sortedSetAdd,
|
||||
isSortedSetMember,
|
||||
getSortedSetRange,
|
||||
sortedSetAdd,
|
||||
getSortedSetRange,
|
||||
getSortedSetRevRange,
|
||||
sortedSetRemove,
|
||||
getSortedSetRange,
|
||||
sortedSetCount,
|
||||
sortedSetScore,
|
||||
sortedSetsScore,
|
||||
getSortedSetRevRangeByScore,
|
||||
getSortedSetUnion,
|
||||
getSortedSetRevUnion
|
||||
];
|
||||
|
||||
async.series(sortedSetTasks, function(err, results) {
|
||||
assert.equal(err, null, 'error in sorted set methods');
|
||||
assert.ok(results);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
after(function() {
|
||||
db.flushdb();
|
||||
});
|
||||
});
|
||||
|
||||
302
tests/database/hash.js
Normal file
302
tests/database/hash.js
Normal file
@@ -0,0 +1,302 @@
|
||||
'use strict';
|
||||
|
||||
var async = require('async'),
|
||||
assert = require('assert'),
|
||||
db = require('../mocks/databasemock');
|
||||
|
||||
describe('Hash methods', function() {
|
||||
var testData = {
|
||||
name: 'baris',
|
||||
age: 99
|
||||
};
|
||||
|
||||
describe('setObject()', function() {
|
||||
it('should create a object', function(done) {
|
||||
db.setObject('testObject1', testData, function(err) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('setObjectField()', function() {
|
||||
it('should add a new field to an object', function(done) {
|
||||
db.setObjectField('testObject1', 'lastname', 'usakli', function(err) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should create a new object with field', function(done) {
|
||||
db.setObjectField('testObject2', 'name', 'ginger', function(err) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getObject()', function() {
|
||||
it('should return falsy if object does not exist', function(done) {
|
||||
db.getObject('doesnotexist', function(err, data) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(!!data, false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should retrieve an object', function(done) {
|
||||
db.getObject('testObject1', function(err, data) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(data.name, testData.name);
|
||||
assert.equal(data.age, testData.age);
|
||||
assert.equal(data.lastname, 'usakli');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getObjects()', function() {
|
||||
it('should return 3 objects with correct data', function(done) {
|
||||
db.getObjects(['testObject1', 'testObject2', 'doesnotexist'], function(err, objects) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(Array.isArray(objects) && objects.length === 3, true);
|
||||
assert.equal(objects[0].name, 'baris');
|
||||
assert.equal(objects[1].name, 'ginger');
|
||||
assert.equal(!!objects[2], false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getObjectField()', function() {
|
||||
it('should return falsy if object does not exist', function(done) {
|
||||
db.getObjectField('doesnotexist', 'fieldName', function(err, value) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(!!value, false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return falsy if field does not exist', function(done) {
|
||||
db.getObjectField('testObject1', 'fieldName', function(err, value) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(!!value, false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should get an objects field', function(done) {
|
||||
db.getObjectField('testObject1', 'lastname', function(err, value) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(value, 'usakli');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getObjectFields()', function() {
|
||||
it('should return an object with falsy values', function(done) {
|
||||
db.getObjectFields('doesnotexist', ['field1', 'field2'], function(err, object) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(typeof object, 'object');
|
||||
assert.equal(!!object.field1, false);
|
||||
assert.equal(!!object.field2, false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return an object with correct fields', function(done) {
|
||||
db.getObjectFields('testObject1', ['lastname', 'age', 'field1'], function(err, object) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(typeof object, 'object');
|
||||
assert.equal(object.lastname, 'usakli');
|
||||
assert.equal(object.age, 99);
|
||||
assert.equal(!!object.field1, false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getObjectsFields()', function() {
|
||||
it('should return an array of objects with correct values', function(done) {
|
||||
db.getObjectsFields(['testObject1', 'testObject2', 'doesnotexist'], ['name', 'age'], function(err, objects) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(Array.isArray(objects), true);
|
||||
assert.equal(objects.length, 3);
|
||||
assert.equal(objects[0].name, 'baris');
|
||||
assert.equal(objects[0].age, 99);
|
||||
assert.equal(objects[1].name, 'ginger');
|
||||
assert.equal(!!objects[2].name, false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getObjectKeys()', function() {
|
||||
it('should return an empty array for a object that does not exist', function(done) {
|
||||
db.getObjectKeys('doesnotexist', function(err, keys) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(Array.isArray(keys) && keys.length === 0, true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return an array of keys for the object\'s fields', function(done) {
|
||||
db.getObjectKeys('testObject1', function(err, keys) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(Array.isArray(keys) && keys.length === 3, true);
|
||||
keys.forEach(function(key) {
|
||||
assert.notEqual(['name', 'lastname', 'age'].indexOf(key), -1);
|
||||
});
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getObjectValues()', function() {
|
||||
it('should return an empty array for a object that does not exist', function(done) {
|
||||
db.getObjectValues('doesnotexist', function(err, values) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(Array.isArray(values) && values.length === 0, true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return an array of values for the object\'s fields', function(done) {
|
||||
db.getObjectValues('testObject1', function(err, values) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(Array.isArray(values) && values.length === 3, true);
|
||||
values.forEach(function(value) {
|
||||
assert.notEqual(['baris', 'usakli', 99].indexOf(value), -1);
|
||||
});
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('isObjectField()', function() {
|
||||
it('should return false if object does not exist', function(done) {
|
||||
db.isObjectField('doesnotexist', 'field1', function(err, value) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(value, false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return false if field does not exist', function(done) {
|
||||
db.isObjectField('testObject1', 'field1', function(err, value) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(value, false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return true if field exists', function(done) {
|
||||
db.isObjectField('testObject1', 'lastname', function(err, value) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(value, true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('deleteObjectField()', function() {
|
||||
it('should delete an objects field', function(done) {
|
||||
db.deleteObjectField('testObject1', 'lastname', function(err) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 1);
|
||||
db.isObjectField('testObject1', 'lastname', function(err, isField) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(isField, false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('incrObjectField()', function() {
|
||||
it('should set an objects field to 1 if object does not exist', function(done) {
|
||||
db.incrObjectField('testObject3', 'field1', function(err, newValue) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(newValue, 1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should increment an object fields by 1 and return it', function(done) {
|
||||
db.incrObjectField('testObject1', 'age', function(err, newValue) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(newValue, 100);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('decrObjectField()', function() {
|
||||
it('should set an objects field to -1 if object does not exist', function(done) {
|
||||
db.decrObjectField('testObject4', 'field1', function(err, newValue) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(newValue, -1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should decrement an object fields by 1 and return it', function(done) {
|
||||
db.decrObjectField('testObject1', 'age', function(err, newValue) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(newValue, 99);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('incrObjectFieldBy()', function() {
|
||||
it('should set an objects field to 5 if object does not exist', function(done) {
|
||||
db.incrObjectFieldBy('testObject5', 'field1', 5, function(err, newValue) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(newValue, 5);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should increment an object fields by passed in value and return it', function(done) {
|
||||
db.incrObjectFieldBy('testObject1', 'age', 11, function(err, newValue) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(newValue, 110);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
after(function() {
|
||||
db.flushdb();
|
||||
});
|
||||
});
|
||||
472
tests/database/sorted.js
Normal file
472
tests/database/sorted.js
Normal file
@@ -0,0 +1,472 @@
|
||||
'use strict';
|
||||
|
||||
var async = require('async'),
|
||||
assert = require('assert'),
|
||||
db = require('../mocks/databasemock');
|
||||
|
||||
describe('Sorted Set methods', function() {
|
||||
|
||||
describe('sortedSetAdd()', function() {
|
||||
it('should add an element to a sorted set', function(done) {
|
||||
db.sortedSetAdd('sorted1', 1, 'value1', function(err) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should add two elements to a sorted set', function(done) {
|
||||
db.sortedSetAdd('sorted2', [1, 2], ['value1', 'value2'], function(err) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should add four elements to a sorted set', function(done) {
|
||||
db.sortedSetAdd('sorted3', [2, 3, 4, 5], ['value2', 'value3', 'value4', 'value5'], function(err) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('sortedSetsAdd()', function() {
|
||||
it('should add an element to two sorted sets', function(done) {
|
||||
db.sortedSetsAdd(['sorted1', 'sorted2'], 3, 'value3', function(err) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSortedSetRange()', function() {
|
||||
it('should return the lowest scored element', function(done) {
|
||||
db.getSortedSetRange('sorted2', 0, 0, function(err, value) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(value, 'value1');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return elements sorted by score lowest to highest', function(done) {
|
||||
db.getSortedSetRange('sorted2', 0, -1, function(err, values) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.deepEqual(values, ['value1', 'value2', 'value3']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSortedSetRevRange()', function() {
|
||||
it('should return the highest scored element', function(done) {
|
||||
db.getSortedSetRevRange('sorted2', 0, 0, function(err, value) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(value, 'value3');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return elements sorted by score highest to lowest', function(done) {
|
||||
db.getSortedSetRevRange('sorted2', 0, -1, function(err, values) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.deepEqual(values, ['value3', 'value2', 'value1']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSortedSetRangeWithScores()', function() {
|
||||
it('should return array of elements sorted by score lowest to highest with scores', function(done) {
|
||||
db.getSortedSetRangeWithScores('sorted2', 0, -1, function(err, values) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.deepEqual(values, [{value: 'value1', score: 1}, {value: 'value2', score: 2}, {value: 'value3', score: 3}]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSortedSetRevRangeWithScores()', function() {
|
||||
it('should return array of elements sorted by score highest to lowest with scores', function(done) {
|
||||
db.getSortedSetRevRangeWithScores('sorted2', 0, -1, function(err, values) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.deepEqual(values, [{value: 'value3', score: 3}, {value: 'value2', score: 2}, {value: 'value1', score: 1}]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('getSortedSetRangeByScore()', function() {
|
||||
it('should get count elements with score between min max sorted by score lowest to highest', function(done) {
|
||||
db.getSortedSetRangeByScore('sorted2', 0, -1, '-inf', 2, function(err, values) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.deepEqual(values, ['value1', 'value2']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSortedSetRevRangeByScore()', function() {
|
||||
it('should get count elements with score between max min sorted by score highest to lowest', function(done) {
|
||||
db.getSortedSetRevRangeByScore('sorted2', 0, -1, '+inf', 2, function(err, values) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.deepEqual(values, ['value3', 'value2']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('getSortedSetRangeByScoreWithScores()', function() {
|
||||
it('should get count elements with score between min max sorted by score lowest to highest with scores', function(done) {
|
||||
db.getSortedSetRangeByScoreWithScores('sorted2', 0, -1, '-inf', 2, function(err, values) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.deepEqual(values, [{value: 'value1', score: 1}, {value: 'value2', score: 2}]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSortedSetRevRangeByScoreWithScores()', function() {
|
||||
it('should get count elements with score between max min sorted by score highest to lowest', function(done) {
|
||||
db.getSortedSetRevRangeByScoreWithScores('sorted2', 0, -1, '+inf', 2, function(err, values) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.deepEqual(values, [{value: 'value3', score: 3}, {value: 'value2', score: 2}]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('sortedSetCount()', function() {
|
||||
it('should return 0 for a sorted set that does not exist', function(done) {
|
||||
db.sortedSetCount('doesnotexist', 0, 10, function(err, count) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(count, 0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return number of elements between scores min max inclusive', function(done) {
|
||||
db.sortedSetCount('sorted2', '-inf', 2, function(err, count) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(count, 2);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('sortedSetCard()', function() {
|
||||
it('should return 0 for a sorted set that does not exist', function(done) {
|
||||
db.sortedSetCard('doesnotexist', function(err, count) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(count, 0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return number of elements in a sorted set', function(done) {
|
||||
db.sortedSetCard('sorted2', function(err, count) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(count, 3);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('sortedSetsCard()', function() {
|
||||
it('should return the number of elements in sorted sets', function(done) {
|
||||
db.sortedSetsCard(['sorted1', 'sorted2', 'doesnotexist'], function(err, counts) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.deepEqual(counts, [2, 3, 0]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('sortedSetRank()', function() {
|
||||
it('should return falsy if sorted set doesnot exist', function(done) {
|
||||
db.sortedSetRank('doesnotexist', 'value1', function(err, rank) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(!!rank, false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return falsy if element isnt in sorted set', function(done) {
|
||||
db.sortedSetRank('sorted2', 'value5', function(err, rank) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(!!rank, false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the rank of the element in the sorted set sorted by lowest to highest score', function(done) {
|
||||
db.sortedSetRank('sorted2', 'value1', function(err, rank) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(rank, 0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('sortedSetRevRank()', function() {
|
||||
it('should return falsy if sorted set doesnot exist', function(done) {
|
||||
db.sortedSetRevRank('doesnotexist', 'value1', function(err, rank) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(!!rank, false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return falsy if element isnt in sorted set', function(done) {
|
||||
db.sortedSetRevRank('sorted2', 'value5', function(err, rank) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(!!rank, false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the rank of the element in the sorted set sorted by highest to lowest score', function(done) {
|
||||
db.sortedSetRevRank('sorted2', 'value1', function(err, rank) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(rank, 2);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('sortedSetsRanks()', function() {
|
||||
it('should return the ranks of values in sorted sets', function(done) {
|
||||
db.sortedSetsRanks(['sorted1', 'sorted2'], ['value1', 'value2'], function(err, ranks) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.deepEqual(ranks, [0, 1]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('sortedSetRanks()', function() {
|
||||
it('should return the ranks of values in a sorted set', function(done) {
|
||||
db.sortedSetRanks('sorted2', ['value2', 'value1', 'value3', 'value4'], function(err, ranks) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.deepEqual(ranks, [1, 0, 2, null]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('sortedSetScore()', function() {
|
||||
it('should return falsy if sorted set does not exist', function(done) {
|
||||
db.sortedSetScore('doesnotexist', 'value1', function(err, score) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(!!score, false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return falsy if element is not in sorted set', function(done) {
|
||||
db.sortedSetScore('sorted2', 'value5', function(err, score) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(!!score, false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the score of an element', function(done) {
|
||||
db.sortedSetScore('sorted2', 'value2', function(err, score) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(score, 2);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('sortedSetsScore()', function() {
|
||||
it('should return the scores of value in sorted sets', function(done) {
|
||||
db.sortedSetsScore(['sorted1', 'sorted2', 'doesnotexist'], 'value2', function(err, scores) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.deepEqual(scores, [null, 2, null]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('sortedSetScores()', function() {
|
||||
it('should return the scores of value in sorted sets', function(done) {
|
||||
db.sortedSetScores('sorted2', ['value2', 'value1', 'doesnotexist'], function(err, scores) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.deepEqual(scores, [2, 1, null]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('isSortedSetMember()', function() {
|
||||
it('should return false if sorted set does not exist', function(done) {
|
||||
db.isSortedSetMember('doesnotexist', 'value1', function(err, isMember) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(isMember, false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return false if element is not in sorted set', function(done) {
|
||||
db.isSortedSetMember('sorted2', 'value5', function(err, isMember) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(isMember, false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return true if element is in sorted set', function(done) {
|
||||
db.isSortedSetMember('sorted2', 'value2', function(err, isMember) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.deepEqual(isMember, true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('isSortedSetMembers()', function() {
|
||||
it('should return an array of booleans indicating membership', function(done) {
|
||||
db.isSortedSetMembers('sorted2', ['value1', 'value2', 'value5'], function(err, isMembers) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.deepEqual(isMembers, [true, true, false]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSortedSetUnion()', function() {
|
||||
it('should return an array of values from both sorted sets sorted by scores lowest to highest', function(done) {
|
||||
db.getSortedSetUnion(['sorted1', 'sorted3'], 0, -1, function(err, values) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.deepEqual(values, ['value1', 'value2', 'value4', 'value5', 'value3']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSortedSetRevUnion()', function() {
|
||||
it('should return an array of values from both sorted sets sorted by scores highest to lowest', function(done) {
|
||||
db.getSortedSetRevUnion(['sorted1', 'sorted3'], 0, -1, function(err, values) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.deepEqual(values, ['value3', 'value5', 'value4', 'value2', 'value1']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('sortedSetIncrBy()', function() {
|
||||
it('should create a sorted set with a field set to 1', function(done) {
|
||||
db.sortedSetIncrBy('sortedIncr', 1, 'field1', function(err, newValue) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(newValue, 1);
|
||||
db.sortedSetScore('sortedIncr', 'field1', function(err, score) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(score, 1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should increment a field of a sorted set by 5', function(done) {
|
||||
db.sortedSetIncrBy('sortedIncr', 5, 'field1', function(err, newValue) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.equal(newValue, 6);
|
||||
db.sortedSetScore('sortedIncr', 'field1', function(err, score) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(score, 6);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('sortedSetRemove()', function() {
|
||||
it('should remove an element from a sorted set', function(done) {
|
||||
db.sortedSetRemove('sorted2', 'value2', function(err) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 1);
|
||||
db.isSortedSetMember('sorted2', 'value2', function(err, isMember) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(isMember, false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('sortedSetsRemove()', function() {
|
||||
it('should remove element from multiple sorted sets', function(done) {
|
||||
db.sortedSetsRemove(['sorted1', 'sorted2'], 'value1', function(err) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 1);
|
||||
db.sortedSetsScore(['sorted1', 'sorted2'], 'value1', function(err, scores) {
|
||||
assert.equal(err, null);
|
||||
assert.deepEqual(scores, [null, null]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('sortedSetsRemoveRangeByScore()', function() {
|
||||
it('should remove elements with scores between min max inclusive', function(done) {
|
||||
db.sortedSetsRemoveRangeByScore(['sorted3'], 4, 5, function(err) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(arguments.length, 1);
|
||||
db.getSortedSetRange('sorted3', 0, -1, function(err, values) {
|
||||
assert.equal(err, null);
|
||||
assert.deepEqual(values, ['value2', 'value3']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
after(function() {
|
||||
db.flushdb();
|
||||
});
|
||||
});
|
||||
@@ -157,6 +157,17 @@ describe('User', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('.search()', function() {
|
||||
it('should return an object containing an array of matching users', function(done) {
|
||||
User.search({query: 'john'}, function(err, searchData) {
|
||||
assert.ifError(err);
|
||||
assert.equal(Array.isArray(searchData.users) && searchData.users.length > 0, true);
|
||||
assert.equal(searchData.users[0].username, 'John Smith');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
after(function() {
|
||||
db.flushdb();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user