From ef9f5dc33fa24ed8caee544a39d4888f44d3fa28 Mon Sep 17 00:00:00 2001 From: Jacob Gable Date: Thu, 14 Nov 2013 20:17:33 -0600 Subject: [PATCH] Pass proxy Ghost interface to Apps Closes #1478 - Create new proxy.js that exposes createProxy method - Pass proxy to App activate/install in lieu of Ghost instance --- core/server/plugins/GhostPlugin.js | 54 ----------------- core/server/plugins/index.js | 5 +- core/server/plugins/loader.js | 7 ++- core/server/plugins/proxy.js | 23 ++++++++ core/test/unit/plugin_proxy_spec.js | 92 +++++++++++++++++++++++++++++ core/test/unit/plugins_spec.js | 61 ------------------- 6 files changed, 120 insertions(+), 122 deletions(-) delete mode 100644 core/server/plugins/GhostPlugin.js create mode 100644 core/server/plugins/proxy.js create mode 100644 core/test/unit/plugin_proxy_spec.js delete mode 100644 core/test/unit/plugins_spec.js diff --git a/core/server/plugins/GhostPlugin.js b/core/server/plugins/GhostPlugin.js deleted file mode 100644 index ec05ec35fe..0000000000 --- a/core/server/plugins/GhostPlugin.js +++ /dev/null @@ -1,54 +0,0 @@ - -var GhostPlugin; - -/** - * GhostPlugin is the base class for a standard plugin. - * @class - * @parameter {Ghost} The current Ghost app instance - */ -GhostPlugin = function (ghost) { - this.app = ghost; -}; - -/** - * A method that will be called on installation. - * Can optionally return a promise if async. - * @parameter {Ghost} The current Ghost app instance - */ -GhostPlugin.prototype.install = function (ghost) { - /*jslint unparam:true*/ - return; -}; - -/** - * A method that will be called on uninstallation. - * Can optionally return a promise if async. - * @parameter {Ghost} The current Ghost app instance - */ -GhostPlugin.prototype.uninstall = function (ghost) { - /*jslint unparam:true*/ - return; -}; - -/** - * A method that will be called when the plugin is enabled. - * Can optionally return a promise if async. - * @parameter {Ghost} The current Ghost app instance - */ -GhostPlugin.prototype.activate = function (ghost) { - /*jslint unparam:true*/ - return; -}; - -/** - * A method that will be called when the plugin is disabled. - * Can optionally return a promise if async. - * @parameter {Ghost} The current Ghost app instance - */ -GhostPlugin.prototype.deactivate = function (ghost) { - /*jslint unparam:true*/ - return; -}; - -module.exports = GhostPlugin; - diff --git a/core/server/plugins/index.js b/core/server/plugins/index.js index 57c6cdbac5..4edda3f4a6 100644 --- a/core/server/plugins/index.js +++ b/core/server/plugins/index.js @@ -3,8 +3,7 @@ var _ = require('underscore'), when = require('when'), errors = require('../errorHandling'), ghostApi, - loader = require('./loader'), - GhostPlugin = require('./GhostPlugin'); + loader = require('./loader'); function getInstalledPlugins() { if (!ghostApi) { @@ -33,8 +32,6 @@ function saveInstalledPlugins(installedPlugins) { } module.exports = { - GhostPlugin: GhostPlugin, - init: function (ghost) { var pluginsToLoad; diff --git a/core/server/plugins/loader.js b/core/server/plugins/loader.js index 26e3f0035b..cb40a3249e 100644 --- a/core/server/plugins/loader.js +++ b/core/server/plugins/loader.js @@ -2,6 +2,7 @@ var path = require('path'), _ = require('underscore'), when = require('when'), + createProxy = require('./proxy'), ghostInstance, loader; @@ -36,7 +37,7 @@ function getPluginByName(name, ghost) { // Check for an actual class, otherwise just use whatever was returned if (_.isFunction(PluginClass)) { - plugin = new PluginClass(ghost); + plugin = new PluginClass(createProxy(ghost)); } else { plugin = PluginClass; } @@ -57,7 +58,7 @@ loader = { // Wrapping the install() with a when because it's possible // to not return a promise from it. - return when(plugin.install(ghost)).then(function () { + return when(plugin.install(createProxy(ghost))).then(function () { return when.resolve(plugin); }); }, @@ -73,7 +74,7 @@ loader = { // Wrapping the activate() with a when because it's possible // to not return a promise from it. - return when(plugin.activate(ghost)).then(function () { + return when(plugin.activate(createProxy(ghost))).then(function () { return when.resolve(plugin); }); } diff --git a/core/server/plugins/proxy.js b/core/server/plugins/proxy.js new file mode 100644 index 0000000000..5b53989bd6 --- /dev/null +++ b/core/server/plugins/proxy.js @@ -0,0 +1,23 @@ +var _ = require('underscore'); + +function createProxy(ghost) { + + return { + filters: { + register: ghost.registerFilter, + unregister: ghost.unregisterFilter + }, + helpers: { + register: ghost.registerThemeHelper, + registerAsync: ghost.registerAsyncThemeHelper + }, + api: { + posts: _.pick(ghost.api.posts, 'browse', 'read'), + tags: ghost.api.tags, + notifications: _.pick(ghost.api.notifications, 'add'), + settings: _.pick(ghost.api.settings, 'read') + } + }; +} + +module.exports = createProxy; \ No newline at end of file diff --git a/core/test/unit/plugin_proxy_spec.js b/core/test/unit/plugin_proxy_spec.js new file mode 100644 index 0000000000..ba828640c1 --- /dev/null +++ b/core/test/unit/plugin_proxy_spec.js @@ -0,0 +1,92 @@ +/*globals describe, beforeEach, afterEach, before, it*/ +var should = require('should'), + sinon = require('sinon'), + _ = require("underscore"), + + // Stuff we are testing + createProxy = require('../../server/plugins/proxy'); + +describe('App Proxy', function () { + + var sandbox, + fakeGhost; + + beforeEach(function () { + sandbox = sinon.sandbox.create(); + + fakeGhost = { + registerFilter: sandbox.stub(), + unregisterFilter: sandbox.stub(), + + registerThemeHelper: sandbox.stub(), + registerAsyncThemeHelper: sandbox.stub(), + + api: { + posts: { + browse: sandbox.stub(), + read: sandbox.stub(), + edit: sandbox.stub(), + add: sandbox.stub(), + destroy: sandbox.stub() + }, + users: { + browse: sandbox.stub(), + read: sandbox.stub(), + edit: sandbox.stub() + }, + tags: { + all: sandbox.stub() + }, + notifications: { + destroy: sandbox.stub(), + add: sandbox.stub() + }, + settings: { + browse: sandbox.stub(), + read: sandbox.stub(), + add: sandbox.stub() + } + } + }; + }); + + afterEach(function () { + sandbox.restore(); + }); + + it('creates a ghost proxy', function () { + var proxy = createProxy(fakeGhost); + + should.exist(proxy.filters); + proxy.filters.register.should.equal(fakeGhost.registerFilter); + proxy.filters.unregister.should.equal(fakeGhost.unregisterFilter); + + should.exist(proxy.helpers); + proxy.helpers.register.should.equal(fakeGhost.registerThemeHelper); + proxy.helpers.registerAsync.should.equal(fakeGhost.registerAsyncThemeHelper); + + should.exist(proxy.api); + + should.exist(proxy.api.posts); + proxy.api.posts.browse.should.equal(fakeGhost.api.posts.browse); + proxy.api.posts.read.should.equal(fakeGhost.api.posts.read); + should.not.exist(proxy.api.posts.edit); + should.not.exist(proxy.api.posts.add); + should.not.exist(proxy.api.posts.destroy); + + should.not.exist(proxy.api.users); + + should.exist(proxy.api.tags); + proxy.api.tags.all.should.equal(fakeGhost.api.tags.all); + + should.exist(proxy.api.notifications); + should.not.exist(proxy.api.notifications.destroy); + proxy.api.notifications.add.should.equal(fakeGhost.api.notifications.add); + + should.exist(proxy.api.settings); + should.not.exist(proxy.api.settings.browse); + proxy.api.settings.read.should.equal(fakeGhost.api.settings.read); + should.not.exist(proxy.api.settings.add); + + }); +}); \ No newline at end of file diff --git a/core/test/unit/plugins_spec.js b/core/test/unit/plugins_spec.js deleted file mode 100644 index 977d4796c4..0000000000 --- a/core/test/unit/plugins_spec.js +++ /dev/null @@ -1,61 +0,0 @@ -/*globals describe, beforeEach, afterEach, before, it*/ -var testUtils = require('../utils'), - should = require('should'), - sinon = require('sinon'), - _ = require("underscore"), - when = require('when'), - knex = require('../../server/models/base').Knex, - errors = require('../../server/errorHandling'), - - // Stuff we are testing - plugins = require('../../server/plugins'), - GhostPlugin = plugins.GhostPlugin, - loader = require('../../server/plugins/loader'); -describe('Plugins', function () { - - var sandbox; - - before(function (done) { - testUtils.clearData().then(function () { - done(); - }, done); - }); - - beforeEach(function (done) { - sandbox = sinon.sandbox.create(); - - testUtils.initData().then(function () { - done(); - }, done); - }); - - afterEach(function (done) { - sandbox.restore(); - - testUtils.clearData().then(function () { - done(); - }, done); - }); - - describe('GhostPlugin Class', function () { - - should.exist(GhostPlugin); - - it('sets app instance', function () { - var fakeGhost = {fake: true}, - plugin = new GhostPlugin(fakeGhost); - - plugin.app.should.equal(fakeGhost); - }); - - it('has default install, uninstall, activate and deactivate methods', function () { - var fakeGhost = {fake: true}, - plugin = new GhostPlugin(fakeGhost); - - _.isFunction(plugin.install).should.equal(true); - _.isFunction(plugin.uninstall).should.equal(true); - _.isFunction(plugin.activate).should.equal(true); - _.isFunction(plugin.deactivate).should.equal(true); - }); - }); -}); \ No newline at end of file