mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-04-01 02:41:39 -05:00
Merge pull request #6612 from ErisDS/channel-contexts
Generate context from channelConfig, not URL
This commit is contained in:
commit
e7fcc9e059
2 changed files with 319 additions and 185 deletions
|
@ -14,10 +14,7 @@
|
|||
var config = require('../../config'),
|
||||
|
||||
// Context patterns, should eventually come from Channel configuration
|
||||
tagPattern = new RegExp('^\\/' + config.routeKeywords.tag + '\\/.+'),
|
||||
authorPattern = new RegExp('^\\/' + config.routeKeywords.author + '\\/.+'),
|
||||
privatePattern = new RegExp('^\\/' + config.routeKeywords.private + '\\/'),
|
||||
indexPattern = new RegExp('^\\/' + config.routeKeywords.page + '\\/'),
|
||||
rssPattern = new RegExp('^\\/rss\\/'),
|
||||
homePattern = new RegExp('^\\/$');
|
||||
|
||||
|
@ -32,27 +29,29 @@ function setResponseContext(req, res, data) {
|
|||
return;
|
||||
}
|
||||
|
||||
// paged context
|
||||
// Paged context - special rule
|
||||
if (!isNaN(pageParam) && pageParam > 1) {
|
||||
res.locals.context.push('paged');
|
||||
}
|
||||
|
||||
if (indexPattern.test(res.locals.relativeUrl)) {
|
||||
res.locals.context.push('index');
|
||||
} else if (homePattern.test(res.locals.relativeUrl)) {
|
||||
// Home context - special rule
|
||||
if (homePattern.test(res.locals.relativeUrl)) {
|
||||
res.locals.context.push('home');
|
||||
res.locals.context.push('index');
|
||||
} else if (rssPattern.test(res.locals.relativeUrl)) {
|
||||
}
|
||||
|
||||
// This is not currently used, as setRequestContext is not called for RSS feeds
|
||||
if (rssPattern.test(res.locals.relativeUrl)) {
|
||||
res.locals.context.push('rss');
|
||||
}
|
||||
|
||||
// Each page can only have at most one of these
|
||||
if (req.channelConfig) {
|
||||
res.locals.context.push(req.channelConfig.name);
|
||||
} else if (privatePattern.test(res.locals.relativeUrl)) {
|
||||
res.locals.context.push('private');
|
||||
} else if (tagPattern.test(res.locals.relativeUrl)) {
|
||||
res.locals.context.push('tag');
|
||||
} else if (authorPattern.test(res.locals.relativeUrl)) {
|
||||
res.locals.context.push('author');
|
||||
} else if (data && data.post && data.post.page) {
|
||||
res.locals.context.push('page');
|
||||
} else {
|
||||
} else if (data && data.post) {
|
||||
res.locals.context.push('post');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
/*globals describe, beforeEach, it*/
|
||||
var should = require('should'),
|
||||
_ = require('lodash'),
|
||||
|
||||
// Stuff we are testing
|
||||
channelConfig = require('../../../../server/controllers/frontend/channel-config'),
|
||||
setResponseContext = require('../../../../server/controllers/frontend/context');
|
||||
|
||||
describe('Contexts', function () {
|
||||
var req, res, data;
|
||||
var req, res, data, setupContext;
|
||||
|
||||
beforeEach(function () {
|
||||
req = {
|
||||
|
@ -17,105 +19,372 @@ describe('Contexts', function () {
|
|||
data = {};
|
||||
});
|
||||
|
||||
/**
|
||||
* A context is created based on the URL, and the channel config if we're rendering
|
||||
* any part of a channel
|
||||
* @param {String} url
|
||||
* @param {String|Object|Integer} [channel]
|
||||
* @param {Integer} [pageParam]
|
||||
*/
|
||||
setupContext = function setupContext(url, channel, pageParam) {
|
||||
res.locals.relativeUrl = url;
|
||||
|
||||
if (channel && _.isString(channel)) {
|
||||
req.channelConfig = channelConfig.get(channel);
|
||||
} else if (channel && _.isNumber(channel)) {
|
||||
pageParam = channel;
|
||||
} else if (channel) {
|
||||
req.channelConfig = channel;
|
||||
}
|
||||
|
||||
if (pageParam) {
|
||||
req.params.page = pageParam;
|
||||
}
|
||||
};
|
||||
|
||||
describe('Unknown', function () {
|
||||
it('should return empty array with no error if all parameters are empty', function () {
|
||||
// Reset all parameters to empty;
|
||||
req = {};
|
||||
res = {};
|
||||
data = {};
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(0);
|
||||
});
|
||||
|
||||
it('should return empty array with no error with basic parameters', function () {
|
||||
// Setup test
|
||||
// BeforeEach sets each of these to the bare minimum that should be provided for determining context
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Index', function () {
|
||||
it('should correctly identify `/` as index', function () {
|
||||
// Setup test by setting relativeUrl
|
||||
res.locals.relativeUrl = '/';
|
||||
describe('Channels', function () {
|
||||
describe('Index', function () {
|
||||
it('should correctly identify index channel', function () {
|
||||
// Setup test
|
||||
setupContext('/does/not/matter/', 'index');
|
||||
|
||||
setResponseContext(req, res, data);
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(2);
|
||||
res.locals.context[0].should.eql('home');
|
||||
res.locals.context[1].should.eql('index');
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('index');
|
||||
});
|
||||
|
||||
it('should correctly identify / as home', function () {
|
||||
// Setup test
|
||||
setupContext('/', 'index');
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(2);
|
||||
res.locals.context[0].should.eql('home');
|
||||
res.locals.context[1].should.eql('index');
|
||||
});
|
||||
|
||||
it('will not identify / as index without config', function () {
|
||||
// Setup test
|
||||
setupContext('/');
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('home');
|
||||
});
|
||||
|
||||
it('will not identify /page/2/ as index & paged without page param', function () {
|
||||
// Setup test
|
||||
setupContext('/page/2/', 'index');
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('index');
|
||||
});
|
||||
|
||||
it('should identify /page/2/ as index & paged with page param', function () {
|
||||
// Setup test
|
||||
setupContext('/page/2/', 'index', 2);
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(2);
|
||||
res.locals.context[0].should.eql('paged');
|
||||
res.locals.context[1].should.eql('index');
|
||||
});
|
||||
});
|
||||
|
||||
it('should correctly identify `/` as home & index', function () {
|
||||
// Setup test by setting relativeUrl
|
||||
res.locals.relativeUrl = '/';
|
||||
describe('Tag', function () {
|
||||
it('should correctly identify tag channel', function () {
|
||||
// Setup test
|
||||
setupContext('/tag/getting-started/', 'tag');
|
||||
|
||||
setResponseContext(req, res, data);
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(2);
|
||||
res.locals.context[0].should.eql('home');
|
||||
res.locals.context[1].should.eql('index');
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('tag');
|
||||
});
|
||||
|
||||
it('will not identify tag channel url without config', function () {
|
||||
// Setup test
|
||||
setupContext('/tag/getting-started/');
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(0);
|
||||
});
|
||||
|
||||
it('will not identify /page/2/ as paged without page param', function () {
|
||||
// Setup test
|
||||
setupContext('/tag/getting-started/page/2/', 'tag');
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('tag');
|
||||
});
|
||||
|
||||
it('should correctly identify /page/2/ as paged with page param', function () {
|
||||
// Setup test
|
||||
setupContext('/tag/getting-started/page/2/', 'tag', 2);
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(2);
|
||||
res.locals.context[0].should.eql('paged');
|
||||
res.locals.context[1].should.eql('tag');
|
||||
});
|
||||
});
|
||||
|
||||
it('will not identify `/page/2/` as index & paged without page param', function () {
|
||||
// Setup test by setting relativeUrl
|
||||
res.locals.relativeUrl = '/page/2/';
|
||||
describe('Author', function () {
|
||||
it('should correctly identify author channel', function () {
|
||||
// Setup test
|
||||
setupContext('/author/pat/', 'author');
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('author');
|
||||
});
|
||||
|
||||
it('will not identify author channel url without config', function () {
|
||||
// Setup test
|
||||
setupContext('/author/pat/');
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(0);
|
||||
});
|
||||
|
||||
it('will not identify /page/2/ as paged without page param', function () {
|
||||
// Setup test
|
||||
setupContext('/author/pat/page/2/', 'author');
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('author');
|
||||
});
|
||||
|
||||
it('should correctly identify /page/2/ as paged with page param', function () {
|
||||
// Setup test
|
||||
setupContext('/author/pat/page/2/', 'author', 2);
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(2);
|
||||
res.locals.context[0].should.eql('paged');
|
||||
res.locals.context[1].should.eql('author');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Custom', function () {
|
||||
var featuredChannel = {
|
||||
name: 'featured'
|
||||
};
|
||||
|
||||
it('will use the channel name for a custom channel', function () {
|
||||
// Setup test
|
||||
setupContext('/featured/', featuredChannel);
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('featured');
|
||||
});
|
||||
|
||||
it('will not identify /page/2/ as paged without page param', function () {
|
||||
// Setup test
|
||||
setupContext('/featured/page/2/', featuredChannel);
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('featured');
|
||||
});
|
||||
|
||||
it('should correctly identify /page/2/ as paged with page param', function () {
|
||||
// Setup test
|
||||
setupContext('/featured/page/2/', featuredChannel, 2);
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(2);
|
||||
res.locals.context[0].should.eql('paged');
|
||||
res.locals.context[1].should.eql('featured');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Posts & Pages', function () {
|
||||
it('should correctly identify a post', function () {
|
||||
// Setup test
|
||||
setupContext('/welcome-to-ghost/');
|
||||
data.post = {};
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('index');
|
||||
res.locals.context[0].should.eql('post');
|
||||
});
|
||||
|
||||
it('should identify `/page/2/` as index & paged with page param', function () {
|
||||
// Setup test by setting relativeUrl
|
||||
res.locals.relativeUrl = '/page/2/';
|
||||
req.params.page = 2;
|
||||
it('will not identify a post without data being set', function () {
|
||||
// Setup test
|
||||
setupContext('/welcome-to-ghost/');
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(2);
|
||||
res.locals.context[0].should.eql('paged');
|
||||
res.locals.context[1].should.eql('index');
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(0);
|
||||
});
|
||||
|
||||
it('should correctly identify a page', function () {
|
||||
// Setup test
|
||||
setupContext('/about/');
|
||||
data.post = {page: true};
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('page');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Private', function () {
|
||||
it('should correctly identify /private/ as the private route', function () {
|
||||
// Setup test
|
||||
setupContext('/private/?r=');
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('private');
|
||||
});
|
||||
});
|
||||
|
||||
describe('RSS', function () {
|
||||
it('should correctly identify `/rss/` as rss', function () {
|
||||
// Setup test by setting relativeUrl
|
||||
res.locals.relativeUrl = '/rss/';
|
||||
// NOTE: this works, but is never used in reality, as setResponseContext isn't called
|
||||
// for RSS feeds at the moment.
|
||||
it('should correctly identify /rss/ as rss', function () {
|
||||
// Setup test
|
||||
setupContext('/rss/');
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('rss');
|
||||
});
|
||||
|
||||
it('will not identify `/rss/2/` as rss & paged without page param', function () {
|
||||
it('will not identify /rss/2/ as rss & paged without page param', function () {
|
||||
// Setup test by setting relativeUrl
|
||||
res.locals.relativeUrl = '/rss/2/';
|
||||
setupContext('/rss/2/');
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
// Check context
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('rss');
|
||||
});
|
||||
|
||||
it('should correctly identify `/rss/2/` as rss & paged with page param', function () {
|
||||
it('should correctly identify /rss/2/ as rss & paged with page param', function () {
|
||||
// Setup test by setting relativeUrl
|
||||
res.locals.relativeUrl = '/rss/2/';
|
||||
req.params.page = 2;
|
||||
setupContext('/rss/2/', 2);
|
||||
|
||||
// Execute test
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
should.exist(res.locals.context);
|
||||
|
@ -124,138 +393,4 @@ describe('Contexts', function () {
|
|||
res.locals.context[1].should.eql('rss');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Tag', function () {
|
||||
it('should correctly identify `/tag/getting-started/` as tag', function () {
|
||||
// Setup test by setting relativeUrl
|
||||
res.locals.relativeUrl = '/tag/getting-started/';
|
||||
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('tag');
|
||||
});
|
||||
|
||||
it('should not identify just `/tag/` as being the tag context', function () {
|
||||
// Setup test by setting relativeUrl
|
||||
res.locals.relativeUrl = '/tag/';
|
||||
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('post');
|
||||
});
|
||||
|
||||
it('will not identify `/tag/getting-started/page/2/ as paged without page param', function () {
|
||||
// Setup test by setting relativeUrl
|
||||
res.locals.relativeUrl = '/tag/getting-started/page/2/';
|
||||
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('tag');
|
||||
});
|
||||
|
||||
it('should correctly identify `/tag/getting-started/page/2/ as paged with page param', function () {
|
||||
// Setup test by setting relativeUrl
|
||||
res.locals.relativeUrl = '/tag/getting-started/page/2/';
|
||||
req.params.page = 2;
|
||||
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(2);
|
||||
res.locals.context[0].should.eql('paged');
|
||||
res.locals.context[1].should.eql('tag');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Author', function () {
|
||||
it('should correctly identify `/author/pat/` as author', function () {
|
||||
// Setup test by setting relativeUrl
|
||||
res.locals.relativeUrl = '/author/pat/';
|
||||
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('author');
|
||||
});
|
||||
|
||||
it('should not identify just `/author/` as being the author context', function () {
|
||||
// Setup test by setting relativeUrl
|
||||
res.locals.relativeUrl = '/author/';
|
||||
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('post');
|
||||
});
|
||||
|
||||
it('will not identify `/author/pat/page/2/ as paged without page param', function () {
|
||||
// Setup test by setting relativeUrl
|
||||
res.locals.relativeUrl = '/author/pat/page/2/';
|
||||
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('author');
|
||||
});
|
||||
|
||||
it('should correctly identify `/author/pat/page/2/ as paged with page param', function () {
|
||||
// Setup test by setting relativeUrl
|
||||
res.locals.relativeUrl = '/author/pat/page/2/';
|
||||
req.params.page = 2;
|
||||
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(2);
|
||||
res.locals.context[0].should.eql('paged');
|
||||
res.locals.context[1].should.eql('author');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Posts & Pages', function () {
|
||||
it('should correctly identify a post', function () {
|
||||
// Setup test by setting relativeUrl
|
||||
res.locals.relativeUrl = '/welcome-to-ghost/';
|
||||
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('post');
|
||||
});
|
||||
|
||||
it('should correctly idenfity a page', function () {
|
||||
// Setup test by setting relativeUrl
|
||||
res.locals.relativeUrl = '/about/';
|
||||
data.post = {page: true};
|
||||
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('page');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Private', function () {
|
||||
it('should correctly identify `/private/` as the private route', function () {
|
||||
// Setup test by setting relativeUrl
|
||||
res.locals.relativeUrl = '/private/?r=';
|
||||
|
||||
setResponseContext(req, res, data);
|
||||
|
||||
should.exist(res.locals.context);
|
||||
res.locals.context.should.be.an.Array().with.lengthOf(1);
|
||||
res.locals.context[0].should.eql('private');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue