diff --git a/src/flags.js b/src/flags.js index 458e2bdf56..03c810794b 100644 --- a/src/flags.js +++ b/src/flags.js @@ -685,5 +685,3 @@ Flags.notify = function (flagObj, uid, callback) { break; } }; - -module.exports = Flags; diff --git a/src/notifications.js b/src/notifications.js index fef4a4a4d2..931e0ad293 100644 --- a/src/notifications.js +++ b/src/notifications.js @@ -331,82 +331,83 @@ Notifications.markReadMultiple = function (nids, uid, callback) { db.getObjectsFields(notificationKeys, ['nid', 'datetime'], next); }, - ], function (err, notificationData) { - if (err) { - return callback(err); - } - - // Filter out notifications that didn't exist - notificationData = notificationData.filter(function (notification) { - return notification && notification.nid; - }); + function (notificationData, next) { + // Filter out notifications that didn't exist + notificationData = notificationData.filter(function (notification) { + return notification && notification.nid; + }); - // Extract nid - nids = notificationData.map(function (notification) { - return notification.nid; - }); + // Extract nid + nids = notificationData.map(function (notification) { + return notification.nid; + }); - var datetimes = notificationData.map(function (notification) { - return (notification && notification.datetime) || Date.now(); - }); + var datetimes = notificationData.map(function (notification) { + return (notification && notification.datetime) || Date.now(); + }); - async.parallel([ - function (next) { - db.sortedSetRemove('uid:' + uid + ':notifications:unread', nids, next); - }, - function (next) { - db.sortedSetAdd('uid:' + uid + ':notifications:read', datetimes, nids, next); - }, - ], function (err) { - callback(err); - }); + async.parallel([ + function (next) { + db.sortedSetRemove('uid:' + uid + ':notifications:unread', nids, next); + }, + function (next) { + db.sortedSetAdd('uid:' + uid + ':notifications:read', datetimes, nids, next); + }, + ], next); + }, + ], function (err) { + callback(err); }); }; Notifications.markAllRead = function (uid, callback) { - db.getSortedSetRevRange('uid:' + uid + ':notifications:unread', 0, 99, function (err, nids) { - if (err) { - return callback(err); - } - - if (!Array.isArray(nids) || !nids.length) { - return callback(); - } + async.waterfall([ + function (next) { + db.getSortedSetRevRange('uid:' + uid + ':notifications:unread', 0, 99, next); + }, + function (nids, next) { + if (!Array.isArray(nids) || !nids.length) { + return next(); + } - Notifications.markReadMultiple(nids, uid, callback); - }); + Notifications.markReadMultiple(nids, uid, next); + }, + ], callback); }; -Notifications.prune = function () { +Notifications.prune = function (callback) { + callback = callback || function () {}; var week = 604800000; var cutoffTime = Date.now() - week; - db.getSortedSetRangeByScore('notifications', 0, 500, '-inf', cutoffTime, function (err, nids) { - if (err) { - return winston.error(err.message); - } - - if (!Array.isArray(nids) || !nids.length) { - return; - } + async.waterfall([ + function (next) { + db.getSortedSetRangeByScore('notifications', 0, 500, '-inf', cutoffTime, next); + }, + function (nids, next) { + if (!Array.isArray(nids) || !nids.length) { + return callback(); + } - var keys = nids.map(function (nid) { - return 'notifications:' + nid; - }); + var keys = nids.map(function (nid) { + return 'notifications:' + nid; + }); - async.parallel([ - function (next) { - db.sortedSetRemove('notifications', nids, next); - }, - function (next) { - db.deleteAll(keys, next); - }, - ], function (err) { - if (err) { - return winston.error('Encountered error pruning notifications: ' + err.message); - } - }); + async.parallel([ + function (next) { + db.sortedSetRemove('notifications', nids, next); + }, + function (next) { + db.deleteAll(keys, next); + }, + ], next); + }, + ], function (err) { + if (err) { + winston.error('Encountered error pruning notifications: ' + err.message); + } + callback(err); }); }; diff --git a/src/user/info.js b/src/user/info.js index 755c7cff8c..056b675ed3 100644 --- a/src/user/info.js +++ b/src/user/info.js @@ -30,21 +30,15 @@ module.exports = function (User) { }, function (_reason, next) { reason = _reason && _reason.length ? _reason[0] : ''; - next(); + next(null, { + uid: uid, + timestamp: timestamp, + expiry: parseInt(expiry, 10), + expiry_readable: new Date(parseInt(expiry, 10)).toString(), + reason: validator.escape(String(reason)), + }); }, - ], function (err) { - if (err) { - return callback(err); - } - - callback(null, { - uid: uid, - timestamp: timestamp, - expiry: parseInt(expiry, 10), - expiry_readable: new Date(parseInt(expiry, 10)).toString(), - reason: validator.escape(String(reason)), - }); - }); + ], callback); }; User.getModerationHistory = function (uid, callback) { @@ -59,48 +53,46 @@ module.exports = function (User) { function (data, next) { getFlagMetadata(data, next); }, - ], function (err, data) { - if (err) { - return callback(err); - } - formatBanData(data); - callback(null, data); - }); + function (data, next) { + formatBanData(data); + next(null, data); + }, + ], callback); }; User.getHistory = function (set, callback) { - db.getSortedSetRevRangeWithScores(set, 0, -1, function (err, data) { - if (err) { - return callback(err); - } - callback(null, data.map(function (set) { - set.timestamp = set.score; - set.timestampISO = utils.toISOString(set.score); - set.value = validator.escape(String(set.value.split(':')[0])); - delete set.score; - return set; - })); - }); + async.waterfall([ + function (next) { + db.getSortedSetRevRangeWithScores(set, 0, -1, next); + }, + function (data, next) { + next(null, data.map(function (set) { + set.timestamp = set.score; + set.timestampISO = utils.toISOString(set.score); + set.value = validator.escape(String(set.value.split(':')[0])); + delete set.score; + return set; + })); + }, + ], callback); }; function getFlagMetadata(data, callback) { var pids = data.flags.map(function (flagObj) { return parseInt(flagObj.value, 10); }); + async.waterfall([ + function (next) { + posts.getPostsFields(pids, ['tid'], next); + }, + function (postData, next) { + var tids = postData.map(function (post) { + return post.tid; + }); - posts.getPostsFields(pids, ['tid'], function (err, postData) { - if (err) { - return callback(err); - } - - var tids = postData.map(function (post) { - return post.tid; - }); - - topics.getTopicsFields(tids, ['title'], function (err, topicData) { - if (err) { - return callback(err); - } + topics.getTopicsFields(tids, ['title'], next); + }, + function (topicData, next) { data.flags = data.flags.map(function (flagObj, idx) { flagObj.pid = flagObj.value; flagObj.timestamp = flagObj.score; @@ -112,10 +104,9 @@ module.exports = function (User) { return _.extend(flagObj, topicData[idx]); }); - - callback(null, data); - }); - }); + next(null, data); + }, + ], callback); } function formatBanData(data) { diff --git a/src/user/profile.js b/src/user/profile.js index 8347d6de74..91956e9bf4 100644 --- a/src/user/profile.js +++ b/src/user/profile.js @@ -195,27 +195,31 @@ module.exports = function (User) { return callback(); } - User.getUserFields(uid, ['username', 'userslug'], function (err, userData) { - if (err) { - return callback(err); - } - - async.parallel([ - function (next) { - updateUidMapping('username', uid, newUsername, userData.username, next); - }, - function (next) { - var newUserslug = utils.slugify(newUsername); - updateUidMapping('userslug', uid, newUserslug, userData.userslug, next); - }, - function (next) { - async.series([ - async.apply(db.sortedSetRemove, 'username:sorted', userData.username.toLowerCase() + ':' + uid), - async.apply(db.sortedSetAdd, 'username:sorted', 0, newUsername.toLowerCase() + ':' + uid), - async.apply(db.sortedSetAdd, 'user:' + uid + ':usernames', Date.now(), newUsername + ':' + Date.now()), - ], next); - }, - ], callback); + async.waterfall([ + function (next) { + User.getUserFields(uid, ['username', 'userslug'], next); + }, + function (userData, next) { + async.parallel([ + function (next) { + updateUidMapping('username', uid, newUsername, userData.username, next); + }, + function (next) { + var newUserslug = utils.slugify(newUsername); + updateUidMapping('userslug', uid, newUserslug, userData.userslug, next); + }, + function (next) { + var now = Date.now(); + async.series([ + async.apply(db.sortedSetRemove, 'username:sorted', userData.username.toLowerCase() + ':' + uid), + async.apply(db.sortedSetAdd, 'username:sorted', 0, newUsername.toLowerCase() + ':' + uid), + async.apply(db.sortedSetAdd, 'user:' + uid + ':usernames', now, newUsername + ':' + now), + ], next); + }, + ], next); + }, + ], function (err) { + callback(err); }); } diff --git a/test/notifications.js b/test/notifications.js index d65b4c0bb5..0100c78737 100644 --- a/test/notifications.js +++ b/test/notifications.js @@ -251,6 +251,10 @@ describe('Notifications', function () { }); }); + it('should prune notifications', function (done) { + notifications.prune(done); + }); + after(function (done) { db.emptydb(done); diff --git a/test/user.js b/test/user.js index 943c348872..bfef9a1178 100644 --- a/test/user.js +++ b/test/user.js @@ -95,7 +95,7 @@ describe('User', function () { assert.ifError(err); assert.strictEqual(username, 'Jane Doe 9'); - done(); + next(); }); }, ], done); @@ -299,7 +299,7 @@ describe('User', function () { }); it('.send() should create a new reset code and reset password', function (done) { - User.reset.send('reset@me.com', function (err, code) { + User.reset.send('reset@me.com', function (err) { if (err) { console.log(err); } @@ -751,7 +751,28 @@ describe('User', function () { }); }); - describe('.getModerationHistory', function () { + describe('user info', function () { + it('should return error if there is no ban reason', function (done) { + User.getLatestBanInfo(123, function (err) { + assert.equal(err.message, 'no-ban-info'); + done(); + }); + }); + + + it('should get history from set', function (done) { + var now = Date.now(); + db.sortedSetAdd('user:' + testUid + ':usernames', now, 'derp:' + now, function (err) { + assert.ifError(err); + User.getHistory('user:' + testUid + ':usernames', function (err, data) { + assert.ifError(err); + assert.equal(data[0].value, 'derp'); + assert.equal(data[0].timestamp, now); + done(); + }); + }); + }); + it('should return the correct ban reason', function (done) { async.series([ function (next) { @@ -960,15 +981,15 @@ describe('User', function () { assert.ifError(err); socketUser.setModerationNote({ uid: adminUid }, { uid: testUid, note: 'this is a test user' }, function (err) { assert.ifError(err); - db.getSortedSetRevRange('uid:' + testUid + ':moderation:notes', 0, 0, function (err, notes) { + socketUser.setModerationNote({ uid: adminUid }, { uid: testUid, note: 'second moderation note' }, function (err) { assert.ifError(err); - notes = notes.map(function (noteData) { - return JSON.parse(noteData); + User.getModerationNotes(testUid, 0, -1, function (err, notes) { + assert.ifError(err); + assert.equal(notes[0].note, 'second moderation note'); + assert.equal(notes[0].uid, adminUid); + assert(notes[0].timestamp); + done(); }); - assert.equal(notes[0].note, 'this is a test user'); - assert.equal(notes[0].uid, adminUid); - assert(notes[0].timestamp); - done(); }); }); });