From 12f366f4b47e70c66bc1c74122fcd7f7a8f8619e Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sun, 16 Oct 2016 16:43:38 +0300 Subject: [PATCH] more tests register/login/logout tests ability to test socket.io emits for logged in users --- package.json | 3 +- src/socket.io/index.js | 2 +- test/authentication.js | 127 +++++++++++++++++++++++++++++++++++++++++ test/mocks/newXhr.js | 30 ++++++++++ test/socket.io.js | 111 +++++++++++++++++++++++++++++++++++ 5 files changed, 271 insertions(+), 2 deletions(-) create mode 100644 test/authentication.js create mode 100644 test/mocks/newXhr.js create mode 100644 test/socket.io.js diff --git a/package.json b/package.json index d2ed886a91..774c69fcf2 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,8 @@ "grunt-contrib-watch": "^1.0.0", "istanbul": "^0.4.2", "mocha": "~3.1.0", - "mocha-lcov-reporter": "^1.2.0" + "mocha-lcov-reporter": "^1.2.0", + "xmlhttprequest": "1.8.0" }, "bugs": { "url": "https://github.com/NodeBB/NodeBB/issues" diff --git a/src/socket.io/index.js b/src/socket.io/index.js index 7df8684d3d..f871f7ecd1 100644 --- a/src/socket.io/index.js +++ b/src/socket.io/index.js @@ -88,7 +88,7 @@ var ratelimit = require('../middleware/ratelimit'); if (process.env.NODE_ENV === 'development') { winston.warn('[socket.io] Unrecognized message: ' + eventName); } - return; + return callback({message: '[[error:invalid-event]]'}); } socket.previousEvents = socket.previousEvents || []; diff --git a/test/authentication.js b/test/authentication.js new file mode 100644 index 0000000000..8694562d0f --- /dev/null +++ b/test/authentication.js @@ -0,0 +1,127 @@ +'use strict'; +/*global require, before*/ + +var assert = require('assert'); +var async = require('async'); +var nconf = require('nconf'); +var request = require('request'); + +var db = require('./mocks/databasemock'); + +describe('authentication', function () { + var jar = request.jar(); + + it('should register and login a user', function (done) { + 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: { + email: 'admin@nodebb.org', + username: 'admin', + password: 'adminpwd', + }, + json: true, + jar: jar, + headers: { + 'x-csrf-token': body.csrf_token + } + }, function (err, response, body) { + assert.ifError(err); + assert(body); + + request({ + url: nconf.get('url') + '/api/me', + json: true, + jar: jar + }, function (err, response, body) { + assert.ifError(err); + assert(body); + assert.equal(body.username, 'admin'); + assert.equal(body.email, 'admin@nodebb.org'); + done() + }); + }); + }); + }); + + it('should logout a user', function (done) { + request({ + url: nconf.get('url') + '/api/config', + json: true, + jar: jar + }, function (err, response, body) { + assert.ifError(err); + + request.post(nconf.get('url') + '/logout', { + form: {}, + json: true, + jar: jar, + headers: { + 'x-csrf-token': body.csrf_token + } + }, function (err, response, body) { + assert.ifError(err); + + request({ + url: nconf.get('url') + '/api/me', + json: true, + jar: jar + }, function (err, response, body) { + assert.ifError(err); + assert.equal(body, 'not-authorized'); + done() + }); + }); + }); + }); + + it('should login a user', function (done) { + 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') + '/login', { + form: { + username: 'admin', + password: 'adminpwd', + }, + json: true, + jar: jar, + headers: { + 'x-csrf-token': body.csrf_token + } + }, function (err, response, body) { + assert.ifError(err); + assert(body); + + request({ + url: nconf.get('url') + '/api/me', + json: true, + jar: jar + }, function (err, response, body) { + assert.ifError(err); + assert(body); + assert.equal(body.username, 'admin'); + assert.equal(body.email, 'admin@nodebb.org'); + done() + }); + }); + }); + }); + + + after(function (done) { + db.flushdb(done); + }); + +}); + diff --git a/test/mocks/newXhr.js b/test/mocks/newXhr.js new file mode 100644 index 0000000000..e63f30abbe --- /dev/null +++ b/test/mocks/newXhr.js @@ -0,0 +1,30 @@ +// see https://gist.github.com/jfromaniello/4087861#gistcomment-1447029 +// XMLHttpRequest to override. +//var xhrPath = '../node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest'; +var xhrPath = '../../node_modules/socket.io-client/node_modules/engine.io-client/node_modules/xmlhttprequest-ssl'; + +// Make initial call to require so module is cached. +require(xhrPath); + +var name = require.resolve(xhrPath); +// Get cached version. +var cachedXhr = require.cache[name]; +var stdXhr = cachedXhr.exports; + +// Callbacks exposes an object that callback functions can be added to. +var callbacks = {}; + +var newXhr = function () { + stdXhr.apply(this, arguments); + for (method in callbacks) { + if (typeof callbacks[method] == "function") { + callbacks[method].apply(this, arguments); + } + } +} + +newXhr.XMLHttpRequest = newXhr; + +cachedXhr.exports = newXhr; +module.exports = newXhr; +module.exports.callbacks = callbacks; \ No newline at end of file diff --git a/test/socket.io.js b/test/socket.io.js new file mode 100644 index 0000000000..dc78a2990f --- /dev/null +++ b/test/socket.io.js @@ -0,0 +1,111 @@ +'use strict'; + +// see https://gist.github.com/jfromaniello/4087861#gistcomment-1447029 + +/* global process, require, before, after*/ + +process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; + +var assert = require('assert'); +var async = require('async'); +var nconf = require('nconf'); +var request = require('request'); +var cookies = request.jar(); + +var db = require('./mocks/databasemock'); +var myXhr = require('./mocks/newXhr'); +var user = require('../src/user'); +var groups = require('../src/groups'); + +describe('socket.io', function () { + + var adminUid; + var io; + + before(function (done) { + async.parallel([ + async.apply(user.create, { username: 'admin', password: 'adminpwd' }), + async.apply(user.create, { username: 'regular', password: 'regularpwd' }) + ], function (err, uids) { + if (err) { + return done(err); + } + + adminUid = uids[0]; + groups.join('administrators', uids[0], done); + }); + }); + + + it('should connect and auth properly', function (done) { + request.get({ + url: nconf.get('url') + '/api/config', + jar: cookies, + json: true + }, function (err, res, body) { + assert.ifError(err); + + request.post(nconf.get('url') + '/login', { + jar: cookies, + form: { + username: 'admin', + password: 'adminpwd' + }, + headers: { + 'x-csrf-token': body.csrf_token + }, + json: true + }, function (err, res, body) { + assert.ifError(err); + + myXhr.callbacks.test2 = function () { + this.setDisableHeaderCheck(true); + var stdOpen = this.open; + this.open = function () { + stdOpen.apply(this, arguments); + this.setRequestHeader('Cookie', res.headers['set-cookie'][0].split(';')[0]); + }; + }; + + io = require('socket.io-client')(nconf.get('url'), {forceNew: true}); + + io.on('connect', function () { + done(); + }); + + io.on('error', function (err) { + done(err); + }); + }); + }); + }); + + it('should return error for unknown event', function (done) { + io.emit('unknown.event', function (err) { + assert(err); + assert.equal(err.message, '[[error:invalid-event]]'); + done(); + }); + }); + + it('should get installed themes', function (done) { + var themes = ['nodebb-theme-lavender', 'nodebb-theme-persona', 'nodebb-theme-vanilla']; + io.emit('admin.themes.getInstalled', function (err, data) { + assert.ifError(err); + assert(data); + var installed = data.map(function (theme) { + return theme.id; + }); + themes.forEach(function (theme) { + assert.notEqual(installed.indexOf(theme), -1); + }); + done(); + }); + }); + + after(function (done) { + done(); + }); + +}); +