diff --git a/core/server/apps/amp/lib/router.js b/core/server/apps/amp/lib/router.js index eff2676a90..29b00836a1 100644 --- a/core/server/apps/amp/lib/router.js +++ b/core/server/apps/amp/lib/router.js @@ -63,7 +63,7 @@ function getPostData(req, res, next) { })); } - helpers.postLookup(urlWithoutSubdirectoryWithoutAmp, {permalinks}) + helpers.postLookup(urlWithoutSubdirectoryWithoutAmp, {permalinks}, res.locals) .then((result) => { if (result && result.post) { req.body.post = result.post; diff --git a/core/server/apps/subscribers/lib/router.js b/core/server/apps/subscribers/lib/router.js index 34e2f407b5..ca49b45ff8 100644 --- a/core/server/apps/subscribers/lib/router.js +++ b/core/server/apps/subscribers/lib/router.js @@ -4,7 +4,6 @@ const path = require('path'), subscribeRouter = express.Router(), bodyParser = require('body-parser'), // Dirty requires - api = require('../../../api'), common = require('../../../lib/common'), urlService = require('../../../services/url'), validator = require('../../../data/validation').validator, @@ -75,6 +74,8 @@ function handleSource(req, res, next) { function storeSubscriber(req, res, next) { req.body.status = 'subscribed'; + const api = require('../../../api')[res.locals.apiVersion]; + if (_.isEmpty(req.body.email)) { return next(new common.errors.ValidationError({message: 'Email cannot be blank.'})); } else if (!validator.isEmail(req.body.email)) { diff --git a/core/server/helpers/get.js b/core/server/helpers/get.js index b1c4de4cf2..8212141bd5 100644 --- a/core/server/helpers/get.js +++ b/core/server/helpers/get.js @@ -104,10 +104,11 @@ get = function get(resource, options) { options.hash = options.hash || {}; options.data = options.data || {}; - var self = this, - data = createFrame(options.data), - apiOptions = options.hash, - apiMethod; + const self = this; + const data = createFrame(options.data); + const apiVersion = data.root._locals.apiVersion; + let apiOptions = options.hash; + let apiMethod; if (!options.fn) { data.error = i18n.t('warnings.helpers.mustBeCalledAsBlock', {helperName: 'get'}); @@ -122,7 +123,7 @@ get = function get(resource, options) { } // Determine if this is a read or browse - apiMethod = isBrowse(resource, apiOptions) ? api[resource].browse : api[resource].read; + apiMethod = isBrowse(resource, apiOptions) ? api[apiVersion][resource].browse : api[apiVersion][resource].read; // Parse the options we're going to pass to the API apiOptions = parseOptions(this, apiOptions); diff --git a/core/server/helpers/prev_next.js b/core/server/helpers/prev_next.js index 9a59db17f0..3fc2b04468 100644 --- a/core/server/helpers/prev_next.js +++ b/core/server/helpers/prev_next.js @@ -49,10 +49,11 @@ buildApiOptions = function buildApiOptions(options, post) { }; fetch = function fetch(options, data) { - var self = this, - apiOptions = buildApiOptions(options, this); + const self = this; + const apiOptions = buildApiOptions(options, this); + const apiVersion = data.root._locals.apiVersion; - return api.posts + return api[apiVersion].posts .browse(apiOptions) .then(function handleSuccess(result) { var related = result.posts[0]; diff --git a/core/server/services/apps/proxy.js b/core/server/services/apps/proxy.js index 23e7d365e6..7f920c6a8f 100644 --- a/core/server/services/apps/proxy.js +++ b/core/server/services/apps/proxy.js @@ -1,5 +1,5 @@ const _ = require('lodash'), - api = require('../../api'), + api = require('../../api/v0.1'), helpers = require('../../helpers/register'), filters = require('../../filters'), common = require('../../lib/common'), diff --git a/core/server/services/routing/controllers/channel.js b/core/server/services/routing/controllers/channel.js index 9d85e27462..993018faec 100644 --- a/core/server/services/routing/controllers/channel.js +++ b/core/server/services/routing/controllers/channel.js @@ -37,7 +37,7 @@ module.exports = function channelController(req, res, next) { } } - return helpers.fetchData(pathOptions, res.routerOptions) + return helpers.fetchData(pathOptions, res.routerOptions, res.locals) .then(function handleResult(result) { // CASE: requested page is greater than number of pages we have if (pathOptions.page > result.meta.pagination.pages) { diff --git a/core/server/services/routing/controllers/collection.js b/core/server/services/routing/controllers/collection.js index 6ac9685543..51b461c367 100644 --- a/core/server/services/routing/controllers/collection.js +++ b/core/server/services/routing/controllers/collection.js @@ -37,7 +37,7 @@ module.exports = function collectionController(req, res, next) { } } - return helpers.fetchData(pathOptions, res.routerOptions) + return helpers.fetchData(pathOptions, res.routerOptions, res.locals) .then(function handleResult(result) { // CASE: requested page is greater than number of pages we have if (pathOptions.page > result.meta.pagination.pages) { diff --git a/core/server/services/routing/controllers/entry.js b/core/server/services/routing/controllers/entry.js index 9f931084a0..b1bd5df3c6 100644 --- a/core/server/services/routing/controllers/entry.js +++ b/core/server/services/routing/controllers/entry.js @@ -12,7 +12,7 @@ const debug = require('ghost-ignition').debug('services:routing:controllers:entr module.exports = function entryController(req, res, next) { debug('entryController', res.routerOptions); - return helpers.postLookup(req.path, res.routerOptions) + return helpers.postLookup(req.path, res.routerOptions, res.locals) .then(function then(lookup) { // Format data 1 const post = lookup ? lookup.post : false; diff --git a/core/server/services/routing/controllers/preview.js b/core/server/services/routing/controllers/preview.js index a67ee2b181..51de526fea 100644 --- a/core/server/services/routing/controllers/preview.js +++ b/core/server/services/routing/controllers/preview.js @@ -1,5 +1,4 @@ const debug = require('ghost-ignition').debug('services:routing:controllers:preview'), - api = require('../../../api'), urlService = require('../../url'), filters = require('../../../filters'), helpers = require('../helpers'); @@ -7,6 +6,8 @@ const debug = require('ghost-ignition').debug('services:routing:controllers:prev module.exports = function previewController(req, res, next) { debug('previewController'); + const api = require('../../../api')[res.locals.apiVersion]; + const params = { uuid: req.params.uuid, status: 'all', diff --git a/core/server/services/routing/controllers/rss.js b/core/server/services/routing/controllers/rss.js index 2ec3cb12de..dbdd5590fa 100644 --- a/core/server/services/routing/controllers/rss.js +++ b/core/server/services/routing/controllers/rss.js @@ -34,7 +34,7 @@ module.exports = function rssController(req, res, next) { // @TODO: this belongs to the rss service const baseUrl = getBaseUrlForRSSReq(req.originalUrl, pathOptions.page); - helpers.fetchData(pathOptions, res.routerOptions) + helpers.fetchData(pathOptions, res.routerOptions, res.locals) .then(function formatResult(result) { const response = _.pick(result, ['posts', 'meta']); diff --git a/core/server/services/routing/controllers/static.js b/core/server/services/routing/controllers/static.js index 588d6a9bdc..2f0a9eb6b1 100644 --- a/core/server/services/routing/controllers/static.js +++ b/core/server/services/routing/controllers/static.js @@ -1,10 +1,10 @@ const _ = require('lodash'), Promise = require('bluebird'), debug = require('ghost-ignition').debug('services:routing:controllers:static'), - api = require('../../../api'), helpers = require('../helpers'); -function processQuery(query) { +function processQuery(query, locals) { + const api = require('../../../api')[locals.apiVersion]; query = _.cloneDeep(query); // Return a promise for the api query @@ -17,7 +17,7 @@ module.exports = function staticController(req, res, next) { let props = {}; _.each(res.routerOptions.data, function (query, name) { - props[name] = processQuery(query); + props[name] = processQuery(query, res.locals); }); return Promise.props(props) diff --git a/core/server/services/routing/helpers/fetch-data.js b/core/server/services/routing/helpers/fetch-data.js index 5671874f3c..a8c7c860a2 100644 --- a/core/server/services/routing/helpers/fetch-data.js +++ b/core/server/services/routing/helpers/fetch-data.js @@ -4,7 +4,6 @@ */ const _ = require('lodash'), Promise = require('bluebird'), - api = require('../../../api'), defaultPostQuery = {}; // The default settings for a default post query @@ -35,7 +34,9 @@ _.extend(defaultPostQuery, queryDefaults, { * @param {String} slugParam * @returns {Promise} promise for an API call */ -function processQuery(query, slugParam) { +function processQuery(query, slugParam, locals) { + const api = require('../../../api')[locals.apiVersion]; + query = _.cloneDeep(query); // Ensure that all the properties are filled out @@ -56,7 +57,7 @@ function processQuery(query, slugParam) { * Wraps the queries using Promise.props to ensure it gets named responses * Does a first round of formatting on the response, and returns */ -function fetchData(pathOptions, routerOptions) { +function fetchData(pathOptions, routerOptions, locals) { pathOptions = pathOptions || {}; routerOptions = routerOptions || {}; @@ -81,11 +82,11 @@ function fetchData(pathOptions, routerOptions) { // CASE: always fetch post entries // The filter can in theory contain a "%s" e.g. filter="primary_tag:%s" - props.posts = processQuery(postQuery, pathOptions.slug); + props.posts = processQuery(postQuery, pathOptions.slug, locals); // CASE: fetch more data defined by the router e.g. tags, authors - see TaxonomyRouter _.each(routerOptions.data, function (query, name) { - props[name] = processQuery(query, pathOptions.slug); + props[name] = processQuery(query, pathOptions.slug, locals); }); return Promise.props(props) diff --git a/core/server/services/routing/helpers/post-lookup.js b/core/server/services/routing/helpers/post-lookup.js index 55e32ccfcb..fbf0c1b53a 100644 --- a/core/server/services/routing/helpers/post-lookup.js +++ b/core/server/services/routing/helpers/post-lookup.js @@ -2,14 +2,14 @@ const _ = require('lodash'), Promise = require('bluebird'), url = require('url'), debug = require('ghost-ignition').debug('services:routing:helpers:post-lookup'), - routeMatch = require('path-match')(), - api = require('../../../api'); + routeMatch = require('path-match')(); -function postLookup(postUrl, routerOptions) { +function postLookup(postUrl, routerOptions, locals) { debug(postUrl); - const targetPath = url.parse(postUrl).path, - permalinks = routerOptions.permalinks; + const api = require('../../../api')[locals.apiVersion]; + const targetPath = url.parse(postUrl).path; + const permalinks = routerOptions.permalinks; let isEditURL = false; diff --git a/core/server/web/shared/middlewares/frontend-client.js b/core/server/web/shared/middlewares/frontend-client.js index e2cebc4b3a..d725baee44 100644 --- a/core/server/web/shared/middlewares/frontend-client.js +++ b/core/server/web/shared/middlewares/frontend-client.js @@ -1,4 +1,3 @@ -const api = require('../../../api'); const labs = require('../../../services/labs'); const common = require('../../../lib/common'); @@ -7,6 +6,8 @@ module.exports = function getFrontendClient(req, res, next) { return next(); } + const api = require('../../../api')['v0.1']; + return api.clients .read({slug: 'ghost-frontend'}) .then((client) => { diff --git a/core/test/unit/helpers/get_spec.js b/core/test/unit/helpers/get_spec.js index eb4dd27d6e..89c49c2344 100644 --- a/core/test/unit/helpers/get_spec.js +++ b/core/test/unit/helpers/get_spec.js @@ -13,6 +13,7 @@ var should = require('should'), describe('{{#get}} helper', function () { var fn, inverse, labsStub; + let locals = {}; before(function () { models.init(); @@ -22,6 +23,8 @@ describe('{{#get}} helper', function () { fn = sandbox.spy(); inverse = sandbox.spy(); labsStub = sandbox.stub(labs, 'isSet').returns(true); + + locals = {root: {_locals: {apiVersion: 'v0.1'}}}; }); afterEach(function () { @@ -63,10 +66,10 @@ describe('{{#get}} helper', function () { meta = {pagination: {}}; beforeEach(function () { - browsePostsStub = sandbox.stub(api.posts, 'browse'); - readPostsStub = sandbox.stub(api.posts, 'read'); - readTagsStub = sandbox.stub(api.tags, 'read').returns(new Promise.resolve({tags: []})); - readUsersStub = sandbox.stub(api.users, 'read').returns(new Promise.resolve({users: []})); + browsePostsStub = sandbox.stub(api["v0.1"].posts, 'browse'); + readPostsStub = sandbox.stub(api["v0.1"].posts, 'read'); + readTagsStub = sandbox.stub(api["v0.1"].tags, 'read').returns(new Promise.resolve({tags: []})); + readUsersStub = sandbox.stub(api["v0.1"].users, 'read').returns(new Promise.resolve({users: []})); browsePostsStub.returns(new Promise.resolve({posts: testPostsArr, meta: meta})); browsePostsStub.withArgs({limit: '3'}).returns(new Promise.resolve({ @@ -85,7 +88,7 @@ describe('{{#get}} helper', function () { helpers.get.call( {}, 'posts', - {hash: {}, fn: fn, inverse: inverse} + {hash: {}, data: locals, fn: fn, inverse: inverse} ).then(function () { labsStub.calledOnce.should.be.true(); @@ -103,7 +106,7 @@ describe('{{#get}} helper', function () { helpers.get.call( {}, 'posts', - {hash: {}, fn: fn, inverse: inverse} + {hash: {}, data: locals, fn: fn, inverse: inverse} ).then(function () { fn.firstCall.args[0].pagination.should.be.an.Object(); fn.firstCall.args[0].meta.should.be.an.Object(); @@ -118,7 +121,7 @@ describe('{{#get}} helper', function () { helpers.get.call( {}, 'posts', - {hash: {limit: '1'}, fn: fn, inverse: inverse} + {hash: {limit: '1'}, data: locals, fn: fn, inverse: inverse} ).then(function () { should.not.exist(fn.firstCall.args[0].pagination); should.not.exist(fn.firstCall.args[0].meta); @@ -132,7 +135,7 @@ describe('{{#get}} helper', function () { helpers.get.call( {}, 'posts', - {hash: {limit: '3'}, fn: fn, inverse: inverse} + {hash: {limit: '3'}, data: locals, fn: fn, inverse: inverse} ).then(function () { fn.calledOnce.should.be.true(); fn.firstCall.args[0].should.be.an.Object().with.property('posts'); @@ -148,7 +151,7 @@ describe('{{#get}} helper', function () { helpers.get.call( {}, 'posts', - {hash: {limit: '1'}, fn: fn, inverse: inverse} + {hash: {limit: '1'}, data: locals, fn: fn, inverse: inverse} ).then(function () { fn.calledOnce.should.be.true(); fn.firstCall.args[0].should.be.an.Object().with.property('posts'); @@ -164,7 +167,7 @@ describe('{{#get}} helper', function () { helpers.get.call( {}, 'posts', - {hash: {limit: '1'}, fn: fn, inverse: inverse} + {hash: {limit: '1'}, data: locals, fn: fn, inverse: inverse} ).then(function () { fn.calledOnce.should.be.true(); fn.firstCall.args[0].should.be.an.Object().with.property('posts'); @@ -180,7 +183,7 @@ describe('{{#get}} helper', function () { helpers.get.call( {}, 'posts', - {hash: {filter: 'tags:test'}, fn: fn, inverse: inverse} + {hash: {filter: 'tags:test'}, data: locals, fn: fn, inverse: inverse} ).then(function () { fn.calledOnce.should.be.true(); fn.firstCall.args[0].should.be.an.Object().with.property('posts'); @@ -195,7 +198,7 @@ describe('{{#get}} helper', function () { helpers.get.call( {}, 'posts', - {hash: {filter: 'author:cameron'}, fn: fn, inverse: inverse} + {hash: {filter: 'author:cameron'}, data: locals, fn: fn, inverse: inverse} ).then(function () { fn.calledOnce.should.be.true(); fn.firstCall.args[0].should.be.an.Object().with.property('posts'); @@ -210,7 +213,7 @@ describe('{{#get}} helper', function () { helpers.get.call( {}, 'posts', - {hash: {filter: 'featured:true'}, fn: fn, inverse: inverse} + {hash: {filter: 'featured:true'}, data: locals, fn: fn, inverse: inverse} ).then(function () { fn.calledOnce.should.be.true(); fn.firstCall.args[0].should.be.an.Object().with.property('posts'); @@ -225,7 +228,7 @@ describe('{{#get}} helper', function () { helpers.get.call( {}, 'posts', - {hash: {id: '2'}, fn: fn, inverse: inverse} + {hash: {id: '2'}, data: locals, fn: fn, inverse: inverse} ).then(function () { fn.calledOnce.should.be.true(); fn.firstCall.args[0].should.be.an.Object().with.property('posts'); @@ -241,7 +244,7 @@ describe('{{#get}} helper', function () { helpers.get.call( {}, 'posts', - {hash: {filter: 'tags:none'}, fn: fn, inverse: inverse} + {hash: {filter: 'tags:none'}, data: locals, fn: fn, inverse: inverse} ).then(function () { fn.calledOnce.should.be.true(); fn.firstCall.args[0].should.be.an.Object().with.property('posts'); @@ -258,7 +261,7 @@ describe('{{#get}} helper', function () { helpers.get.call( {}, 'magic', - {hash: {}, fn: fn, inverse: inverse} + {hash: {}, data: locals, fn: fn, inverse: inverse} ).then(function () { fn.called.should.be.false(); inverse.calledOnce.should.be.true(); @@ -274,7 +277,7 @@ describe('{{#get}} helper', function () { helpers.get.call( {}, 'posts', - {hash: {status: 'thing!'}, fn: fn, inverse: inverse} + {hash: {status: 'thing!'}, data: locals, fn: fn, inverse: inverse} ).then(function () { fn.called.should.be.false(); inverse.calledOnce.should.be.true(); @@ -289,7 +292,8 @@ describe('{{#get}} helper', function () { it('should show warning for call without any options', function (done) { helpers.get.call( {}, - 'posts' + 'posts', + {data: locals} ).then(function () { fn.called.should.be.false(); inverse.called.should.be.false(); @@ -302,20 +306,20 @@ describe('{{#get}} helper', function () { describe('path resolution', function () { var browseStub, readStub, pubDate = new Date(), - data = { + resource = { post: {id: 3, title: 'Test 3', author: {slug: 'cameron'}, tags: [{slug: 'test'}, {slug: 'magic'}], published_at: pubDate} }; beforeEach(function () { - browseStub = sandbox.stub(api.posts, 'browse').returns(new Promise.resolve()); - readStub = sandbox.stub(api.posts, 'read').returns(new Promise.resolve()); + browseStub = sandbox.stub(api["v0.1"].posts, 'browse').returns(new Promise.resolve()); + readStub = sandbox.stub(api["v0.1"].posts, 'read').returns(new Promise.resolve()); }); it('should resolve post.tags alias', function (done) { helpers.get.call( - data, + resource, 'posts', - {hash: {filter: 'tags:[{{post.tags}}]'}, fn: fn, inverse: inverse} + {hash: {filter: 'tags:[{{post.tags}}]'}, data: locals, fn: fn, inverse: inverse} ).then(function () { browseStub.firstCall.args.should.be.an.Array().with.lengthOf(1); browseStub.firstCall.args[0].should.be.an.Object().with.property('filter'); @@ -327,9 +331,9 @@ describe('{{#get}} helper', function () { it('should resolve post.author alias', function (done) { helpers.get.call( - data, + resource, 'posts', - {hash: {filter: 'author:{{post.author}}'}, fn: fn, inverse: inverse} + {hash: {filter: 'author:{{post.author}}'}, data: locals, fn: fn, inverse: inverse} ).then(function () { browseStub.firstCall.args.should.be.an.Array().with.lengthOf(1); browseStub.firstCall.args[0].should.be.an.Object().with.property('filter'); @@ -341,9 +345,9 @@ describe('{{#get}} helper', function () { it('should resolve basic path', function (done) { helpers.get.call( - data, + resource, 'posts', - {hash: {filter: 'id:-{{post.id}}'}, fn: fn, inverse: inverse} + {hash: {filter: 'id:-{{post.id}}'}, data: locals, fn: fn, inverse: inverse} ).then(function () { browseStub.firstCall.args.should.be.an.Array().with.lengthOf(1); browseStub.firstCall.args[0].should.be.an.Object().with.property('filter'); @@ -355,9 +359,9 @@ describe('{{#get}} helper', function () { it('should handle arrays the same as handlebars', function (done) { helpers.get.call( - data, + resource, 'posts', - {hash: {filter: 'tags:{{post.tags.[0].slug}}'}, fn: fn, inverse: inverse} + {hash: {filter: 'tags:{{post.tags.[0].slug}}'}, data: locals, fn: fn, inverse: inverse} ).then(function () { browseStub.firstCall.args.should.be.an.Array().with.lengthOf(1); browseStub.firstCall.args[0].should.be.an.Object().with.property('filter'); @@ -369,9 +373,9 @@ describe('{{#get}} helper', function () { it('should handle dates', function (done) { helpers.get.call( - data, + resource, 'posts', - {hash: {filter: "published_at:<='{{post.published_at}}'"}, fn: fn, inverse: inverse} + {hash: {filter: "published_at:<='{{post.published_at}}'"}, data: locals, fn: fn, inverse: inverse} ).then(function () { browseStub.firstCall.args.should.be.an.Array().with.lengthOf(1); browseStub.firstCall.args[0].should.be.an.Object().with.property('filter'); @@ -383,9 +387,9 @@ describe('{{#get}} helper', function () { it('should output nothing if path does not resolve', function (done) { helpers.get.call( - data, + resource, 'posts', - {hash: {filter: 'id:{{post.thing}}'}, fn: fn, inverse: inverse} + {hash: {filter: 'id:{{post.thing}}'}, data: locals, fn: fn, inverse: inverse} ).then(function () { browseStub.firstCall.args.should.be.an.Array().with.lengthOf(1); browseStub.firstCall.args[0].should.be.an.Object().with.property('filter'); diff --git a/core/test/unit/helpers/next_post_spec.js b/core/test/unit/helpers/next_post_spec.js index 9ef140f111..1dc89ccdd1 100644 --- a/core/test/unit/helpers/next_post_spec.js +++ b/core/test/unit/helpers/next_post_spec.js @@ -10,15 +10,20 @@ var should = require('should'), sandbox = sinon.sandbox.create(); describe('{{next_post}} helper', function () { + let locals; var browsePostStub; + beforeEach(function () { + locals = {root: {_locals: {apiVersion: 'v0.1'}}}; + }); + afterEach(function () { sandbox.restore(); }); describe('with valid post data - ', function () { beforeEach(function () { - browsePostStub = sandbox.stub(api.posts, 'browse').callsFake(function (options) { + browsePostStub = sandbox.stub(api['v0.1'].posts, 'browse').callsFake(function (options) { if (options.filter.indexOf('published_at:>') > -1) { return Promise.resolve({ posts: [{slug: '/next/', title: 'post 3'}] @@ -30,7 +35,7 @@ describe('{{next_post}} helper', function () { it('shows \'if\' template with next post data', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'next_post', fn: fn, inverse: inverse}; + optionsData = {name: 'next_post', data: locals, fn: fn, inverse: inverse}; helpers.next_post .call({ @@ -60,7 +65,7 @@ describe('{{next_post}} helper', function () { describe('for valid post with no next post', function () { beforeEach(function () { - browsePostStub = sandbox.stub(api.posts, 'browse').callsFake(function (options) { + browsePostStub = sandbox.stub(api['v0.1'].posts, 'browse').callsFake(function (options) { if (options.filter.indexOf('published_at:>') > -1) { return Promise.resolve({posts: []}); } @@ -70,7 +75,7 @@ describe('{{next_post}} helper', function () { it('shows \'else\' template', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'next_post', fn: fn, inverse: inverse}; + optionsData = {name: 'next_post', data: locals, fn: fn, inverse: inverse}; helpers.next_post .call({ @@ -98,7 +103,7 @@ describe('{{next_post}} helper', function () { describe('for invalid post data', function () { beforeEach(function () { - browsePostStub = sandbox.stub(api.posts, 'browse').callsFake(function (options) { + browsePostStub = sandbox.stub(api['v0.1'].posts, 'browse').callsFake(function (options) { if (options.filter.indexOf('published_at:>') > -1) { return Promise.resolve({}); } @@ -108,7 +113,7 @@ describe('{{next_post}} helper', function () { it('shows \'else\' template', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'next_post', fn: fn, inverse: inverse}; + optionsData = {name: 'next_post', data: locals, fn: fn, inverse: inverse}; helpers.next_post .call({}, optionsData) @@ -125,7 +130,7 @@ describe('{{next_post}} helper', function () { describe('for page', function () { beforeEach(function () { - browsePostStub = sandbox.stub(api.posts, 'browse').callsFake(function (options) { + browsePostStub = sandbox.stub(api['v0.1'].posts, 'browse').callsFake(function (options) { if (options.filter.indexOf('published_at:>') > -1) { return Promise.resolve({posts: [{slug: '/previous/', title: 'post 1'}]}); } @@ -135,7 +140,7 @@ describe('{{next_post}} helper', function () { it('shows \'else\' template', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'next_post', fn: fn, inverse: inverse}; + optionsData = {name: 'next_post', data: locals, fn: fn, inverse: inverse}; helpers.next_post .call({ @@ -160,7 +165,7 @@ describe('{{next_post}} helper', function () { describe('for unpublished post', function () { beforeEach(function () { - browsePostStub = sandbox.stub(api.posts, 'browse').callsFake(function (options) { + browsePostStub = sandbox.stub(api['v0.1'].posts, 'browse').callsFake(function (options) { if (options.filter.indexOf('published_at:>') > -1) { return Promise.resolve({posts: [{slug: '/next/', title: 'post 3'}]}); } @@ -170,7 +175,7 @@ describe('{{next_post}} helper', function () { it('shows \'else\' template', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'next_post', fn: fn, inverse: inverse}; + optionsData = {name: 'next_post', data: locals, fn: fn, inverse: inverse}; helpers.next_post .call({ @@ -194,7 +199,7 @@ describe('{{next_post}} helper', function () { describe('with "in" option', function () { beforeEach(function () { - browsePostStub = sandbox.stub(api.posts, 'browse').callsFake(function (options) { + browsePostStub = sandbox.stub(api['v0.1'].posts, 'browse').callsFake(function (options) { if (options.filter.indexOf('published_at:>') > -1) { return Promise.resolve({ posts: [{slug: '/next/', title: 'post 1'}] @@ -206,7 +211,7 @@ describe('{{next_post}} helper', function () { it('shows \'if\' template with prev post data with primary_tag set', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'next_post', fn: fn, inverse: inverse, hash: {in: 'primary_tag'}}; + optionsData = {name: 'next_post', data: locals, fn: fn, inverse: inverse, hash: {in: 'primary_tag'}}; helpers.next_post .call({ @@ -238,7 +243,7 @@ describe('{{next_post}} helper', function () { it('shows \'if\' template with prev post data with primary_author set', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'next_post', fn: fn, inverse: inverse, hash: {in: 'primary_author'}}; + optionsData = {name: 'next_post', data: locals, fn: fn, inverse: inverse, hash: {in: 'primary_author'}}; helpers.next_post .call({ @@ -270,7 +275,7 @@ describe('{{next_post}} helper', function () { it('shows \'if\' template with prev post data with author set', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'next_post', fn: fn, inverse: inverse, hash: {in: 'author'}}; + optionsData = {name: 'next_post', data: locals, fn: fn, inverse: inverse, hash: {in: 'author'}}; helpers.next_post .call({ @@ -302,7 +307,7 @@ describe('{{next_post}} helper', function () { it('shows \'if\' template with prev post data & ignores in author if author isnt present', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'next_post', fn: fn, inverse: inverse, hash: {in: 'author'}}; + optionsData = {name: 'next_post', data: locals, fn: fn, inverse: inverse, hash: {in: 'author'}}; helpers.next_post .call({ @@ -333,7 +338,7 @@ describe('{{next_post}} helper', function () { it('shows \'if\' template with prev post data & ignores unknown in value', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'next_post', fn: fn, inverse: inverse, hash: {in: 'magic'}}; + optionsData = {name: 'next_post', data: locals, fn: fn, inverse: inverse, hash: {in: 'magic'}}; helpers.next_post .call({ @@ -365,7 +370,7 @@ describe('{{next_post}} helper', function () { describe('general error handling', function () { beforeEach(function () { - browsePostStub = sandbox.stub(api.posts, 'browse').callsFake(function () { + browsePostStub = sandbox.stub(api['v0.1'].posts, 'browse').callsFake(function () { return Promise.reject(new common.errors.NotFoundError({message: 'Something wasn\'t found'})); }); }); @@ -373,7 +378,7 @@ describe('{{next_post}} helper', function () { it('should handle error from the API', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'next_post', fn: fn, inverse: inverse}; + optionsData = {name: 'next_post', data: locals, fn: fn, inverse: inverse}; helpers.next_post .call({ diff --git a/core/test/unit/helpers/prev_post_spec.js b/core/test/unit/helpers/prev_post_spec.js index 0154d34fc3..365cf01b46 100644 --- a/core/test/unit/helpers/prev_post_spec.js +++ b/core/test/unit/helpers/prev_post_spec.js @@ -11,6 +11,11 @@ var should = require('should'), describe('{{prev_post}} helper', function () { var browsePostStub; + let locals; + + beforeEach(function () { + locals = {root: {_locals: {apiVersion: 'v0.1'}}}; + }); afterEach(function () { sandbox.restore(); @@ -18,7 +23,7 @@ describe('{{prev_post}} helper', function () { describe('with valid post data - ', function () { beforeEach(function () { - browsePostStub = sandbox.stub(api.posts, 'browse').callsFake(function (options) { + browsePostStub = sandbox.stub(api['v0.1'].posts, 'browse').callsFake(function (options) { if (options.filter.indexOf('published_at:<=') > -1) { return Promise.resolve({ posts: [{slug: '/previous/', title: 'post 1'}] @@ -30,7 +35,7 @@ describe('{{prev_post}} helper', function () { it('shows \'if\' template with previous post data', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'prev_post', fn: fn, inverse: inverse}; + optionsData = {name: 'prev_post', data: locals, fn: fn, inverse: inverse}; helpers.prev_post .call({ @@ -60,7 +65,7 @@ describe('{{prev_post}} helper', function () { describe('for valid post with no previous post', function () { beforeEach(function () { - browsePostStub = sandbox.stub(api.posts, 'browse').callsFake(function (options) { + browsePostStub = sandbox.stub(api['v0.1'].posts, 'browse').callsFake(function (options) { if (options.filter.indexOf('published_at:<=') > -1) { return Promise.resolve({posts: []}); } @@ -70,7 +75,7 @@ describe('{{prev_post}} helper', function () { it('shows \'else\' template', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'prev_post', fn: fn, inverse: inverse}; + optionsData = {name: 'prev_post', data: locals, fn: fn, inverse: inverse}; helpers.prev_post .call({ @@ -98,7 +103,7 @@ describe('{{prev_post}} helper', function () { describe('for invalid post data', function () { beforeEach(function () { - browsePostStub = sandbox.stub(api.posts, 'browse').callsFake(function (options) { + browsePostStub = sandbox.stub(api['v0.1'].posts, 'browse').callsFake(function (options) { if (options.filter.indexOf('published_at:<=') > -1) { return Promise.resolve({}); } @@ -108,7 +113,7 @@ describe('{{prev_post}} helper', function () { it('shows \'else\' template', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'prev_post', fn: fn, inverse: inverse}; + optionsData = {name: 'prev_post', data: locals, fn: fn, inverse: inverse}; helpers.prev_post .call({}, optionsData) @@ -125,7 +130,7 @@ describe('{{prev_post}} helper', function () { describe('for page', function () { beforeEach(function () { - browsePostStub = sandbox.stub(api.posts, 'browse').callsFake(function (options) { + browsePostStub = sandbox.stub(api['v0.1'].posts, 'browse').callsFake(function (options) { if (options.filter.indexOf('published_at:<=') > -1) { return Promise.resolve({posts: [{slug: '/previous/', title: 'post 1'}]}); } @@ -135,7 +140,7 @@ describe('{{prev_post}} helper', function () { it('shows \'else\' template', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'prev_post', fn: fn, inverse: inverse}; + optionsData = {name: 'prev_post', data: locals, fn: fn, inverse: inverse}; helpers.prev_post .call({ @@ -160,7 +165,7 @@ describe('{{prev_post}} helper', function () { describe('for unpublished post', function () { beforeEach(function () { - browsePostStub = sandbox.stub(api.posts, 'browse').callsFake(function (options) { + browsePostStub = sandbox.stub(api['v0.1'].posts, 'browse').callsFake(function (options) { if (options.filter.indexOf('published_at:<=') > -1) { return Promise.resolve({posts: [{slug: '/previous/', title: 'post 1'}]}); } @@ -170,7 +175,7 @@ describe('{{prev_post}} helper', function () { it('shows \'else\' template', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'prev_post', fn: fn, inverse: inverse}; + optionsData = {name: 'prev_post', data: locals, fn: fn, inverse: inverse}; helpers.prev_post .call({ @@ -194,7 +199,7 @@ describe('{{prev_post}} helper', function () { describe('with "in" option', function () { beforeEach(function () { - browsePostStub = sandbox.stub(api.posts, 'browse').callsFake(function (options) { + browsePostStub = sandbox.stub(api['v0.1'].posts, 'browse').callsFake(function (options) { if (options.filter.indexOf('published_at:<=') > -1) { return Promise.resolve({ posts: [{slug: '/previous/', title: 'post 1'}] @@ -206,7 +211,7 @@ describe('{{prev_post}} helper', function () { it('shows \'if\' template with prev post data with primary_tag set', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'prev_post', fn: fn, inverse: inverse, hash: {in: 'primary_tag'}}; + optionsData = {name: 'prev_post', data: locals, fn: fn, inverse: inverse, hash: {in: 'primary_tag'}}; helpers.prev_post .call({ @@ -238,7 +243,7 @@ describe('{{prev_post}} helper', function () { it('shows \'if\' template with prev post data with primary_author set', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'prev_post', fn: fn, inverse: inverse, hash: {in: 'primary_author'}}; + optionsData = {name: 'prev_post', data: locals, fn: fn, inverse: inverse, hash: {in: 'primary_author'}}; helpers.prev_post .call({ @@ -270,7 +275,7 @@ describe('{{prev_post}} helper', function () { it('shows \'if\' template with prev post data with author set', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'prev_post', fn: fn, inverse: inverse, hash: {in: 'author'}}; + optionsData = {name: 'prev_post', data: locals, fn: fn, inverse: inverse, hash: {in: 'author'}}; helpers.prev_post .call({ @@ -302,7 +307,7 @@ describe('{{prev_post}} helper', function () { it('shows \'if\' template with prev post data & ignores in author if author isnt present', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'prev_post', fn: fn, inverse: inverse, hash: {in: 'author'}}; + optionsData = {name: 'prev_post', data: locals, fn: fn, inverse: inverse, hash: {in: 'author'}}; helpers.prev_post .call({ @@ -333,7 +338,7 @@ describe('{{prev_post}} helper', function () { it('shows \'if\' template with prev post data & ignores unknown in value', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'prev_post', fn: fn, inverse: inverse, hash: {in: 'magic'}}; + optionsData = {name: 'prev_post', data: locals, fn: fn, inverse: inverse, hash: {in: 'magic'}}; helpers.prev_post .call({ @@ -365,7 +370,7 @@ describe('{{prev_post}} helper', function () { describe('general error handling', function () { beforeEach(function () { - browsePostStub = sandbox.stub(api.posts, 'browse').callsFake(function () { + browsePostStub = sandbox.stub(api['v0.1'].posts, 'browse').callsFake(function () { return Promise.reject(new common.errors.NotFoundError({message: 'Something wasn\'t found'})); }); }); @@ -373,7 +378,7 @@ describe('{{prev_post}} helper', function () { it('should handle error from the API', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'prev_post', fn: fn, inverse: inverse}; + optionsData = {name: 'prev_post', data: locals, fn: fn, inverse: inverse}; helpers.prev_post .call({ diff --git a/core/test/unit/services/routing/controllers/preview_spec.js b/core/test/unit/services/routing/controllers/preview_spec.js index 5992be3287..c79c8df29b 100644 --- a/core/test/unit/services/routing/controllers/preview_spec.js +++ b/core/test/unit/services/routing/controllers/preview_spec.js @@ -7,6 +7,7 @@ const should = require('should'), filters = require('../../../../../server/filters'), controllers = require('../../../../../server/services/routing/controllers'), helpers = require('../../../../../server/services/routing/helpers'), + themes = require('../../../../../server/services/themes'), urlService = require('../../../../../server/services/url'), sandbox = sinon.sandbox.create(), EDITOR_URL = '/editor/'; @@ -43,7 +44,9 @@ describe('Unit - services/routing/controllers/preview', function () { }; res = { - locals: {}, + locals: { + apiVersion: 'v0.1' + }, render: sinon.spy(), redirect: sinon.spy(), set: sinon.spy() diff --git a/core/test/unit/services/routing/controllers/static_spec.js b/core/test/unit/services/routing/controllers/static_spec.js index 39dd438440..ea4c03a309 100644 --- a/core/test/unit/services/routing/controllers/static_spec.js +++ b/core/test/unit/services/routing/controllers/static_spec.js @@ -42,9 +42,10 @@ describe('Unit - services/routing/controllers/static', function () { sandbox.stub(themeService, 'getActive').returns({ config: function (key) { - key.should.eql('posts_per_page'); - return postsPerPage; - } + if (key === 'posts_per_page') { + return postsPerPage; + } + } }); sandbox.stub(helpers, 'renderer').get(function () { @@ -64,7 +65,10 @@ describe('Unit - services/routing/controllers/static', function () { res = { routerOptions: {}, render: sinon.spy(), - redirect: sinon.spy() + redirect: sinon.spy(), + locals: { + apiVersion: 'v0.1' + } }; }); diff --git a/core/test/unit/services/routing/helpers/fetch-data_spec.js b/core/test/unit/services/routing/helpers/fetch-data_spec.js index f40c873b9a..8793a1480f 100644 --- a/core/test/unit/services/routing/helpers/fetch-data_spec.js +++ b/core/test/unit/services/routing/helpers/fetch-data_spec.js @@ -6,7 +6,7 @@ const should = require('should'), sandbox = sinon.sandbox.create(); describe('Unit - services/routing/helpers/fetch-data', function () { - let posts, tags, users; + let posts, tags, locals; beforeEach(function () { posts = [ @@ -34,6 +34,8 @@ describe('Unit - services/routing/helpers/fetch-data', function () { }); sandbox.stub(api.tags, 'read').resolves({tags: tags}); + + locals = {apiVersion: 'v0.1'}; }); afterEach(function () { @@ -41,7 +43,7 @@ describe('Unit - services/routing/helpers/fetch-data', function () { }); it('should handle no options', function (done) { - helpers.fetchData().then(function (result) { + helpers.fetchData(null, null, locals).then(function (result) { should.exist(result); result.should.be.an.Object().with.properties('posts', 'meta'); result.should.not.have.property('data'); @@ -56,7 +58,7 @@ describe('Unit - services/routing/helpers/fetch-data', function () { }); it('should handle path options with page/limit', function (done) { - helpers.fetchData({page: 2, limit: 10}).then(function (result) { + helpers.fetchData({page: 2, limit: 10}, null, locals).then(function (result) { should.exist(result); result.should.be.an.Object().with.properties('posts', 'meta'); result.should.not.have.property('data'); @@ -89,7 +91,7 @@ describe('Unit - services/routing/helpers/fetch-data', function () { } }; - helpers.fetchData(pathOptions, routerOptions).then(function (result) { + helpers.fetchData(pathOptions, routerOptions, locals).then(function (result) { should.exist(result); result.should.be.an.Object().with.properties('posts', 'meta', 'data'); result.data.should.be.an.Object().with.properties('featured'); @@ -123,7 +125,7 @@ describe('Unit - services/routing/helpers/fetch-data', function () { } }; - helpers.fetchData(pathOptions, routerOptions).then(function (result) { + helpers.fetchData(pathOptions, routerOptions, locals).then(function (result) { should.exist(result); result.should.be.an.Object().with.properties('posts', 'meta', 'data'); @@ -159,7 +161,7 @@ describe('Unit - services/routing/helpers/fetch-data', function () { } }; - helpers.fetchData(pathOptions, routerOptions).then(function (result) { + helpers.fetchData(pathOptions, routerOptions, locals).then(function (result) { should.exist(result); result.should.be.an.Object().with.properties('posts', 'meta', 'data'); result.data.should.be.an.Object().with.properties('tag'); diff --git a/core/test/unit/services/routing/helpers/post-lookup_spec.js b/core/test/unit/services/routing/helpers/post-lookup_spec.js index cd7e0cbe3d..aff9295987 100644 --- a/core/test/unit/services/routing/helpers/post-lookup_spec.js +++ b/core/test/unit/services/routing/helpers/post-lookup_spec.js @@ -7,7 +7,7 @@ const should = require('should'), sandbox = sinon.sandbox.create(); describe('Unit - services/routing/helpers/post-lookup', function () { - let posts; + let posts, locals; afterEach(function () { sandbox.restore(); @@ -15,6 +15,8 @@ describe('Unit - services/routing/helpers/post-lookup', function () { beforeEach(function () { sandbox.stub(api.posts, 'read'); + + locals = {apiVersion: 'v0.1'}; }); describe('Permalinks: /:slug/', function () { @@ -36,7 +38,7 @@ describe('Unit - services/routing/helpers/post-lookup', function () { it('can lookup absolute url: /:slug/', function (done) { const testUrl = 'http://127.0.0.1:2369' + posts[0].url; - helpers.postLookup(testUrl, routerOptions).then(function (lookup) { + helpers.postLookup(testUrl, routerOptions, locals).then(function (lookup) { api.posts.read.calledOnce.should.be.true(); should.exist(lookup.post); lookup.post.should.have.property('url', posts[0].url); @@ -49,7 +51,7 @@ describe('Unit - services/routing/helpers/post-lookup', function () { it('can lookup relative url: /:slug/', function (done) { const testUrl = posts[0].url; - helpers.postLookup(testUrl, routerOptions).then(function (lookup) { + helpers.postLookup(testUrl, routerOptions, locals).then(function (lookup) { api.posts.read.calledOnce.should.be.true(); should.exist(lookup.post); lookup.post.should.have.property('url', posts[0].url); @@ -62,7 +64,7 @@ describe('Unit - services/routing/helpers/post-lookup', function () { it('cannot lookup absolute url: /:year/:month/:day/:slug/', function (done) { const testUrl = 'http://127.0.0.1:2369/2016/01/01' + posts[0].url; - helpers.postLookup(testUrl, routerOptions) + helpers.postLookup(testUrl, routerOptions, locals) .then(function (lookup) { api.posts.read.calledOnce.should.be.false(); should.not.exist(lookup); @@ -74,7 +76,7 @@ describe('Unit - services/routing/helpers/post-lookup', function () { it('cannot lookup relative url: /:year/:month/:day/:slug/', function (done) { const testUrl = '/2016/01/01' + posts[0].url; - helpers.postLookup(testUrl, routerOptions) + helpers.postLookup(testUrl, routerOptions, locals) .then(function (lookup) { api.posts.read.calledOnce.should.be.false(); should.not.exist(lookup); @@ -103,7 +105,7 @@ describe('Unit - services/routing/helpers/post-lookup', function () { it('cannot lookup absolute url: /:slug/', function (done) { const testUrl = 'http://127.0.0.1:2369/' + posts[0].slug; - helpers.postLookup(testUrl, routerOptions) + helpers.postLookup(testUrl, routerOptions, locals) .then(function (lookup) { api.posts.read.calledOnce.should.be.false(); should.not.exist(lookup); @@ -115,7 +117,7 @@ describe('Unit - services/routing/helpers/post-lookup', function () { it('cannot lookup relative url using :slug', function (done) { const testUrl = posts[0].slug; - helpers.postLookup(testUrl, routerOptions) + helpers.postLookup(testUrl, routerOptions, locals) .then(function (lookup) { api.posts.read.calledOnce.should.be.false(); should.not.exist(lookup); @@ -127,7 +129,7 @@ describe('Unit - services/routing/helpers/post-lookup', function () { it('can lookup absolute url: /:year/:month/:day/:slug/', function (done) { const testUrl = 'http://127.0.0.1:2369' + posts[0].url; - helpers.postLookup(testUrl, routerOptions) + helpers.postLookup(testUrl, routerOptions, locals) .then(function (lookup) { api.posts.read.calledOnce.should.be.true(); should.exist(lookup.post); @@ -142,7 +144,7 @@ describe('Unit - services/routing/helpers/post-lookup', function () { it('can lookup relative url: /:year/:month/:day/:slug/', function (done) { const testUrl = posts[0].url; - helpers.postLookup(testUrl, routerOptions) + helpers.postLookup(testUrl, routerOptions, locals) .then(function (lookup) { api.posts.read.calledOnce.should.be.true(); should.exist(lookup.post); @@ -172,7 +174,7 @@ describe('Unit - services/routing/helpers/post-lookup', function () { it('can lookup absolute url: /:slug/edit/', function (done) { const testUrl = 'http://127.0.0.1:2369' + posts[0].url + 'edit/'; - helpers.postLookup(testUrl, routerOptions) + helpers.postLookup(testUrl, routerOptions, locals) .then(function (lookup) { api.posts.read.calledOnce.should.be.true(); lookup.post.should.have.property('url', posts[0].url); @@ -185,7 +187,7 @@ describe('Unit - services/routing/helpers/post-lookup', function () { it('can lookup relative url: /:slug/edit/', function (done) { const testUrl = posts[0].url + 'edit/'; - helpers.postLookup(testUrl, routerOptions) + helpers.postLookup(testUrl, routerOptions, locals) .then(function (lookup) { api.posts.read.calledOnce.should.be.true(); lookup.post.should.have.property('url', posts[0].url); @@ -198,7 +200,7 @@ describe('Unit - services/routing/helpers/post-lookup', function () { it('cannot lookup absolute url: /:year/:month/:day/:slug/edit/', function (done) { const testUrl = 'http://127.0.0.1:2369/2016/01/01' + posts[0].url + 'edit/'; - helpers.postLookup(testUrl, routerOptions) + helpers.postLookup(testUrl, routerOptions, locals) .then(function (lookup) { api.posts.read.calledOnce.should.be.false(); should.not.exist(lookup); @@ -210,7 +212,7 @@ describe('Unit - services/routing/helpers/post-lookup', function () { it('cannot lookup relative url: /:year/:month/:day/:slug/edit/', function (done) { const testUrl = '/2016/01/01' + posts[0].url + 'edit/'; - helpers.postLookup(testUrl, routerOptions) + helpers.postLookup(testUrl, routerOptions, locals) .then(function (lookup) { api.posts.read.calledOnce.should.be.false(); should.not.exist(lookup); @@ -222,7 +224,7 @@ describe('Unit - services/routing/helpers/post-lookup', function () { it('unknown url option', function (done) { const testUrl = posts[0].url + 'not-edit/'; - helpers.postLookup(testUrl, routerOptions) + helpers.postLookup(testUrl, routerOptions, locals) .then(function (lookup) { api.posts.read.calledOnce.should.be.false(); should.not.exist(lookup);