From feb359f7d45fd781e54cf4ca6f57282f1195c7ee Mon Sep 17 00:00:00 2001 From: barisusakli Date: Mon, 27 Feb 2017 20:16:36 +0300 Subject: [PATCH 1/9] closes #5479 --- src/controllers/categories.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/controllers/categories.js b/src/controllers/categories.js index 8112dead67..12f07f971e 100644 --- a/src/controllers/categories.js +++ b/src/controllers/categories.js @@ -13,10 +13,10 @@ var categoriesController = {}; categoriesController.list = function (req, res, next) { res.locals.metaTags = [{ name: 'title', - content: validator.escape(String(meta.config.title || 'NodeBB')), + content: String(meta.config.title || 'NodeBB'), }, { name: 'description', - content: validator.escape(String(meta.config.description || '')), + content: String(meta.config.description || ''), }, { property: 'og:title', content: '[[pages:categories]]', From 86a8b8ab9304e89da6c69e1dfec73d95cebf7d0c Mon Sep 17 00:00:00 2001 From: psychobunny Date: Mon, 27 Feb 2017 15:27:07 -0500 Subject: [PATCH 2/9] posts:votes sorted set --- src/posts.js | 3 +++ src/upgrade.js | 46 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/posts.js b/src/posts.js index 2f9132a25b..83b8e39a1f 100644 --- a/src/posts.js +++ b/src/posts.js @@ -248,6 +248,9 @@ var plugins = require('./plugins'); }, ], next); }, + function (next) { + db.sortedSetAdd('posts:votes', postData.votes, postData.pid, next); + }, function (next) { Posts.setPostFields(postData.pid, { upvotes: postData.upvotes, downvotes: postData.downvotes }, next); }, diff --git a/src/upgrade.js b/src/upgrade.js index 46075ff5e9..14b394efb1 100644 --- a/src/upgrade.js +++ b/src/upgrade.js @@ -12,7 +12,7 @@ var schemaDate; var thisSchemaDate; // IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema -var latestSchema = Date.UTC(2017, 1, 25); +var latestSchema = Date.UTC(2017, 1, 27); Upgrade.check = function (callback) { db.get('schemaDate', function (err, value) { @@ -479,6 +479,50 @@ Upgrade.upgrade = function (callback) { next(); } }, + function (next) { + thisSchemaDate = Date.UTC(2017, 1, 27); + var schemaName = '[2017/2/27] New sorted set posts:votes'; + + if (schemaDate < thisSchemaDate) { + updatesMade = true; + winston.verbose(schemaName); + + db.getSortedSetRange('categories:cid', 0, -1, function (err, cids) { + if (err) { + return next(err); + } + + async.eachSeries(cids, function (cid, next) { + db.getSortedSetRevRange('cid:' + cid + ':pids', 0, -1, function (err, pids) { + if (err || !pids) { + return next(err); + } + + async.each(pids, function(pid, next) { + db.getObjectFields('post:' + pid, ['upvotes', 'downvotes'], function (err, postData) { + if (err || !postData) { + return next(err); + } + + var votes = parseInt(postData.upvotes || 0, 10) - parseInt(postData.downvotes || 0, 10); + db.sortedSetAdd('posts:votes', votes, pid, next); + }); + }, next); + }); + }, function (err) { + if (err) { + return next(err); + } + + winston.info(schemaName + ' - done'); + Upgrade.update(thisSchemaDate, next); + }); + }); + } else { + winston.info(schemaName + ' - skipped!'); + next(); + } + }, // Add new schema updates here // IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema IN LINE 24!!! ], function (err) { From 5d9b6062d6f72cb8d9d40e0ce9555dc619cde4cd Mon Sep 17 00:00:00 2001 From: psychobunny Date: Mon, 27 Feb 2017 17:03:40 -0500 Subject: [PATCH 3/9] simpler method for getting pids --- src/upgrade.js | 44 +++++++++++++++++--------------------------- 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/src/upgrade.js b/src/upgrade.js index 14b394efb1..8976a63290 100644 --- a/src/upgrade.js +++ b/src/upgrade.js @@ -480,43 +480,33 @@ Upgrade.upgrade = function (callback) { } }, function (next) { - thisSchemaDate = Date.UTC(2017, 1, 27); + thisSchemaDate = Date.UTC(2017, 1, 28); var schemaName = '[2017/2/27] New sorted set posts:votes'; if (schemaDate < thisSchemaDate) { updatesMade = true; winston.verbose(schemaName); - db.getSortedSetRange('categories:cid', 0, -1, function (err, cids) { + require('./batch').processSortedSet('posts:pid', function (pids, next) { + async.each(pids, function (pid, next) { + async.each(pids, function (pid, next) { + db.getObjectFields('post:' + pid, ['upvotes', 'downvotes'], function (err, postData) { + if (err || !postData) { + return next(err); + } + + var votes = parseInt(postData.upvotes || 0, 10) - parseInt(postData.downvotes || 0, 10); + db.sortedSetAdd('posts:votes', votes, pid, next); + }); + }, next); + }, next); + }, {}, function (err) { if (err) { return next(err); } - async.eachSeries(cids, function (cid, next) { - db.getSortedSetRevRange('cid:' + cid + ':pids', 0, -1, function (err, pids) { - if (err || !pids) { - return next(err); - } - - async.each(pids, function(pid, next) { - db.getObjectFields('post:' + pid, ['upvotes', 'downvotes'], function (err, postData) { - if (err || !postData) { - return next(err); - } - - var votes = parseInt(postData.upvotes || 0, 10) - parseInt(postData.downvotes || 0, 10); - db.sortedSetAdd('posts:votes', votes, pid, next); - }); - }, next); - }); - }, function (err) { - if (err) { - return next(err); - } - - winston.info(schemaName + ' - done'); - Upgrade.update(thisSchemaDate, next); - }); + winston.info(schemaName + ' - done'); + Upgrade.update(thisSchemaDate, next); }); } else { winston.info(schemaName + ' - skipped!'); From 7bdbe7d9db6536c4e22e7b89d5ad91d3936ef3ce Mon Sep 17 00:00:00 2001 From: psychobunny Date: Mon, 27 Feb 2017 17:04:36 -0500 Subject: [PATCH 4/9] wrong date --- src/upgrade.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/upgrade.js b/src/upgrade.js index 8976a63290..038f7b8389 100644 --- a/src/upgrade.js +++ b/src/upgrade.js @@ -480,7 +480,7 @@ Upgrade.upgrade = function (callback) { } }, function (next) { - thisSchemaDate = Date.UTC(2017, 1, 28); + thisSchemaDate = Date.UTC(2017, 1, 27); var schemaName = '[2017/2/27] New sorted set posts:votes'; if (schemaDate < thisSchemaDate) { From 06eabbc5076a093740aaad1358785eafae944a7a Mon Sep 17 00:00:00 2001 From: psychobunny Date: Mon, 27 Feb 2017 17:07:17 -0500 Subject: [PATCH 5/9] typo --- src/upgrade.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/upgrade.js b/src/upgrade.js index 038f7b8389..2b4510b099 100644 --- a/src/upgrade.js +++ b/src/upgrade.js @@ -489,16 +489,14 @@ Upgrade.upgrade = function (callback) { require('./batch').processSortedSet('posts:pid', function (pids, next) { async.each(pids, function (pid, next) { - async.each(pids, function (pid, next) { - db.getObjectFields('post:' + pid, ['upvotes', 'downvotes'], function (err, postData) { - if (err || !postData) { - return next(err); - } + db.getObjectFields('post:' + pid, ['upvotes', 'downvotes'], function (err, postData) { + if (err || !postData) { + return next(err); + } - var votes = parseInt(postData.upvotes || 0, 10) - parseInt(postData.downvotes || 0, 10); - db.sortedSetAdd('posts:votes', votes, pid, next); - }); - }, next); + var votes = parseInt(postData.upvotes || 0, 10) - parseInt(postData.downvotes || 0, 10); + db.sortedSetAdd('posts:votes', votes, pid, next); + }); }, next); }, {}, function (err) { if (err) { From ef93ef3dd4e26803e3c19a2c8a3268fb3e15d9e7 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Tue, 28 Feb 2017 12:23:42 +0300 Subject: [PATCH 6/9] if user does not have settings object skip --- src/upgrade.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/upgrade.js b/src/upgrade.js index 8c04611941..a96cdf508e 100644 --- a/src/upgrade.js +++ b/src/upgrade.js @@ -356,8 +356,8 @@ Upgrade.upgrade = function (callback) { batch.processSortedSet('users:joindate', function (ids, next) { async.each(ids, function (uid, next) { - user.getSettings(uid, function (err, settings) { - if (err) { + db.getObject('user:' + uid + ':settings', function (err, settings) { + if (err || !settings) { return next(err); } From bb1045c5a09d778cd39a32db7c2bf3e9eb983e07 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Tue, 28 Feb 2017 12:29:49 +0300 Subject: [PATCH 7/9] remove unused require --- src/controllers/categories.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/controllers/categories.js b/src/controllers/categories.js index 12f07f971e..d5cd04b504 100644 --- a/src/controllers/categories.js +++ b/src/controllers/categories.js @@ -2,7 +2,6 @@ var async = require('async'); var nconf = require('nconf'); -var validator = require('validator'); var categories = require('../categories'); var meta = require('../meta'); From 8a0cf6c0ac61cdec0719a136f2f5c951677e13a7 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Tue, 28 Feb 2017 15:16:49 +0300 Subject: [PATCH 8/9] more admin socket tests --- src/meta/errors.js | 24 ++--- src/socket.io/admin.js | 99 +++++++++++---------- test/meta.js | 11 +++ test/socket.io.js | 194 +++++++++++++++++++++++++++++++++++++---- 4 files changed, 252 insertions(+), 76 deletions(-) diff --git a/src/meta/errors.js b/src/meta/errors.js index 085cb84fea..fb169764ba 100644 --- a/src/meta/errors.js +++ b/src/meta/errors.js @@ -1,5 +1,6 @@ 'use strict'; +var async = require('async'); var validator = require('validator'); var db = require('../database'); @@ -16,18 +17,19 @@ module.exports = function (Meta) { }; Meta.errors.get = function (escape, callback) { - db.getSortedSetRevRangeWithScores('errors:404', 0, -1, function (err, data) { - if (err) { - return callback(err); - } + async.waterfall([ + function (next) { + db.getSortedSetRevRangeWithScores('errors:404', 0, -1, next); + }, + function (data, next) { + data = data.map(function (nfObject) { + nfObject.value = escape ? validator.escape(String(nfObject.value || '')) : nfObject.value; + return nfObject; + }); - data = data.map(function (nfObject) { - nfObject.value = escape ? validator.escape(String(nfObject.value || '')) : nfObject.value; - return nfObject; - }); - - callback(null, data); - }); + next(null, data); + }, + ], callback); }; Meta.errors.clear = function (callback) { diff --git a/src/socket.io/admin.js b/src/socket.io/admin.js index 0e7c277dfd..9eba77f39b 100644 --- a/src/socket.io/admin.js +++ b/src/socket.io/admin.js @@ -93,17 +93,18 @@ SocketAdmin.themes.set = function (socket, data, callback) { return callback(new Error('[[error:invalid-data]]')); } - var wrappedCallback = function (err) { - if (err) { - return callback(err); - } - meta.themes.set(data, callback); - }; - if (data.type === 'bootswatch') { - wrappedCallback(); - } else { - widgets.reset(wrappedCallback); - } + async.waterfall([ + function (next) { + if (data.type === 'bootswatch') { + setImmediate(next); + } else { + widgets.reset(next); + } + }, + function (next) { + meta.themes.set(data, next); + }, + ], callback); }; SocketAdmin.plugins.toggleActive = function (socket, plugin_id, callback) { @@ -125,7 +126,7 @@ SocketAdmin.plugins.orderActivePlugins = function (socket, data, callback) { if (plugin && plugin.name) { db.sortedSetAdd('plugins:active', plugin.order || 0, plugin.name, next); } else { - next(); + setImmediate(next); } }, callback); }; @@ -148,7 +149,7 @@ SocketAdmin.config.set = function (socket, data, callback) { } var _data = {}; _data[data.key] = data.value; - SocketAdmin.config.setMultiple(socket, data, callback); + SocketAdmin.config.setMultiple(socket, _data, callback); }; SocketAdmin.config.setMultiple = function (socket, data, callback) { @@ -204,6 +205,10 @@ SocketAdmin.email.test = function (socket, data, callback) { }; SocketAdmin.analytics.get = function (socket, data, callback) { + if (!data || !data.graph || !data.units) { + return callback(new Error('[[error:invalid-data]]')); + } + // Default returns views from past 24 hours, by hour if (data.units === 'days') { data.amount = 30; @@ -211,34 +216,30 @@ SocketAdmin.analytics.get = function (socket, data, callback) { data.amount = 24; } - if (data && data.graph && data.units && data.amount) { - if (data.graph === 'traffic') { - async.parallel({ - uniqueVisitors: function (next) { - if (data.units === 'days') { - analytics.getDailyStatsForSet('analytics:uniquevisitors', data.until || Date.now(), data.amount, next); - } else { - analytics.getHourlyStatsForSet('analytics:uniquevisitors', data.until || Date.now(), data.amount, next); - } - }, - pageviews: function (next) { - if (data.units === 'days') { - analytics.getDailyStatsForSet('analytics:pageviews', data.until || Date.now(), data.amount, next); - } else { - analytics.getHourlyStatsForSet('analytics:pageviews', data.until || Date.now(), data.amount, next); - } - }, - monthlyPageViews: function (next) { - analytics.getMonthlyPageViews(next); - }, - }, function (err, data) { - data.pastDay = data.pageviews.reduce(function (a, b) { return parseInt(a, 10) + parseInt(b, 10); }); - data.pageviews[data.pageviews.length - 1] = parseInt(data.pageviews[data.pageviews.length - 1], 10) + analytics.getUnwrittenPageviews(); - callback(err, data); - }); - } - } else { - callback(new Error('Invalid analytics call')); + if (data.graph === 'traffic') { + async.parallel({ + uniqueVisitors: function (next) { + if (data.units === 'days') { + analytics.getDailyStatsForSet('analytics:uniquevisitors', data.until || Date.now(), data.amount, next); + } else { + analytics.getHourlyStatsForSet('analytics:uniquevisitors', data.until || Date.now(), data.amount, next); + } + }, + pageviews: function (next) { + if (data.units === 'days') { + analytics.getDailyStatsForSet('analytics:pageviews', data.until || Date.now(), data.amount, next); + } else { + analytics.getHourlyStatsForSet('analytics:pageviews', data.until || Date.now(), data.amount, next); + } + }, + monthlyPageViews: function (next) { + analytics.getMonthlyPageViews(next); + }, + }, function (err, data) { + data.pastDay = data.pageviews.reduce(function (a, b) { return parseInt(a, 10) + parseInt(b, 10); }); + data.pageviews[data.pageviews.length - 1] = parseInt(data.pageviews[data.pageviews.length - 1], 10) + analytics.getUnwrittenPageviews(); + callback(err, data); + }); } }; @@ -259,13 +260,15 @@ SocketAdmin.deleteAllEvents = function (socket, data, callback) { }; SocketAdmin.getSearchDict = function (socket, data, callback) { - user.getSettings(socket.uid, function (err, settings) { - if (err) { - return callback(err); - } - var lang = settings.userLang || meta.config.defaultLang || 'en-GB'; - getAdminSearchDict(lang, callback); - }); + async.waterfall([ + function (next) { + user.getSettings(socket.uid, next); + }, + function (settings, next) { + var lang = settings.userLang || meta.config.defaultLang || 'en-GB'; + getAdminSearchDict(lang, next); + }, + ], callback); }; SocketAdmin.deleteAllSessions = function (socket, data, callback) { diff --git a/test/meta.js b/test/meta.js index 9d1a69b00c..4544570b42 100644 --- a/test/meta.js +++ b/test/meta.js @@ -123,6 +123,17 @@ describe('meta', function () { }); }); + it('should set single config value', function (done) { + socketAdmin.config.set({ uid: fooUid }, { key: 'someKey', value: 'someValue' }, function (err) { + assert.ifError(err); + meta.configs.getFields(['someKey'], function (err, data) { + assert.ifError(err); + assert.equal(data.someKey, 'someValue'); + done(); + }); + }); + }); + it('should set config value', function (done) { meta.configs.set('someField', 'someValue', function (err) { assert.ifError(err); diff --git a/test/socket.io.js b/test/socket.io.js index 780fdb49aa..095c3b5440 100644 --- a/test/socket.io.js +++ b/test/socket.io.js @@ -16,6 +16,9 @@ var user = require('../src/user'); var groups = require('../src/groups'); var categories = require('../src/categories'); var helpers = require('./helpers'); +var meta = require('../src/meta'); + +var socketAdmin = require('../src/socket.io/admin'); describe('socket.io', function () { var io; @@ -156,7 +159,6 @@ describe('socket.io', function () { }); it('should make user admin', function (done) { - var socketAdmin = require('../src/socket.io/admin'); socketAdmin.user.makeAdmins({ uid: adminUid }, [regularUid], function (err) { assert.ifError(err); groups.isMember(regularUid, 'administrators', function (err, isMember) { @@ -168,7 +170,6 @@ describe('socket.io', function () { }); it('should make user non-admin', function (done) { - var socketAdmin = require('../src/socket.io/admin'); socketAdmin.user.removeAdmins({ uid: adminUid }, [regularUid], function (err) { assert.ifError(err); groups.isMember(regularUid, 'administrators', function (err, isMember) { @@ -180,7 +181,6 @@ describe('socket.io', function () { }); describe('create/delete', function () { - var socketAdmin = require('../src/socket.io/admin'); var uid; it('should create a user', function (done) { socketAdmin.user.createUser({ uid: adminUid }, { username: 'foo1' }, function (err, _uid) { @@ -214,7 +214,6 @@ describe('socket.io', function () { }); it('should error with invalid data', function (done) { - var socketAdmin = require('../src/socket.io/admin'); socketAdmin.user.createUser({ uid: adminUid }, null, function (err) { assert.equal(err.message, '[[error:invalid-data]]'); done(); @@ -222,7 +221,6 @@ describe('socket.io', function () { }); it('should reset lockouts', function (done) { - var socketAdmin = require('../src/socket.io/admin'); socketAdmin.user.resetLockouts({ uid: adminUid }, [regularUid], function (err) { assert.ifError(err); done(); @@ -230,7 +228,6 @@ describe('socket.io', function () { }); it('should reset flags', function (done) { - var socketAdmin = require('../src/socket.io/admin'); socketAdmin.user.resetFlags({ uid: adminUid }, [regularUid], function (err) { assert.ifError(err); done(); @@ -239,7 +236,6 @@ describe('socket.io', function () { describe('validation emails', function () { - var socketAdmin = require('../src/socket.io/admin'); var meta = require('../src/meta'); it('should validate emails', function (done) { @@ -254,7 +250,6 @@ describe('socket.io', function () { }); it('should error with invalid uids', function (done) { - var socketAdmin = require('../src/socket.io/admin'); socketAdmin.user.sendValidationEmail({ uid: adminUid }, null, function (err) { assert.equal(err.message, '[[error:invalid-data]]'); done(); @@ -262,7 +257,6 @@ describe('socket.io', function () { }); it('should error if email validation is not required', function (done) { - var socketAdmin = require('../src/socket.io/admin'); socketAdmin.user.sendValidationEmail({ uid: adminUid }, [regularUid], function (err) { assert.equal(err.message, '[[error:email-confirmations-are-disabled]]'); done(); @@ -270,7 +264,6 @@ describe('socket.io', function () { }); it('should send validation email', function (done) { - var socketAdmin = require('../src/socket.io/admin'); meta.config.requireEmailConfirmation = 1; socketAdmin.user.sendValidationEmail({ uid: adminUid }, [regularUid], function (err) { assert.ifError(err); @@ -281,7 +274,6 @@ describe('socket.io', function () { }); it('should search users', function (done) { - var socketAdmin = require('../src/socket.io/admin'); socketAdmin.user.search({ uid: adminUid }, { query: 'reg', searchBy: 'username' }, function (err, data) { assert.ifError(err); assert.equal(data.matchCount, 1); @@ -337,6 +329,13 @@ describe('socket.io', function () { }); }); + it('should error to get daily analytics with invalid data', function (done) { + io.emit('admin.analytics.get', null, function (err) { + assert.equal(err.message, '[[error:invalid-data]]'); + done(); + }); + }); + it('should get daily analytics', function (done) { io.emit('admin.analytics.get', { graph: 'traffic', units: 'days' }, function (err, data) { assert.ifError(err); @@ -356,7 +355,6 @@ describe('socket.io', function () { }); it('should return error', function (done) { - var socketAdmin = require('../src/socket.io/admin'); socketAdmin.before({ uid: 10 }, 'someMethod', {}, function (err) { assert.equal(err.message, '[[error:no-privileges]]'); done(); @@ -364,8 +362,6 @@ describe('socket.io', function () { }); it('should get room stats', function (done) { - var socketAdmin = require('../src/socket.io/admin'); - io.emit('meta.rooms.enter', { enter: 'topic_1' }, function (err) { assert.ifError(err); socketAdmin.rooms.getAll({ uid: 10 }, {}, function (err) { @@ -387,8 +383,6 @@ describe('socket.io', function () { }); it('should get room stats', function (done) { - var socketAdmin = require('../src/socket.io/admin'); - io.emit('meta.rooms.enter', { enter: 'category_1' }, function (err) { assert.ifError(err); socketAdmin.rooms.getAll({ uid: 10 }, {}, function (err) { @@ -405,7 +399,6 @@ describe('socket.io', function () { }); it('should get admin search dictionary', function (done) { - var socketAdmin = require('../src/socket.io/admin'); socketAdmin.getSearchDict({ uid: adminUid }, {}, function (err, data) { assert.ifError(err); assert(Array.isArray(data)); @@ -416,6 +409,173 @@ describe('socket.io', function () { }); }); + it('should fire event', function (done) { + io.on('testEvent', function (data) { + assert.equal(data.foo, 1); + done(); + }); + socketAdmin.fireEvent({ uid: adminUid }, { name: 'testEvent', payload: { foo: 1 } }, function (err) { + assert.ifError(err); + }); + }); + + it('should error with invalid data', function (done) { + socketAdmin.themes.set({ uid: adminUid }, null, function (err) { + assert.equal(err.message, '[[error:invalid-data]]'); + done(); + }); + }); + + it('should set theme to bootswatch', function (done) { + socketAdmin.themes.set({ uid: adminUid }, { type: 'bootswatch', src: 'darkly' }, function (err) { + assert.ifError(err); + meta.configs.get('theme:src', function (err, id) { + assert.ifError(err); + assert.equal(id, 'darkly'); + done(); + }); + }); + }); + + it('should set theme to local persona', function (done) { + socketAdmin.themes.set({ uid: adminUid }, { type: 'local', id: 'nodebb-theme-persona' }, function (err) { + assert.ifError(err); + meta.configs.get('theme:id', function (err, id) { + assert.ifError(err); + assert.equal(id, 'nodebb-theme-persona'); + done(); + }); + }); + }); + + it('should toggle plugin active', function (done) { + socketAdmin.plugins.toggleActive({ uid: adminUid }, 'nodebb-plugin-location-to-map', function (err, data) { + assert.ifError(err); + assert.deepEqual(data, { id: 'nodebb-plugin-location-to-map', active: true }); + done(); + }); + }); + + it('should toggle plugin install', function (done) { + socketAdmin.plugins.toggleInstall({ uid: adminUid }, { id: 'nodebb-plugin-location-to-map', version: 'latest' }, function (err, data) { + assert.ifError(err); + assert.equal(data.name, 'nodebb-plugin-location-to-map'); + done(); + }); + }); + + it('should get list of active plugins', function (done) { + socketAdmin.plugins.getActive({ uid: adminUid }, {}, function (err, data) { + assert.ifError(err); + assert(Array.isArray(data)); + done(); + }); + }); + + it('should order active plugins', function (done) { + var data = [ + { name: 'nodebb-theme-persona', order: 0 }, + { name: 'nodebb-plugin-dbsearch', order: 1 }, + { ignoreme: 'wrong data' }, + ]; + socketAdmin.plugins.orderActivePlugins({ uid: adminUid }, data, function (err) { + assert.ifError(err); + db.sortedSetRank('plugins:active', 'nodebb-plugin-dbsearch', function (err, rank) { + assert.ifError(err); + assert.equal(rank, 1); + done(); + }); + }); + }); + + it('should upgrade plugin', function (done) { + socketAdmin.plugins.upgrade({ uid: adminUid }, { id: 'nodebb-plugin-location-to-map', version: 'latest' }, function (err) { + assert.ifError(err); + done(); + }); + }); + + it('should error with invalid data', function (done) { + socketAdmin.widgets.set({ uid: adminUid }, null, function (err) { + assert.equal(err.message, '[[error:invalid-data]]'); + done(); + }); + }); + + it('should error with invalid data', function (done) { + var data = { template: 'global', location: 'sidebar', widgets: [{ widget: 'html', data: { html: 'test', title: 'test', container: '' } }] }; + socketAdmin.widgets.set({ uid: adminUid }, data, function (err) { + assert.ifError(err); + db.getObjectField('widgets:global', 'sidebar', function (err, widgetData) { + assert.ifError(err); + + assert.equal(JSON.parse(widgetData)[0].data.html, 'test'); + done(); + }); + }); + }); + + it('should clear sitemap cache', function (done) { + socketAdmin.settings.clearSitemapCache({ uid: adminUid }, {}, function (err) { + assert.ifError(err); + done(); + }); + }); + + it('should send test email', function (done) { + socketAdmin.email.test({ uid: adminUid }, { template: 'digest.tpl' }, function (err) { + assert.ifError(err); + done(); + }); + }); + + it('should get logs', function (done) { + var fs = require('fs'); + var path = require('path'); + meta.logs.path = path.join(nconf.get('base_dir'), 'test/files', 'output.log'); + fs.appendFile(meta.logs.path, 'some logs', function (err) { + assert.ifError(err); + + socketAdmin.logs.get({ uid: adminUid }, {}, function (err, data) { + assert.ifError(err); + assert(data); + done(); + }); + }); + }); + + it('should clear logs', function (done) { + socketAdmin.logs.clear({ uid: adminUid }, {}, function (err) { + assert.ifError(err); + socketAdmin.logs.get({ uid: adminUid }, {}, function (err, data) { + assert.ifError(err); + assert.equal(data.length, 0); + done(); + }); + }); + }); + + it('should clear errors', function (done) { + socketAdmin.errors.clear({ uid: adminUid }, {}, function (err) { + assert.ifError(err); + db.exists('error:404', function (err, exists) { + assert.ifError(err); + assert(!exists); + done(); + }); + }); + }); + + it('shoudl delete all events', function (done) { + socketAdmin.deleteAllEvents({ uid: adminUid }, {}, function (err) { + assert.ifError(err); + db.sortedSetCard('events:time', function (err, count) { + assert.ifError(err); + assert.equal(count, 0); + done(); + }); + }); + }); after(function (done) { db.emptydb(done); From 2e47cf4db31edfa3d9a38b7bd21d16cdadbd8dee Mon Sep 17 00:00:00 2001 From: barisusakli Date: Tue, 28 Feb 2017 16:42:10 +0300 Subject: [PATCH 9/9] intersititial test --- src/controllers/index.js | 46 +++++++++++++++---------------- src/plugins/hooks.js | 7 +++++ test/controllers.js | 59 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 85 insertions(+), 27 deletions(-) diff --git a/src/controllers/index.js b/src/controllers/index.js index 1ec1696e21..59f5527ef4 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -201,37 +201,35 @@ Controllers.registerInterstitial = function (req, res, next) { return res.redirect(nconf.get('relative_path') + '/register'); } - plugins.fireHook('filter:register.interstitial', { - userData: req.session.registration, - interstitials: [], - }, function (err, data) { - if (err) { - return next(err); - } - - if (!data.interstitials.length) { - // No interstitials, redirect to home - delete req.session.registration; - return res.redirect('/'); - } - - var renders = data.interstitials.map(function (interstitial) { - return async.apply(req.app.render.bind(req.app), interstitial.template, interstitial.data || {}); - }); - var errors = req.flash('error'); - - async.parallel(renders, function (err, sections) { - if (err) { - return next(err); + async.waterfall([ + function (next) { + plugins.fireHook('filter:register.interstitial', { + userData: req.session.registration, + interstitials: [], + }, next); + }, + function (data, next) { + if (!data.interstitials.length) { + // No interstitials, redirect to home + delete req.session.registration; + return res.redirect('/'); } + var renders = data.interstitials.map(function (interstitial) { + return async.apply(req.app.render.bind(req.app), interstitial.template, interstitial.data || {}); + }); + + async.parallel(renders, next); + }, + function (sections) { + var errors = req.flash('error'); res.render('registerComplete', { title: '[[pages:registration-complete]]', errors: errors, sections: sections, }); - }); - }); + }, + ], next); }; Controllers.compose = function (req, res, next) { diff --git a/src/plugins/hooks.js b/src/plugins/hooks.js index 208eaae1b8..12303555fc 100644 --- a/src/plugins/hooks.js +++ b/src/plugins/hooks.js @@ -75,6 +75,13 @@ module.exports = function (Plugins) { } }; + Plugins.unregisterHook = function (id, hook, method) { + var hooks = Plugins.loadedHooks[hook] || []; + Plugins.loadedHooks[hook] = hooks.filter(function (hookData) { + return hookData && hookData.id !== id && hookData.method !== method; + }); + }; + Plugins.fireHook = function (hook, params, callback) { callback = typeof callback === 'function' ? callback : function () {}; diff --git a/test/controllers.js b/test/controllers.js index c456d3fd69..d79235d16f 100644 --- a/test/controllers.js +++ b/test/controllers.js @@ -136,6 +136,59 @@ describe('Controllers', function () { }); }); + it('should load /register/complete', function (done) { + var plugins = require('../src/plugins'); + function hookMethod(data, next) { + data.interstitials.push({ template: 'topic.tpl', data: {} }); + next(null, data); + } + + plugins.registerHook('myTestPlugin', { + hook: 'filter:register.interstitial', + method: hookMethod, + }); + + var data = { + username: 'interstitial', + password: '123456', + email: 'test@me.com', + }; + + var jar = request.jar(); + request({ + url: nconf.get('url') + '/api/config', + json: true, + jar: jar, + }, function (err, response, body) { + assert.ifError(err); + + request.post(nconf.get('url') + '/register', { + form: data, + json: true, + jar: jar, + headers: { + 'x-csrf-token': body.csrf_token, + }, + }, function (err, res, body) { + assert.ifError(err); + assert.equal(res.statusCode, 200); + assert.equal(body.referrer, nconf.get('relative_path') + '/register/complete'); + request(nconf.get('url') + '/api/register/complete', { + jar: jar, + json: true, + }, function (err, res, body) { + assert.ifError(err); + assert.equal(res.statusCode, 200); + assert(body.sections); + assert(body.errors); + assert(body.title); + plugins.unregisterHook('myTestPlugin', 'filter:register.interstitial', hookMethod); + done(); + }); + }); + }); + }); + it('should load /robots.txt', function (done) { request(nconf.get('url') + '/robots.txt', function (err, res, body) { assert.ifError(err); @@ -471,7 +524,7 @@ describe('Controllers', function () { hidden: 1, }, function (err) { assert.ifError(err); - request(nconf.get('url') + '/groups/hidden-group/members', function (err, res, body) { + request(nconf.get('url') + '/groups/hidden-group/members', function (err, res) { assert.ifError(err); assert.equal(res.statusCode, 404); done(); @@ -531,7 +584,7 @@ describe('Controllers', function () { headers: { 'x-csrf-token': csrf_token, }, - }, function (err, res, body) { + }, function (err, res) { assert.ifError(err); assert.equal(res.statusCode, 404); done(); @@ -689,7 +742,7 @@ describe('Controllers', function () { }); it('should return 503 in maintenance mode', function (done) { - request(nconf.get('url') + '/recent', { json: true }, function (err, res, body) { + request(nconf.get('url') + '/recent', { json: true }, function (err, res) { assert.ifError(err); assert.equal(res.statusCode, 503); done();