0
Fork 0
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:
Sebastian Gierlinger 2016-03-21 09:49:35 +01:00
commit e7fcc9e059
2 changed files with 319 additions and 185 deletions

View file

@ -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');
}
}

View file

@ -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');
});
});
});