2014-09-03 19:42:55 +04:00
|
|
|
/*globals describe, before, beforeEach, afterEach, it*/
|
2014-06-05 01:26:03 +04:00
|
|
|
/*jshint expr:true*/
|
|
|
|
var should = require('should'),
|
2014-08-17 10:17:23 +04:00
|
|
|
Promise = require('bluebird'),
|
2014-01-03 00:57:37 +04:00
|
|
|
sinon = require('sinon'),
|
2014-03-22 02:31:58 +04:00
|
|
|
express = require('express'),
|
2014-06-05 01:26:03 +04:00
|
|
|
rewire = require('rewire'),
|
2014-08-23 20:19:13 +04:00
|
|
|
_ = require('lodash'),
|
2013-09-06 20:07:25 +04:00
|
|
|
|
|
|
|
// Stuff we are testing
|
2014-06-05 01:26:03 +04:00
|
|
|
|
2014-03-22 02:31:58 +04:00
|
|
|
colors = require('colors'),
|
2014-08-23 20:19:13 +04:00
|
|
|
config = rewire('../../server/config'),
|
2014-05-09 14:11:29 +04:00
|
|
|
errors = rewire('../../server/errors'),
|
2013-07-16 22:57:19 +04:00
|
|
|
// storing current environment
|
2014-03-22 02:31:58 +04:00
|
|
|
currentEnv = process.env.NODE_ENV;
|
2013-07-16 22:57:19 +04:00
|
|
|
|
2014-06-05 01:26:03 +04:00
|
|
|
// This is not useful but required for jshint
|
|
|
|
colors.setTheme({silly: 'rainbow'});
|
|
|
|
|
2014-03-22 02:31:58 +04:00
|
|
|
describe('Error handling', function () {
|
2013-05-26 22:51:58 +04:00
|
|
|
|
2013-06-25 15:43:15 +04:00
|
|
|
// Just getting rid of jslint unused error
|
|
|
|
should.exist(errors);
|
2013-05-26 22:51:58 +04:00
|
|
|
|
2014-01-03 00:57:37 +04:00
|
|
|
describe('Throwing', function () {
|
2014-06-05 01:26:03 +04:00
|
|
|
it('throws error objects', function () {
|
|
|
|
var toThrow = new Error('test1'),
|
2014-01-03 00:57:37 +04:00
|
|
|
runThrowError = function () {
|
|
|
|
errors.throwError(toThrow);
|
|
|
|
};
|
2013-05-26 22:51:58 +04:00
|
|
|
|
2014-06-05 01:26:03 +04:00
|
|
|
runThrowError.should['throw']('test1');
|
2014-01-03 00:57:37 +04:00
|
|
|
});
|
2013-05-26 22:51:58 +04:00
|
|
|
|
2014-06-05 01:26:03 +04:00
|
|
|
it('throws error strings', function () {
|
|
|
|
var toThrow = 'test2',
|
2014-01-03 00:57:37 +04:00
|
|
|
runThrowError = function () {
|
|
|
|
errors.throwError(toThrow);
|
|
|
|
};
|
2013-05-26 22:51:58 +04:00
|
|
|
|
2014-06-05 01:26:03 +04:00
|
|
|
runThrowError.should['throw']('test2');
|
2014-01-03 00:57:37 +04:00
|
|
|
});
|
2013-05-26 22:51:58 +04:00
|
|
|
|
2014-06-05 01:26:03 +04:00
|
|
|
it('throws error even if nothing passed', function () {
|
2014-01-03 00:57:37 +04:00
|
|
|
var runThrowError = function () {
|
2013-06-25 15:43:15 +04:00
|
|
|
errors.throwError();
|
|
|
|
};
|
2013-05-26 22:51:58 +04:00
|
|
|
|
2014-06-05 01:26:03 +04:00
|
|
|
runThrowError.should['throw']('An error occurred');
|
2014-01-03 00:57:37 +04:00
|
|
|
});
|
2013-06-25 15:43:15 +04:00
|
|
|
});
|
2013-05-26 22:51:58 +04:00
|
|
|
|
2014-01-03 00:57:37 +04:00
|
|
|
describe('Logging', function () {
|
|
|
|
var logStub;
|
|
|
|
|
|
|
|
beforeEach(function () {
|
2014-03-22 02:31:58 +04:00
|
|
|
logStub = sinon.stub(console, 'error');
|
2014-01-03 00:57:37 +04:00
|
|
|
// give environment a value that will console log
|
2014-06-05 01:26:03 +04:00
|
|
|
process.env.NODE_ENV = 'development';
|
2014-01-03 00:57:37 +04:00
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(function () {
|
|
|
|
logStub.restore();
|
|
|
|
// reset the environment
|
|
|
|
process.env.NODE_ENV = currentEnv;
|
|
|
|
});
|
|
|
|
|
2014-03-22 02:31:58 +04:00
|
|
|
it('logs errors from error objects', function () {
|
|
|
|
var err = new Error('test1');
|
2014-01-03 00:57:37 +04:00
|
|
|
|
|
|
|
errors.logError(err);
|
|
|
|
|
|
|
|
// Calls log with message on Error objects
|
2014-03-22 02:31:58 +04:00
|
|
|
logStub.calledOnce.should.be.true;
|
|
|
|
logStub.calledWith('\nERROR:'.red, err.message.red, '\n', '\n', err.stack, '\n').should.be.true;
|
2014-01-03 00:57:37 +04:00
|
|
|
});
|
|
|
|
|
2014-03-22 02:31:58 +04:00
|
|
|
it('logs errors from strings', function () {
|
|
|
|
var err = 'test2';
|
2013-05-27 23:27:41 +04:00
|
|
|
|
2014-01-03 00:57:37 +04:00
|
|
|
errors.logError(err);
|
2013-05-27 23:27:41 +04:00
|
|
|
|
2014-01-03 00:57:37 +04:00
|
|
|
// Calls log with string on strings
|
2014-03-22 02:31:58 +04:00
|
|
|
logStub.calledOnce.should.be.true;
|
|
|
|
logStub.calledWith('\nERROR:'.red, err.red, '\n').should.be.true;
|
2014-01-03 00:57:37 +04:00
|
|
|
});
|
2013-05-26 22:51:58 +04:00
|
|
|
|
2014-03-22 02:31:58 +04:00
|
|
|
it('logs errors from an error object and two string arguments', function () {
|
|
|
|
var err = new Error('test1'),
|
|
|
|
message = 'Testing';
|
2013-05-26 22:51:58 +04:00
|
|
|
|
2014-01-03 00:57:37 +04:00
|
|
|
errors.logError(err, message, message);
|
2013-05-26 22:51:58 +04:00
|
|
|
|
2014-01-03 00:57:37 +04:00
|
|
|
// Calls log with message on Error objects
|
2014-03-22 02:31:58 +04:00
|
|
|
logStub.calledOnce.should.be.true;
|
2014-06-05 01:26:03 +04:00
|
|
|
logStub.calledWith(
|
|
|
|
'\nERROR:'.red, err.message.red, '\n', message.white, '\n', message.green, '\n', err.stack, '\n'
|
|
|
|
);
|
2014-01-03 00:57:37 +04:00
|
|
|
});
|
2013-05-26 22:51:58 +04:00
|
|
|
|
2014-03-22 02:31:58 +04:00
|
|
|
it('logs errors from three string arguments', function () {
|
|
|
|
var message = 'Testing';
|
2014-01-03 00:57:37 +04:00
|
|
|
|
|
|
|
errors.logError(message, message, message);
|
|
|
|
|
|
|
|
// Calls log with message on Error objects
|
2014-03-22 02:31:58 +04:00
|
|
|
logStub.calledOnce.should.be.true;
|
2014-06-05 01:26:03 +04:00
|
|
|
logStub.calledWith(
|
|
|
|
'\nERROR:'.red, message.red, '\n', message.white, '\n', message.green, '\n'
|
|
|
|
).should.be.true;
|
2014-01-03 00:57:37 +04:00
|
|
|
});
|
2013-05-26 22:51:58 +04:00
|
|
|
|
2014-03-22 02:31:58 +04:00
|
|
|
it('logs errors from an undefined error argument', function () {
|
|
|
|
var message = 'Testing';
|
2014-01-04 00:07:08 +04:00
|
|
|
|
|
|
|
errors.logError(undefined, message, message);
|
|
|
|
|
|
|
|
// Calls log with message on Error objects
|
|
|
|
|
2014-03-22 02:31:58 +04:00
|
|
|
logStub.calledOnce.should.be.true;
|
2014-06-05 01:26:03 +04:00
|
|
|
logStub.calledWith(
|
2014-09-03 19:42:55 +04:00
|
|
|
'\nERROR:'.red, 'An unknown error occurred.'.red, '\n', message.white, '\n', message.green, '\n'
|
2014-06-05 01:26:03 +04:00
|
|
|
).should.be.true;
|
2014-01-04 00:07:08 +04:00
|
|
|
});
|
|
|
|
|
2014-03-22 02:31:58 +04:00
|
|
|
it('logs errors from an undefined context argument', function () {
|
|
|
|
var message = 'Testing';
|
2014-01-04 00:07:08 +04:00
|
|
|
|
|
|
|
errors.logError(message, undefined, message);
|
|
|
|
|
|
|
|
// Calls log with message on Error objects
|
|
|
|
|
2014-03-22 02:31:58 +04:00
|
|
|
logStub.calledOnce.should.be.true;
|
|
|
|
logStub.calledWith('\nERROR:'.red, message.red, '\n', message.green, '\n').should.be.true;
|
2014-01-04 00:07:08 +04:00
|
|
|
});
|
|
|
|
|
2014-03-22 02:31:58 +04:00
|
|
|
it('logs errors from an undefined help argument', function () {
|
|
|
|
var message = 'Testing';
|
2014-01-04 00:07:08 +04:00
|
|
|
|
|
|
|
errors.logError(message, message, undefined);
|
|
|
|
|
|
|
|
// Calls log with message on Error objects
|
|
|
|
|
2014-03-22 02:31:58 +04:00
|
|
|
logStub.calledOnce.should.be.true;
|
|
|
|
logStub.calledWith('\nERROR:'.red, message.red, '\n', message.white, '\n').should.be.true;
|
2014-01-04 00:07:08 +04:00
|
|
|
});
|
|
|
|
|
2014-03-22 02:31:58 +04:00
|
|
|
it('logs errors from a null error argument', function () {
|
|
|
|
var message = 'Testing';
|
2014-01-04 00:07:08 +04:00
|
|
|
|
|
|
|
errors.logError(null, message, message);
|
|
|
|
|
|
|
|
// Calls log with message on Error objects
|
|
|
|
|
2014-03-22 02:31:58 +04:00
|
|
|
logStub.calledOnce.should.be.true;
|
2014-06-05 01:26:03 +04:00
|
|
|
logStub.calledWith(
|
|
|
|
'\nERROR:'.red, 'An unknown error occurred.'.red, '\n', message.white, '\n', message.green, '\n'
|
|
|
|
).should.be.true;
|
2014-01-04 00:07:08 +04:00
|
|
|
});
|
|
|
|
|
2014-03-22 02:31:58 +04:00
|
|
|
it('logs errors from a null context argument', function () {
|
|
|
|
var message = 'Testing';
|
2014-01-04 00:07:08 +04:00
|
|
|
|
|
|
|
errors.logError(message, null, message);
|
|
|
|
|
|
|
|
// Calls log with message on Error objects
|
|
|
|
|
2014-03-22 02:31:58 +04:00
|
|
|
logStub.calledOnce.should.be.true;
|
|
|
|
logStub.firstCall.calledWith('\nERROR:'.red, message.red, '\n', message.green, '\n').should.be.true;
|
2014-01-04 00:07:08 +04:00
|
|
|
});
|
|
|
|
|
2014-03-22 02:31:58 +04:00
|
|
|
it('logs errors from a null help argument', function () {
|
|
|
|
var message = 'Testing';
|
2014-01-04 00:07:08 +04:00
|
|
|
|
|
|
|
errors.logError(message, message, null);
|
|
|
|
|
|
|
|
// Calls log with message on Error objects
|
|
|
|
|
2014-03-22 02:31:58 +04:00
|
|
|
logStub.calledOnce.should.be.true;
|
|
|
|
logStub.firstCall.calledWith('\nERROR:'.red, message.red, '\n', message.white, '\n').should.be.true;
|
|
|
|
|
2014-01-04 00:07:08 +04:00
|
|
|
});
|
|
|
|
|
2014-03-22 02:31:58 +04:00
|
|
|
it('logs promise errors and redirects', function (done) {
|
2014-08-17 10:17:23 +04:00
|
|
|
var req = null,
|
2014-01-03 00:57:37 +04:00
|
|
|
res = {
|
|
|
|
redirect: function () {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
},
|
2014-03-22 02:31:58 +04:00
|
|
|
redirectStub = sinon.stub(res, 'redirect');
|
2013-07-16 22:57:19 +04:00
|
|
|
|
2014-01-03 00:57:37 +04:00
|
|
|
// give environment a value that will console log
|
2014-08-17 10:17:23 +04:00
|
|
|
Promise.reject().then(function () {
|
2014-03-22 02:31:58 +04:00
|
|
|
throw new Error('Ran success handler');
|
|
|
|
}, errors.logErrorWithRedirect('test1', null, null, '/testurl', req, res));
|
2014-01-03 00:57:37 +04:00
|
|
|
|
2014-08-17 10:17:23 +04:00
|
|
|
Promise.reject().catch(function () {
|
2014-03-22 02:31:58 +04:00
|
|
|
logStub.calledWith('\nERROR:'.red, 'test1'.red).should.equal(true);
|
2014-01-03 00:57:37 +04:00
|
|
|
logStub.restore();
|
|
|
|
|
|
|
|
redirectStub.calledWith('/testurl').should.equal(true);
|
|
|
|
redirectStub.restore();
|
|
|
|
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
2013-06-25 15:43:15 +04:00
|
|
|
});
|
2013-05-26 22:51:58 +04:00
|
|
|
|
2014-01-03 00:57:37 +04:00
|
|
|
describe('Rendering', function () {
|
2014-03-27 00:43:16 +04:00
|
|
|
var sandbox,
|
|
|
|
originalConfig;
|
2013-05-26 22:51:58 +04:00
|
|
|
|
2014-01-03 00:57:37 +04:00
|
|
|
before(function () {
|
2014-08-23 20:19:13 +04:00
|
|
|
originalConfig = _.cloneDeep(config._config);
|
|
|
|
errors.__set__('getConfigModule', sinon.stub().returns(_.merge({}, originalConfig, {
|
2014-07-17 18:33:21 +04:00
|
|
|
'paths': {
|
|
|
|
'themePath': '/content/themes',
|
|
|
|
'availableThemes': {
|
|
|
|
'casper': {
|
|
|
|
'assets': null,
|
|
|
|
'default.hbs': '/content/themes/casper/default.hbs',
|
|
|
|
'index.hbs': '/content/themes/casper/index.hbs',
|
|
|
|
'page.hbs': '/content/themes/casper/page.hbs',
|
|
|
|
'tag.hbs': '/content/themes/casper/tag.hbs'
|
|
|
|
},
|
|
|
|
'theme-with-error': {
|
|
|
|
'error.hbs': ''
|
2014-03-27 00:43:16 +04:00
|
|
|
}
|
|
|
|
}
|
2014-07-17 18:33:21 +04:00
|
|
|
}
|
2014-08-23 20:19:13 +04:00
|
|
|
})));
|
2014-03-27 00:43:16 +04:00
|
|
|
errors.updateActiveTheme('casper');
|
2014-01-03 00:57:37 +04:00
|
|
|
});
|
2013-05-26 22:51:58 +04:00
|
|
|
|
2014-01-03 00:57:37 +04:00
|
|
|
beforeEach(function () {
|
|
|
|
sandbox = sinon.sandbox.create();
|
2013-05-26 22:51:58 +04:00
|
|
|
});
|
2014-01-03 00:57:37 +04:00
|
|
|
|
|
|
|
afterEach(function () {
|
|
|
|
sandbox.restore();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Renders end-of-middleware 404 errors correctly', function (done) {
|
|
|
|
var req = {method: 'GET'},
|
|
|
|
res = express.response;
|
|
|
|
|
|
|
|
sandbox.stub(express.response, 'render', function (view, options, fn) {
|
2014-06-05 01:26:03 +04:00
|
|
|
/*jshint unused:false */
|
2014-01-03 00:57:37 +04:00
|
|
|
view.should.match(/user-error\.hbs/);
|
|
|
|
|
|
|
|
// Test that the message is correct
|
|
|
|
options.message.should.equal('Page Not Found');
|
|
|
|
options.code.should.equal(404);
|
|
|
|
this.statusCode.should.equal(404);
|
|
|
|
|
|
|
|
// Test that the headers are correct
|
2014-06-05 01:26:03 +04:00
|
|
|
this._headers['cache-control'].should.equal(
|
|
|
|
'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'
|
|
|
|
);
|
2014-01-03 00:57:37 +04:00
|
|
|
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
|
|
|
|
sandbox.stub(express.response, 'status', function (status) {
|
|
|
|
res.statusCode = status;
|
|
|
|
return res;
|
|
|
|
});
|
|
|
|
|
|
|
|
errors.error404(req, res, done);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Renders thrown 404 errors correctly', function (done) {
|
|
|
|
var err = new Error('A thing was not found'),
|
|
|
|
req = {method: 'GET'},
|
|
|
|
res = express.response;
|
|
|
|
|
|
|
|
sandbox.stub(express.response, 'render', function (view, options, fn) {
|
2014-06-05 01:26:03 +04:00
|
|
|
/*jshint unused:false */
|
2014-01-03 00:57:37 +04:00
|
|
|
view.should.match(/user-error\.hbs/);
|
|
|
|
|
|
|
|
// Test that the message is correct
|
|
|
|
options.message.should.equal('Page Not Found');
|
|
|
|
options.code.should.equal(404);
|
|
|
|
this.statusCode.should.equal(404);
|
|
|
|
|
|
|
|
// Test that the headers are correct
|
2014-06-05 01:26:03 +04:00
|
|
|
this._headers['cache-control'].should.equal(
|
|
|
|
'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'
|
|
|
|
);
|
2014-01-03 00:57:37 +04:00
|
|
|
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
|
|
|
|
sandbox.stub(express.response, 'status', function (status) {
|
|
|
|
res.statusCode = status;
|
|
|
|
return res;
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
err.status = 404;
|
|
|
|
errors.error500(err, req, res, null);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Renders thrown errors correctly', function (done) {
|
|
|
|
var err = new Error('I am a big bad error'),
|
|
|
|
req = {method: 'GET'},
|
|
|
|
res = express.response;
|
|
|
|
|
|
|
|
sandbox.stub(express.response, 'render', function (view, options, fn) {
|
2014-06-05 01:26:03 +04:00
|
|
|
/*jshint unused:false */
|
2014-01-03 00:57:37 +04:00
|
|
|
view.should.match(/user-error\.hbs/);
|
|
|
|
|
|
|
|
// Test that the message is correct
|
|
|
|
options.message.should.equal('I am a big bad error');
|
|
|
|
options.code.should.equal(500);
|
|
|
|
this.statusCode.should.equal(500);
|
|
|
|
|
|
|
|
// Test that the headers are correct
|
2014-06-05 01:26:03 +04:00
|
|
|
this._headers['cache-control'].should.equal(
|
|
|
|
'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'
|
|
|
|
);
|
2014-01-03 00:57:37 +04:00
|
|
|
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
|
|
|
|
sandbox.stub(express.response, 'status', function (status) {
|
|
|
|
res.statusCode = status;
|
|
|
|
return res;
|
|
|
|
});
|
|
|
|
|
|
|
|
errors.error500(err, req, res, null);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Renders 500 errors correctly', function (done) {
|
|
|
|
var err = new Error('I am a big bad error'),
|
|
|
|
req = {method: 'GET'},
|
|
|
|
res = express.response;
|
|
|
|
|
|
|
|
sandbox.stub(express.response, 'render', function (view, options, fn) {
|
2014-06-05 01:26:03 +04:00
|
|
|
/*jshint unused:false */
|
2014-01-03 00:57:37 +04:00
|
|
|
view.should.match(/user-error\.hbs/);
|
|
|
|
|
|
|
|
// Test that the message is correct
|
|
|
|
options.message.should.equal('I am a big bad error');
|
|
|
|
options.code.should.equal(500);
|
|
|
|
this.statusCode.should.equal(500);
|
|
|
|
|
|
|
|
// Test that the headers are correct
|
2014-06-05 01:26:03 +04:00
|
|
|
this._headers['cache-control'].should.equal(
|
|
|
|
'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'
|
|
|
|
);
|
2014-01-03 00:57:37 +04:00
|
|
|
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
|
|
|
|
sandbox.stub(express.response, 'status', function (status) {
|
|
|
|
res.statusCode = status;
|
|
|
|
return res;
|
|
|
|
});
|
|
|
|
|
|
|
|
err.code = 500;
|
|
|
|
errors.error500(err, req, res, null);
|
2013-07-16 22:57:19 +04:00
|
|
|
});
|
2014-06-05 01:26:03 +04:00
|
|
|
|
2014-09-03 19:42:55 +04:00
|
|
|
it('Renders custom error template if one exists', function (done) {
|
2014-03-27 00:43:16 +04:00
|
|
|
var code = 404,
|
2014-09-03 19:42:55 +04:00
|
|
|
error = {message: 'Custom view test'},
|
2014-03-27 00:43:16 +04:00
|
|
|
req = {
|
|
|
|
session: null
|
|
|
|
},
|
|
|
|
res = {
|
2014-09-03 19:42:55 +04:00
|
|
|
status: function (code) {
|
2014-06-05 01:26:03 +04:00
|
|
|
/*jshint unused:false*/
|
2014-03-27 00:43:16 +04:00
|
|
|
return this;
|
|
|
|
},
|
2014-09-03 19:42:55 +04:00
|
|
|
render: function (view, model, fn) {
|
2014-06-05 01:26:03 +04:00
|
|
|
/*jshint unused:false*/
|
2014-03-27 00:43:16 +04:00
|
|
|
view.should.eql('error');
|
|
|
|
errors.updateActiveTheme('casper');
|
|
|
|
done();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
next = null;
|
|
|
|
errors.updateActiveTheme('theme-with-error');
|
|
|
|
errors.renderErrorPage(code, error, req, res, next);
|
2014-05-06 00:58:58 +04:00
|
|
|
});
|
2013-05-26 22:51:58 +04:00
|
|
|
});
|
2014-03-05 07:22:00 +04:00
|
|
|
});
|