0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-03-11 02:12:21 -05:00

Improve Middleware Code Coverage

refs #5286
- finished tests for check-ssl.js
This commit is contained in:
Sebastian Gierlinger 2015-09-08 18:05:22 +02:00
parent c8dd095c36
commit 762824690a
2 changed files with 151 additions and 79 deletions

View file

@ -1,5 +1,6 @@
var config = require('../config'), var config = require('../config'),
url = require('url'); url = require('url'),
checkSSL;
function isSSLrequired(isAdmin, configUrl, forceAdminSSL) { function isSSLrequired(isAdmin, configUrl, forceAdminSSL) {
var forceSSL = url.parse(configUrl).protocol === 'https:' ? true : false; var forceSSL = url.parse(configUrl).protocol === 'https:' ? true : false;
@ -46,7 +47,7 @@ function sslForbiddenOrRedirect(opt) {
// Check to see if we should use SSL // Check to see if we should use SSL
// and redirect if needed // and redirect if needed
function checkSSL(req, res, next) { checkSSL = function checkSSL(req, res, next) {
if (isSSLrequired(res.isAdmin, config.url, config.forceAdminSSL)) { if (isSSLrequired(res.isAdmin, config.url, config.forceAdminSSL)) {
if (!req.secure) { if (!req.secure) {
var response = sslForbiddenOrRedirect({ var response = sslForbiddenOrRedirect({
@ -64,9 +65,6 @@ function checkSSL(req, res, next) {
} }
} }
next(); next();
} };
module.exports = checkSSL; module.exports = checkSSL;
// SSL helper functions are exported primarily for unit testing.
module.exports.isSSLrequired = isSSLrequired;
module.exports.sslForbiddenOrRedirect = sslForbiddenOrRedirect;

View file

@ -1,92 +1,166 @@
/*globals describe, it, beforeEach, afterEach */ /*globals describe, it, beforeEach, afterEach */
/*jshint expr:true*/ /*jshint expr:true*/
var sinon = require('sinon'), var sinon = require('sinon'),
should = require('should'),
config = require('../../../server/config'),
checkSSL = require('../../../server/middleware/check-ssl'); checkSSL = require('../../../server/middleware/check-ssl');
should.equal(true, true);
describe('checkSSL', function () { describe('checkSSL', function () {
var sandbox, res, req, next; var res, req, next, sandbox;
beforeEach(function () { beforeEach(function () {
sandbox = sinon.sandbox.create(); sandbox = sinon.sandbox.create();
req = sinon.spy(); req = {};
res = sinon.spy(); res = {};
next = sinon.spy(); next = sandbox.spy();
}); });
afterEach(function () { afterEach(function () {
sandbox.restore(); sandbox.restore();
}); });
it('skips if already on SSL', function () { it('should not require SSL (frontend)', function (done) {
res.isAdmin = true; req.url = '/';
req.isSecure = true; config.set({
url: 'http://default.com:2368/'
});
checkSSL(req, res, next); checkSSL(req, res, next);
next.called.should.be.true; next.called.should.be.true;
}); next.calledWith().should.be.true;
}); done();
});
describe('isSSLRequired', function () {
var isSSLrequired = checkSSL.isSSLrequired; it('should require SSL (frontend)', function (done) {
req.url = '/';
it('SSL is required if config.url starts with https', function () { req.secure = true;
isSSLrequired(undefined, 'https://example.com', undefined).should.be.true; config.set({
}); url: 'https://default.com:2368/'
});
it('SSL is required if isAdmin and config.forceAdminSSL is set', function () { checkSSL(req, res, next);
isSSLrequired(true, 'http://example.com', true).should.be.true; next.called.should.be.true;
}); next.calledWith().should.be.true;
done();
it('SSL is not required if config.url starts with "http:/" and forceAdminSSL is not set', function () { });
isSSLrequired(false, 'http://example.com', false).should.be.false;
}); it('should not require SSL (admin)', function (done) {
}); req.url = '/ghost';
res.isAdmin = true;
describe('sslForbiddenOrRedirect', function () { config.set({
var sslForbiddenOrRedirect = checkSSL.sslForbiddenOrRedirect; url: 'http://default.com:2368/'
it('Return forbidden if config forces admin SSL for AdminSSL redirect is false.', function () { });
var response = sslForbiddenOrRedirect({ checkSSL(req, res, next);
forceAdminSSL: {redirect: false}, next.called.should.be.true;
configUrl: 'http://example.com' next.calledWith().should.be.true;
}); done();
response.isForbidden.should.be.true; });
});
it('should not redirect with SSL (admin)', function (done) {
it('If not forbidden, should produce SSL to redirect to when config.url ends with no slash', function () { req.url = '/ghost';
var response = sslForbiddenOrRedirect({ res.isAdmin = true;
forceAdminSSL: {redirect: true}, res.secure = true;
configUrl: 'http://example.com/config/path', config.set({
reqUrl: '/req/path' url: 'http://default.com:2368/'
}); });
response.isForbidden.should.be.false; checkSSL(req, res, next);
response.redirectUrl({}).should.equal('https://example.com/config/path/req/path'); next.called.should.be.true;
}); next.calledWith().should.be.true;
done();
it('If config ends is slash, potential double-slash in resulting URL is removed', function () { });
var response = sslForbiddenOrRedirect({
forceAdminSSL: {redirect: true}, it('should not redirect with force admin SSL (admin)', function (done) {
configUrl: 'http://example.com/config/path/', req.url = '/ghost';
reqUrl: '/req/path' res.isAdmin = true;
}); req.secure = true;
response.redirectUrl({}).should.equal('https://example.com/config/path/req/path'); config.set({
}); url: 'http://default.com:2368/',
forceAdminSSL: true
it('If config.urlSSL is provided it is preferred over config.url', function () { });
var response = sslForbiddenOrRedirect({ checkSSL(req, res, next);
forceAdminSSL: {redirect: true}, next.called.should.be.true;
configUrl: 'http://example.com/config/path/', next.calledWith().should.be.true;
configUrlSSL: 'https://example.com/ssl/config/path/', done();
reqUrl: '/req/path' });
});
response.redirectUrl({}).should.equal('https://example.com/ssl/config/path/req/path'); it('should redirect with force admin SSL (admin)', function (done) {
}); req.url = '/ghost/';
res.isAdmin = true;
it('query string in request is preserved in redirect URL', function () { res.redirect = {};
var response = sslForbiddenOrRedirect({ req.secure = false;
forceAdminSSL: {redirect: true}, config.set({
configUrl: 'http://example.com/config/path/', url: 'http://default.com:2368/',
configUrlSSL: 'https://example.com/ssl/config/path/', urlSSL: '',
reqUrl: '/req/path' forceAdminSSL: true
}); });
response.redirectUrl({a: 'b'}).should.equal('https://example.com/ssl/config/path/req/path?a=b'); sandbox.stub(res, 'redirect', function (statusCode, url) {
statusCode.should.eql(301);
url.should.not.be.empty;
url.should.eql('https://default.com:2368/ghost/');
return;
});
checkSSL(req, res, next);
next.called.should.be.false;
done();
});
it('should redirect with with config.url being SSL (frontend)', function (done) {
req.url = '';
req.secure = false;
res.redirect = {};
config.set({
url: 'https://default.com:2368',
urlSSL: '',
forceAdminSSL: true
});
sandbox.stub(res, 'redirect', function (statusCode, url) {
statusCode.should.eql(301);
url.should.not.be.empty;
url.should.eql('https://default.com:2368/');
return;
});
checkSSL(req, res, next);
next.called.should.be.false;
done();
});
it('should redirect to urlSSL (admin)', function (done) {
req.url = '/ghost/';
res.isAdmin = true;
res.redirect = {};
req.secure = false;
config.set({
url: 'http://default.com:2368/',
urlSSL: 'https://ssl-domain.com:2368/'
});
sandbox.stub(res, 'redirect', function (statusCode, url) {
statusCode.should.eql(301);
url.should.not.be.empty;
url.should.eql('https://ssl-domain.com:2368/ghost/');
return;
});
checkSSL(req, res, next);
next.called.should.be.false;
done();
});
it('should not redirect if redirect:false (admin)', function (done) {
req.url = '/ghost/';
res.isAdmin = true;
res.sendStatus = {};
req.secure = false;
config.set({
url: 'http://default.com:2368/',
forceAdminSSL: {
redirect: false
}
});
sandbox.stub(res, 'sendStatus', function (statusCode) {
statusCode.should.eql(403);
return;
});
checkSSL(req, res, next);
next.called.should.be.false;
done();
}); });
}); });