Ghost/core/test/unit/middleware/theme-handler_spec.js

203 lines
7.6 KiB
JavaScript
Raw Normal View History

var sinon = require('sinon'),
should = require('should'),
express = require('express'),
Promise = require('bluebird'),
fs = require('fs'),
hbs = require('express-hbs'),
themeHandler = require('../../../server/middleware/theme-handler'),
🎨 configurable logging with bunyan (#7431) - 🛠 add bunyan and prettyjson, remove morgan - ✨ add logging module - GhostLogger class that handles setup of bunyan - PrettyStream for stdout - ✨ config for logging - @TODO: testing level fatal? - ✨ log each request via GhostLogger (express middleware) - @TODO: add errors to output - 🔥 remove errors.updateActiveTheme - we can read the value from config - 🔥 remove 15 helper functions in core/server/errors/index.js - all these functions get replaced by modules: 1. logging 2. error middleware handling for html/json 3. error creation (which will be part of PR #7477) - ✨ add express error handler for html/json - one true error handler for express responses - contains still some TODO's, but they are not high priority for first implementation/integration - this middleware only takes responsibility of either rendering html responses or return json error responses - 🎨 use new express error handler in middleware/index - 404 and 500 handling - 🎨 return error instead of error message in permissions/index.js - the rule for error handling should be: if you call a unit, this unit should return a custom Ghost error - 🎨 wrap serve static module - rule: if you call a module/unit, you should always wrap this error - it's always the same rule - so the caller never has to worry about what comes back - it's always a clear error instance - in this case: we return our notfounderror if serve static does not find the resource - this avoid having checks everywhere - 🎨 replace usages of errors/index.js functions and adapt tests - use logging.error, logging.warn - make tests green - remove some usages of logging and throwing api errors -> because when a request is involved, logging happens automatically - 🐛 return errorDetails to Ghost-Admin - errorDetails is used for Theme error handling - 🎨 use 500er error for theme is missing error in theme-handler - 🎨 extend file rotation to 1w
2016-10-04 18:33:43 +03:00
logging = require('../../../server/logging'),
api = require('../../../server/api'),
configUtils = require('../../utils/configUtils'),
sandbox = sinon.sandbox.create();
describe('Theme Handler', function () {
var req, res, next, blogApp;
beforeEach(function () {
req = sinon.spy();
res = sinon.spy();
next = sinon.spy();
blogApp = express();
req.app = blogApp;
});
afterEach(function () {
sandbox.restore();
configUtils.restore();
});
describe('ghostLocals', function () {
it('sets all locals', function () {
req.path = '/awesome-post';
themeHandler.ghostLocals(req, res, next);
res.locals.should.be.an.Object();
should.exist(res.locals.version);
should.exist(res.locals.safeVersion);
res.locals.relativeUrl.should.equal(req.path);
next.called.should.be.true();
});
});
describe('activateTheme', function () {
it('should activate new theme with partials', function () {
🎨 configurable logging with bunyan (#7431) - 🛠 add bunyan and prettyjson, remove morgan - ✨ add logging module - GhostLogger class that handles setup of bunyan - PrettyStream for stdout - ✨ config for logging - @TODO: testing level fatal? - ✨ log each request via GhostLogger (express middleware) - @TODO: add errors to output - 🔥 remove errors.updateActiveTheme - we can read the value from config - 🔥 remove 15 helper functions in core/server/errors/index.js - all these functions get replaced by modules: 1. logging 2. error middleware handling for html/json 3. error creation (which will be part of PR #7477) - ✨ add express error handler for html/json - one true error handler for express responses - contains still some TODO's, but they are not high priority for first implementation/integration - this middleware only takes responsibility of either rendering html responses or return json error responses - 🎨 use new express error handler in middleware/index - 404 and 500 handling - 🎨 return error instead of error message in permissions/index.js - the rule for error handling should be: if you call a unit, this unit should return a custom Ghost error - 🎨 wrap serve static module - rule: if you call a module/unit, you should always wrap this error - it's always the same rule - so the caller never has to worry about what comes back - it's always a clear error instance - in this case: we return our notfounderror if serve static does not find the resource - this avoid having checks everywhere - 🎨 replace usages of errors/index.js functions and adapt tests - use logging.error, logging.warn - make tests green - remove some usages of logging and throwing api errors -> because when a request is involved, logging happens automatically - 🐛 return errorDetails to Ghost-Admin - errorDetails is used for Theme error handling - 🎨 use 500er error for theme is missing error in theme-handler - 🎨 extend file rotation to 1w
2016-10-04 18:33:43 +03:00
var fsStub = sandbox.stub(fs, 'stat', function (path, cb) {
cb(null, {isDirectory: function () { return true; }});
}),
hbsStub = sandbox.spy(hbs, 'express3');
themeHandler.activateTheme(blogApp, 'casper');
fsStub.calledOnce.should.be.true();
hbsStub.calledOnce.should.be.true();
hbsStub.firstCall.args[0].should.be.an.Object().and.have.property('partialsDir');
hbsStub.firstCall.args[0].partialsDir.should.have.lengthOf(2);
blogApp.get('activeTheme').should.equal('casper');
});
it('should activate new theme without partials', function () {
🎨 configurable logging with bunyan (#7431) - 🛠 add bunyan and prettyjson, remove morgan - ✨ add logging module - GhostLogger class that handles setup of bunyan - PrettyStream for stdout - ✨ config for logging - @TODO: testing level fatal? - ✨ log each request via GhostLogger (express middleware) - @TODO: add errors to output - 🔥 remove errors.updateActiveTheme - we can read the value from config - 🔥 remove 15 helper functions in core/server/errors/index.js - all these functions get replaced by modules: 1. logging 2. error middleware handling for html/json 3. error creation (which will be part of PR #7477) - ✨ add express error handler for html/json - one true error handler for express responses - contains still some TODO's, but they are not high priority for first implementation/integration - this middleware only takes responsibility of either rendering html responses or return json error responses - 🎨 use new express error handler in middleware/index - 404 and 500 handling - 🎨 return error instead of error message in permissions/index.js - the rule for error handling should be: if you call a unit, this unit should return a custom Ghost error - 🎨 wrap serve static module - rule: if you call a module/unit, you should always wrap this error - it's always the same rule - so the caller never has to worry about what comes back - it's always a clear error instance - in this case: we return our notfounderror if serve static does not find the resource - this avoid having checks everywhere - 🎨 replace usages of errors/index.js functions and adapt tests - use logging.error, logging.warn - make tests green - remove some usages of logging and throwing api errors -> because when a request is involved, logging happens automatically - 🐛 return errorDetails to Ghost-Admin - errorDetails is used for Theme error handling - 🎨 use 500er error for theme is missing error in theme-handler - 🎨 extend file rotation to 1w
2016-10-04 18:33:43 +03:00
var fsStub = sandbox.stub(fs, 'stat', function (path, cb) {
cb(null, null);
}),
hbsStub = sandbox.spy(hbs, 'express3');
themeHandler.activateTheme(blogApp, 'casper');
fsStub.calledOnce.should.be.true();
hbsStub.calledOnce.should.be.true();
hbsStub.firstCall.args[0].should.be.an.Object().and.have.property('partialsDir');
hbsStub.firstCall.args[0].partialsDir.should.have.lengthOf(1);
blogApp.get('activeTheme').should.equal('casper');
});
});
describe('configHbsForContext', function () {
it('handles non secure context', function () {
res.locals = {};
themeHandler.configHbsForContext(req, res, next);
should.not.exist(res.locals.secure);
next.called.should.be.true();
});
it('handles secure context', function () {
var themeOptSpy = sandbox.stub(hbs, 'updateTemplateOptions');
req.secure = true;
res.locals = {};
configUtils.set({urlSSL: 'https://secure.blog'});
themeHandler.configHbsForContext(req, res, next);
themeOptSpy.calledOnce.should.be.true();
themeOptSpy.firstCall.args[0].should.be.an.Object().and.have.property('data');
themeOptSpy.firstCall.args[0].data.should.be.an.Object().and.have.property('blog');
themeOptSpy.firstCall.args[0].data.blog.should.be.an.Object().and.have.property('url');
themeOptSpy.firstCall.args[0].data.blog.url.should.eql('https://secure.blog');
res.locals.secure.should.equal(true);
next.called.should.be.true();
});
it('sets view path', function () {
req.secure = true;
res.locals = {};
blogApp.set('activeTheme', 'casper');
themeHandler.configHbsForContext(req, res, next);
blogApp.get('views').should.not.be.undefined();
});
it('sets view path', function () {
req.secure = true;
res.locals = {};
blogApp.set('activeTheme', 'casper');
themeHandler.configHbsForContext(req, res, next);
blogApp.get('views').should.not.be.undefined();
});
});
describe('updateActiveTheme', function () {
it('updates the active theme if changed', function (done) {
var activateThemeSpy = sandbox.spy(themeHandler, 'activateTheme');
sandbox.stub(api.settings, 'read').withArgs(sandbox.match.has('key', 'activeTheme')).returns(Promise.resolve({
settings: [{
key: 'activeKey',
value: 'casper'
}]
}));
blogApp.set('activeTheme', 'not-casper');
configUtils.set({paths: {availableThemes: {casper: {}}}});
themeHandler.updateActiveTheme(req, res, function () {
activateThemeSpy.called.should.be.true();
done();
});
});
it('does not update the active theme if not changed', function (done) {
var activateThemeSpy = sandbox.spy(themeHandler, 'activateTheme');
sandbox.stub(api.settings, 'read').withArgs(sandbox.match.has('key', 'activeTheme')).returns(Promise.resolve({
settings: [{
key: 'activeKey',
value: 'casper'
}]
}));
blogApp.set('activeTheme', 'casper');
configUtils.set({paths: {availableThemes: {casper: {}}}});
themeHandler.updateActiveTheme(req, res, function () {
activateThemeSpy.called.should.be.false();
done();
});
});
it('throws error if theme is missing', function (done) {
🎨 configurable logging with bunyan (#7431) - 🛠 add bunyan and prettyjson, remove morgan - ✨ add logging module - GhostLogger class that handles setup of bunyan - PrettyStream for stdout - ✨ config for logging - @TODO: testing level fatal? - ✨ log each request via GhostLogger (express middleware) - @TODO: add errors to output - 🔥 remove errors.updateActiveTheme - we can read the value from config - 🔥 remove 15 helper functions in core/server/errors/index.js - all these functions get replaced by modules: 1. logging 2. error middleware handling for html/json 3. error creation (which will be part of PR #7477) - ✨ add express error handler for html/json - one true error handler for express responses - contains still some TODO's, but they are not high priority for first implementation/integration - this middleware only takes responsibility of either rendering html responses or return json error responses - 🎨 use new express error handler in middleware/index - 404 and 500 handling - 🎨 return error instead of error message in permissions/index.js - the rule for error handling should be: if you call a unit, this unit should return a custom Ghost error - 🎨 wrap serve static module - rule: if you call a module/unit, you should always wrap this error - it's always the same rule - so the caller never has to worry about what comes back - it's always a clear error instance - in this case: we return our notfounderror if serve static does not find the resource - this avoid having checks everywhere - 🎨 replace usages of errors/index.js functions and adapt tests - use logging.error, logging.warn - make tests green - remove some usages of logging and throwing api errors -> because when a request is involved, logging happens automatically - 🐛 return errorDetails to Ghost-Admin - errorDetails is used for Theme error handling - 🎨 use 500er error for theme is missing error in theme-handler - 🎨 extend file rotation to 1w
2016-10-04 18:33:43 +03:00
var activateThemeSpy = sandbox.spy(themeHandler, 'activateTheme');
sandbox.stub(api.settings, 'read').withArgs(sandbox.match.has('key', 'activeTheme')).returns(Promise.resolve({
settings: [{
key: 'activeKey',
value: 'rasper'
}]
}));
🎨 configurable logging with bunyan (#7431) - 🛠 add bunyan and prettyjson, remove morgan - ✨ add logging module - GhostLogger class that handles setup of bunyan - PrettyStream for stdout - ✨ config for logging - @TODO: testing level fatal? - ✨ log each request via GhostLogger (express middleware) - @TODO: add errors to output - 🔥 remove errors.updateActiveTheme - we can read the value from config - 🔥 remove 15 helper functions in core/server/errors/index.js - all these functions get replaced by modules: 1. logging 2. error middleware handling for html/json 3. error creation (which will be part of PR #7477) - ✨ add express error handler for html/json - one true error handler for express responses - contains still some TODO's, but they are not high priority for first implementation/integration - this middleware only takes responsibility of either rendering html responses or return json error responses - 🎨 use new express error handler in middleware/index - 404 and 500 handling - 🎨 return error instead of error message in permissions/index.js - the rule for error handling should be: if you call a unit, this unit should return a custom Ghost error - 🎨 wrap serve static module - rule: if you call a module/unit, you should always wrap this error - it's always the same rule - so the caller never has to worry about what comes back - it's always a clear error instance - in this case: we return our notfounderror if serve static does not find the resource - this avoid having checks everywhere - 🎨 replace usages of errors/index.js functions and adapt tests - use logging.error, logging.warn - make tests green - remove some usages of logging and throwing api errors -> because when a request is involved, logging happens automatically - 🐛 return errorDetails to Ghost-Admin - errorDetails is used for Theme error handling - 🎨 use 500er error for theme is missing error in theme-handler - 🎨 extend file rotation to 1w
2016-10-04 18:33:43 +03:00
blogApp.set('activeTheme', 'not-casper');
configUtils.set({paths: {availableThemes: {casper: {}}}});
themeHandler.updateActiveTheme(req, res, function (err) {
should.exist(err);
activateThemeSpy.called.should.be.false();
err.message.should.eql('The currently active theme "rasper" is missing.');
done();
});
});
it('throws only warns if theme is missing for admin req', function (done) {
var activateThemeSpy = sandbox.spy(themeHandler, 'activateTheme'),
loggingWarnStub = sandbox.spy(logging, 'warn');
sandbox.stub(api.settings, 'read').withArgs(sandbox.match.has('key', 'activeTheme')).returns(Promise.resolve({
settings: [{
key: 'activeKey',
value: 'rasper'
}]
}));
res.isAdmin = true;
blogApp.set('activeTheme', 'not-casper');
configUtils.set({paths: {availableThemes: {casper: {}}}});
themeHandler.updateActiveTheme(req, res, function () {
activateThemeSpy.called.should.be.false();
loggingWarnStub.called.should.be.true();
loggingWarnStub.calledWith('The currently active theme "rasper" is missing.').should.be.true();
done();
});
});
});
});