From c8c02a65fa16036904321e39f86da7d48681e022 Mon Sep 17 00:00:00 2001 From: Harry Wolff Date: Fri, 6 Dec 2013 09:13:15 -0500 Subject: [PATCH] Remove ghost.js fixes #1575 - Moves most code that was in ghost.js into ./core/server/index.js - Creates ./core/server/config/theme.js to hold all theme configurations (which previously lived on ghost.blogGlobals()) - Removed ghost.server, passing it in as an argument where needed and allowing middleware to hold onto a reference for lazy use. --- core/ghost.js | 132 -------------------- core/server/config/index.js | 6 + core/server/config/loader.js | 6 + core/server/config/paths.js | 3 +- core/server/config/theme.js | 42 +++++++ core/server/helpers/index.js | 21 ++-- core/server/index.js | 82 ++++++++++-- core/server/middleware/index.js | 118 +++++++++-------- core/server/middleware/middleware.js | 11 +- core/server/plugins/index.js | 8 +- core/server/routes/admin.js | 23 +--- core/test/unit/ghost_spec.js | 47 ------- core/test/unit/middleware_spec.js | 8 +- core/test/unit/server_helpers_index_spec.js | 18 ++- core/test/unit/server_spec.js | 5 +- 15 files changed, 233 insertions(+), 297 deletions(-) delete mode 100644 core/ghost.js create mode 100644 core/server/config/theme.js delete mode 100644 core/test/unit/ghost_spec.js diff --git a/core/ghost.js b/core/ghost.js deleted file mode 100644 index 30b84862ae..0000000000 --- a/core/ghost.js +++ /dev/null @@ -1,132 +0,0 @@ -// # Ghost Module -// Defines core methods required to build the application - -// Module dependencies -var config = require('./server/config'), - when = require('when'), - express = require('express'), - errors = require('./server/errorHandling'), - _ = require('underscore'), - url = require('url'), - models = require('./server/models'), - permissions = require('./server/permissions'), - uuid = require('node-uuid'), - api = require('./server/api'), - -// Variables - Ghost, - instance; - -// ## Module Methods -/** - * @method Ghost - * @returns {*} - * @constructor - */ -Ghost = function () { - - if (!instance) { - instance = this; - - instance.globals = {}; - - // Holds the dbhash (mainly used for cookie secret) - instance.dbHash = undefined; - - _.extend(instance, { - // there's no management here to be sure this has loaded - dataProvider: models, - blogGlobals: function () { - /* this is a bit of a hack until we have a better way to combine settings and config - * this data is what becomes globally available to themes */ - return instance.globals; - }, - getGlobals: function () { - return when.all([ - api.settings.read('title'), - api.settings.read('description'), - api.settings.read('logo'), - api.settings.read('cover') - ]).then(function (globals) { - - instance.globals.path = config.paths().path; - - instance.globals.url = config().url; - instance.globals.title = globals[0].value; - instance.globals.description = globals[1].value; - instance.globals.logo = globals[2] ? globals[2].value : ''; - instance.globals.cover = globals[3] ? globals[3].value : ''; - return; - }); - } - }); - } - return instance; -}; - -// Initialise the application -Ghost.prototype.init = function () { - var self = this; - - function doFirstRun() { - var firstRunMessage = [ - 'Welcome to Ghost.', - 'You\'re running under the ', - process.env.NODE_ENV, - 'environment.', - - 'Your URL is set to', - '' + config().url + '.', - 'See http://docs.ghost.org for instructions.' - ]; - - return api.notifications.add({ - type: 'info', - message: firstRunMessage.join(' '), - status: 'persistent', - id: 'ghost-first-run' - }); - } - - function initDbHashAndFirstRun() { - return when(models.Settings.read('dbHash')).then(function (dbhash) { - // we already ran this, chill - self.dbHash = dbhash.attributes.value; - return dbhash.attributes.value; - }).otherwise(function (error) { - /*jslint unparam:true*/ - // this is where all the "first run" functionality should go - var dbhash = uuid.v4(); - return when(models.Settings.add({key: 'dbHash', value: dbhash, type: 'core'})).then(function () { - self.dbHash = dbhash; - return dbhash; - }).then(doFirstRun); - }); - } - - // ### Initialisation - return when.join( - // Initialise the models - self.dataProvider.init(), - // Calculate paths - config.paths.updatePaths(config().url) - ).then(function () { - // Populate any missing default settings - return models.Settings.populateDefaults(); - }).then(function () { - // Initialize the settings cache - return api.init(); - }).then(function () { - - return self.getGlobals(); - }).then(function () { - return when.join( - // Check for or initialise a dbHash. - initDbHashAndFirstRun(), - // Initialize the permissions actions and objects - permissions.init() - ); - }).otherwise(errors.logAndThrowError); -}; - -module.exports = Ghost; diff --git a/core/server/config/index.js b/core/server/config/index.js index 8b785b9e57..e286c006a8 100644 --- a/core/server/config/index.js +++ b/core/server/config/index.js @@ -1,6 +1,11 @@ +// General entry point for all configuration data +// +// This file itself is a wrapper for the root level config.js file. +// All other files that need to reference config.js should use this file. var loader = require('./loader'), paths = require('./paths'), + theme = require('./theme'), ghostConfig; // Returns NODE_ENV config object @@ -24,5 +29,6 @@ function loadConfig() { config.load = loadConfig; config.paths = paths; +config.theme = theme; module.exports = config; \ No newline at end of file diff --git a/core/server/config/loader.js b/core/server/config/loader.js index be8befe801..b3ac64747f 100644 --- a/core/server/config/loader.js +++ b/core/server/config/loader.js @@ -1,3 +1,9 @@ +// This file manages the root level config.js. +// It will create config.js from config.exampe.js +// if it doesn't exist and then always attempt to load +// config.js into memory, error and quitting if config.js +// has an improper format. + var fs = require('fs'), url = require('url'), when = require('when'), diff --git a/core/server/config/paths.js b/core/server/config/paths.js index a5252b530d..bea7adcc35 100644 --- a/core/server/config/paths.js +++ b/core/server/config/paths.js @@ -1,4 +1,5 @@ - +// Contains all path information to be used throughout +// the codebase. var path = require('path'), when = require('when'), diff --git a/core/server/config/theme.js b/core/server/config/theme.js new file mode 100644 index 0000000000..cb6fc4afee --- /dev/null +++ b/core/server/config/theme.js @@ -0,0 +1,42 @@ +// Holds all theme configuration information +// that as mostly used by templates and handlebar helpers. + +var when = require('when'), + +// Variables + theme, + themeConfig = {}, + update; + + +function theme() { + return themeConfig; +} + +// We must pass the api and config object +// into this method due to circular dependencies. +// If we were to require the api module here +// there would be a race condition where the ./models/base +// tries to access the config() object before it is created. +// And we can't require('./index') from here because it is circular. +function update(api, config) { + return when.all([ + api.settings.read('title'), + api.settings.read('description'), + api.settings.read('logo'), + api.settings.read('cover') + ]).then(function (globals) { + + themeConfig.path = config.paths().path; + + themeConfig.url = config().url; + themeConfig.title = globals[0].value; + themeConfig.description = globals[1].value; + themeConfig.logo = globals[2] ? globals[2].value : ''; + themeConfig.cover = globals[3] ? globals[3].value : ''; + return; + }); +} + +module.exports = theme; +module.exports.update = update; diff --git a/core/server/helpers/index.js b/core/server/helpers/index.js index 891ca9ab77..a34e34c60c 100644 --- a/core/server/helpers/index.js +++ b/core/server/helpers/index.js @@ -94,7 +94,7 @@ coreHelpers.url = function (options) { slug: function () { return self.slug; }, id: function () { return self.id; } }, - blog = coreHelpers.ghost.blogGlobals(), + blog = coreHelpers.config.theme(), isAbsolute = options && options.hash.absolute; return api.settings.read('permalinks').then(function (permalinks) { if (isAbsolute) { @@ -125,7 +125,7 @@ coreHelpers.url = function (options) { // flag outputs the asset path for the Ghost admin coreHelpers.asset = function (context, options) { var output = '', - subDir = coreHelpers.ghost.blogGlobals().path, + subDir = coreHelpers.config.theme().path, isAdmin = options && options.hash && options.hash.ghost; if (subDir === '/') { @@ -264,7 +264,7 @@ coreHelpers.fileStorage = function (context, options) { coreHelpers.ghostScriptTags = function () { var scriptFiles = [], - blog = coreHelpers.ghost.blogGlobals(); + blog = coreHelpers.config.theme(); if (isProduction) { scriptFiles.push("ghost.min.js"); @@ -347,7 +347,7 @@ coreHelpers.post_class = function (options) { coreHelpers.ghost_head = function (options) { /*jslint unparam:true*/ - var blog = coreHelpers.ghost.blogGlobals(), + var blog = coreHelpers.config.theme(), root = blog.path === '/' ? '' : blog.path, head = [], majorMinor = /^(\d+\.)?(\d+)/, @@ -359,7 +359,7 @@ coreHelpers.ghost_head = function (options) { head.push(''); if (this.ghostRoot) { - head.push(''); + head.push(''); } return filters.doFilter('ghost_head', head).then(function (head) { @@ -371,7 +371,7 @@ coreHelpers.ghost_head = function (options) { coreHelpers.ghost_foot = function (options) { /*jslint unparam:true*/ var foot = []; - foot.push(''); + foot.push(''); return filters.doFilter('ghost_foot', foot).then(function (foot) { var footString = _.reduce(foot, function (memo, item) { return memo + ' ' + item; }, ''); @@ -385,7 +385,7 @@ coreHelpers.meta_title = function (options) { blog; if (_.isString(this.ghostRoot)) { if (!this.ghostRoot || this.ghostRoot === '/' || this.ghostRoot === '' || this.ghostRoot.match(/\/page/)) { - blog = coreHelpers.ghost.blogGlobals(); + blog = coreHelpers.config.theme(); title = blog.title; } else { title = this.post.title; @@ -405,7 +405,7 @@ coreHelpers.meta_description = function (options) { if (_.isString(this.ghostRoot)) { if (!this.ghostRoot || this.ghostRoot === '/' || this.ghostRoot === '' || this.ghostRoot.match(/\/page/)) { - blog = coreHelpers.ghost.blogGlobals(); + blog = coreHelpers.config.theme(); description = blog.description; } else { description = ''; @@ -592,12 +592,9 @@ function registerAsyncThemeHelper(name, fn) { }); } -registerHelpers = function (ghost, config) { +registerHelpers = function (config) { var paginationHelper; - // Expose this so our helpers can use it in their code. - coreHelpers.ghost = ghost; - // And expose config coreHelpers.config = config; diff --git a/core/server/index.js b/core/server/index.js index 526626b448..71f1c04b04 100644 --- a/core/server/index.js +++ b/core/server/index.js @@ -14,16 +14,19 @@ var config = require('./config'), path = require('path'), Polyglot = require('node-polyglot'), mailer = require('./mail'), - Ghost = require('../ghost'), helpers = require('./helpers'), middleware = require('./middleware'), routes = require('./routes'), packageInfo = require('../../package.json'), + models = require('./models'), + permissions = require('./permissions'), + uuid = require('node-uuid'), + api = require('./api'), // Variables - ghost = new Ghost(), setup, - init; + init, + dbHash; // If we're in development mode, require "when/console/monitor" // for help in seeing swallowed promise errors, and log any @@ -32,6 +35,43 @@ if (process.env.NODE_ENV === 'development') { require('when/monitor/console'); } +function doFirstRun() { + var firstRunMessage = [ + 'Welcome to Ghost.', + 'You\'re running under the ', + process.env.NODE_ENV, + 'environment.', + + 'Your URL is set to', + '' + config().url + '.', + 'See http://docs.ghost.org for instructions.' + ]; + + return api.notifications.add({ + type: 'info', + message: firstRunMessage.join(' '), + status: 'persistent', + id: 'ghost-first-run' + }); +} + +function initDbHashAndFirstRun() { + return when(models.Settings.read('dbHash')).then(function (hash) { + // we already ran this, chill + // Holds the dbhash (mainly used for cookie secret) + dbHash = hash.attributes.value; + return dbHash; + }).otherwise(function (error) { + /*jslint unparam:true*/ + // this is where all the "first run" functionality should go + var hash = uuid.v4(); + return when(models.Settings.add({key: 'dbHash', value: hash, type: 'core'})).then(function () { + dbHash = hash; + return dbHash; + }).then(doFirstRun); + }); +} + // Sets up the express server instance. // Instantiates the ghost singleton, // helpers, routes, middleware, and plugins. @@ -41,13 +81,36 @@ function setup(server) { // Set up Polygot instance on the require module Polyglot.instance = new Polyglot(); - when(ghost.init()).then(function () { + // ### Initialisation + when.join( + // Initialise the models + models.init(), + // Calculate paths + config.paths.updatePaths(config().url) + ).then(function () { + // Populate any missing default settings + return models.Settings.populateDefaults(); + }).then(function () { + // Initialize the settings cache + return api.init(); + }).then(function () { + // We must pass the api and config object + // into this method due to circular dependencies. + return config.theme.update(api, config); + }).then(function () { + return when.join( + // Check for or initialise a dbHash. + initDbHashAndFirstRun(), + // Initialize the permissions actions and objects + permissions.init() + ); + }).then(function () { return when.join( // Initialise mail after first run, // passing in config module to prevent // circular dependencies. mailer.init(), - helpers.loadCoreHelpers(ghost, config) + helpers.loadCoreHelpers(config) ); }).then(function () { @@ -56,13 +119,13 @@ function setup(server) { server.set('view engine', 'hbs'); // set the configured URL - server.set('ghost root', ghost.blogGlobals().path); + server.set('ghost root', config.theme().path); // return the correct mime type for woff filess express['static'].mime.define({'application/font-woff': ['woff']}); // ## Middleware - middleware(server); + middleware(server, dbHash); // ## Routing @@ -138,11 +201,8 @@ function setup(server) { } - // Expose the express server on the ghost instance. - ghost.server = server; - // Initialize plugins then start the server - plugins.init(ghost).then(function () { + plugins.init().then(function () { // ## Start Ghost App if (getSocket()) { diff --git a/core/server/middleware/index.js b/core/server/middleware/index.js index 7d0b50b70d..2a780f47df 100644 --- a/core/server/middleware/index.js +++ b/core/server/middleware/index.js @@ -11,13 +11,13 @@ var middleware = require('./middleware'), api = require('../api'), path = require('path'), hbs = require('express-hbs'), - Ghost = require('../../ghost'), config = require('../config'), storage = require('../storage'), packageInfo = require('../../../package.json'), BSStore = require('../bookshelf-session'), + models = require('../models'), - ghost = new Ghost(); + expressServer; // ##Custom Middleware @@ -30,7 +30,7 @@ function ghostLocals(req, res, next) { res.locals.version = packageInfo.version; res.locals.path = req.path; // Strip off the subdir part of the path - res.locals.ghostRoot = req.path.replace(ghost.blogGlobals().path.replace(/\/$/, ''), ''); + res.locals.ghostRoot = req.path.replace(config.theme().path.replace(/\/$/, ''), ''); if (res.isAdmin) { res.locals.csrfToken = req.csrfToken(); @@ -74,19 +74,19 @@ function initViews(req, res, next) { if (!res.isAdmin) { // self.globals is a hack til we have a better way of getting combined settings & config - hbsOptions = {templateOptions: {data: {blog: ghost.blogGlobals()}}}; + hbsOptions = {templateOptions: {data: {blog: config.theme()}}}; api.settings.read('activeTheme').then(function (activeTheme) { if (config.paths().availableThemes[activeTheme.value].hasOwnProperty('partials')) { // Check that the theme has a partials directory before trying to use it hbsOptions.partialsDir = path.join(config.paths().themePath, activeTheme.value, 'partials'); } - ghost.server.engine('hbs', hbs.express3(hbsOptions)); - ghost.server.set('views', path.join(config.paths().themePath, activeTheme.value)); + expressServer.engine('hbs', hbs.express3(hbsOptions)); + expressServer.set('views', path.join(config.paths().themePath, activeTheme.value)); }); } else { - ghost.server.engine('hbs', hbs.express3({partialsDir: config.paths().adminViews + 'partials'})); - ghost.server.set('views', config.paths().adminViews); + expressServer.engine('hbs', hbs.express3({partialsDir: config.paths().adminViews + 'partials'})); + expressServer.set('views', config.paths().adminViews); } next(); @@ -95,17 +95,17 @@ function initViews(req, res, next) { // ### Activate Theme // Helper for manageAdminAndTheme function activateTheme(activeTheme) { - var stackLocation = _.indexOf(ghost.server.stack, _.find(ghost.server.stack, function (stackItem) { + var stackLocation = _.indexOf(expressServer.stack, _.find(expressServer.stack, function (stackItem) { return stackItem.route === '' && stackItem.handle.name === 'settingEnabled'; })); // clear the view cache - ghost.server.cache = {}; - ghost.server.disable(ghost.server.get('activeTheme')); - ghost.server.set('activeTheme', activeTheme); - ghost.server.enable(ghost.server.get('activeTheme')); + expressServer.cache = {}; + expressServer.disable(expressServer.get('activeTheme')); + expressServer.set('activeTheme', activeTheme); + expressServer.enable(expressServer.get('activeTheme')); if (stackLocation) { - ghost.server.stack[stackLocation].handle = middleware.whenEnabled(ghost.server.get('activeTheme'), middleware.staticTheme()); + expressServer.stack[stackLocation].handle = middleware.whenEnabled(expressServer.get('activeTheme'), middleware.staticTheme()); } // Update user error template @@ -117,22 +117,22 @@ function activateTheme(activeTheme) { // This is used to ensure the right content is served, and is not for security purposes function manageAdminAndTheme(req, res, next) { // TODO improve this regex - if (ghost.blogGlobals().path === '/') { + if (config.theme().path === '/') { res.isAdmin = /(^\/ghost\/)/.test(req.url); } else { - res.isAdmin = new RegExp("^\\" + ghost.blogGlobals().path + "\\/ghost\\/").test(req.url); + res.isAdmin = new RegExp("^\\" + config.theme().path + "\\/ghost\\/").test(req.url); } if (res.isAdmin) { - ghost.server.enable('admin'); - ghost.server.disable(ghost.server.get('activeTheme')); + expressServer.enable('admin'); + expressServer.disable(expressServer.get('activeTheme')); } else { - ghost.server.enable(ghost.server.get('activeTheme')); - ghost.server.disable('admin'); + expressServer.enable(expressServer.get('activeTheme')); + expressServer.disable('admin'); } api.settings.read('activeTheme').then(function (activeTheme) { // Check if the theme changed - if (activeTheme.value !== ghost.server.get('activeTheme')) { + if (activeTheme.value !== expressServer.get('activeTheme')) { // Change theme if (!config.paths().availableThemes.hasOwnProperty(activeTheme.value)) { if (!res.isAdmin) { @@ -147,79 +147,99 @@ function manageAdminAndTheme(req, res, next) { }); } -module.exports = function (server) { +// Redirect to signup if no users are currently created +function redirectToSignup(req, res, next) { + var root = expressServer.get('ghost root').replace(/\/$/, ''); + /*jslint unparam:true*/ + api.users.browse().then(function (users) { + if (users.length === 0) { + return res.redirect(root + '/ghost/signup/'); + } + next(); + }).otherwise(function (err) { + return next(new Error(err)); + }); +} + +module.exports = function (server, dbHash) { var oneYear = 31536000000, root = config.paths().webroot, corePath = path.join(config.paths().appRoot, 'core'); + // Cache express server instance + expressServer = server; + middleware.cacheServer(expressServer); + // Logging configuration - if (server.get('env') !== 'development') { - server.use(express.logger()); + if (expressServer.get('env') !== 'development') { + expressServer.use(express.logger()); } else { - server.use(express.logger('dev')); + expressServer.use(express.logger('dev')); } // Favicon - server.use(root, express.favicon(corePath + '/shared/favicon.ico')); + expressServer.use(root, express.favicon(corePath + '/shared/favicon.ico')); // Shared static config - server.use(root + '/shared', express['static'](path.join(corePath, '/shared'))); + expressServer.use(root + '/shared', express['static'](path.join(corePath, '/shared'))); - server.use(root + '/content/images', storage.get_storage().serve()); + expressServer.use(root + '/content/images', storage.get_storage().serve()); // Serve our built scripts; can't use /scripts here because themes already are - server.use(root + '/built/scripts', express['static'](path.join(corePath, '/built/scripts'), { + expressServer.use(root + '/built/scripts', express['static'](path.join(corePath, '/built/scripts'), { // Put a maxAge of one year on built scripts maxAge: oneYear })); // First determine whether we're serving admin or theme content - server.use(manageAdminAndTheme); + expressServer.use(manageAdminAndTheme); // Admin only config - server.use(root + '/ghost', middleware.whenEnabled('admin', express['static'](path.join(corePath, '/client/assets')))); + expressServer.use(root + '/ghost', middleware.whenEnabled('admin', express['static'](path.join(corePath, '/client/assets')))); // Theme only config - server.use(middleware.whenEnabled(server.get('activeTheme'), middleware.staticTheme())); + expressServer.use(middleware.whenEnabled(expressServer.get('activeTheme'), middleware.staticTheme())); // Add in all trailing slashes - server.use(slashes()); + expressServer.use(slashes()); - server.use(express.json()); - server.use(express.urlencoded()); + expressServer.use(express.json()); + expressServer.use(express.urlencoded()); - server.use(root + '/ghost/upload/', express.multipart()); - server.use(root + '/ghost/upload/', express.multipart({uploadDir: __dirname + '/content/images'})); - server.use(root + '/ghost/api/v0.1/db/', express.multipart()); + expressServer.use(root + '/ghost/upload/', express.multipart()); + expressServer.use(root + '/ghost/upload/', express.multipart({uploadDir: __dirname + '/content/images'})); + expressServer.use(root + '/ghost/api/v0.1/db/', express.multipart()); // Session handling - server.use(express.cookieParser()); - server.use(express.session({ - store: new BSStore(ghost.dataProvider), - secret: ghost.dbHash, + expressServer.use(express.cookieParser()); + expressServer.use(express.session({ + store: new BSStore(models), + secret: dbHash, cookie: { path: root + '/ghost', maxAge: 12 * 60 * 60 * 1000 } })); //enable express csrf protection - server.use(middleware.conditionalCSRF); + expressServer.use(middleware.conditionalCSRF); // local data - server.use(ghostLocals); + expressServer.use(ghostLocals); // So on every request we actually clean out reduntant passive notifications from the server side - server.use(middleware.cleanNotifications); + expressServer.use(middleware.cleanNotifications); // Initialise the views - server.use(initViews); + expressServer.use(initViews); // process the application routes - server.use(root, server.router); + expressServer.use(root, expressServer.router); // ### Error handling // 404 Handler - server.use(errors.error404); + expressServer.use(errors.error404); // 500 Handler - server.use(errors.error500); + expressServer.use(errors.error500); }; // Export middleware functions directly module.exports.middleware = middleware; +// Expose middleware functions in this file as well +module.exports.middleware.redirectToSignup = redirectToSignup; \ No newline at end of file diff --git a/core/server/middleware/middleware.js b/core/server/middleware/middleware.js index 506191d5e5..d666fe3c18 100644 --- a/core/server/middleware/middleware.js +++ b/core/server/middleware/middleware.js @@ -4,11 +4,10 @@ var _ = require('underscore'), express = require('express'), - Ghost = require('../../ghost'), config = require('../config'), path = require('path'), api = require('../api'), - ghost = new Ghost(); + expressServer; function isBlackListedFileType(file) { var blackListedFileTypes = ['.hbs', '.md', '.json'], @@ -16,6 +15,10 @@ function isBlackListedFileType(file) { return _.contains(blackListedFileTypes, ext); } +function cacheServer(server) { + expressServer = server; +} + var middleware = { // ### Auth Middleware @@ -102,7 +105,8 @@ var middleware = { // From https://github.com/senchalabs/connect/issues/676#issuecomment-9569658 whenEnabled: function (setting, fn) { return function settingEnabled(req, res, next) { - if (ghost.server.enabled(setting)) { + // Set from server/middleware/index.js for now + if (expressServer.enabled(setting)) { fn(req, res, next); } else { next(); @@ -139,3 +143,4 @@ var middleware = { }; module.exports = middleware; +module.exports.cacheServer = cacheServer; \ No newline at end of file diff --git a/core/server/plugins/index.js b/core/server/plugins/index.js index 275d35955d..52ce57c1c3 100644 --- a/core/server/plugins/index.js +++ b/core/server/plugins/index.js @@ -31,7 +31,7 @@ function saveInstalledPlugins(installedPlugins) { } module.exports = { - init: function (ghost) { + init: function () { var pluginsToLoad; try { @@ -60,14 +60,14 @@ module.exports = { loadPromises = _.map(pluginsToLoad, function (plugin) { // If already installed, just activate the plugin if (_.contains(installedPlugins, plugin)) { - return loader.activatePluginByName(plugin, ghost).then(function (loadedPlugin) { + return loader.activatePluginByName(plugin).then(function (loadedPlugin) { return recordLoadedPlugin(plugin, loadedPlugin); }); } // Install, then activate the plugin - return loader.installPluginByName(plugin, ghost).then(function () { - return loader.activatePluginByName(plugin, ghost); + return loader.installPluginByName(plugin).then(function () { + return loader.activatePluginByName(plugin); }).then(function (loadedPlugin) { return recordLoadedPlugin(plugin, loadedPlugin); }); diff --git a/core/server/routes/admin.js b/core/server/routes/admin.js index 2f07c52a61..a1b41e511b 100644 --- a/core/server/routes/admin.js +++ b/core/server/routes/admin.js @@ -1,24 +1,7 @@ var admin = require('../controllers/admin'), api = require('../api'), middleware = require('../middleware').middleware, - Ghost = require('../../ghost'), - url = require('url'), - - ghost = new Ghost(); - -// Redirect to signup if no users are currently created -function redirectToSignup(req, res, next) { - var root = ghost.server.get('ghost root').replace(/\/$/, ''); - /*jslint unparam:true*/ - api.users.browse().then(function (users) { - if (users.length === 0) { - return res.redirect(root + '/ghost/signup/'); - } - next(); - }).otherwise(function (err) { - return next(new Error(err)); - }); -} + url = require('url'); module.exports = function (server) { var root = server.get('ghost root').replace(/\/$/, ''); @@ -46,7 +29,7 @@ module.exports = function (server) { }); server.get('/ghost/signout/', admin.logout); - server.get('/ghost/signin/', redirectToSignup, middleware.redirectToDashboard, admin.login); + server.get('/ghost/signin/', middleware.redirectToSignup, middleware.redirectToDashboard, admin.login); server.get('/ghost/signup/', middleware.redirectToDashboard, admin.signup); server.get('/ghost/forgotten/', middleware.redirectToDashboard, admin.forgotten); server.post('/ghost/forgotten/', admin.generateResetToken); @@ -73,5 +56,5 @@ module.exports = function (server) { /*jslint unparam:true*/ res.redirect(root + '/ghost/'); }); - server.get('/ghost/', redirectToSignup, middleware.auth, admin.index); + server.get('/ghost/', middleware.redirectToSignup, middleware.auth, admin.index); }; \ No newline at end of file diff --git a/core/test/unit/ghost_spec.js b/core/test/unit/ghost_spec.js deleted file mode 100644 index a21625d68d..0000000000 --- a/core/test/unit/ghost_spec.js +++ /dev/null @@ -1,47 +0,0 @@ -/*globals describe, before, beforeEach, afterEach, it*/ -var testUtils = require('../utils'), - should = require('should'), - sinon = require('sinon'), - when = require('when'), - path = require('path'), - _ = require('underscore'), - - // Stuff we are testing - config = require('../../server/config'), - Ghost = require('../../ghost'); - -describe("Ghost API", function () { - var sandbox, - ghost; - - before(function (done) { - testUtils.clearData().then(function () { - done(); - }, done); - }); - - beforeEach(function (done) { - sandbox = sinon.sandbox.create(); - - testUtils.initData().then(function () { - ghost = new Ghost(); - done(); - }, done); - }); - - afterEach(function () { - sandbox.restore(); - }); - - after(function (done) { - testUtils.clearData().then(function () { - done(); - }, done); - }); - - it("is a singleton", function () { - var ghost2 = new Ghost(); - - should.strictEqual(ghost, ghost2); - }); -}); \ No newline at end of file diff --git a/core/test/unit/middleware_spec.js b/core/test/unit/middleware_spec.js index c5b9b6b070..76405d3418 100644 --- a/core/test/unit/middleware_spec.js +++ b/core/test/unit/middleware_spec.js @@ -5,14 +5,13 @@ var assert = require('assert'), when = require('when'), _ = require('underscore'), express = require('express'), - Ghost = require('../../ghost'), api = require('../../server/api'); middleware = require('../../server/middleware').middleware; describe('Middleware', function () { describe('auth', function () { - var req, res, ghost = new Ghost(); + var req, res; beforeEach(function (done) { req = { @@ -199,11 +198,11 @@ describe('Middleware', function () { }); describe('whenEnabled', function () { - var cbFn, ghost = new Ghost(); + var cbFn, server; beforeEach(function () { cbFn = sinon.spy(); - ghost.server = { + server = { enabled: function (setting) { if (setting === 'enabled') { return true; @@ -212,6 +211,7 @@ describe('Middleware', function () { } } }; + middleware.cacheServer(server); }); it('should call function if setting is enabled', function (done) { diff --git a/core/test/unit/server_helpers_index_spec.js b/core/test/unit/server_helpers_index_spec.js index 9c2a841f57..d98755b6f7 100644 --- a/core/test/unit/server_helpers_index_spec.js +++ b/core/test/unit/server_helpers_index_spec.js @@ -10,23 +10,21 @@ var testUtils = require('../utils'), // Stuff we are testing handlebars = require('express-hbs').handlebars, helpers = require('../../server/helpers'), - Ghost = require('../../ghost'); + config = require('../../server/config'); describe('Core Helpers', function () { var ghost, sandbox, - blogGlobalsStub, apiStub; beforeEach(function (done) { - ghost = new Ghost(); sandbox = sinon.sandbox.create(); apiStub = sandbox.stub(api.settings , 'read', function () { return when({value: 'casper'}); }); - blogGlobalsStub = sandbox.stub(ghost, 'blogGlobals', function () { + config.theme = sandbox.stub(config, 'theme', function () { return { path: '', //url: 'http://127.0.0.1:2368', @@ -36,7 +34,7 @@ describe('Core Helpers', function () { }; }); - helpers.loadCoreHelpers(ghost).then(function () { + helpers.loadCoreHelpers(config).then(function () { done(); }, done); }); @@ -372,7 +370,7 @@ describe('Core Helpers', function () { it('can render single page with no pagination necessary', function (done) { var rendered; - helpers.loadCoreHelpers(ghost).then(function () { + helpers.loadCoreHelpers().then(function () { rendered = helpers.pagination.call({pagination: {page: 1, prev: undefined, next: undefined, limit: 15, total: 8, pages: 1}}); should.exist(rendered); // strip out carriage returns and compare. @@ -387,7 +385,7 @@ describe('Core Helpers', function () { it('can render first page of many with older posts link', function (done) { var rendered; - helpers.loadCoreHelpers(ghost).then(function () { + helpers.loadCoreHelpers().then(function () { rendered = helpers.pagination.call({pagination: {page: 1, prev: undefined, next: 2, limit: 15, total: 8, pages: 3}}); should.exist(rendered); @@ -402,7 +400,7 @@ describe('Core Helpers', function () { it('can render middle pages of many with older and newer posts link', function (done) { var rendered; - helpers.loadCoreHelpers(ghost).then(function () { + helpers.loadCoreHelpers().then(function () { rendered = helpers.pagination.call({pagination: {page: 2, prev: 1, next: 3, limit: 15, total: 8, pages: 3}}); should.exist(rendered); @@ -418,7 +416,7 @@ describe('Core Helpers', function () { it('can render last page of many with newer posts link', function (done) { var rendered; - helpers.loadCoreHelpers(ghost).then(function () { + helpers.loadCoreHelpers().then(function () { rendered = helpers.pagination.call({pagination: {page: 3, prev: 2, next: undefined, limit: 15, total: 8, pages: 3}}); should.exist(rendered); @@ -433,7 +431,7 @@ describe('Core Helpers', function () { }); it('validates values', function (done) { - helpers.loadCoreHelpers(ghost).then(function () { + helpers.loadCoreHelpers().then(function () { var runErrorTest = function (data) { return function () { helpers.pagination.call(data); diff --git a/core/test/unit/server_spec.js b/core/test/unit/server_spec.js index 02db54f2fb..a348e3f102 100644 --- a/core/test/unit/server_spec.js +++ b/core/test/unit/server_spec.js @@ -4,10 +4,7 @@ var net = require('net'), should = require('should'), request = require('request'), server = require('../../server'), - Ghost = require('../../ghost'), - config = require('../../../config'), - - ghost = new Ghost(); + config = require('../../../config'); describe('Server', function () { var port = config.testing.server.port,