2
1
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2023-12-13 21:00:40 +01:00

🔥 🎨 Cleanup & simplify theme helpers (#8223)

no issue

🔥 Remove adminHbs concept from tests
🔥 Get rid of unnecessary helper test utils
🔥 Remove helper missing code
- this hasn't been registered / used for ages 😱
- gscan no longer allows us to activate themes that have missing helpers, so this wouldn't be used anyway
TODO: consider whether we should make a way to override this?

🎨 Reduce coupling inside of /helpers
🎨 Use settingsCache in ghost_foot
 Labs util for enabling helpers
🎨 Move loadCoreHelpers to blog
- This needs a proper home, but at the very least it doesn't belong
in server/app.js!

🎨 Use settingsCache in ghost_head
This commit is contained in:
Hannah Wolfe 2017-03-23 19:00:58 +00:00 committed by Katharina Irrgang
parent 5b161a2856
commit 3cea203459
40 changed files with 229 additions and 478 deletions

View file

@ -52,11 +52,6 @@ module.exports = function setupParentApp() {
// This sets global res.locals which are needed everywhere // This sets global res.locals which are needed everywhere
parentApp.use(ghostLocals); parentApp.use(ghostLocals);
// @TODO where should this live?!
// Load helpers
require('./helpers').loadCoreHelpers();
debug('Helpers done');
// Mount the apps on the parentApp // Mount the apps on the parentApp
// API // API
// @TODO: finish refactoring the API app // @TODO: finish refactoring the API app

View file

@ -1,32 +1,20 @@
// Dirty requires! // Dirty requires!
var hbs = require('express-hbs'), var labs = require('../../../../utils/labs');
logging = require('../../../../logging'),
i18n = require('../../../../i18n'),
labs = require('../../../../utils/labs'),
errorMessages = [
i18n.t('warnings.helpers.helperNotAvailable', {helperName: 'subscribe_form'}),
i18n.t('warnings.helpers.apiMustBeEnabled', {helperName: 'subscribe_form', flagName: 'subscribers'}),
i18n.t('warnings.helpers.seeLink', {url: 'http://support.ghost.org/subscribers-beta/'})
];
module.exports = function registerHelpers(ghost) { module.exports = function registerHelpers(ghost) {
var err;
ghost.helpers.register('input_email', require('./input_email')); ghost.helpers.register('input_email', require('./input_email'));
ghost.helpers.register('subscribe_form', function labsEnabledHelper() { ghost.helpers.register('subscribe_form', function labsEnabledHelper() {
if (labs.isSet('subscribers') === true) { var self = this,
return require('./subscribe_form').apply(this, arguments); args = arguments;
}
err = new Error(); return labs.enabledHelper({
err.message = i18n.t('warnings.helpers.helperNotAvailable', {helperName: 'subscribe_form'}); flagKey: 'subscribers',
err.context = i18n.t('warnings.helpers.apiMustBeEnabled', {helperName: 'subscribe_form', flagName: 'subscribers'}); flagName: 'Subscribers',
err.help = i18n.t('warnings.helpers.seeLink', {url: 'http://support.ghost.org/subscribers-beta/'}); helperName: 'subscribe_form',
helpUrl: 'http://support.ghost.org/subscribers-beta/'
logging.error(err); }, function executeHelper() {
return require('./subscribe_form').apply(self, args);
return new hbs.handlebars.SafeString('<script>console.error("' + errorMessages.join(' ') + '");</script>'); });
}); });
}; };

View file

@ -53,6 +53,13 @@ module.exports = function setupBlogApp() {
// Serve blog images using the storage adapter // Serve blog images using the storage adapter
blogApp.use('/' + utils.url.STATIC_IMAGE_URL_PREFIX, storage.getStorage().serve()); blogApp.use('/' + utils.url.STATIC_IMAGE_URL_PREFIX, storage.getStorage().serve());
// @TODO find this a better home
// We do this here, at the top level, because helpers require so much stuff.
// Moving this to being inside themes, where it probably should be requires the proxy to be refactored
// Else we end up with circular dependencies
require('../helpers').loadCoreHelpers();
debug('Helpers done');
// Theme middleware // Theme middleware
// This should happen AFTER any shared assets are served, as it only changes things to do with templates // This should happen AFTER any shared assets are served, as it only changes things to do with templates
// At this point the active theme object is already updated, so we have the right path, so it can probably // At this point the active theme object is already updated, so we have the right path, so it can probably

View file

@ -1,24 +1,24 @@
// # Get Helper // # Get Helper
// Usage: `{{#get "posts" limit="5"}}`, `{{#get "tags" limit="all"}}` // Usage: `{{#get "posts" limit="5"}}`, `{{#get "tags" limit="all"}}`
// Fetches data from the API // Fetches data from the API
var _ = require('lodash'), var _ = require('lodash'),
hbs = require('express-hbs'), hbs = require('express-hbs'),
Promise = require('bluebird'), Promise = require('bluebird'),
errors = require('../errors'), jsonpath = require('jsonpath'),
logging = require('../logging'),
api = require('../api'), logging = require('../logging'),
jsonpath = require('jsonpath'), i18n = require('../i18n'),
labs = require('../utils/labs'), api = require('../api'),
i18n = require('../i18n'), labs = require('../utils/labs'),
resources, resources,
pathAliases, pathAliases,
get; get;
// Endpoints that the helper is able to access // Endpoints that the helper is able to access
resources = ['posts', 'tags', 'users']; resources = ['posts', 'tags', 'users'];
// Short forms of paths which we should understand // Short forms of paths which we should understand
pathAliases = { pathAliases = {
'post.tags': 'post.tags[*].slug', 'post.tags': 'post.tags[*].slug',
'post.author': 'post.author.slug' 'post.author': 'post.author.slug'
}; };
@ -139,23 +139,17 @@ get = function get(resource, options) {
}); });
}; };
module.exports = function getWithLabs(resource, options) { module.exports = function getLabsWrapper() {
var self = this, err; var self = this,
args = arguments;
if (labs.isSet('publicAPI') === true) { return labs.enabledHelper({
// get helper is active flag: 'publicAPI',
return get.call(self, resource, options); flagName: 'Public API',
} else { helperName: 'get',
err = new errors.GhostError({ helpUrl: 'http://support.ghost.org/public-api-beta/',
message: i18n.t('warnings.helpers.get.helperNotAvailable'), async: true
context: i18n.t('warnings.helpers.get.apiMustBeEnabled'), }, function executeHelper() {
help: i18n.t('warnings.helpers.get.seeLink', {url: 'http://support.ghost.org/public-api-beta'}) return get.apply(self, args);
}); });
logging.error(err);
return Promise.resolve(function noGetHelper() {
return '<script>console.error(' + JSON.stringify(err) + ');</script>';
});
}
}; };

View file

@ -5,24 +5,26 @@
// //
// We use the name ghost_foot to match the helper for consistency: // We use the name ghost_foot to match the helper for consistency:
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers // jscs:disable requireCamelCaseOrUpperCaseIdentifiers
var hbs = require('express-hbs'),
var hbs = require('express-hbs'), SafeString = hbs.handlebars.SafeString,
_ = require('lodash'), _ = require('lodash'),
filters = require('../filters'), filters = require('../filters'),
api = require('../api'), settingsCache = require('../settings/cache'),
ghost_foot; ghost_foot;
ghost_foot = function (options) { ghost_foot = function ghost_foot() {
/*jshint unused:false*/ var foot = [],
var foot = []; codeInjection = settingsCache.get('ghost_foot');
return api.settings.read({key: 'ghost_foot'}).then(function (response) { if (!_.isEmpty(codeInjection)) {
foot.push(response.settings[0].value); foot.push(codeInjection);
return filters.doFilter('ghost_foot', foot); }
}).then(function (foot) {
var footString = _.reduce(foot, function (memo, item) { return memo + ' ' + item; }, ''); return filters
return new hbs.handlebars.SafeString(footString.trim()); .doFilter('ghost_foot', foot)
}); .then(function (foot) {
return new SafeString(foot.join(' ').trim());
});
}; };
module.exports = ghost_foot; module.exports = ghost_foot;

View file

@ -85,6 +85,7 @@ function ghost_head(options) {
var metaData, var metaData,
client, client,
head = [], head = [],
codeInjection = settingsCache.get('ghost_head'),
context = this.context ? this.context : null, context = this.context ? this.context : null,
useStructuredData = !config.isPrivacyDisabled('useStructuredData'), useStructuredData = !config.isPrivacyDisabled('useStructuredData'),
safeVersion = this.safeVersion, safeVersion = this.safeVersion,
@ -153,11 +154,9 @@ function ghost_head(options) {
escapeExpression(metaData.blog.title) + '" href="' + escapeExpression(metaData.blog.title) + '" href="' +
escapeExpression(metaData.rssUrl) + '" />'); escapeExpression(metaData.rssUrl) + '" />');
return api.settings.read({key: 'ghost_head'});
}).then(function (response) {
// no code injection for amp context!!! // no code injection for amp context!!!
if (!_.includes(context, 'amp')) { if (!_.includes(context, 'amp') && !_.isEmpty(codeInjection)) {
head.push(response.settings[0].value); head.push(codeInjection);
} }
return filters.doFilter('ghost_head', head); return filters.doFilter('ghost_head', head);
}).then(function (head) { }).then(function (head) {

View file

@ -1,13 +1,12 @@
var hbs = require('express-hbs'), var hbs = require('express-hbs'),
Promise = require('bluebird'), Promise = require('bluebird'),
errors = require('../errors'), errors = require('../errors'),
logging = require('../logging'), config = require('../config'),
utils = require('./utils'),
i18n = require('../i18n'),
coreHelpers = {}, coreHelpers = {},
registerHelpers; registerHelpers;
if (!utils.isProduction) { // @TODO think about a config option for this e.g. theme.devmode?
if (config.get('env') !== 'production') {
hbs.handlebars.logger.level = 0; hbs.handlebars.logger.level = 0;
} }
@ -40,16 +39,6 @@ coreHelpers.title = require('./title');
coreHelpers.twitter_url = require('./twitter_url'); coreHelpers.twitter_url = require('./twitter_url');
coreHelpers.url = require('./url'); coreHelpers.url = require('./url');
coreHelpers.helperMissing = function (arg) {
if (arguments.length === 2) {
return undefined;
}
logging.error(new errors.GhostError({
message: i18n.t('warnings.helpers.index.missingHelper', {arg: arg})
}));
};
// Register an async handlebars helper for a given handlebars instance // Register an async handlebars helper for a given handlebars instance
function registerAsyncHelper(hbs, name, fn) { function registerAsyncHelper(hbs, name, fn) {
hbs.registerAsyncHelper(name, function (context, options, cb) { hbs.registerAsyncHelper(name, function (context, options, cb) {

View file

@ -1,5 +1,4 @@
var _ = require('lodash'), var _ = require('lodash'),
config = require('../config'),
utils; utils;
utils = { utils = {
@ -7,7 +6,6 @@ utils = {
linkTemplate: _.template('<a href="<%= url %>"><%= text %></a>'), linkTemplate: _.template('<a href="<%= url %>"><%= text %></a>'),
scriptTemplate: _.template('<script src="<%= source %>?v=<%= version %>"></script>'), scriptTemplate: _.template('<script src="<%= source %>?v=<%= version %>"></script>'),
inputTemplate: _.template('<input class="<%= className %>" type="<%= type %>" name="<%= name %>" <%= extras %> />'), inputTemplate: _.template('<input class="<%= className %>" type="<%= type %>" name="<%= name %>" <%= extras %> />'),
isProduction: config.get('env') === 'production',
// @TODO this can probably be made more generic and used in more places // @TODO this can probably be made more generic and used in more places
findKey: function findKey(key, object, data) { findKey: function findKey(key, object, data) {
if (object && _.has(object, key) && !_.isEmpty(object[key])) { if (object && _.has(object, key) && !_.isEmpty(object[key])) {

View file

@ -483,17 +483,14 @@
}, },
"helpers": { "helpers": {
"helperNotAvailable": "The \\{\\{{helperName}\\}\\} helper is not available.", "helperNotAvailable": "The \\{\\{{helperName}\\}\\} helper is not available.",
"apiMustBeEnabled": "The {flagName} labs flag must be enabled if you wish to use the \\{\\{{helperName}\\}\\} helper.", "flagMustBeEnabled": "The {flagName} labs flag must be enabled if you wish to use the \\{\\{{helperName}\\}\\} helper.",
"seeLink": "See {url}", "seeLink": "See {url}",
"foreach": { "foreach": {
"iteratorNeeded": "Need to pass an iterator to #foreach" "iteratorNeeded": "Need to pass an iterator to #foreach"
}, },
"get": { "get": {
"mustBeCalledAsBlock": "Get helper must be called as a block", "mustBeCalledAsBlock": "Get helper must be called as a block",
"invalidResource": "Invalid resource given to get helper", "invalidResource": "Invalid resource given to get helper"
"helperNotAvailable": "The \\{\\{get\\}\\} helper is not available.",
"apiMustBeEnabled": "Public API access must be enabled if you wish to use the \\{\\{get\\}\\} helper.",
"seeLink": "See {url}"
}, },
"has": { "has": {
"invalidAttribute": "Invalid or no attribute given to has helper" "invalidAttribute": "Invalid or no attribute given to has helper"

View file

@ -1,9 +1,46 @@
var settingsCache = require('../settings/cache'), var settingsCache = require('../settings/cache'),
flagIsSet; _ = require('lodash'),
Promise = require('bluebird'),
hbs = require('express-hbs'),
errors = require('../errors'),
logging = require('../logging'),
i18n = require('../i18n'),
labs = module.exports = {};
flagIsSet = function flagIsSet(flag) { labs.isSet = function isSet(flag) {
var labsConfig = settingsCache.get('labs'); var labsConfig = settingsCache.get('labs');
return labsConfig && labsConfig[flag] && labsConfig[flag] === true; return labsConfig && labsConfig[flag] && labsConfig[flag] === true;
}; };
module.exports.isSet = flagIsSet; labs.enabledHelper = function enabledHelper(options, callback) {
var errDetails, errString;
if (labs.isSet(options.flagKey) === true) {
// helper is active, use the callback
return callback();
}
// Else, the helper is not active and we need to handle this as an error
errDetails = {
message: i18n.t('warnings.helpers.helperNotAvailable', {helperName: options.helperName}),
context: i18n.t('warnings.helpers.flagMustBeEnabled', {
helperName: options.helperName,
flagName: options.flagName
}),
help: i18n.t('warnings.helpers.seeLink', {url: options.helpUrl})
};
logging.error(new errors.GhostError(errDetails));
errString = new hbs.handlebars.SafeString(
'<script>console.error("' + _.values(errDetails).join(' ') + '");</script>'
);
if (options.async) {
return Promise.resolve(function asyncError() {
return errString;
});
}
return errString;
};

View file

@ -1,11 +1,8 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
sinon = require('sinon'), sinon = require('sinon'),
hbs = require('express-hbs'),
utils = require('./utils'),
configUtils = require('../../utils/configUtils'), configUtils = require('../../utils/configUtils'),
helpers = require('../../../server/helpers'), helpers = require('../../../server/helpers'),
settingsCache = require('../../../server/settings/cache'), settingsCache = require('../../../server/settings/cache'),
handlebars = hbs.handlebars,
sandbox = sinon.sandbox.create(); sandbox = sinon.sandbox.create();
@ -13,7 +10,6 @@ describe('{{asset}} helper', function () {
var rendered, localSettingsCache = {}; var rendered, localSettingsCache = {};
before(function () { before(function () {
utils.loadHelpers();
configUtils.set({assetHash: 'abc'}); configUtils.set({assetHash: 'abc'});
sandbox.stub(settingsCache, 'get', function (key) { sandbox.stub(settingsCache, 'get', function (key) {
@ -26,10 +22,6 @@ describe('{{asset}} helper', function () {
sandbox.restore(); sandbox.restore();
}); });
it('has loaded asset helper', function () {
should.exist(handlebars.helpers.asset);
});
describe('no subdirectory', function () { describe('no subdirectory', function () {
it('handles favicon correctly', function () { it('handles favicon correctly', function () {
// with ghost set // with ghost set

View file

@ -1,20 +1,9 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
hbs = require('express-hbs'),
utils = require('./utils'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'); helpers = require('../../../server/helpers');
describe('{{author}} helper', function () { describe('{{author}} helper', function () {
before(function () {
utils.loadHelpers();
});
it('has loaded author helper', function () {
should.exist(handlebars.helpers.author);
});
it('Returns the link to the author from the context', function () { it('Returns the link to the author from the context', function () {
var data = {author: {name: 'abc 123', slug: 'abc123', bio: '', website: '', status: '', location: ''}}, var data = {author: {name: 'abc 123', slug: 'abc123', bio: '', website: '', status: '', location: ''}},
result = helpers.author.call(data, {hash: {}}); result = helpers.author.call(data, {hash: {}});

View file

@ -1,16 +1,12 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
hbs = require('express-hbs'),
utils = require('./utils'),
themeList = require('../../../server/themes').list, themeList = require('../../../server/themes').list,
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'); helpers = require('../../../server/helpers');
describe('{{body_class}} helper', function () { describe('{{body_class}} helper', function () {
var options = {}; var options = {};
before(function () { before(function () {
utils.loadHelpers();
themeList.init({ themeList.init({
casper: { casper: {
assets: null, assets: null,
@ -38,10 +34,6 @@ describe('{{body_class}} helper', function () {
themeList.init(); themeList.init();
}); });
it('has loaded body_class helper', function () {
should.exist(handlebars.helpers.body_class);
});
it('can render class string', function () { it('can render class string', function () {
options.data.root.context = ['home']; options.data.root.context = ['home'];

View file

@ -1,20 +1,9 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
hbs = require('express-hbs'),
utils = require('./utils'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'); helpers = require('../../../server/helpers');
describe('{{content}} helper', function () { describe('{{content}} helper', function () {
before(function () {
utils.loadHelpers();
});
it('has loaded content helper', function () {
should.exist(handlebars.helpers.content);
});
it('can render content', function () { it('can render content', function () {
var html = 'Hello World', var html = 'Hello World',
rendered = helpers.content.call({html: html}); rendered = helpers.content.call({html: html});

View file

@ -1,21 +1,10 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
hbs = require('express-hbs'),
utils = require('./utils'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'), helpers = require('../../../server/helpers'),
moment = require('moment-timezone'); moment = require('moment-timezone');
describe('{{date}} helper', function () { describe('{{date}} helper', function () {
before(function () {
utils.loadHelpers();
});
it('is loaded', function () {
should.exist(handlebars.helpers.date);
});
it('creates properly formatted date strings', function () { it('creates properly formatted date strings', function () {
var testDates = [ var testDates = [
'2013-12-31T11:28:58.593+02:00', '2013-12-31T11:28:58.593+02:00',

View file

@ -1,20 +1,9 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
hbs = require('express-hbs'),
utils = require('./utils'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'); helpers = require('../../../server/helpers');
describe('{{encode}} helper', function () { describe('{{encode}} helper', function () {
before(function () {
utils.loadHelpers();
});
it('has loaded encode helper', function () {
should.exist(handlebars.helpers.encode);
});
it('can escape URI', function () { it('can escape URI', function () {
var uri = '$pecial!Charact3r(De[iver]y)Foo #Bar', var uri = '$pecial!Charact3r(De[iver]y)Foo #Bar',
expected = '%24pecial!Charact3r(De%5Biver%5Dy)Foo%20%23Bar', expected = '%24pecial!Charact3r(De%5Biver%5Dy)Foo%20%23Bar',

View file

@ -1,20 +1,9 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
hbs = require('express-hbs'),
utils = require('./utils'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'); helpers = require('../../../server/helpers');
describe('{{excerpt}} Helper', function () { describe('{{excerpt}} Helper', function () {
before(function () {
utils.loadHelpers();
});
it('has loaded excerpt helper', function () {
should.exist(handlebars.helpers.excerpt);
});
it('can render excerpt', function () { it('can render excerpt', function () {
var html = 'Hello World', var html = 'Hello World',
rendered = helpers.excerpt.call({html: html}); rendered = helpers.excerpt.call({html: html});

View file

@ -1,26 +1,15 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
hbs = require('express-hbs'),
utils = require('./utils'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'); helpers = require('../../../server/helpers');
describe('{{facebook_url}} helper', function () { describe('{{facebook_url}} helper', function () {
var options = {data: {blog: {}}}; var options = {data: {blog: {}}};
before(function () {
utils.loadHelpers();
});
beforeEach(function () { beforeEach(function () {
options.data.blog = {facebook: ''}; options.data.blog = {facebook: ''};
}); });
it('has loaded facebook_url helper', function () {
should.exist(handlebars.helpers.facebook_url);
});
it('should output the facebook url for @blog, if no other facebook username is provided', function () { it('should output the facebook url for @blog, if no other facebook username is provided', function () {
options.data.blog = {facebook: 'hey'}; options.data.blog = {facebook: 'hey'};

View file

@ -1,11 +1,8 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
sinon = require('sinon'), sinon = require('sinon'),
_ = require('lodash'), _ = require('lodash'),
hbs = require('express-hbs'),
utils = require('./utils'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'), helpers = require('../../../server/helpers'),
sandbox = sinon.sandbox.create(); sandbox = sinon.sandbox.create();
@ -13,10 +10,6 @@ var should = require('should'),
describe('{{#foreach}} helper', function () { describe('{{#foreach}} helper', function () {
var options, context, _this, resultData; var options, context, _this, resultData;
before(function () {
utils.loadHelpers();
});
afterEach(function () { afterEach(function () {
sandbox.restore(); sandbox.restore();
}); });
@ -42,10 +35,6 @@ describe('{{#foreach}} helper', function () {
helpers.foreach.call(self, context, options); helpers.foreach.call(self, context, options);
} }
it('is loaded', function () {
should.exist(handlebars.helpers.foreach);
});
it('should not populate data if no private data is supplied (array)', function () { it('should not populate data if no private data is supplied (array)', function () {
delete options.data; delete options.data;
options.hash = { options.hash = {
@ -261,7 +250,8 @@ describe('{{#foreach}} helper', function () {
}); });
describe('(compile)', function () { describe('(compile)', function () {
var objectHash = { var handlebars = require('express-hbs').handlebars,
objectHash = {
posts: { posts: {
first: {title: 'first'}, first: {title: 'first'},
second: {title: 'second'}, second: {title: 'second'},
@ -288,6 +278,10 @@ describe('{{#foreach}} helper', function () {
result.should.eql(expected); result.should.eql(expected);
} }
before(function () {
handlebars.registerHelper('foreach', helpers.foreach);
});
/** Many of these are copied direct from the handlebars spec */ /** Many of these are copied direct from the handlebars spec */
it('object and @key', function () { it('object and @key', function () {
var templateString = '<ul>{{#foreach posts}}<li>{{@key}} {{title}}</li>{{/foreach}}</ul>', var templateString = '<ul>{{#foreach posts}}<li>{{@key}} {{title}}</li>{{/foreach}}</ul>',

View file

@ -1,11 +1,8 @@
var should = require('should'), var should = require('should'),
sinon = require('sinon'), sinon = require('sinon'),
hbs = require('express-hbs'),
Promise = require('bluebird'), Promise = require('bluebird'),
utils = require('./utils'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'), helpers = require('../../../server/helpers'),
api = require('../../../server/api'), api = require('../../../server/api'),
@ -14,24 +11,41 @@ var should = require('should'),
sandbox = sinon.sandbox.create(); sandbox = sinon.sandbox.create();
describe('{{#get}} helper', function () { describe('{{#get}} helper', function () {
var fn, inverse; var fn, inverse, labsStub;
before(function () {
utils.loadHelpers();
});
beforeEach(function () { beforeEach(function () {
fn = sandbox.spy(); fn = sandbox.spy();
inverse = sandbox.spy(); inverse = sandbox.spy();
sandbox.stub(labs, 'isSet').returns(true); labsStub = sandbox.stub(labs, 'isSet').returns(true);
}); });
afterEach(function () { afterEach(function () {
sandbox.restore(); sandbox.restore();
}); });
it('has loaded get block helper', function () { it('errors correctly if labs flag not set', function (done) {
should.exist(handlebars.helpers.get); labsStub.returns(false);
helpers.get.call(
{},
'posts',
{hash: {}, fn: fn, inverse: inverse}
).then(function (result) {
labsStub.calledOnce.should.be.true();
fn.called.should.be.false();
inverse.called.should.be.false();
should.exist(result);
result.should.be.a.Function();
result().should.be.an.Object().with.property(
'string',
'<script>console.error("The {{get}} helper is not available. ' +
'The Public API labs flag must be enabled if you wish to use the {{get}} helper. ' +
'See http://support.ghost.org/public-api-beta/");</script>'
);
done();
}).catch(done);
}); });
describe('posts', function () { describe('posts', function () {
@ -42,6 +56,7 @@ describe('{{#get}} helper', function () {
{id: 4, title: 'Test Post 4'} {id: 4, title: 'Test Post 4'}
], ],
meta = {pagination: {}}; meta = {pagination: {}};
beforeEach(function () { beforeEach(function () {
browsePostsStub = sandbox.stub(api.posts, 'browse'); browsePostsStub = sandbox.stub(api.posts, 'browse');
readPostsStub = sandbox.stub(api.posts, 'read'); readPostsStub = sandbox.stub(api.posts, 'read');
@ -67,6 +82,8 @@ describe('{{#get}} helper', function () {
'posts', 'posts',
{hash: {}, fn: fn, inverse: inverse} {hash: {}, fn: fn, inverse: inverse}
).then(function () { ).then(function () {
labsStub.calledOnce.should.be.true();
fn.called.should.be.true(); fn.called.should.be.true();
fn.firstCall.args[0].should.be.an.Object().with.property('posts'); fn.firstCall.args[0].should.be.an.Object().with.property('posts');
fn.firstCall.args[0].posts.should.eql(testPostsArr); fn.firstCall.args[0].posts.should.eql(testPostsArr);
@ -330,9 +347,6 @@ describe('{{#get}} helper', function () {
}); });
it('should handle arrays the same as handlebars', function (done) { it('should handle arrays the same as handlebars', function (done) {
var tpl = handlebars.compile('{{post.tags.[0].slug}}'),
output = tpl(data);
helpers.get.call( helpers.get.call(
data, data,
'posts', 'posts',
@ -340,7 +354,7 @@ describe('{{#get}} helper', function () {
).then(function () { ).then(function () {
browseStub.firstCall.args.should.be.an.Array().with.lengthOf(1); browseStub.firstCall.args.should.be.an.Array().with.lengthOf(1);
browseStub.firstCall.args[0].should.be.an.Object().with.property('filter'); browseStub.firstCall.args[0].should.be.an.Object().with.property('filter');
browseStub.firstCall.args[0].filter.should.eql('tags:' + output); browseStub.firstCall.args[0].filter.should.eql('tags:test');
done(); done();
}).catch(done); }).catch(done);

View file

@ -1,36 +1,25 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
sinon = require('sinon'), sinon = require('sinon'),
Promise = require('bluebird'),
rewire = require('rewire'),
hbs = require('express-hbs'),
utils = require('./utils'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars, helpers = require('../../../server/helpers'),
helpers = rewire('../../../server/helpers'), settingsCache = require('../../../server/settings/cache'),
api = require('../../../server/api'),
sandbox = sinon.sandbox.create(); sandbox = sinon.sandbox.create();
describe('{{ghost_foot}} helper', function () { describe('{{ghost_foot}} helper', function () {
before(function () { var settingsCacheStub;
utils.loadHelpers();
});
afterEach(function () { afterEach(function () {
sandbox.restore(); sandbox.restore();
}); });
it('has loaded ghost_foot helper', function () { beforeEach(function () {
should.exist(handlebars.helpers.ghost_foot); settingsCacheStub = sandbox.stub(settingsCache, 'get');
}); });
it('outputs correct injected code', function (done) { it('outputs correct injected code', function (done) {
sandbox.stub(api.settings, 'read', function () { settingsCacheStub.withArgs('ghost_foot').returns('<script type="text/javascript">var test = \'I am a variable!\'</script>');
return Promise.resolve({
settings: [{value: '<script type="text/javascript">var test = \'I am a variable!\'</script>'}]
});
});
helpers.ghost_foot.call().then(function (rendered) { helpers.ghost_foot.call().then(function (rendered) {
should.exist(rendered); should.exist(rendered);
@ -39,4 +28,26 @@ describe('{{ghost_foot}} helper', function () {
done(); done();
}).catch(done); }).catch(done);
}); });
it('outputs handles code injection being empty', function (done) {
settingsCacheStub.withArgs('ghost_foot').returns('');
helpers.ghost_foot.call().then(function (rendered) {
should.exist(rendered);
rendered.string.should.eql('');
done();
}).catch(done);
});
it('outputs handles code injection being undefined', function (done) {
settingsCacheStub.withArgs('ghost_foot').returns(undefined);
helpers.ghost_foot.call().then(function (rendered) {
should.exist(rendered);
rendered.string.should.eql('');
done();
}).catch(done);
});
}); });

View file

@ -1,26 +1,17 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
sinon = require('sinon'), sinon = require('sinon'),
_ = require('lodash'), _ = require('lodash'),
Promise = require('bluebird'), Promise = require('bluebird'),
hbs = require('express-hbs'),
moment = require('moment'), moment = require('moment'),
utils = require('./utils'),
configUtils = require('../../utils/configUtils'), configUtils = require('../../utils/configUtils'),
helpers = require('../../../server/helpers'), helpers = require('../../../server/helpers'),
api = require('../../../server/api'), api = require('../../../server/api'),
labs = require('../../../server/utils/labs'), labs = require('../../../server/utils/labs'),
settingsCache = require('../../../server/settings/cache'), settingsCache = require('../../../server/settings/cache'),
handlebars = hbs.handlebars,
sandbox = sinon.sandbox.create(); sandbox = sinon.sandbox.create();
describe('{{ghost_head}} helper', function () { describe('{{ghost_head}} helper', function () {
var settingsReadStub;
before(function () {
utils.loadHelpers();
});
afterEach(function () { afterEach(function () {
sandbox.restore(); sandbox.restore();
configUtils.restore(); configUtils.restore();
@ -28,12 +19,6 @@ describe('{{ghost_head}} helper', function () {
// TODO: stub `getImageDimensions` to make things faster // TODO: stub `getImageDimensions` to make things faster
beforeEach(function () { beforeEach(function () {
settingsReadStub = sandbox.stub(api.settings, 'read').returns(new Promise.resolve({
settings: [
{value: ''}
]
}));
sandbox.stub(api.clients, 'read').returns(new Promise.resolve({ sandbox.stub(api.clients, 'read').returns(new Promise.resolve({
clients: [ clients: [
{slug: 'ghost-frontend', secret: 'a1bcde23cfe5', status: 'enabled'} {slug: 'ghost-frontend', secret: 'a1bcde23cfe5', status: 'enabled'}
@ -59,10 +44,6 @@ describe('{{ghost_head}} helper', function () {
configUtils.set('url', 'http://testurl.com/'); configUtils.set('url', 'http://testurl.com/');
}); });
it('has loaded ghost_head helper', function () {
should.exist(handlebars.helpers.ghost_head);
});
it('returns meta tag string on paginated index page without structured data and schema', function (done) { it('returns meta tag string on paginated index page without structured data and schema', function (done) {
helpers.ghost_head.call( helpers.ghost_head.call(
{safeVersion: '0.3', relativeUrl: '/page/2/', context: ['paged', 'index']}, {safeVersion: '0.3', relativeUrl: '/page/2/', context: ['paged', 'index']},
@ -1040,14 +1021,11 @@ describe('{{ghost_head}} helper', function () {
title: 'Ghost', title: 'Ghost',
description: 'blog description', description: 'blog description',
cover: '/content/images/blog-cover.png', cover: '/content/images/blog-cover.png',
icon: '/content/images/favicon.png' icon: '/content/images/favicon.png',
ghost_head: '<style>body {background: red;}</style>'
}; };
beforeEach(function () { beforeEach(function () {
settingsReadStub.returns(new Promise.resolve({
settings: [{value: '<style>body {background: red;}</style>'}]
}));
sandbox.stub(settingsCache, 'get', function (key) { sandbox.stub(settingsCache, 'get', function (key) {
return localSettingsCache[key]; return localSettingsCache[key];
}); });

View file

@ -1,27 +1,16 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
sinon = require('sinon'), sinon = require('sinon'),
hbs = require('express-hbs'),
utils = require('./utils'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'), helpers = require('../../../server/helpers'),
sandbox = sinon.sandbox.create(); sandbox = sinon.sandbox.create();
describe('{{#has}} helper', function () { describe('{{#has}} helper', function () {
before(function () {
utils.loadHelpers();
});
afterEach(function () { afterEach(function () {
sandbox.restore(); sandbox.restore();
}); });
it('has loaded has block helper', function () {
should.exist(handlebars.helpers.has);
});
it('should handle tag list that validates true', function () { it('should handle tag list that validates true', function () {
var fn = sandbox.spy(), var fn = sandbox.spy(),
inverse = sandbox.spy(); inverse = sandbox.spy();

View file

@ -1,11 +1,8 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
sinon = require('sinon'), sinon = require('sinon'),
hbs = require('express-hbs'),
utils = require('./utils'),
configUtils = require('../../utils/configUtils'), configUtils = require('../../utils/configUtils'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'), helpers = require('../../../server/helpers'),
sandbox = sinon.sandbox.create(); sandbox = sinon.sandbox.create();
@ -13,7 +10,6 @@ var should = require('should'),
describe('{{image}} helper', function () { describe('{{image}} helper', function () {
before(function () { before(function () {
configUtils.set({url: 'http://testurl.com/'}); configUtils.set({url: 'http://testurl.com/'});
utils.loadHelpers();
}); });
afterEach(function () { afterEach(function () {
@ -24,10 +20,6 @@ describe('{{image}} helper', function () {
configUtils.restore(); configUtils.restore();
}); });
it('has loaded image helper', function () {
should.exist(handlebars.helpers.image);
});
it('should output relative url of image', function () { it('should output relative url of image', function () {
var rendered = helpers.image.call({ var rendered = helpers.image.call({
image: '/content/images/image-relative-url.png', image: '/content/images/image-relative-url.png',

View file

@ -1,26 +1,15 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
sinon = require('sinon'), sinon = require('sinon'),
hbs = require('express-hbs'),
utils = require('./utils'),
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'), helpers = require('../../../server/helpers'),
logging = require('../../../server/logging'), logging = require('../../../server/logging'),
sandbox = sinon.sandbox.create(); sandbox = sinon.sandbox.create();
describe('{{#is}} helper', function () { describe('{{#is}} helper', function () {
before(function () {
utils.loadHelpers();
});
afterEach(function () { afterEach(function () {
sandbox.restore(); sandbox.restore();
}); });
it('has loaded is block helper', function () {
should.exist(handlebars.helpers.is);
});
// All positive tests // All positive tests
it('should match single context "index"', function () { it('should match single context "index"', function () {
var fn = sandbox.spy(), var fn = sandbox.spy(),

View file

@ -1,9 +1,6 @@
var should = require('should'), var should = require('should'),
sinon = require('sinon'), sinon = require('sinon'),
hbs = require('express-hbs'),
utils = require('./utils'),
configUtils = require('../../utils/configUtils'), configUtils = require('../../utils/configUtils'),
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'), helpers = require('../../../server/helpers'),
settingsCache = require('../../../server/settings/cache'), settingsCache = require('../../../server/settings/cache'),
@ -11,8 +8,6 @@ var should = require('should'),
describe('{{meta_description}} helper', function () { describe('{{meta_description}} helper', function () {
before(function () { before(function () {
utils.loadHelpers();
sandbox.stub(settingsCache, 'get').returns('Just a blogging platform.'); sandbox.stub(settingsCache, 'get').returns('Just a blogging platform.');
}); });
@ -21,10 +16,6 @@ describe('{{meta_description}} helper', function () {
sandbox.restore(); sandbox.restore();
}); });
it('has loaded meta_description helper', function () {
should.exist(handlebars.helpers.meta_description);
});
it('returns correct blog description', function () { it('returns correct blog description', function () {
var rendered = helpers.meta_description.call( var rendered = helpers.meta_description.call(
{}, {},

View file

@ -1,9 +1,6 @@
var should = require('should'), var should = require('should'),
sinon = require('sinon'), sinon = require('sinon'),
hbs = require('express-hbs'),
utils = require('./utils'),
configUtils = require('../../utils/configUtils'), configUtils = require('../../utils/configUtils'),
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'), helpers = require('../../../server/helpers'),
settingsCache = require('../../../server/settings/cache'), settingsCache = require('../../../server/settings/cache'),
@ -11,8 +8,6 @@ var should = require('should'),
describe('{{meta_title}} helper', function () { describe('{{meta_title}} helper', function () {
before(function () { before(function () {
utils.loadHelpers();
sandbox.stub(settingsCache, 'get', function (key) { sandbox.stub(settingsCache, 'get', function (key) {
return { return {
title: 'Ghost' title: 'Ghost'
@ -25,10 +20,6 @@ describe('{{meta_title}} helper', function () {
sandbox.restore(); sandbox.restore();
}); });
it('has loaded meta_title helper', function () {
should.exist(handlebars.helpers.meta_title);
});
it('returns correct title for homepage', function () { it('returns correct title for homepage', function () {
var rendered = helpers.meta_title.call( var rendered = helpers.meta_title.call(
{}, {},

View file

@ -1,11 +1,10 @@
var should = require('should'), var should = require('should'),
hbs = require('express-hbs'), hbs = require('express-hbs'),
utils = require('./utils'),
configUtils = require('../../utils/configUtils'), configUtils = require('../../utils/configUtils'),
path = require('path'), path = require('path'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'); helpers = require('../../../server/helpers');
describe('{{navigation}} helper', function () { describe('{{navigation}} helper', function () {
@ -17,7 +16,6 @@ describe('{{navigation}} helper', function () {
optionsData; optionsData;
before(function (done) { before(function (done) {
utils.loadHelpers();
hbs.express3({ hbs.express3({
partialsDir: [configUtils.config.get('paths').helperTemplates] partialsDir: [configUtils.config.get('paths').helperTemplates]
}); });
@ -25,6 +23,10 @@ describe('{{navigation}} helper', function () {
hbs.cachePartials(function () { hbs.cachePartials(function () {
done(); done();
}); });
// The navigation partial expects this helper
// @TODO: change to register with Ghost's own registration tools
hbs.registerHelper('url', helpers.url);
}); });
beforeEach(function () { beforeEach(function () {
@ -40,10 +42,6 @@ describe('{{navigation}} helper', function () {
}; };
}); });
it('has loaded navigation helper', function () {
should.exist(handlebars.helpers.navigation);
});
it('should throw errors on invalid data', function () { it('should throw errors on invalid data', function () {
// Test 1: navigation = string // Test 1: navigation = string
optionsData.data.blog.navigation = 'not an object'; optionsData.data.blog.navigation = 'not an object';
@ -187,7 +185,6 @@ describe('{{navigation}} helper with custom template', function () {
var optionsData; var optionsData;
before(function (done) { before(function (done) {
utils.loadHelpers();
hbs.express3({ hbs.express3({
partialsDir: [path.resolve(configUtils.config.get('paths').corePath, 'test/unit/server_helpers/test_tpl')] partialsDir: [path.resolve(configUtils.config.get('paths').corePath, 'test/unit/server_helpers/test_tpl')]
}); });

View file

@ -1,11 +1,7 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
sinon = require('sinon'), sinon = require('sinon'),
Promise = require('bluebird'), Promise = require('bluebird'),
hbs = require('express-hbs'),
utils = require('./utils'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'), helpers = require('../../../server/helpers'),
api = require('../../../server/api'), api = require('../../../server/api'),
@ -20,7 +16,6 @@ describe('{{next_post}} helper', function () {
describe('with valid post data - ', function () { describe('with valid post data - ', function () {
beforeEach(function () { beforeEach(function () {
utils.loadHelpers();
readPostStub = sandbox.stub(api.posts, 'read', function (options) { readPostStub = sandbox.stub(api.posts, 'read', function (options) {
if (options.include.indexOf('next') === 0) { if (options.include.indexOf('next') === 0) {
return Promise.resolve({ return Promise.resolve({
@ -30,10 +25,6 @@ describe('{{next_post}} helper', function () {
}); });
}); });
it('has loaded next_post helper', function () {
should.exist(handlebars.helpers.prev_post);
});
it('shows \'if\' template with next post data', function (done) { it('shows \'if\' template with next post data', function (done) {
var fn = sinon.spy(), var fn = sinon.spy(),
inverse = sinon.spy(), inverse = sinon.spy(),
@ -63,7 +54,6 @@ describe('{{next_post}} helper', function () {
describe('for valid post with no next post', function () { describe('for valid post with no next post', function () {
beforeEach(function () { beforeEach(function () {
utils.loadHelpers();
readPostStub = sandbox.stub(api.posts, 'read', function (options) { readPostStub = sandbox.stub(api.posts, 'read', function (options) {
if (options.include.indexOf('next') === 0) { if (options.include.indexOf('next') === 0) {
return Promise.resolve({posts: [{slug: '/current/', title: 'post 2'}]}); return Promise.resolve({posts: [{slug: '/current/', title: 'post 2'}]});
@ -95,7 +85,6 @@ describe('{{next_post}} helper', function () {
describe('for invalid post data', function () { describe('for invalid post data', function () {
beforeEach(function () { beforeEach(function () {
utils.loadHelpers();
readPostStub = sandbox.stub(api.posts, 'read', function (options) { readPostStub = sandbox.stub(api.posts, 'read', function (options) {
if (options.include.indexOf('next') === 0) { if (options.include.indexOf('next') === 0) {
return Promise.resolve({}); return Promise.resolve({});
@ -121,7 +110,6 @@ describe('{{next_post}} helper', function () {
describe('for unpublished post', function () { describe('for unpublished post', function () {
beforeEach(function () { beforeEach(function () {
utils.loadHelpers();
readPostStub = sandbox.stub(api.posts, 'read', function (options) { readPostStub = sandbox.stub(api.posts, 'read', function (options) {
if (options.include.indexOf('next') === 0) { if (options.include.indexOf('next') === 0) {
return Promise.resolve({ return Promise.resolve({

View file

@ -1,26 +1,15 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
hbs = require('express-hbs'),
utils = require('./utils'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'); helpers = require('../../../server/helpers');
describe('{{page_url}} helper', function () { describe('{{page_url}} helper', function () {
var options = {data: {root: {pagination: {}}}}; var options = {data: {root: {pagination: {}}}};
before(function () {
utils.loadHelpers();
});
beforeEach(function () { beforeEach(function () {
options.data.root = {pagination: {}}; options.data.root = {pagination: {}};
}); });
it('has loaded page_url helper', function () {
should.exist(handlebars.helpers.page_url);
});
it('can return a valid url when the relative URL is /', function () { it('can return a valid url when the relative URL is /', function () {
options.data.root.relativeUrl = '/'; options.data.root.relativeUrl = '/';
options.data.root.pagination.next = 3; options.data.root.pagination.next = 3;

View file

@ -1,21 +1,22 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
hbs = require('express-hbs'), hbs = require('express-hbs'),
utils = require('./utils'),
configUtils = require('../../utils/configUtils'), configUtils = require('../../utils/configUtils'),
path = require('path'), path = require('path'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'); helpers = require('../../../server/helpers');
describe('{{pagination}} helper', function () { describe('{{pagination}} helper', function () {
before(function (done) { before(function (done) {
utils.loadHelpers();
hbs.express3({partialsDir: [configUtils.config.get('paths').helperTemplates]}); hbs.express3({partialsDir: [configUtils.config.get('paths').helperTemplates]});
hbs.cachePartials(function () { hbs.cachePartials(function () {
done(); done();
}); });
// The pagination partial expects this helper
// @TODO: change to register with Ghost's own registration tools
hbs.registerHelper('page_url', helpers.page_url);
}); });
var paginationRegex = /class="pagination"/, var paginationRegex = /class="pagination"/,
@ -23,10 +24,6 @@ describe('{{pagination}} helper', function () {
olderRegex = /class="older-posts"/, olderRegex = /class="older-posts"/,
pageRegex = /class="page-number"/; pageRegex = /class="page-number"/;
it('has loaded pagination helper', function () {
should.exist(handlebars.helpers.pagination);
});
it('should throw if pagination data is incorrect', function () { it('should throw if pagination data is incorrect', function () {
var runHelper = function (data) { var runHelper = function (data) {
return function () { return function () {
@ -126,7 +123,6 @@ describe('{{pagination}} helper', function () {
describe('{{pagination}} helper with custom template', function () { describe('{{pagination}} helper with custom template', function () {
before(function (done) { before(function (done) {
utils.loadHelpers();
hbs.express3({partialsDir: [path.resolve(configUtils.config.get('paths').corePath, 'test/unit/server_helpers/test_tpl')]}); hbs.express3({partialsDir: [path.resolve(configUtils.config.get('paths').corePath, 'test/unit/server_helpers/test_tpl')]});
hbs.cachePartials(function () { hbs.cachePartials(function () {

View file

@ -1,20 +1,9 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
hbs = require('express-hbs'),
utils = require('./utils'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'); helpers = require('../../../server/helpers');
describe('{{plural}} helper', function () { describe('{{plural}} helper', function () {
before(function () {
utils.loadHelpers();
});
it('has loaded plural helper', function () {
should.exist(handlebars.helpers.plural);
});
it('will show no-value string', function () { it('will show no-value string', function () {
var expected = 'No Posts', var expected = 'No Posts',
rendered = helpers.plural.call({}, 0, { rendered = helpers.plural.call({}, 0, {

View file

@ -1,20 +1,9 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
hbs = require('express-hbs'),
utils = require('./utils'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'); helpers = require('../../../server/helpers');
describe('{{post_class}} helper', function () { describe('{{post_class}} helper', function () {
before(function () {
utils.loadHelpers();
});
it('has loaded postclass helper', function () {
should.exist(handlebars.helpers.post_class);
});
it('can render class string', function () { it('can render class string', function () {
var rendered = helpers.post_class.call({}); var rendered = helpers.post_class.call({});

View file

@ -1,11 +1,8 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
sinon = require('sinon'), sinon = require('sinon'),
Promise = require('bluebird'), Promise = require('bluebird'),
hbs = require('express-hbs'),
utils = require('./utils'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'), helpers = require('../../../server/helpers'),
api = require('../../../server/api'), api = require('../../../server/api'),
@ -20,7 +17,6 @@ describe('{{prev_post}} helper', function () {
describe('with valid post data - ', function () { describe('with valid post data - ', function () {
beforeEach(function () { beforeEach(function () {
utils.loadHelpers();
readPostStub = sandbox.stub(api.posts, 'read', function (options) { readPostStub = sandbox.stub(api.posts, 'read', function (options) {
if (options.include.indexOf('previous') === 0) { if (options.include.indexOf('previous') === 0) {
return Promise.resolve({ return Promise.resolve({
@ -30,10 +26,6 @@ describe('{{prev_post}} helper', function () {
}); });
}); });
it('has loaded prev_post helper', function () {
should.exist(handlebars.helpers.prev_post);
});
it('shows \'if\' template with previous post data', function (done) { it('shows \'if\' template with previous post data', function (done) {
var fn = sinon.spy(), var fn = sinon.spy(),
inverse = sinon.spy(), inverse = sinon.spy(),
@ -64,7 +56,6 @@ describe('{{prev_post}} helper', function () {
describe('for valid post with no previous post', function () { describe('for valid post with no previous post', function () {
beforeEach(function () { beforeEach(function () {
utils.loadHelpers();
readPostStub = sandbox.stub(api.posts, 'read', function (options) { readPostStub = sandbox.stub(api.posts, 'read', function (options) {
if (options.include.indexOf('previous') === 0) { if (options.include.indexOf('previous') === 0) {
return Promise.resolve({posts: [{slug: '/current/', title: 'post 2'}]}); return Promise.resolve({posts: [{slug: '/current/', title: 'post 2'}]});
@ -97,7 +88,6 @@ describe('{{prev_post}} helper', function () {
describe('for invalid post data', function () { describe('for invalid post data', function () {
beforeEach(function () { beforeEach(function () {
utils.loadHelpers();
readPostStub = sandbox.stub(api.posts, 'read', function (options) { readPostStub = sandbox.stub(api.posts, 'read', function (options) {
if (options.include.indexOf('previous') === 0) { if (options.include.indexOf('previous') === 0) {
return Promise.resolve({}); return Promise.resolve({});
@ -123,7 +113,6 @@ describe('{{prev_post}} helper', function () {
describe('for unpublished post', function () { describe('for unpublished post', function () {
beforeEach(function () { beforeEach(function () {
utils.loadHelpers();
readPostStub = sandbox.stub(api.posts, 'read', function (options) { readPostStub = sandbox.stub(api.posts, 'read', function (options) {
if (options.include.indexOf('previous') === 0) { if (options.include.indexOf('previous') === 0) {
return Promise.resolve({ return Promise.resolve({

View file

@ -1,28 +1,16 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
sinon = require('sinon'), sinon = require('sinon'),
hbs = require('express-hbs'),
utils = require('./utils'),
rewire = require('rewire'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars, helpers = require('../../../server/helpers'),
helpers = rewire('../../../server/helpers'),
sandbox = sinon.sandbox.create(); sandbox = sinon.sandbox.create();
describe('{{tags}} helper', function () { describe('{{tags}} helper', function () {
before(function () {
utils.loadHelpers();
});
afterEach(function () { afterEach(function () {
sandbox.restore(); sandbox.restore();
}); });
it('has loaded tags helper', function () {
should.exist(handlebars.helpers.tags);
});
it('can return string with tags', function () { it('can return string with tags', function () {
var tags = [{name: 'foo'}, {name: 'bar'}], var tags = [{name: 'foo'}, {name: 'bar'}],
rendered = helpers.tags.call( rendered = helpers.tags.call(

View file

@ -1,20 +1,9 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
hbs = require('express-hbs'),
utils = require('./utils'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'); helpers = require('../../../server/helpers');
describe('{{title}} Helper', function () { describe('{{title}} Helper', function () {
before(function () {
utils.loadHelpers();
});
it('has loaded title helper', function () {
should.exist(handlebars.helpers.title);
});
it('can render title', function () { it('can render title', function () {
var title = 'Hello World', var title = 'Hello World',
rendered = helpers.title.call({title: title}); rendered = helpers.title.call({title: title});

View file

@ -1,26 +1,15 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
hbs = require('express-hbs'),
utils = require('./utils'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'); helpers = require('../../../server/helpers');
describe('{{twitter_url}} helper', function () { describe('{{twitter_url}} helper', function () {
var options = {data: {blog: {}}}; var options = {data: {blog: {}}};
before(function () {
utils.loadHelpers();
});
beforeEach(function () { beforeEach(function () {
options.data.blog = {twitter: ''}; options.data.blog = {twitter: ''};
}); });
it('has loaded twitter_url helper', function () {
should.exist(handlebars.helpers.twitter_url);
});
it('should output the twitter url for @blog, if no other twitter username is provided', function () { it('should output the twitter url for @blog, if no other twitter username is provided', function () {
options.data.blog = {twitter: '@hey'}; options.data.blog = {twitter: '@hey'};

View file

@ -1,12 +1,9 @@
var should = require('should'), var should = require('should'), // jshint ignore:line
sinon = require('sinon'), sinon = require('sinon'),
Promise = require('bluebird'), Promise = require('bluebird'),
hbs = require('express-hbs'),
utils = require('./utils'),
configUtils = require('../../utils/configUtils'), configUtils = require('../../utils/configUtils'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'), helpers = require('../../../server/helpers'),
api = require('../../../server/api'), api = require('../../../server/api'),
@ -17,7 +14,6 @@ describe('{{url}} helper', function () {
before(function () { before(function () {
configUtils.set({url: 'http://testurl.com/'}); configUtils.set({url: 'http://testurl.com/'});
utils.loadHelpers();
}); });
beforeEach(function () { beforeEach(function () {
@ -35,10 +31,6 @@ describe('{{url}} helper', function () {
configUtils.restore(); configUtils.restore();
}); });
it('has loaded url helper', function () {
should.exist(handlebars.helpers.url);
});
it('should return the slug with a prefix slash if the context is a post', function () { it('should return the slug with a prefix slash if the context is a post', function () {
rendered = helpers.url.call({ rendered = helpers.url.call({
html: 'content', html: 'content',

View file

@ -1,20 +0,0 @@
// # Helper Test Utils
//
// Contains shared code for intialising tests
//
// @TODO refactor this file out of existence
// I believe if we refactor the handlebars instances and helpers to be more self-contained and modular
// We can likely have init functions which replace the need for this file
var hbs = require('express-hbs'),
// Stuff we are testing
helpers = require('../../../server/helpers'),
utils = {};
utils.loadHelpers = function () {
var adminHbs = hbs.create();
helpers.loadCoreHelpers(adminHbs);
};
module.exports = utils;

View file

@ -1,34 +1,37 @@
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers // jscs:disable requireCamelCaseOrUpperCaseIdentifiers
var should = require('should'), var should = require('should'), // jshint ignore:line
rewire = require('rewire'), _ = require('lodash'),
hbs = require('express-hbs'), hbs = require('express-hbs'),
// Stuff we are testing // Stuff we are testing
helpers = require.main.require('core/server/helpers');
helpers = rewire('../../server/helpers');
describe('Helpers', function () { describe('Helpers', function () {
beforeEach(function () { var hbsHelpers = ['each', 'if', 'unless', 'with', 'helperMissing', 'blockHelperMissing', 'log', 'lookup'],
var adminHbs = hbs.create(); ghostHelpers = [
helpers = rewire('../../server/helpers'); 'asset', 'author', 'body_class', 'content', 'date', 'encode', 'excerpt', 'facebook_url', 'foreach', 'get',
helpers.loadCoreHelpers(adminHbs); 'ghost_foot', 'ghost_head', 'has', 'image', 'is', 'meta_description', 'meta_title', 'navigation',
}); 'next_post', 'page_url', 'pagination', 'plural', 'post_class', 'prev_post', 'tags', 'title', 'twitter_url',
'url'
],
expectedHelpers = _.concat(hbsHelpers, ghostHelpers);
describe('helperMissing', function () { describe('Load Core Helpers', function () {
it('should not throw an error', function () { before(function () {
var helperMissing = helpers.__get__('coreHelpers.helperMissing'); helpers.loadCoreHelpers();
});
should.exist(helperMissing); // This will work when we finish refactoring
it.skip('should have exactly the right helpers', function () {
var foundHelpers, missingHelpers, unexpectedHelpers;
function runHelper() { foundHelpers = _.keys(hbs.handlebars.helpers);
var args = arguments;
return function () {
helperMissing.apply(null, args);
};
}
runHelper('test helper').should.not.throwError(); missingHelpers = _.difference(expectedHelpers, foundHelpers);
runHelper('test helper', 'second argument').should.not.throwError(); unexpectedHelpers = _.difference(foundHelpers, expectedHelpers);
missingHelpers.should.be.an.Array().with.lengthOf(0);
unexpectedHelpers.should.be.an.Array().with.lengthOf(0);
}); });
}); });
}); });