From 0201c431d76c52a7558bfb13f2727d3570e26489 Mon Sep 17 00:00:00 2001 From: Katharina Irrgang Date: Fri, 3 Feb 2017 14:15:11 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A5=20do=20not=20store=20settings=20in?= =?UTF-8?q?=20config=20(#7924)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🎨 🔥 do not store settings in config and make settings cache easier available - remove remembering settings value in theme config - if we need a cache value, we are asking the settings cache directly - instead of settings.getSettingSync we use settings.cache.get - added TODO: - think about moving the settings cache out of api/settings - we could create a folder named cache cache/settings - this settings cache listens on model changes for settings - decoupling * 🔥 remove timezone from config - no need to store in overrides config and in defaults settings * 🎨 context object helper - replace config.get('theme') by settings cache * 🎨 replace config.get('theme') by settings.cache.get * 🎨 adapt tests * fixes from comments --- core/server/api/configuration.js | 3 +- core/server/api/settings.js | 92 +++++---------- core/server/apps/amp/lib/router.js | 5 +- core/server/config/overrides.json | 3 - .../server/controllers/frontend/fetch-data.js | 4 +- .../controllers/frontend/post-lookup.js | 5 +- core/server/data/meta/asset_url.js | 7 +- core/server/data/meta/context_object.js | 13 +- core/server/data/meta/description.js | 7 +- core/server/data/meta/index.js | 29 ++++- core/server/data/meta/title.js | 13 +- core/server/data/xml/rss/index.js | 5 +- core/server/helpers/ghost_head.js | 15 ++- core/server/index.js | 4 +- core/server/mail/GhostMailer.js | 4 +- core/server/middleware/serve-favicon.js | 9 +- core/server/middleware/theme-handler.js | 30 +++-- core/server/utils/labs.js | 5 +- core/server/utils/url.js | 5 +- core/test/functional/routes/frontend_spec.js | 50 +++++--- core/test/integration/api/api_posts_spec.js | 20 +++- .../test/integration/api/api_settings_spec.js | 6 +- .../integration/model/model_posts_spec.js | 35 ++++-- core/test/unit/config/index_spec.js | 62 ---------- .../controllers/frontend/fetch-data_spec.js | 16 ++- .../unit/controllers/frontend/index_spec.js | 81 +++---------- .../controllers/frontend/post-lookup_spec.js | 20 ++-- core/test/unit/ghost_url_spec.js | 1 - core/test/unit/mail/GhostMailer_spec.js | 32 +++-- core/test/unit/metadata/author_image_spec.js | 28 ++--- .../test/unit/metadata/context_object_spec.js | 14 ++- core/test/unit/metadata/title_spec.js | 64 +++++----- .../unit/middleware/serve-favicon_spec.js | 61 ++++------ core/test/unit/rss_spec.js | 23 ++-- core/test/unit/server_helpers/asset_spec.js | 29 +++-- .../unit/server_helpers/ghost_head_spec.js | 111 ++++++++++-------- .../server_helpers/meta_description_spec.js | 15 ++- .../unit/server_helpers/meta_title_spec.js | 15 ++- core/test/unit/utils/url_spec.js | 38 ++++-- 39 files changed, 493 insertions(+), 486 deletions(-) diff --git a/core/server/api/configuration.js b/core/server/api/configuration.js index 2c1b1b5d8c..00d33d4a9d 100644 --- a/core/server/api/configuration.js +++ b/core/server/api/configuration.js @@ -2,6 +2,7 @@ // RESTful API for browsing the configuration var _ = require('lodash'), config = require('../config'), + settingsCache = require('../api/settings').cache, ghostVersion = require('../utils/ghost-version'), models = require('../models'), Promise = require('bluebird'), @@ -29,7 +30,7 @@ function getBaseConfig() { useGravatar: !config.isPrivacyDisabled('useGravatar'), publicAPI: config.get('publicAPI') === true, blogUrl: utils.url.urlFor('home', true), - blogTitle: config.get('theme').title, + blogTitle: settingsCache.get('title'), routeKeywords: config.get('routeKeywords') }; } diff --git a/core/server/api/settings.js b/core/server/api/settings.js index 7c81142776..28532f39ad 100644 --- a/core/server/api/settings.js +++ b/core/server/api/settings.js @@ -6,15 +6,12 @@ var _ = require('lodash'), config = require('../config'), canThis = require('../permissions').canThis, errors = require('../errors'), - logging = require('../logging'), utils = require('./utils'), i18n = require('../i18n'), - globalUtils = require('../utils'), docName = 'settings', settings, - updateConfigCache, updateSettingsCache, settingsFilter, filterPaths, @@ -31,49 +28,6 @@ var _ = require('lodash'), */ settingsCache = {}; -/** -* ### Updates Config Theme Settings -* Maintains the cache of theme specific variables that are reliant on settings. -* @private -*/ -updateConfigCache = function () { - var labsValue = {}; - - if (settingsCache.labs && settingsCache.labs.value) { - try { - labsValue = JSON.parse(settingsCache.labs.value); - } catch (err) { - logging.error(new errors.GhostError({ - err: err, - message: i18n.t('errors.api.settings.invalidJsonInLabs'), - context: i18n.t('errors.api.settings.labsColumnCouldNotBeParsed'), - help: i18n.t('errors.api.settings.tryUpdatingLabs') - })); - } - } - - // @TODO: why are we putting the settings cache values into config?we could access the cache directly - // @TODO: plus: why do we assign the values to the prefix "theme"? - // @TODO: might be related to https://github.com/TryGhost/Ghost/issues/7488 - config.set('theme:title', (settingsCache.title && settingsCache.title.value) || ''); - config.set('theme:description', (settingsCache.description && settingsCache.description.value) || ''); - config.set('theme:logo', (settingsCache.logo && settingsCache.logo.value) || ''); - config.set('theme:cover', (settingsCache.cover && settingsCache.cover.value) || ''); - config.set('theme:navigation', (settingsCache.navigation && JSON.parse(settingsCache.navigation.value)) || []); - config.set('theme:postsPerPage', (settingsCache.postsPerPage && settingsCache.postsPerPage.value) || config.get('theme').postsPerPage); - config.set('theme:permalinks', (settingsCache.permalinks && settingsCache.permalinks.value) || config.get('theme').permalinks); - config.set('theme:twitter', (settingsCache.twitter && settingsCache.twitter.value) || ''); - config.set('theme:facebook', (settingsCache.facebook && settingsCache.facebook.value) || ''); - config.set('theme:timezone', (settingsCache.activeTimezone && settingsCache.activeTimezone.value) || config.get('theme').timezone); - config.set('theme:url', globalUtils.url.urlFor('home', true)); - config.set('theme:amp', (settingsCache.amp && settingsCache.amp.value === 'true')); - config.set('theme:icon', settingsCache.icon && settingsCache.icon.value); - - _.each(labsValue, function (value, key) { - config.set('labs:' + key, value); - }); -}; - /** * ### Update Settings Cache * Maintain the internal cache of the settings object @@ -90,8 +44,6 @@ updateSettingsCache = function (settings, options) { settingsCache[key] = setting; }); - updateConfigCache(); - return Promise.resolve(settingsCache); } @@ -99,7 +51,7 @@ updateSettingsCache = function (settings, options) { .then(function (result) { // keep reference and update all keys _.extend(settingsCache, readSettingsResult(result.models)); - updateConfigCache(); + return settingsCache; }); }; @@ -187,6 +139,7 @@ readSettingsResult = function (settingsModels) { apps = config.get('paths').availableApps, res; + // @TODO: remove availableThemes from settings cache and create an endpoint to fetch themes if (settings.activeTheme && themes) { res = filterPaths(themes, settings.activeTheme.value); @@ -255,7 +208,7 @@ populateDefaultSetting = function (key) { return Promise.reject(err); } - // TODO: Different kind of error? + // TODO: different kind of error? return Promise.reject(new errors.NotFoundError({message: i18n.t('errors.api.settings.problemFindingSetting', {key: key})})); }); }; @@ -434,19 +387,36 @@ settings = { module.exports = settings; /** - * synchronous function to get cached settings value - * returns the value of the settings entry + * @TODO: + * - move settings cache somewhere else e.q. listen on model changes + * + * IMPORTANT: + * We store settings with a type and a key in the database. + * + * { + * type: core + * key: dbHash + * value: ... + * } + * + * But the settings cache does not allow requesting a value by type, only by key. + * e.g. settings.cache.get('dbHash') */ -module.exports.getSettingSync = function getSettingSync(key) { - return settingsCache[key] && settingsCache[key].value; -}; +module.exports.cache = { + get: function get(key) { + if (!settingsCache[key]) { + return; + } -/** - * synchronous function to get all cached settings values - * returns everything for now - */ -module.exports.getSettingsSync = function getSettingsSync() { - return settingsCache; + try { + return JSON.parse(settingsCache[key].value); + } catch (err) { + return settingsCache[key].value; + } + }, + getAll: function getAll() { + return settingsCache; + } }; module.exports.updateSettingsCache = updateSettingsCache; diff --git a/core/server/apps/amp/lib/router.js b/core/server/apps/amp/lib/router.js index 72b93ebd6f..335e986f14 100644 --- a/core/server/apps/amp/lib/router.js +++ b/core/server/apps/amp/lib/router.js @@ -5,8 +5,8 @@ var path = require('path'), i18n = require('../../../i18n'), // Dirty requires - config = require('../../../config'), errors = require('../../../errors'), + settingsCache = require('../../../api/settings').cache, templates = require('../../../controllers/frontend/templates'), postLookup = require('../../../controllers/frontend/post-lookup'), setResponseContext = require('../../../controllers/frontend/context'); @@ -36,6 +36,7 @@ function controller(req, res, next) { function getPostData(req, res, next) { req.body = req.body || {}; + postLookup(res.locals.relativeUrl) .then(function (result) { if (result && result.post) { @@ -50,7 +51,7 @@ function getPostData(req, res, next) { } function checkIfAMPIsEnabled(req, res, next) { - var ampIsEnabled = config.get('theme:amp'); + var ampIsEnabled = settingsCache.get('amp'); if (ampIsEnabled) { return next(); diff --git a/core/server/config/overrides.json b/core/server/config/overrides.json index 0607b48e35..afab6a7547 100644 --- a/core/server/config/overrides.json +++ b/core/server/config/overrides.json @@ -63,9 +63,6 @@ "cannotScheduleAPostBeforeInMinutes": 2, "publishAPostBySchedulerToleranceInMinutes": 2 }, - "theme": { - "timezone": "Etc/UTC" - }, "maintenance": { "enabled": false } diff --git a/core/server/controllers/frontend/fetch-data.js b/core/server/controllers/frontend/fetch-data.js index 6ae5675a10..4d6a118abc 100644 --- a/core/server/controllers/frontend/fetch-data.js +++ b/core/server/controllers/frontend/fetch-data.js @@ -4,8 +4,8 @@ */ var api = require('../../api'), _ = require('lodash'), - config = require('../../config'), Promise = require('bluebird'), + settingsCache = api.settings.cache, queryDefaults, defaultPostQuery = {}; @@ -33,7 +33,7 @@ _.extend(defaultPostQuery, queryDefaults, { function fetchPostsPerPage(options) { options = options || {}; - var postsPerPage = parseInt(config.get('theme').postsPerPage); + var postsPerPage = parseInt(settingsCache.get('postsPerPage')); // No negative posts per page, must be number if (!isNaN(postsPerPage) && postsPerPage > 0) { diff --git a/core/server/controllers/frontend/post-lookup.js b/core/server/controllers/frontend/post-lookup.js index dcfec10def..f73dc020d9 100644 --- a/core/server/controllers/frontend/post-lookup.js +++ b/core/server/controllers/frontend/post-lookup.js @@ -3,8 +3,7 @@ var _ = require('lodash'), url = require('url'), routeMatch = require('path-match')(), api = require('../../api'), - config = require('../../config'), - + settingsCache = api.settings.cache, optionsFormat = '/:options?'; function getOptionsFormat(linkStructure) { @@ -13,7 +12,7 @@ function getOptionsFormat(linkStructure) { function postLookup(postUrl) { var postPath = url.parse(postUrl).path, - postPermalink = config.get('theme').permalinks, + postPermalink = settingsCache.get('permalinks'), pagePermalink = '/:slug/', isEditURL = false, matchFuncPost, diff --git a/core/server/data/meta/asset_url.js b/core/server/data/meta/asset_url.js index 59e4d6ff76..b5b8871c13 100644 --- a/core/server/data/meta/asset_url.js +++ b/core/server/data/meta/asset_url.js @@ -1,4 +1,5 @@ var config = require('../../config'), + settingsCache = require('../../api/settings').cache, utils = require('../../utils'); function getAssetUrl(path, isAdmin, minify) { @@ -19,7 +20,11 @@ function getAssetUrl(path, isAdmin, minify) { if (isAdmin) { output = utils.url.urlJoin(utils.url.getSubdir(), '/favicon.ico'); } else { - output = config.get('theme:icon') ? utils.url.urlJoin(utils.url.getSubdir(), utils.url.urlFor('image', {image: config.get('theme:icon')})) : utils.url.urlJoin(utils.url.getSubdir(), '/favicon.ico'); + if (settingsCache.get('icon')) { + output = utils.url.urlJoin(utils.url.getSubdir(), utils.url.urlFor('image', {image: settingsCache.get('icon')})); + } else { + output = utils.url.urlJoin(utils.url.getSubdir(), '/favicon.ico'); + } } } // Get rid of any leading slash on the path diff --git a/core/server/data/meta/context_object.js b/core/server/data/meta/context_object.js index 6e032c2ad4..0407fd1db2 100644 --- a/core/server/data/meta/context_object.js +++ b/core/server/data/meta/context_object.js @@ -1,8 +1,15 @@ -var config = require('../../config'), - _ = require('lodash'); +var settingsCache = require('../../api/settings').cache, + _ = require('lodash'); function getContextObject(data, context) { - var blog = config.get('theme'), + /** + * If the data object does not contain the requested context, we return the fallback object. + */ + var blog = { + cover: settingsCache.get('cover'), + twitter: settingsCache.get('twitter'), + facebook: settingsCache.get('facebook') + }, contextObject; context = _.includes(context, 'page') || _.includes(context, 'amp') ? 'post' : context; diff --git a/core/server/data/meta/description.js b/core/server/data/meta/description.js index e517b84fa5..fc9e8901c7 100644 --- a/core/server/data/meta/description.js +++ b/core/server/data/meta/description.js @@ -1,16 +1,17 @@ var _ = require('lodash'), - config = require('../../config'); + settingsCache = require('../../api/settings').cache; function getDescription(data, root) { var description = '', - context = root ? root.context : null; + context = root ? root.context : null, + blogDescription = settingsCache.get('description'); if (data.meta_description) { description = data.meta_description; } else if (_.includes(context, 'paged')) { description = ''; } else if (_.includes(context, 'home')) { - description = config.get('theme').description; + description = blogDescription; } else if (_.includes(context, 'author') && data.author) { description = data.author.meta_description || data.author.bio; } else if (_.includes(context, 'tag') && data.tag) { diff --git a/core/server/data/meta/index.js b/core/server/data/meta/index.js index 3c5b0032fa..798eb5660e 100644 --- a/core/server/data/meta/index.js +++ b/core/server/data/meta/index.js @@ -1,6 +1,5 @@ -var _ = require('lodash'), - Promise = require('bluebird'), - config = require('../../config'), +var Promise = require('bluebird'), + settingsCache = require('../../api/settings').cache, utils = require('../../utils'), getUrl = require('./url'), getImageDimensions = require('./image-dimensions'), @@ -46,12 +45,30 @@ function getMetaData(data, root) { publishedDate: getPublishedDate(data), modifiedDate: getModifiedDate(data), ogType: getOgType(data), - blog: _.cloneDeep(config.get('theme')) + // @TODO: pass into each meta helper - wrap each helper + blog: { + title: settingsCache.get('title'), + description: settingsCache.get('description'), + url: utils.url.urlFor('home', true), + facebook: settingsCache.get('facebook'), + twitter: settingsCache.get('twitter'), + timezone: settingsCache.get('activeTimezone'), + navigation: settingsCache.get('navigation'), + posts_per_page: settingsCache.get('postsPerPage'), + icon: settingsCache.get('icon'), + cover: settingsCache.get('cover'), + logo: settingsCache.get('logo'), + amp: settingsCache.get('amp') + } }; metaData.blog.logo = {}; - metaData.blog.logo.url = config.get('theme').logo ? - utils.url.urlFor('image', {image: config.get('theme').logo}, true) : utils.url.urlJoin(utils.url.urlFor('admin'), 'img/ghosticon.jpg'); + + if (settingsCache.get('logo')) { + metaData.blog.logo.url = utils.url.urlFor('image', {image: settingsCache.get('logo')}, true); + } else { + metaData.blog.logo.url = utils.url.urlJoin(utils.url.urlFor('admin'), 'img/ghosticon.jpg'); + } // TODO: cleanup these if statements if (data.post && data.post.html) { diff --git a/core/server/data/meta/title.js b/core/server/data/meta/title.js index 8850edf980..2ca6e4d80e 100644 --- a/core/server/data/meta/title.js +++ b/core/server/data/meta/title.js @@ -1,28 +1,29 @@ var _ = require('lodash'), - config = require('../../config'); + settingsCache = require('../../api/settings').cache; function getTitle(data, root) { var title = '', context = root ? root.context : null, - blog = config.get('theme'), + blogTitle = settingsCache.get('title'), pagination = root ? root.pagination : null, pageString = ''; if (pagination && pagination.total > 1) { pageString = ' - Page ' + pagination.page; } + if (data.meta_title) { title = data.meta_title; } else if (_.includes(context, 'home')) { - title = blog.title; + title = blogTitle; } else if (_.includes(context, 'author') && data.author) { - title = data.author.name + pageString + ' - ' + blog.title; + title = data.author.name + pageString + ' - ' + blogTitle; } else if (_.includes(context, 'tag') && data.tag) { - title = data.tag.meta_title || data.tag.name + pageString + ' - ' + blog.title; + title = data.tag.meta_title || data.tag.name + pageString + ' - ' + blogTitle; } else if ((_.includes(context, 'post') || _.includes(context, 'page')) && data.post) { title = data.post.meta_title || data.post.title; } else { - title = blog.title + pageString; + title = blogTitle + pageString; } return (title || '').trim(); diff --git a/core/server/data/xml/rss/index.js b/core/server/data/xml/rss/index.js index 8a96ce5204..10c3ec0a4b 100644 --- a/core/server/data/xml/rss/index.js +++ b/core/server/data/xml/rss/index.js @@ -7,6 +7,7 @@ var crypto = require('crypto'), i18n = require('../../../i18n'), filters = require('../../../filters'), processUrls = require('../../../utils/make-absolute-urls'), + settingsCache = require('../../../api/settings').cache, // Really ugly temporary hack for location of things fetchData = require('../../../controllers/frontend/fetch-data'), @@ -41,8 +42,8 @@ function getData(channelOpts, slugParam) { if (result.data && result.data.tag) { titleStart = result.data.tag[0].name + ' - ' || ''; } if (result.data && result.data.author) { titleStart = result.data.author[0].name + ' - ' || ''; } - response.title = titleStart + config.get('theme').title; - response.description = config.get('theme').description; + response.title = titleStart + settingsCache.get('title'); + response.description = settingsCache.get('description'); response.results = { posts: result.posts, meta: result.meta diff --git a/core/server/helpers/ghost_head.js b/core/server/helpers/ghost_head.js index 3fc505045d..7d365295fc 100644 --- a/core/server/helpers/ghost_head.js +++ b/core/server/helpers/ghost_head.js @@ -17,18 +17,21 @@ var getMetaData = require('../data/meta'), Promise = require('bluebird'), labs = require('../utils/labs'), utils = require('../utils'), - api = require('../api'); + api = require('../api'), + settingsCache = api.settings.cache; function getClient() { if (labs.isSet('publicAPI') === true) { return api.clients.read({slug: 'ghost-frontend'}).then(function (client) { client = client.clients[0]; + if (client.status === 'enabled') { return { id: client.slug, secret: client.secret }; } + return {}; }); } @@ -42,6 +45,7 @@ function writeMetaTag(property, content, type) { function finaliseStructuredData(metaData) { var head = []; + _.each(metaData.structuredData, function (content, property) { if (property === 'article:tag') { _.each(metaData.keywords, function (keyword) { @@ -57,6 +61,7 @@ function finaliseStructuredData(metaData) { escapeExpression(content))); } }); + return head; } @@ -88,9 +93,10 @@ function ghost_head(options) { metaData: getMetaData(this, options.data.root), client: getClient() }, + blogIcon = settingsCache.get('icon'), // CASE: blog icon is not set in config, we serve the default - iconType = !config.get('theme:icon') ? 'x-icon' : config.get('theme:icon').match(/\/favicon\.ico$/i) ? 'x-icon' : 'png', - favicon = !config.get('theme:icon') ? '/favicon.ico' : utils.url.urlFor('image', {image: config.get('theme:icon')}); + iconType = !blogIcon ? 'x-icon' : blogIcon.match(/\/favicon\.ico$/i) ? 'x-icon' : 'png', + favicon = !blogIcon ? '/favicon.ico' : utils.url.urlFor('image', {image: blogIcon}); return Promise.props(fetch).then(function (response) { client = response.client; @@ -104,7 +110,7 @@ function ghost_head(options) { head.push(''); // show amp link in post when 1. we are not on the amp page and 2. amp is enabled - if (_.includes(context, 'post') && !_.includes(context, 'amp') && config.get('theme:amp')) { + if (_.includes(context, 'post') && !_.includes(context, 'amp') && settingsCache.get('amp')) { head.push(''); } @@ -138,6 +144,7 @@ function ghost_head(options) { head.push(''); + head.push(''); diff --git a/core/server/index.js b/core/server/index.js index 3853482723..f021b2611d 100644 --- a/core/server/index.js +++ b/core/server/index.js @@ -151,8 +151,8 @@ function init(options) { ghostAuthUrl: config.get('auth:url'), redirectUri: utils.url.urlFor('admin', true), clientUri: utils.url.urlFor('home', true), - clientName: api.settings.getSettingSync('title'), - clientDescription: api.settings.getSettingSync('description') + clientName: api.settings.cache.get('title'), + clientDescription: api.settings.cache.get('description') }).then(function (response) { parentApp.use(response.auth); }).catch(function onAuthError(err) { diff --git a/core/server/mail/GhostMailer.js b/core/server/mail/GhostMailer.js index a9da262e6c..8ec1b78166 100644 --- a/core/server/mail/GhostMailer.js +++ b/core/server/mail/GhostMailer.js @@ -5,6 +5,7 @@ var _ = require('lodash'), nodemailer = require('nodemailer'), validator = require('validator'), config = require('../config'), + settingsCache = require('../api/settings').cache, i18n = require('../i18n'), utils = require('../utils'); @@ -31,8 +32,7 @@ GhostMailer.prototype.from = function () { // If we do have a from address, and it's just an email if (validator.isEmail(from)) { - defaultBlogTitle = config.get('theme').title ? config.get('theme').title : i18n.t('common.mail.title', {domain: this.getDomain()}); - + defaultBlogTitle = settingsCache.get('title') || i18n.t('common.mail.title', {domain: this.getDomain()}); from = '"' + defaultBlogTitle + '" <' + from + '>'; } diff --git a/core/server/middleware/serve-favicon.js b/core/server/middleware/serve-favicon.js index 68bbadb0e4..d123ad99c0 100644 --- a/core/server/middleware/serve-favicon.js +++ b/core/server/middleware/serve-favicon.js @@ -1,7 +1,7 @@ var fs = require('fs'), path = require('path'), storage = require('../storage'), - config = require('../config'), + settingsCache = require('../api/settings').cache, utils = require('../utils'), crypto = require('crypto'), buildContentResponse, @@ -35,13 +35,13 @@ function serveFavicon() { // we are using an express route to skip /content/images and the result is a image path // based on config.getContentPath('images') + req.path // in this case we don't use path rewrite, that's why we have to make it manually - filePath = config.get('theme:icon').replace(/\/content\/images\//, ''); + filePath = settingsCache.get('icon').replace(/\/content\/images\//, ''); var originalExtension = path.extname(filePath).toLowerCase(), requestedExtension = path.extname(req.path).toLowerCase(); // CASE: custom favicon exists, load it from local file storage - if (config.get('theme:icon')) { + if (settingsCache.get('icon')) { // depends on the uploaded icon extension if (originalExtension !== requestedExtension) { return res.redirect(302, '/favicon' + originalExtension); @@ -52,8 +52,7 @@ function serveFavicon() { return next(err); } - iconType = config.get('theme:icon').match(/\/favicon\.ico$/i) ? 'x-icon' : 'png'; - + iconType = settingsCache.get('icon').match(/\/favicon\.ico$/i) ? 'x-icon' : 'png'; content = buildContentResponse(iconType, buf); res.writeHead(200, content.headers); diff --git a/core/server/middleware/theme-handler.js b/core/server/middleware/theme-handler.js index 6e6e0aea60..8c7161058b 100644 --- a/core/server/middleware/theme-handler.js +++ b/core/server/middleware/theme-handler.js @@ -3,7 +3,9 @@ var _ = require('lodash'), path = require('path'), hbs = require('express-hbs'), api = require('../api'), + settingsCache = api.settings.cache, config = require('../config'), + utils = require('../utils'), logging = require('../logging'), errors = require('../errors'), i18n = require('../i18n'), @@ -13,8 +15,21 @@ themeHandler = { // ### configHbsForContext Middleware // Setup handlebars for the current context (admin or theme) configHbsForContext: function configHbsForContext(req, res, next) { - var themeData = _.cloneDeep(config.get('theme')), - labsData = _.cloneDeep(config.get('labs')), + var themeData = { + title: settingsCache.get('title'), + description: settingsCache.get('description'), + url: utils.url.urlFor('home', true), + facebook: settingsCache.get('facebook'), + twitter: settingsCache.get('twitter'), + timezone: settingsCache.get('activeTimezone'), + navigation: settingsCache.get('navigation'), + posts_per_page: settingsCache.get('postsPerPage'), + icon: settingsCache.get('icon'), + cover: settingsCache.get('cover'), + logo: settingsCache.get('logo'), + amp: settingsCache.get('amp') + }, + labsData = _.cloneDeep(settingsCache.get('labs')), blogApp = req.app; if (req.secure && config.get('urlSSL')) { @@ -22,11 +37,12 @@ themeHandler = { themeData.url = config.get('urlSSL').replace(/\/$/, ''); } - // Change camelCase to snake_case - themeData.posts_per_page = themeData.postsPerPage; - delete themeData.postsPerPage; - - hbs.updateTemplateOptions({data: {blog: themeData, labs: labsData}}); + hbs.updateTemplateOptions({ + data: { + blog: themeData, + labs: labsData + } + }); if (config.getContentPath('themes') && blogApp.get('activeTheme')) { blogApp.set('views', path.join(config.getContentPath('themes'), blogApp.get('activeTheme'))); diff --git a/core/server/utils/labs.js b/core/server/utils/labs.js index 7c7cc95f2f..b7ac182d27 100644 --- a/core/server/utils/labs.js +++ b/core/server/utils/labs.js @@ -1,9 +1,8 @@ -var config = require('../config'), +var settingsCache = require('../api/settings').cache, flagIsSet; flagIsSet = function flagIsSet(flag) { - var labsConfig = config.get('labs'); - + var labsConfig = settingsCache.get('labs'); return labsConfig && labsConfig[flag] && labsConfig[flag] === true; }; diff --git a/core/server/utils/url.js b/core/server/utils/url.js index df1131052c..2a522bef01 100644 --- a/core/server/utils/url.js +++ b/core/server/utils/url.js @@ -5,6 +5,7 @@ var moment = require('moment-timezone'), _ = require('lodash'), url = require('url'), config = require('./../config'), + settingsCache = require('./../api/settings').cache, // @TODO: unify this with routes.apiBaseUrl apiPath = '/ghost/api/v0.1'; @@ -146,8 +147,8 @@ function createUrl(urlPath, absolute, secure) { */ function urlPathForPost(post) { var output = '', - permalinks = config.get('theme').permalinks, - publishedAtMoment = moment.tz(post.published_at || Date.now(), config.get('theme').timezone), + permalinks = settingsCache.get('permalinks'), + publishedAtMoment = moment.tz(post.published_at || Date.now(), settingsCache.get('activeTimezone')), tags = { year: function () { return publishedAtMoment.format('YYYY'); }, month: function () { return publishedAtMoment.format('MM'); }, diff --git a/core/test/functional/routes/frontend_spec.js b/core/test/functional/routes/frontend_spec.js index 8272698ea6..705e37eef8 100644 --- a/core/test/functional/routes/frontend_spec.js +++ b/core/test/functional/routes/frontend_spec.js @@ -6,10 +6,12 @@ var request = require('supertest'), should = require('should'), moment = require('moment'), + sinon = require('sinon'), cheerio = require('cheerio'), testUtils = require('../../utils'), - configUtils = require('../../utils/configUtils'), - ghost = testUtils.startGhost; + settingsCache = require('../../../server/api/settings').cache, + sandbox = sinon.sandbox.create(), + ghost = testUtils.startGhost; describe('Frontend Routing', function () { function doEnd(done) { @@ -48,6 +50,10 @@ describe('Frontend Routing', function () { }); }); + afterEach(function () { + sandbox.restore(); + }); + describe('Date permalinks', function () { before(function (done) { // Only way to swap permalinks setting is to login and visit the URL because @@ -312,16 +318,20 @@ describe('Frontend Routing', function () { }); it('should not render AMP, when AMP is disabled', function (done) { - after(function () { - configUtils.restore(); + var originalFn = settingsCache.get; + + sandbox.stub(settingsCache, 'get', function (key) { + if (key !== 'amp') { + return originalFn(key); + } + + return false; }); - configUtils.set('theme:amp', false); - request.get('/welcome-to-ghost/amp/') - .expect(404) - .expect(/Page not found/) - .end(doEnd(done)); + .expect(404) + .expect(/Page not found/) + .end(doEnd(done)); }); }); @@ -550,11 +560,16 @@ describe('Frontend Routing', function () { }); it('/blog/welcome-to-ghost/amp/ should 200', function (done) { - after(function () { - configUtils.restore(); + var originalFn = settingsCache.get; + + sandbox.stub(settingsCache, 'get', function (key) { + if (key !== 'amp') { + return originalFn(key); + } + + return true; }); - configUtils.set('theme:amp', true); request.get('/blog/welcome-to-ghost/amp/') .expect(200) .end(doEnd(done)); @@ -637,11 +652,16 @@ describe('Frontend Routing', function () { }); it('/blog/welcome-to-ghost/amp/ should 200', function (done) { - after(function () { - configUtils.restore(); + var originalFn = settingsCache.get; + + sandbox.stub(settingsCache, 'get', function (key) { + if (key !== 'amp') { + return originalFn(key); + } + + return true; }); - configUtils.set('theme:amp', true); request.get('/blog/welcome-to-ghost/amp/') .expect(200) .end(doEnd(done)); diff --git a/core/test/integration/api/api_posts_spec.js b/core/test/integration/api/api_posts_spec.js index 3f32d6ab42..164ae283b2 100644 --- a/core/test/integration/api/api_posts_spec.js +++ b/core/test/integration/api/api_posts_spec.js @@ -1,5 +1,6 @@ var Promise = require('bluebird'), should = require('should'), + sinon = require('sinon'), _ = require('lodash'), ObjectId = require('bson-objectid'), testUtils = require('../../utils'), @@ -7,9 +8,13 @@ var Promise = require('bluebird'), errors = require('../../../server/errors'), db = require('../../../server/data/db'), models = require('../../../server/models'), - PostAPI = require('../../../server/api/posts'); + PostAPI = require('../../../server/api/posts'), + settingsCache = require('../../../server/api/settings').cache, + sandbox = sinon.sandbox.create(); describe('Post API', function () { + var localSettingsCache = {}; + before(testUtils.teardown); afterEach(testUtils.teardown); beforeEach(testUtils.setup('users:roles', 'perms:post', 'perms:init')); @@ -40,11 +45,22 @@ describe('Post API', function () { .catch(done); }); + beforeEach(function () { + sandbox.stub(settingsCache, 'get', function (key) { + return localSettingsCache[key]; + }); + }); + + afterEach(function () { + sandbox.restore(); + localSettingsCache = {}; + }); + should.exist(PostAPI); describe('Browse', function () { beforeEach(function () { - configUtils.set('theme:permalinks', '/:slug/'); + localSettingsCache.permalinks = '/:slug/'; }); afterEach(function () { diff --git a/core/test/integration/api/api_settings_spec.js b/core/test/integration/api/api_settings_spec.js index fa0d2f19d5..327bb1e423 100644 --- a/core/test/integration/api/api_settings_spec.js +++ b/core/test/integration/api/api_settings_spec.js @@ -115,10 +115,10 @@ describe('Settings API', function () { }); it('can edit', function () { - var testReference = SettingsAPI.getSettingsSync(); + var testReference = SettingsAPI.cache.getAll(); // see default-settings.json - SettingsAPI.getSettingSync('title').should.eql('Ghost'); + SettingsAPI.cache.get('title').should.eql('Ghost'); testReference.title.value.should.eql('Ghost'); return callApiWithContext(defaultContext, 'edit', {settings: [{key: 'title', value: 'UpdatedGhost'}]}, {}) @@ -128,7 +128,7 @@ describe('Settings API', function () { response.settings.length.should.equal(1); testUtils.API.checkResponse(response.settings[0], 'setting'); - SettingsAPI.getSettingSync('title').should.eql('UpdatedGhost'); + SettingsAPI.cache.get('title').should.eql('UpdatedGhost'); testReference.title.value.should.eql('UpdatedGhost'); }); }); diff --git a/core/test/integration/model/model_posts_spec.js b/core/test/integration/model/model_posts_spec.js index a3f562a456..b667a73259 100644 --- a/core/test/integration/model/model_posts_spec.js +++ b/core/test/integration/model/model_posts_spec.js @@ -4,17 +4,16 @@ var testUtils = require('../../utils'), _ = require('lodash'), Promise = require('bluebird'), sinon = require('sinon'), - - // Stuff we are testing sequence = require('../../../server/utils/sequence'), + settingsCache = require('../../../server/api/settings').cache, ghostBookshelf = require('../../../server/models/base'), PostModel = require('../../../server/models/post').Post, TagModel = require('../../../server/models/tag').Tag, events = require('../../../server/events'), errors = require('../../../server/errors'), + configUtils = require('../../utils/configUtils'), DataGenerator = testUtils.DataGenerator, context = testUtils.context.owner, - configUtils = require('../../utils/configUtils'), sandbox = sinon.sandbox.create(); /** @@ -64,7 +63,11 @@ describe('Post Model', function () { describe('findAll', function () { beforeEach(function () { - configUtils.set('theme:permalinks', '/:slug/'); + sandbox.stub(settingsCache, 'get', function (key) { + return { + permalinks: '/:slug/' + }[key]; + }); }); it('can findAll', function (done) { @@ -94,9 +97,11 @@ describe('Post Model', function () { describe('findPage', function () { beforeEach(function () { - configUtils.set({theme: { - permalinks: '/:slug/' - }}); + sandbox.stub(settingsCache, 'get', function (key) { + return { + permalinks: '/:slug/' + }[key]; + }); }); it('can findPage (default)', function (done) { @@ -281,7 +286,11 @@ describe('Post Model', function () { describe('findOne', function () { beforeEach(function () { - configUtils.set('theme:permalinks', '/:slug/'); + sandbox.stub(settingsCache, 'get', function (key) { + return { + permalinks: '/:slug/' + }[key]; + }); }); it('can findOne', function (done) { @@ -328,7 +337,13 @@ describe('Post Model', function () { }); it('can findOne, returning a dated permalink', function (done) { - configUtils.set('theme:permalinks', '/:year/:month/:day/:slug/'); + settingsCache.get.restore(); + + sandbox.stub(settingsCache, 'get', function (key) { + return { + permalinks: '/:year/:month/:day/:slug/' + }[key]; + }); PostModel.findOne({id: testUtils.DataGenerator.Content.posts[0].id}) .then(function (result) { @@ -347,6 +362,7 @@ describe('Post Model', function () { describe('edit', function () { beforeEach(function () { eventsTriggered = {}; + sandbox.stub(events, 'emit', function (eventName, eventObj) { if (!eventsTriggered[eventName]) { eventsTriggered[eventName] = []; @@ -827,6 +843,7 @@ describe('Post Model', function () { describe('add', function () { beforeEach(function () { eventsTriggered = {}; + sandbox.stub(events, 'emit', function (eventName, eventObj) { if (!eventsTriggered[eventName]) { eventsTriggered[eventName] = []; diff --git a/core/test/unit/config/index_spec.js b/core/test/unit/config/index_spec.js index e5a6d26834..425d84af70 100644 --- a/core/test/unit/config/index_spec.js +++ b/core/test/unit/config/index_spec.js @@ -4,14 +4,12 @@ var should = require('should'), path = require('path'), rewire = require('rewire'), _ = require('lodash'), - i18n = require('../../../server/i18n'), configUtils = require('../../utils/configUtils'); should.equal(true, true); describe('Config', function () { before(function () { - i18n.init(); configUtils.restore(); }); @@ -84,66 +82,6 @@ describe('Config', function () { }); }); - describe('Theme', function () { - beforeEach(function () { - configUtils.set({ - url: 'http://my-ghost-blog.com', - theme: { - title: 'casper', - description: 'casper', - logo: 'casper', - cover: 'casper', - timezone: 'Etc/UTC', - icon: 'core/shared/favicon.ico' - } - }); - }); - - it('should have exactly the right keys', function () { - var themeConfig = configUtils.config.get('theme'); - - // This will fail if there are any extra keys - themeConfig.should.have.keys('title', 'description', 'logo', 'cover', 'timezone', 'icon'); - }); - - it('should have the correct values for each key', function () { - var themeConfig = configUtils.config.get('theme'); - - // Check values are as we expect - themeConfig.should.have.property('title', 'casper'); - themeConfig.should.have.property('description', 'casper'); - themeConfig.should.have.property('logo', 'casper'); - themeConfig.should.have.property('cover', 'casper'); - themeConfig.should.have.property('timezone', 'Etc/UTC'); - themeConfig.should.have.property('icon', 'core/shared/favicon.ico'); - }); - }); - - describe('Timezone default', function () { - it('should use timezone from settings when set', function () { - var themeConfig = configUtils.config.get('theme'); - - // Check values are as we expect - themeConfig.should.have.property('timezone', 'Etc/UTC'); - - configUtils.set({ - theme: { - timezone: 'Africa/Cairo' - } - }); - - configUtils.config.get('theme').should.have.property('timezone', 'Africa/Cairo'); - }); - - it('should set theme object with timezone by default', function () { - var themeConfig = configUtils.defaultConfig; - - // Check values are as we expect - themeConfig.should.have.property('theme'); - themeConfig.theme.should.have.property('timezone', 'Etc/UTC'); - }); - }); - describe('Index', function () { it('should have exactly the right keys', function () { var pathConfig = configUtils.config.get('paths'); diff --git a/core/test/unit/controllers/frontend/fetch-data_spec.js b/core/test/unit/controllers/frontend/fetch-data_spec.js index 10ee405ae0..62b3c796c1 100644 --- a/core/test/unit/controllers/frontend/fetch-data_spec.js +++ b/core/test/unit/controllers/frontend/fetch-data_spec.js @@ -15,6 +15,7 @@ describe('fetchData', function () { beforeEach(function () { apiPostsStub = sandbox.stub(api.posts, 'browse') .returns(new Promise.resolve({posts: [], meta: {pagination: {}}})); + apiTagStub = sandbox.stub(api.tags, 'read').returns(new Promise.resolve({tags: []})); apiUserStub = sandbox.stub(api.users, 'read').returns(new Promise.resolve({users: []})); }); @@ -26,7 +27,7 @@ describe('fetchData', function () { describe('channel config', function () { beforeEach(function () { - configUtils.set({theme: {postsPerPage: 10}}); + sandbox.stub(api.settings.cache, 'get').returns(10); }); it('should handle no post options', function (done) { @@ -66,7 +67,10 @@ describe('fetchData', function () { featured: { type: 'browse', resource: 'posts', - options: {filter: 'featured:true', limit: 3} + options: { + filter: 'featured:true', + limit: 3 + } } } }; @@ -89,7 +93,9 @@ describe('fetchData', function () { it('should handle multiple queries with page param', function (done) { var channelOpts = { - postOptions: {page: 2}, + postOptions: { + page: 2 + }, data: { featured: { type: 'browse', @@ -148,7 +154,7 @@ describe('fetchData', function () { describe('valid postsPerPage', function () { beforeEach(function () { - configUtils.set({theme: {postsPerPage: 10}}); + sandbox.stub(api.settings.cache, 'get').returns(10); }); it('Adds limit & includes to options by default', function (done) { @@ -164,7 +170,7 @@ describe('fetchData', function () { describe('invalid postsPerPage', function () { beforeEach(function () { - configUtils.set({theme: {postsPerPage: '-1'}}); + sandbox.stub(api.settings.cache, 'get').returns(-1); }); it('Will not add limit if postsPerPage is not valid', function (done) { diff --git a/core/test/unit/controllers/frontend/index_spec.js b/core/test/unit/controllers/frontend/index_spec.js index bbc1fe922a..6ad27e7391 100644 --- a/core/test/unit/controllers/frontend/index_spec.js +++ b/core/test/unit/controllers/frontend/index_spec.js @@ -3,20 +3,27 @@ var moment = require('moment'), sinon = require('sinon'), Promise = require('bluebird'), _ = require('lodash'), - -// Stuff we are testing api = require('../../../../server/api'), frontend = require('../../../../server/controllers/frontend'), - configUtils = require('../../../utils/configUtils'), + settingsCache = api.settings.cache, sandbox = sinon.sandbox.create(); describe('Frontend Controller', function () { - var adminEditPagePath = '/ghost/editor/'; + var adminEditPagePath = '/ghost/editor/', localSettingsCache = {permalinks: '/:slug/'}; afterEach(function () { sandbox.restore(); configUtils.restore(); + localSettingsCache = { + permalinks: '/:slug/' + }; + }); + + beforeEach(function () { + sandbox.stub(settingsCache, 'get', function (key) { + return localSettingsCache[key]; + }); }); // Helper function to prevent unit tests @@ -86,13 +93,8 @@ describe('Frontend Controller', function () { var post = _.find(mockPosts, function (mock) { return mock.posts[0].slug === args.slug; }); - return Promise.resolve(post || {posts: []}); - }); - configUtils.set({ - theme: { - permalinks: '/:slug/' - } + return Promise.resolve(post || {posts: []}); }); casper = { @@ -118,14 +120,6 @@ describe('Frontend Controller', function () { describe('static pages', function () { describe('custom page templates', function () { - beforeEach(function () { - configUtils.set({ - theme: { - permalinks: '/:slug/' - } - }); - }); - it('it will render a custom page-slug template if it exists', function (done) { configUtils.set({paths: {availableThemes: {casper: casper}}}); req.path = '/' + mockPosts[2].posts[0].slug + '/'; @@ -173,14 +167,6 @@ describe('Frontend Controller', function () { }); describe('permalink set to slug', function () { - beforeEach(function () { - configUtils.set({ - theme: { - permalinks: '/:slug/' - } - }); - }); - it('will render static page via /:slug/', function (done) { configUtils.set({paths: {availableThemes: {casper: casper}}}); @@ -247,11 +233,7 @@ describe('Frontend Controller', function () { describe('permalink set to date', function () { beforeEach(function () { - configUtils.set({ - theme: { - permalinks: '/:year/:month/:day/:slug/' - } - }); + localSettingsCache.permalinks = '/:year/:month/:day/:slug/'; }); it('will render static page via /:slug', function (done) { @@ -307,12 +289,6 @@ describe('Frontend Controller', function () { describe('post', function () { describe('permalink set to slug', function () { beforeEach(function () { - configUtils.set({ - theme: { - permalinks: '/:slug/' - } - }); - mockPosts[1].posts[0].url = '/' + mockPosts[1].posts[0].slug + '/'; }); @@ -399,11 +375,7 @@ describe('Frontend Controller', function () { describe('permalink set to date', function () { beforeEach(function () { - configUtils.set({ - theme: { - permalinks: '/:year/:month/:day/:slug/' - } - }); + localSettingsCache.permalinks = '/:year/:month/:day/:slug/'; var date = moment(mockPosts[1].posts[0].published_at).format('YYYY/MM/DD'); mockPosts[1].posts[0].url = '/' + date + '/' + mockPosts[1].posts[0].slug + '/'; @@ -446,6 +418,7 @@ describe('Frontend Controller', function () { // Handle Edit append it('will redirect post to admin edit page via /YYYY/MM/DD/:slug/edit/', function (done) { var dateFormat = moment(mockPosts[1].posts[0].published_at).format('YYYY/MM/DD'); + req.path = '/' + [dateFormat, mockPosts[1].posts[0].slug, 'edit'].join('/') + '/'; res.redirect = function (arg) { res.render.called.should.be.false(); @@ -479,11 +452,7 @@ describe('Frontend Controller', function () { describe('permalink set to author', function () { beforeEach(function () { - configUtils.set({ - theme: { - permalinks: 'author/:slug/' - } - }); + localSettingsCache.permalinks = 'author/:slug/'; // set post url to permalink-defined url mockPosts[1].posts[0].url = '/test/' + mockPosts[1].posts[0].slug + '/'; @@ -569,11 +538,7 @@ describe('Frontend Controller', function () { describe('permalink set to custom format', function () { beforeEach(function () { - configUtils.set({ - theme: { - permalinks: '/:year/:slug/' - } - }); + localSettingsCache.permalinks = '/:year/:slug/'; configUtils.set({paths: {availableThemes: {casper: casper}}}); @@ -686,11 +651,7 @@ describe('Frontend Controller', function () { describe('permalink set to custom format no slash', function () { beforeEach(function () { - configUtils.set({ - theme: { - permalinks: '/:year/:slug/' - } - }); + localSettingsCache.permalinks = '/:year/:slug/'; var date = moment(mockPosts[1].posts[0].published_at).format('YYYY'); mockPosts[1].posts[0].url = '/' + date + '/' + mockPosts[1].posts[0].slug + '/'; @@ -780,12 +741,6 @@ describe('Frontend Controller', function () { return Promise.resolve(post || {posts: []}); }); - configUtils.set({ - theme: { - permalinks: '/:slug/' - } - }); - req = { app: {get: function () {return 'casper'; }}, path: '/', params: {}, route: {} diff --git a/core/test/unit/controllers/frontend/post-lookup_spec.js b/core/test/unit/controllers/frontend/post-lookup_spec.js index 76efbb0929..df05b7e987 100644 --- a/core/test/unit/controllers/frontend/post-lookup_spec.js +++ b/core/test/unit/controllers/frontend/post-lookup_spec.js @@ -2,28 +2,31 @@ var should = require('should'), sinon = require('sinon'), Promise = require('bluebird'), configUtils = require('../../../utils/configUtils'), - - // Things we are testing api = require('../../../../server/api'), postLookup = require('../../../../server/controllers/frontend/post-lookup'), - + settingsCache = api.settings.cache, sandbox = sinon.sandbox.create(); describe('postLookup', function () { - var postAPIStub; + var postAPIStub, localSettingsCache = {}; afterEach(function () { sandbox.restore(); configUtils.restore(); + localSettingsCache = {}; }); beforeEach(function () { postAPIStub = sandbox.stub(api.posts, 'read'); + + sandbox.stub(settingsCache, 'get', function (key) { + return localSettingsCache[key]; + }); }); describe('Permalinks: /:slug/', function () { beforeEach(function () { - configUtils.set({theme: {permalinks: '/:slug/'}}); + localSettingsCache.permalinks = '/:slug/'; postAPIStub.withArgs({slug: 'welcome-to-ghost', include: 'author,tags'}) .returns(new Promise.resolve({posts: [{ @@ -79,7 +82,7 @@ describe('postLookup', function () { describe('Permalinks: /:year/:month/:day/:slug/', function () { beforeEach(function () { - configUtils.set({theme: {permalinks: '/:year/:month/:day/:slug/'}}); + localSettingsCache.permalinks = '/:year/:month/:day/:slug/'; postAPIStub.withArgs({slug: 'welcome-to-ghost', include: 'author,tags'}) .returns(new Promise.resolve({posts: [{ @@ -135,7 +138,7 @@ describe('postLookup', function () { describe('Edit URLs', function () { beforeEach(function () { - configUtils.set({theme: {permalinks: '/:slug/'}}); + localSettingsCache.permalinks = '/:slug/'; postAPIStub.withArgs({slug: 'welcome-to-ghost', include: 'author,tags'}) .returns(new Promise.resolve({posts: [{ @@ -192,9 +195,10 @@ describe('postLookup', function () { }).catch(done); }); }); + describe('AMP URLs', function () { beforeEach(function () { - configUtils.set({theme: {permalinks: '/:slug/'}}); + localSettingsCache.permalinks = '/:slug/'; postAPIStub.withArgs({slug: 'welcome-to-ghost', include: 'author,tags'}) .returns(new Promise.resolve({posts: [{ diff --git a/core/test/unit/ghost_url_spec.js b/core/test/unit/ghost_url_spec.js index 2f116c2c8a..098cb1bee9 100644 --- a/core/test/unit/ghost_url_spec.js +++ b/core/test/unit/ghost_url_spec.js @@ -1,4 +1,3 @@ -/* globals describe, beforeEach, afterEach, it */ var should = require('should'), ghostUrl = require('../../shared/ghost-url'), configUtils = require('../utils/configUtils'), diff --git a/core/test/unit/mail/GhostMailer_spec.js b/core/test/unit/mail/GhostMailer_spec.js index 15ae8a91f0..d11e09ec8a 100644 --- a/core/test/unit/mail/GhostMailer_spec.js +++ b/core/test/unit/mail/GhostMailer_spec.js @@ -1,10 +1,11 @@ var should = require('should'), Promise = require('bluebird'), - - // Stuff we are testing + sinon = require('sinon'), mail = require('../../../server/mail'), + api = require('../../../server/api'), configUtils = require('../../utils/configUtils'), i18n = require('../../../server/i18n'), + sandbox = sinon.sandbox.create(), mailer, // Mock SMTP config @@ -40,8 +41,8 @@ i18n.init(); describe('Mail: Ghostmailer', function () { afterEach(function () { mailer = null; - configUtils.restore(); + sandbox.restore(); }); it('should attach mail provider to ghost instance', function () { @@ -177,19 +178,22 @@ describe('Mail: Ghostmailer', function () { }); it('should fall back to [blog.title] ', function () { + sandbox.stub(api.settings.cache, 'get').returns('Test'); + // Standard domain - configUtils.set({url: 'http://default.com', mail: {from: null}, theme: {title: 'Test'}}); + configUtils.set({url: 'http://default.com', mail: {from: null}}); mailer = new mail.GhostMailer(); mailer.from().should.equal('"Test" '); // Trailing slash - configUtils.set({url: 'http://default.com/', mail: {from: null}, theme: {title: 'Test'}}); + configUtils.set({url: 'http://default.com/', mail: {from: null}}); + mailer.from().should.equal('"Test" '); // Strip Port - configUtils.set({url: 'http://default.com:2368/', mail: {from: null}, theme: {title: 'Test'}}); + configUtils.set({url: 'http://default.com:2368/', mail: {from: null}}); mailer.from().should.equal('"Test" '); }); @@ -203,41 +207,43 @@ describe('Mail: Ghostmailer', function () { }); it('should attach blog title if from or fromaddress are only email addresses', function () { + sandbox.stub(api.settings.cache, 'get').returns('Test'); + // from and fromaddress are both set - configUtils.set({mail: {from: 'from@default.com', fromaddress: 'fa@default.com'}, theme: {title: 'Test'}}); + configUtils.set({mail: {from: 'from@default.com', fromaddress: 'fa@default.com'}}); mailer = new mail.GhostMailer(); mailer.from().should.equal('"Test" '); // only from set - configUtils.set({mail: {from: 'from@default.com', fromaddress: null}, theme: {title: 'Test'}}); + configUtils.set({mail: {from: 'from@default.com', fromaddress: null}}); mailer.from().should.equal('"Test" '); // only fromaddress set - configUtils.set({mail: {from: null, fromaddress: 'fa@default.com'}, theme: {title: 'Test'}}); + configUtils.set({mail: {from: null, fromaddress: 'fa@default.com'}}); mailer.from().should.equal('"Test" '); }); it('should ignore theme title if from address is Title format', function () { // from and fromaddress are both set - configUtils.set({mail: {from: '"R2D2" ', fromaddress: '"C3PO" '}, theme: {title: 'Test'}}); + configUtils.set({mail: {from: '"R2D2" ', fromaddress: '"C3PO" '}}); mailer = new mail.GhostMailer(); mailer.from().should.equal('"R2D2" '); // only from set - configUtils.set({mail: {from: '"R2D2" ', fromaddress: null}, theme: {title: 'Test'}}); + configUtils.set({mail: {from: '"R2D2" ', fromaddress: null}}); mailer.from().should.equal('"R2D2" '); // only fromaddress set - configUtils.set({mail: {from: null, fromaddress: '"C3PO" '}, theme: {title: 'Test'}}); + configUtils.set({mail: {from: null, fromaddress: '"C3PO" '}}); mailer.from().should.equal('"C3PO" '); }); it('should use default title if not theme title is provided', function () { - configUtils.set({url: 'http://default.com:2368/', mail: {from: null}, theme: {title: null}}); + configUtils.set({url: 'http://default.com:2368/', mail: {from: null}}); mailer = new mail.GhostMailer(); diff --git a/core/test/unit/metadata/author_image_spec.js b/core/test/unit/metadata/author_image_spec.js index dc882e5f7b..5bad548d16 100644 --- a/core/test/unit/metadata/author_image_spec.js +++ b/core/test/unit/metadata/author_image_spec.js @@ -1,10 +1,11 @@ -var getAuthorImage = require('../../../server/data/meta/author_image'), - should = require('should'), - configUtils = require('../../utils/configUtils'); +var should = require('should'), + sinon = require('sinon'), + getAuthorImage = require('../../../server/data/meta/author_image'), + sandbox = sinon.sandbox.create(); describe('getAuthorImage', function () { afterEach(function () { - configUtils.restore(); + sandbox.restore(); }); it('should return author image url if post and has url', function () { @@ -16,6 +17,7 @@ describe('getAuthorImage', function () { } } }, false); + imageUrl.should.equal('/content/images/2016/01/myimage.jpg'); }); @@ -66,6 +68,7 @@ describe('getAuthorImage', function () { } } }); + should(imageUrl).equal(null); }); @@ -74,6 +77,7 @@ describe('getAuthorImage', function () { context: ['post'], post: {} }); + should(imageUrl).equal(null); }); @@ -81,21 +85,7 @@ describe('getAuthorImage', function () { var imageUrl = getAuthorImage({ context: ['tag'] }); + should(imageUrl).equal(null); }); - - it('should return config theme author image if context is a post and no post', - function () { - configUtils.set({ - theme: { - author: { - image: '/content/images/2016/01/myimage.jpg' - } - } - }); - var imageUrl = getAuthorImage({ - context: ['post'] - }); - imageUrl.should.match(/\/content\/images\/2016\/01\/myimage\.jpg$/); - }); }); diff --git a/core/test/unit/metadata/context_object_spec.js b/core/test/unit/metadata/context_object_spec.js index e5c5e74d32..0f6cf4ddce 100644 --- a/core/test/unit/metadata/context_object_spec.js +++ b/core/test/unit/metadata/context_object_spec.js @@ -1,6 +1,8 @@ var should = require('should'), + sinon = require('sinon'), getContextObject = require('../../../server/data/meta/context_object.js'), - configUtils = require('../../utils/configUtils'); + settingsCache = require('../../../server/api/settings').cache, + sandbox = sinon.sandbox.create(); describe('getContextObject', function () { var data, context, contextObject; @@ -47,11 +49,15 @@ describe('getContextObject', function () { describe('override blog', function () { before(function () { - configUtils.set({theme: {foo: 'bar'}}); + sandbox.stub(settingsCache, 'get', function (key) { + return { + cover: 'test.png' + }[key]; + }); }); after(function () { - configUtils.restore(); + sandbox.restore(); }); it('should return blog context object for unknown context', function () { @@ -60,7 +66,7 @@ describe('getContextObject', function () { contextObject = getContextObject(data, context); should.exist(contextObject); - contextObject.should.have.property('foo', 'bar'); + contextObject.should.have.property('cover', 'test.png'); }); }); }); diff --git a/core/test/unit/metadata/title_spec.js b/core/test/unit/metadata/title_spec.js index 27ab17c76a..ae62644f3c 100644 --- a/core/test/unit/metadata/title_spec.js +++ b/core/test/unit/metadata/title_spec.js @@ -1,9 +1,24 @@ -var getTitle = require('../../../server/data/meta/title'), - configUtils = require('../../utils/configUtils'); + +var sinon = require('sinon'), + should = require('should'), + getTitle = require('../../../server/data/meta/title'), + settingsCache = require('../../../server/api/settings').cache, + sandbox = sinon.sandbox.create(); + +should.equal(true, true); describe('getTitle', function () { + var localSettingsCache = {}; + + beforeEach(function () { + sandbox.stub(settingsCache, 'get', function (key) { + return localSettingsCache[key]; + }); + }); + afterEach(function () { - configUtils.restore(); + sandbox.restore(); + localSettingsCache = {}; }); it('should return meta_title if on data root', function () { @@ -15,36 +30,26 @@ describe('getTitle', function () { }); it('should return blog title if on home', function () { - configUtils.set({ - theme: { - title: 'My blog title' - } - }); + localSettingsCache.title = 'My blog title'; var title = getTitle({}, {context: 'home'}); title.should.equal('My blog title'); }); it('should return author name - blog title if on data author page', function () { - configUtils.set({ - theme: { - title: 'My blog title 2' - } - }); + localSettingsCache.title = 'My blog title 2'; + var title = getTitle({ author: { name: 'Author Name' } }, {context: ['author']}); + title.should.equal('Author Name - My blog title 2'); }); it('should return author page title if on data author page with more then one page', function () { - configUtils.set({ - theme: { - title: 'My blog title 2' - } - }); + localSettingsCache.title = 'My blog title 2'; var title = getTitle({ author: { @@ -62,11 +67,7 @@ describe('getTitle', function () { }); it('should return tag name - blog title if on data tag page no meta_title', function () { - configUtils.set({ - theme: { - title: 'My blog title 3' - } - }); + localSettingsCache.title = 'My blog title 3'; var title = getTitle({ tag: { @@ -78,11 +79,7 @@ describe('getTitle', function () { }); it('should return tag name - page - blog title if on data tag page no meta_title', function () { - configUtils.set({ - theme: { - title: 'My blog title 3' - } - }); + localSettingsCache.title = 'My blog title 3'; var title = getTitle({ tag: { @@ -126,6 +123,7 @@ describe('getTitle', function () { title: 'My awesome post!' } }, {context: ['amp', 'post']}); + title.should.equal('My awesome post!'); }); @@ -135,6 +133,7 @@ describe('getTitle', function () { title: 'My awesome page!' } }, {context: ['page']}); + title.should.equal('My awesome page!'); }); @@ -144,6 +143,7 @@ describe('getTitle', function () { title: 'My awesome page!' } }, {context: ['amp', 'page']}); + title.should.equal('My awesome page!'); }); @@ -154,6 +154,7 @@ describe('getTitle', function () { meta_title: 'My Tag Meta Title Post! ' } }, {context: ['post']}); + title.should.equal('My Tag Meta Title Post!'); }); @@ -164,15 +165,12 @@ describe('getTitle', function () { meta_title: 'My Tag Meta Title Post! ' } }, {context: ['amp', 'post']}); + title.should.equal('My Tag Meta Title Post!'); }); it('should return blog title with page if unknown type', function () { - configUtils.set({ - theme: { - title: 'My blog title 4' - } - }); + localSettingsCache.title = 'My blog title 4'; var title = getTitle({}, { context: ['paged'], diff --git a/core/test/unit/middleware/serve-favicon_spec.js b/core/test/unit/middleware/serve-favicon_spec.js index e04e24517e..650bfdf640 100644 --- a/core/test/unit/middleware/serve-favicon_spec.js +++ b/core/test/unit/middleware/serve-favicon_spec.js @@ -2,6 +2,7 @@ var sinon = require('sinon'), should = require('should'), express = require('express'), serveFavicon = require('../../../server/middleware/serve-favicon'), + settingsCache = require('../../../server/api/settings').cache, configUtils = require('../../utils/configUtils'), path = require('path'), sandbox = sinon.sandbox.create(); @@ -9,7 +10,7 @@ var sinon = require('sinon'), should.equal(true, true); describe('Serve Favicon', function () { - var req, res, next, blogApp; + var req, res, next, blogApp, localSettingsCache = {}; beforeEach(function () { req = sinon.spy(); @@ -17,11 +18,16 @@ describe('Serve Favicon', function () { next = sinon.spy(); blogApp = express(); req.app = blogApp; + + sandbox.stub(settingsCache, 'get', function (key) { + return localSettingsCache[key]; + }); }); afterEach(function () { sandbox.restore(); configUtils.restore(); + localSettingsCache = {}; }); describe('serveFavicon', function () { @@ -37,17 +43,14 @@ describe('Serve Favicon', function () { middleware(req, res, next); next.called.should.be.true(); }); + describe('serves', function () { it('custom uploaded favicon.png', function (done) { var middleware = serveFavicon(); req.path = '/favicon.png'; - configUtils.set('paths:contentPath', path.join(__dirname, '../../../test/utils/fixtures/')); - configUtils.set({ - theme: { - icon: 'favicon.png' - } - }); + configUtils.set('paths:contentPath', path.join(__dirname, '../../../test/utils/fixtures/')); + localSettingsCache.icon = 'favicon.png'; res = { writeHead: function (statusCode) { @@ -61,16 +64,13 @@ describe('Serve Favicon', function () { middleware(req, res, next); }); + it('custom uploaded favicon.ico', function (done) { var middleware = serveFavicon(); req.path = '/favicon.ico'; - configUtils.set('paths:contentPath', path.join(__dirname, '../../../test/utils/fixtures/')); - configUtils.set({ - theme: { - icon: 'favicon.ico' - } - }); + configUtils.set('paths:contentPath', path.join(__dirname, '../../../test/utils/fixtures/')); + localSettingsCache.icon = 'favicon.ico'; res = { writeHead: function (statusCode) { @@ -84,16 +84,13 @@ describe('Serve Favicon', function () { middleware(req, res, next); }); + it('default favicon.ico', function (done) { var middleware = serveFavicon(); req.path = '/favicon.ico'; - configUtils.set('paths:corePath', path.join(__dirname, '../../../test/utils/fixtures/')); - configUtils.set({ - theme: { - icon: '' - } - }); + configUtils.set('paths:corePath', path.join(__dirname, '../../../test/utils/fixtures/')); + localSettingsCache.icon = ''; res = { writeHead: function (statusCode) { @@ -108,17 +105,14 @@ describe('Serve Favicon', function () { middleware(req, res, next); }); }); + describe('redirects', function () { it('to custom favicon.ico when favicon.png is requested', function (done) { var middleware = serveFavicon(); req.path = '/favicon.png'; - configUtils.set('paths:contentPath', path.join(__dirname, '../../../test/utils/fixtures/')); - configUtils.set({ - theme: { - icon: 'favicon.ico' - } - }); + configUtils.set('paths:contentPath', path.join(__dirname, '../../../test/utils/fixtures/')); + localSettingsCache.icon = 'favicon.ico'; res = { redirect: function (statusCode) { @@ -129,16 +123,13 @@ describe('Serve Favicon', function () { middleware(req, res, next); }); + it('to custom favicon.png when favicon.ico is requested', function (done) { var middleware = serveFavicon(); req.path = '/favicon.ico'; - configUtils.set('paths:contentPath', path.join(__dirname, '../../../test/utils/fixtures/')); - configUtils.set({ - theme: { - icon: 'favicon.png' - } - }); + configUtils.set('paths:contentPath', path.join(__dirname, '../../../test/utils/fixtures/')); + localSettingsCache.icon = 'favicon.png'; res = { redirect: function (statusCode) { @@ -153,13 +144,9 @@ describe('Serve Favicon', function () { it('to favicon.ico when favicon.png is requested', function (done) { var middleware = serveFavicon(); req.path = '/favicon.png'; - configUtils.set('paths:corePath', path.join(__dirname, '../../../test/utils/fixtures/')); - configUtils.set({ - theme: { - icon: '' - } - }); + configUtils.set('paths:corePath', path.join(__dirname, '../../../test/utils/fixtures/')); + localSettingsCache.icon = ''; res = { redirect: function (statusCode) { diff --git a/core/test/unit/rss_spec.js b/core/test/unit/rss_spec.js index 0386418085..ae91a344b9 100644 --- a/core/test/unit/rss_spec.js +++ b/core/test/unit/rss_spec.js @@ -4,13 +4,9 @@ var should = require('should'), _ = require('lodash'), Promise = require('bluebird'), testUtils = require('../utils'), - channelConfig = require('../../server/controllers/frontend/channel-config'), - - // Things that get overridden api = require('../../server/api'), rss = rewire('../../server/data/xml/rss'), - configUtils = require('../utils/configUtils'); // Helper function to prevent unit tests @@ -281,6 +277,7 @@ describe('RSS', function () { describe('dataBuilder', function () { var apiBrowseStub, apiTagStub, apiUserStub; + beforeEach(function () { apiBrowseStub = sandbox.stub(api.posts, 'browse', function () { return Promise.resolve({posts: [], meta: {pagination: {pages: 3}}}); @@ -306,11 +303,19 @@ describe('RSS', function () { set: sinon.stub() }; - configUtils.set({url: 'http://my-ghost-blog.com', theme: { - title: 'Test', - description: 'Some Text', - permalinks: '/:slug/' - }}); + sandbox.stub(api.settings.cache, 'get', function (key) { + var obj = { + title: 'Test', + description: 'Some Text', + permalinks: '/:slug/' + }; + + return obj[key]; + }); + + configUtils.set({ + url: 'http://my-ghost-blog.com' + }); }); it('should process the data correctly for the index feed', function (done) { diff --git a/core/test/unit/server_helpers/asset_spec.js b/core/test/unit/server_helpers/asset_spec.js index fddbf75ce8..b27a55ff43 100644 --- a/core/test/unit/server_helpers/asset_spec.js +++ b/core/test/unit/server_helpers/asset_spec.js @@ -1,22 +1,28 @@ var should = require('should'), hbs = require('express-hbs'), + sinon = require('sinon'), utils = require('./utils'), configUtils = require('../../utils/configUtils'), - -// Stuff we are testing - handlebars = hbs.handlebars, - helpers = require('../../../server/helpers'); + helpers = require('../../../server/helpers'), + settingsCache = require('../../../server/api/settings').cache, + sandbox = sinon.sandbox.create(), + handlebars = hbs.handlebars; describe('{{asset}} helper', function () { - var rendered; + var rendered, localSettingsCache = {}; before(function () { utils.loadHelpers(); configUtils.set({assetHash: 'abc'}); + + sandbox.stub(settingsCache, 'get', function (key) { + return localSettingsCache[key]; + }); }); after(function () { configUtils.restore(); + sandbox.restore(); }); it('has loaded asset helper', function () { @@ -37,7 +43,8 @@ describe('{{asset}} helper', function () { }); it('handles custom favicon correctly', function () { - configUtils.set('theme:icon', '/content/images/favicon.png'); + localSettingsCache.icon = '/content/images/favicon.png'; + // with ghost set and png rendered = helpers.asset('favicon.png', {hash: {ghost: 'true'}}); should.exist(rendered); @@ -48,7 +55,7 @@ describe('{{asset}} helper', function () { should.exist(rendered); String(rendered).should.equal('/content/images/favicon.png'); - configUtils.set('theme:icon', '/content/images/favicon.ico'); + localSettingsCache.icon = '/content/images/favicon.ico'; // with ghost set and ico rendered = helpers.asset('favicon.ico', {hash: {ghost: 'true'}}); @@ -62,7 +69,8 @@ describe('{{asset}} helper', function () { }); it('handles shared assets correctly', function () { - configUtils.set('theme:icon', ''); + localSettingsCache.icon = ''; + // with ghost set rendered = helpers.asset('shared/asset.js', {hash: {ghost: 'true'}}); should.exist(rendered); @@ -107,7 +115,8 @@ describe('{{asset}} helper', function () { }); it('handles custom favicon correctly', function () { - configUtils.set('theme:icon', '/content/images/favicon.png'); + localSettingsCache.icon = '/content/images/favicon.png'; + // with ghost set and png rendered = helpers.asset('favicon.png', {hash: {ghost: 'true'}}); should.exist(rendered); @@ -118,7 +127,7 @@ describe('{{asset}} helper', function () { should.exist(rendered); String(rendered).should.equal('/blog/content/images/favicon.png'); - configUtils.set('theme:icon', '/content/images/favicon.ico'); + localSettingsCache.icon = '/content/images/favicon.ico'; // with ghost set and ico rendered = helpers.asset('favicon.ico', {hash: {ghost: 'true'}}); diff --git a/core/test/unit/server_helpers/ghost_head_spec.js b/core/test/unit/server_helpers/ghost_head_spec.js index 2e345d9521..8a706527ef 100644 --- a/core/test/unit/server_helpers/ghost_head_spec.js +++ b/core/test/unit/server_helpers/ghost_head_spec.js @@ -3,18 +3,15 @@ var should = require('should'), _ = require('lodash'), Promise = require('bluebird'), hbs = require('express-hbs'), + moment = require('moment'), utils = require('./utils'), configUtils = require('../../utils/configUtils'), - moment = require('moment'), - -// Stuff we are testing - handlebars = hbs.handlebars, helpers = require('../../../server/helpers'), api = require('../../../server/api'), - labs = require('../../../server/utils/labs'), - - sandbox = sinon.sandbox.create(); + settingsCache = api.settings.cache, + handlebars = hbs.handlebars, + sandbox = sinon.sandbox.create(); describe('{{ghost_head}} helper', function () { var settingsReadStub; @@ -46,16 +43,19 @@ describe('{{ghost_head}} helper', function () { }); describe('without Code Injection', function () { + var localSettingsCache = { + title: 'Ghost', + description: 'blog description', + cover: '/content/images/blog-cover.png', + amp: true + }; + beforeEach(function () { - configUtils.set({ - url: 'http://testurl.com/', - theme: { - title: 'Ghost', - description: 'blog description', - cover: '/content/images/blog-cover.png', - amp: true - } + sandbox.stub(settingsCache, 'get', function (key) { + return localSettingsCache[key]; }); + + configUtils.set('url', 'http://testurl.com/'); }); it('has loaded ghost_head helper', function () { @@ -882,15 +882,10 @@ describe('{{ghost_head}} helper', function () { describe('with /blog subdirectory', function () { beforeEach(function () { + localSettingsCache.icon = '/content/images/favicon.png'; + configUtils.set({ - url: 'http://testurl.com/blog/', - theme: { - title: 'Ghost', - description: 'blog description', - cover: '/content/images/blog-cover.png', - amp: true, - icon: '/content/images/favicon.png' - } + url: 'http://testurl.com/blog/' }); }); @@ -912,16 +907,21 @@ describe('{{ghost_head}} helper', function () { }); describe('with changed origin in config file', function () { + var localSettingsCache = { + title: 'Ghost', + description: 'blog description', + cover: '/content/images/blog-cover.png', + amp: true, + icon: '/content/images/favicon.png' + }; + beforeEach(function () { + sandbox.stub(settingsCache, 'get', function (key) { + return localSettingsCache[key]; + }); + configUtils.set({ url: 'http://testurl.com/blog/', - theme: { - title: 'Ghost', - description: 'blog description', - cover: '/content/images/blog-cover.png', - amp: true, - icon: '/content/images/favicon.png' - }, referrerPolicy: 'origin' }); }); @@ -941,16 +941,21 @@ describe('{{ghost_head}} helper', function () { }); describe('with useStructuredData is set to false in config file', function () { + var localSettingsCache = { + title: 'Ghost', + description: 'blog description', + cover: '/content/images/blog-cover.png', + amp: true, + icon: '/content/images/favicon.png' + }; + beforeEach(function () { + sandbox.stub(settingsCache, 'get', function (key) { + return localSettingsCache[key]; + }); + configUtils.set({ url: 'http://testurl.com/', - theme: { - title: 'Ghost', - description: 'blog description', - cover: '/content/images/blog-cover.png', - amp: true, - icon: '/content/images/favicon.png' - }, privacy: { useStructuredData: false } @@ -995,19 +1000,24 @@ describe('{{ghost_head}} helper', function () { }); describe('with Code Injection', function () { + var localSettingsCache = { + title: 'Ghost', + description: 'blog description', + cover: '/content/images/blog-cover.png', + icon: '/content/images/favicon.png' + }; + beforeEach(function () { settingsReadStub.returns(new Promise.resolve({ settings: [{value: ''}] })); + sandbox.stub(settingsCache, 'get', function (key) { + return localSettingsCache[key]; + }); + configUtils.set({ - url: 'http://testurl.com/', - theme: { - title: 'Ghost', - description: 'blog description', - cover: '/content/images/blog-cover.png', - icon: '/content/images/favicon.png' - } + url: 'http://testurl.com/' }); }); @@ -1126,12 +1136,17 @@ describe('{{ghost_head}} helper', function () { }); describe('amp is disabled', function () { + var localSettingsCache = { + amp: false + }; + beforeEach(function () { configUtils.set({ - url: 'http://testurl.com/', - theme: { - amp: false - } + url: 'http://testurl.com/' + }); + + sandbox.stub(settingsCache, 'get', function (key) { + return localSettingsCache[key]; }); }); diff --git a/core/test/unit/server_helpers/meta_description_spec.js b/core/test/unit/server_helpers/meta_description_spec.js index 81fe908da6..294e74cfae 100644 --- a/core/test/unit/server_helpers/meta_description_spec.js +++ b/core/test/unit/server_helpers/meta_description_spec.js @@ -1,24 +1,23 @@ var should = require('should'), + sinon = require('sinon'), hbs = require('express-hbs'), utils = require('./utils'), configUtils = require('../../utils/configUtils'), - -// Stuff we are testing handlebars = hbs.handlebars, - helpers = require('../../../server/helpers'); + sandbox = sinon.sandbox.create(), + helpers = require('../../../server/helpers'), + settingsCache = require('../../../server/api/settings').cache; describe('{{meta_description}} helper', function () { before(function () { utils.loadHelpers(); - configUtils.set({ - theme: { - description: 'Just a blogging platform.' - } - }); + + sandbox.stub(settingsCache, 'get').returns('Just a blogging platform.'); }); after(function () { configUtils.restore(); + sandbox.restore(); }); it('has loaded meta_description helper', function () { diff --git a/core/test/unit/server_helpers/meta_title_spec.js b/core/test/unit/server_helpers/meta_title_spec.js index 77b49f0d1b..809e657917 100644 --- a/core/test/unit/server_helpers/meta_title_spec.js +++ b/core/test/unit/server_helpers/meta_title_spec.js @@ -1,24 +1,27 @@ var should = require('should'), + sinon = require('sinon'), hbs = require('express-hbs'), utils = require('./utils'), configUtils = require('../../utils/configUtils'), - -// Stuff we are testing handlebars = hbs.handlebars, - helpers = require('../../../server/helpers'); + sandbox = sinon.sandbox.create(), + helpers = require('../../../server/helpers'), + settingsCache = require('../../../server/api/settings').cache; describe('{{meta_title}} helper', function () { before(function () { utils.loadHelpers(); - configUtils.set({ - theme: { + + sandbox.stub(settingsCache, 'get', function (key) { + return { title: 'Ghost' - } + }[key]; }); }); after(function () { configUtils.restore(); + sandbox.restore(); }); it('has loaded meta_title helper', function () { diff --git a/core/test/unit/utils/url_spec.js b/core/test/unit/utils/url_spec.js index a43c1ff27f..688430dd0f 100644 --- a/core/test/unit/utils/url_spec.js +++ b/core/test/unit/utils/url_spec.js @@ -2,9 +2,12 @@ var should = require('should'), _ = require('lodash'), moment = require('moment'), + sinon = require('sinon'), utils = require('../../../server/utils'), + settingsCache = require('../../../server/api/settings').cache, configUtils = require('../../utils/configUtils'), testUtils = require('../../utils'), + sandbox = sinon.sandbox.create(), config = configUtils.config; describe('Url', function () { @@ -14,6 +17,7 @@ describe('Url', function () { afterEach(function () { configUtils.restore(); + sandbox.restore(); }); describe('getProtectedSlugs', function () { @@ -343,9 +347,17 @@ describe('Url', function () { }); describe('urlPathForPost', function () { - it('permalink is /:slug/, timezone is default', function () { - configUtils.set('theme:permalinks', '/:slug/'); + var localSettingsCache = { + permalinks: '/:slug/' + }; + beforeEach(function () { + sandbox.stub(settingsCache, 'get', function (key) { + return localSettingsCache[key]; + }); + }); + + it('permalink is /:slug/, timezone is default', function () { var testData = testUtils.DataGenerator.Content.posts[2], postLink = '/short-and-sweet/'; @@ -353,8 +365,8 @@ describe('Url', function () { }); it('permalink is /:year/:month/:day/:slug, blog timezone is Los Angeles', function () { - configUtils.set('theme:timezone', 'America/Los_Angeles'); - configUtils.set('theme:permalinks', '/:year/:month/:day/:slug/'); + localSettingsCache.activeTimezone = 'America/Los_Angeles'; + localSettingsCache.permalinks = '/:year/:month/:day/:slug/'; var testData = testUtils.DataGenerator.Content.posts[2], postLink = '/2016/05/17/short-and-sweet/'; @@ -364,8 +376,8 @@ describe('Url', function () { }); it('permalink is /:year/:month/:day/:slug, blog timezone is Asia Tokyo', function () { - configUtils.set('theme:timezone', 'Asia/Tokyo'); - configUtils.set('theme:permalinks', '/:year/:month/:day/:slug/'); + localSettingsCache.activeTimezone = 'Asia/Tokyo'; + localSettingsCache.permalinks = '/:year/:month/:day/:slug/'; var testData = testUtils.DataGenerator.Content.posts[2], postLink = '/2016/05/18/short-and-sweet/'; @@ -375,8 +387,8 @@ describe('Url', function () { }); it('post is page, no permalink usage allowed at all', function () { - configUtils.set('theme:timezone', 'America/Los_Angeles'); - configUtils.set('theme:permalinks', '/:year/:month/:day/:slug/'); + localSettingsCache.activeTimezone = 'America/Los_Angeles'; + localSettingsCache.permalinks = '/:year/:month/:day/:slug/'; var testData = testUtils.DataGenerator.Content.posts[5], postLink = '/static-page-test/'; @@ -385,8 +397,8 @@ describe('Url', function () { }); it('permalink is /:year/:id:/:author', function () { - configUtils.set('theme:timezone', 'America/Los_Angeles'); - configUtils.set('theme:permalinks', '/:year/:id/:author/'); + localSettingsCache.activeTimezone = 'America/Los_Angeles'; + localSettingsCache.permalinks = '/:year/:id/:author/'; var testData = _.merge(testUtils.DataGenerator.Content.posts[2], {id: 3}, {author: {slug: 'joe-blog'}}), postLink = '/2015/3/joe-blog/'; @@ -396,8 +408,8 @@ describe('Url', function () { }); it('permalink is /:year/:id:/:author', function () { - configUtils.set('theme:timezone', 'Europe/Berlin'); - configUtils.set('theme:permalinks', '/:year/:id/:author/'); + localSettingsCache.activeTimezone = 'Europe/Berlin'; + localSettingsCache.permalinks = '/:year/:id/:author/'; var testData = _.merge(testUtils.DataGenerator.Content.posts[2], {id: 3}, {author: {slug: 'joe-blog'}}), postLink = '/2016/3/joe-blog/'; @@ -407,7 +419,7 @@ describe('Url', function () { }); it('post is not published yet', function () { - configUtils.set('theme:permalinks', '/:year/:month/:day/:slug/'); + localSettingsCache.permalinks = '/:year/:month/:day/:slug/'; var testData = _.merge(testUtils.DataGenerator.Content.posts[2], {id: 3, published_at: null}), nowMoment = moment(),