mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-20 22:42:53 -05:00
Adds support for additional permalink structures
fixes #2057 - uses express’ Route object to create RegExp’s that we use to check the incoming path - refactored structure of fronted controller single tests to be easier to read - amend regex to incorporate new allowed permalink structure
This commit is contained in:
parent
d28d65bf5e
commit
b066e732dd
4 changed files with 471 additions and 281 deletions
|
@ -9,13 +9,17 @@ var moment = require('moment'),
|
|||
_ = require('lodash'),
|
||||
url = require('url'),
|
||||
when = require('when'),
|
||||
Route = require('express').Route,
|
||||
|
||||
api = require('../api'),
|
||||
config = require('../config'),
|
||||
errors = require('../errorHandling'),
|
||||
filters = require('../../server/filters'),
|
||||
|
||||
frontendControllers;
|
||||
frontendControllers,
|
||||
// Cache static post permalink regex
|
||||
staticPostPermalink = new Route(null, '/:slug/:edit?');
|
||||
|
||||
|
||||
frontendControllers = {
|
||||
'homepage': function (req, res, next) {
|
||||
|
@ -65,22 +69,52 @@ frontendControllers = {
|
|||
});
|
||||
},
|
||||
'single': function (req, res, next) {
|
||||
// From route check if a date was parsed
|
||||
// from the regex
|
||||
var dateInSlug = req.params[0] ? true : false;
|
||||
when.join(
|
||||
api.settings.read('permalinks'),
|
||||
api.posts.read({slug: req.params[1]})
|
||||
).then(function (promises) {
|
||||
var permalink = promises[0].value,
|
||||
post = promises[1];
|
||||
var path = req.path,
|
||||
params,
|
||||
editFormat,
|
||||
usingStaticPermalink = false;
|
||||
|
||||
api.settings.read('permalinks').then(function (permalink) {
|
||||
editFormat = permalink.value[permalink.value.length - 1] === '/' ? ':edit?' : '/:edit?';
|
||||
|
||||
// Convert saved permalink into an express Route object
|
||||
permalink = new Route(null, permalink.value + editFormat);
|
||||
|
||||
// Check if the path matches the permalink structure.
|
||||
//
|
||||
// If there are no matches found we then
|
||||
// need to verify it's not a static post,
|
||||
// and test against that permalink structure.
|
||||
if (permalink.match(path) === false) {
|
||||
// If there are still no matches then return.
|
||||
if (staticPostPermalink.match(path) === false) {
|
||||
// Throw specific error
|
||||
// to break out of the promise chain.
|
||||
throw new Error('no match');
|
||||
}
|
||||
|
||||
permalink = staticPostPermalink;
|
||||
usingStaticPermalink = true;
|
||||
}
|
||||
|
||||
params = permalink.params;
|
||||
|
||||
// Sanitize params we're going to use to lookup the post.
|
||||
var postLookup = _.pick(permalink.params, 'slug', 'id');
|
||||
|
||||
// Query database to find post
|
||||
return api.posts.read(postLookup);
|
||||
}).then(function (post) {
|
||||
|
||||
if (!post) {
|
||||
return next();
|
||||
}
|
||||
|
||||
function render() {
|
||||
// If we're ready to render the page but the last param is 'edit' then we'll send you to the edit page.
|
||||
if (req.params[2] && req.params[2] === 'edit') {
|
||||
if (params.edit !== undefined) {
|
||||
return res.redirect(config().paths.subdir + '/ghost/editor/' + post.id + '/');
|
||||
}
|
||||
|
||||
filters.doFilter('prePostsRender', post).then(function (post) {
|
||||
api.settings.read('activeTheme').then(function (activeTheme) {
|
||||
var paths = config().paths.availableThemes[activeTheme.value],
|
||||
|
@ -90,34 +124,59 @@ frontendControllers = {
|
|||
});
|
||||
}
|
||||
|
||||
if (!post) {
|
||||
return next();
|
||||
}
|
||||
|
||||
// Check that the date in the URL matches the published date of the post, else 404
|
||||
if (dateInSlug && req.params[0] !== moment(post.published_at).format('YYYY/MM/DD/')) {
|
||||
return next();
|
||||
}
|
||||
|
||||
// A page can only be rendered when there is no date in the url.
|
||||
// A post can either be rendered with a date in the url depending on the permalink setting.
|
||||
// For all other conditions return 404.
|
||||
if (post.page === 1 && dateInSlug === false) {
|
||||
return render();
|
||||
}
|
||||
|
||||
if (post.page === 0) {
|
||||
// Handle post rendering
|
||||
if ((permalink === '/:slug/' && dateInSlug === false) ||
|
||||
(permalink !== '/:slug/' && dateInSlug === true)) {
|
||||
// If we've checked the path with the static permalink structure
|
||||
// then the post must be a static post.
|
||||
// If it is not then we must return.
|
||||
if (usingStaticPermalink) {
|
||||
if (post.page === 1) {
|
||||
return render();
|
||||
}
|
||||
|
||||
return next();
|
||||
}
|
||||
|
||||
next();
|
||||
// If there is any date based paramter in the slug
|
||||
// we will check it against the post published date
|
||||
// to verify it's correct.
|
||||
if (params.year || params.month || params.day) {
|
||||
var slugDate = [],
|
||||
slugFormat = [];
|
||||
|
||||
if (params.year) {
|
||||
slugDate.push(params.year);
|
||||
slugFormat.push('YYYY');
|
||||
}
|
||||
|
||||
if (params.month) {
|
||||
slugDate.push(params.month);
|
||||
slugFormat.push('MM');
|
||||
}
|
||||
|
||||
if (params.day) {
|
||||
slugDate.push(params.day);
|
||||
slugFormat.push('DD');
|
||||
}
|
||||
|
||||
slugDate = slugDate.join('/');
|
||||
slugFormat = slugFormat.join('/');
|
||||
|
||||
if (slugDate === moment(post.published_at).format(slugFormat)) {
|
||||
return render();
|
||||
}
|
||||
|
||||
return next();
|
||||
}
|
||||
|
||||
render();
|
||||
|
||||
}).otherwise(function (err) {
|
||||
// If we've thrown an error message
|
||||
// of 'no match' then we found
|
||||
// no path match.
|
||||
if (err.message === 'no match') {
|
||||
return next();
|
||||
}
|
||||
|
||||
var e = new Error(err.message);
|
||||
e.status = err.errorCode;
|
||||
return next(e);
|
||||
|
|
|
@ -57,8 +57,8 @@
|
|||
"permalinks": {
|
||||
"defaultValue": "/:slug/",
|
||||
"validations": {
|
||||
"is": "^(/:?[a-z]+){1,}/$",
|
||||
"regex": "(:id|:slug)",
|
||||
"is": "^(\/:?[a-z0-9_-]+){1,5}\/$",
|
||||
"regex": "(:id|:slug|:year|:month|:day)",
|
||||
"notContains": "/ghost/"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,14 +7,6 @@ module.exports = function (server) {
|
|||
server.get('/rss/', frontend.rss);
|
||||
server.get('/rss/:page/', frontend.rss);
|
||||
server.get('/page/:page/', frontend.homepage);
|
||||
// Only capture the :slug part of the URL
|
||||
// This regex will always have two capturing groups,
|
||||
// one for date, and one for the slug.
|
||||
// Examples:
|
||||
// Given `/plain-slug/` the req.params would be [undefined, 'plain-slug']
|
||||
// Given `/2012/12/24/plain-slug/` the req.params would be ['2012/12/24/', 'plain-slug']
|
||||
// Given `/plain-slug/edit/` the req.params would be [undefined, 'plain-slug', 'edit']
|
||||
server.get(/^\/([0-9]{4}\/[0-9]{2}\/[0-9]{2}\/)?([^\/.]*)\/$/, frontend.single);
|
||||
server.get(/^\/([0-9]{4}\/[0-9]{2}\/[0-9]{2}\/)?([^\/.]*)\/edit\/$/, frontend.edit);
|
||||
server.get('/', frontend.homepage);
|
||||
server.get('*', frontend.single);
|
||||
};
|
|
@ -161,11 +161,25 @@ describe('Frontend Controller', function () {
|
|||
'markdown': 'The test normal post content',
|
||||
'page': 0,
|
||||
'published_at': new Date('2014/1/2').getTime()
|
||||
},
|
||||
// Helper function to prevent unit tests
|
||||
// from failing via timeout when they
|
||||
// should just immediately fail
|
||||
failTest = function(done, msg) {
|
||||
return function() {
|
||||
done(new Error(msg));
|
||||
};
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
sandbox.stub(api.posts, 'read', function (args) {
|
||||
return when(args.slug === mockStaticPost.slug ? mockStaticPost : mockPost);
|
||||
if (args.slug) {
|
||||
return when(args.slug === mockStaticPost.slug ? mockStaticPost : mockPost);
|
||||
} else if (args.id) {
|
||||
return when(args.id === mockStaticPost.id ? mockStaticPost : mockPost);
|
||||
} else {
|
||||
return when({});
|
||||
}
|
||||
});
|
||||
|
||||
apiSettingsStub = sandbox.stub(api.settings, 'read');
|
||||
|
@ -191,282 +205,407 @@ describe('Frontend Controller', function () {
|
|||
}));
|
||||
});
|
||||
|
||||
describe('permalink set to slug', function () {
|
||||
beforeEach(function () {
|
||||
apiSettingsStub.withArgs('permalinks').returns(when({
|
||||
value: '/:slug/'
|
||||
}));
|
||||
});
|
||||
describe('static pages', function () {
|
||||
|
||||
it('can render a static page', function (done) {
|
||||
var req = {
|
||||
params: [undefined, mockStaticPost.slug]
|
||||
},
|
||||
res = {
|
||||
render: function (view, context) {
|
||||
assert.equal(view, 'page');
|
||||
assert.equal(context.post, mockStaticPost);
|
||||
done();
|
||||
}
|
||||
};
|
||||
describe('permalink set to slug', function () {
|
||||
beforeEach(function () {
|
||||
apiSettingsStub.withArgs('permalinks').returns(when({
|
||||
value: '/:slug/'
|
||||
}));
|
||||
});
|
||||
|
||||
frontend.single(req, res, null);
|
||||
});
|
||||
it('will render static page via /:slug', function (done) {
|
||||
var req = {
|
||||
path: '/' + mockStaticPost.slug
|
||||
},
|
||||
res = {
|
||||
render: function (view, context) {
|
||||
assert.equal(view, 'page');
|
||||
assert.equal(context.post, mockStaticPost);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
it('will NOT render a static page accessed as a date url', function (done) {
|
||||
var req = {
|
||||
params: ['2012/12/30/', mockStaticPost.slug]
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy()
|
||||
};
|
||||
frontend.single(req, res, failTest(done));
|
||||
});
|
||||
|
||||
frontend.single(req, res, function () {
|
||||
res.render.called.should.be.false;
|
||||
done();
|
||||
it('will NOT render static page via /YYY/MM/DD/:slug', function (done) {
|
||||
var req = {
|
||||
path: '/' + ['2012/12/30', mockStaticPost.slug].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy()
|
||||
};
|
||||
|
||||
frontend.single(req, res, function () {
|
||||
res.render.called.should.be.false;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('will redirect static page to admin edit page via /:slug/edit', function (done) {
|
||||
var req = {
|
||||
path: '/' + [mockStaticPost.slug, 'edit'].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: function(arg) {
|
||||
res.render.called.should.be.false;
|
||||
arg.should.eql(adminEditPagePath + mockStaticPost.id + '/');
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
frontend.single(req, res, failTest(done));
|
||||
});
|
||||
|
||||
it('will NOT redirect static page to admin edit page via /YYYY/MM/DD/:slug/edit', function (done) {
|
||||
var req = {
|
||||
path: '/' + ['2012/12/30', mockStaticPost.slug, 'edit'].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: sinon.spy()
|
||||
};
|
||||
|
||||
frontend.single(req, res, function () {
|
||||
res.render.called.should.be.false;
|
||||
res.redirect.called.should.be.false;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('can render a normal post', function (done) {
|
||||
var req = {
|
||||
params: [undefined, mockPost.slug]
|
||||
},
|
||||
res = {
|
||||
render: function (view, context) {
|
||||
assert.equal(view, 'post');
|
||||
assert(context.post, 'Context object has post attribute');
|
||||
assert.equal(context.post, mockPost);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
frontend.single(req, res, null);
|
||||
});
|
||||
|
||||
it('will NOT render a normal post accessed as a date url', function (done) {
|
||||
var req = {
|
||||
params: ['2012/12/30/', mockPost.slug]
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy()
|
||||
};
|
||||
|
||||
frontend.single(req, res, function () {
|
||||
res.render.called.should.be.false;
|
||||
done();
|
||||
describe('permalink set to date', function () {
|
||||
beforeEach(function () {
|
||||
apiSettingsStub.withArgs('permalinks').returns(when({
|
||||
value: '/:year/:month/:day/:slug/'
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
// Handle Edit append
|
||||
it('will redirect to admin edit page for a normal post', function (done) {
|
||||
var req = {
|
||||
params: [undefined, mockPost.slug, 'edit']
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: function(arg) {
|
||||
res.render.called.should.be.false;
|
||||
arg.should.eql(adminEditPagePath + mockPost.id + '/');
|
||||
done();
|
||||
}
|
||||
};
|
||||
it('will render static page via /:slug', function (done) {
|
||||
var req = {
|
||||
path: '/' + mockStaticPost.slug
|
||||
},
|
||||
res = {
|
||||
render: function (view, context) {
|
||||
assert.equal(view, 'page');
|
||||
assert.equal(context.post, mockStaticPost);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
frontend.single(req, res, null);
|
||||
});
|
||||
|
||||
it('will NOT redirect to admin edit page for a normal post accessed as a date url', function (done) {
|
||||
var req = {
|
||||
params: ['2012/12/30/', mockPost.slug, 'edit']
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: sinon.spy()
|
||||
};
|
||||
|
||||
frontend.single(req, res, function () {
|
||||
res.render.called.should.be.false;
|
||||
res.redirect.called.should.be.false;
|
||||
done();
|
||||
frontend.single(req, res, failTest(done));
|
||||
});
|
||||
});
|
||||
|
||||
it('will redirect to admin edit page for a static page accessed as a slug', function (done) {
|
||||
var req = {
|
||||
params: [undefined, mockStaticPost.slug, 'edit']
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: function(arg) {
|
||||
res.render.called.should.be.false;
|
||||
arg.should.eql(adminEditPagePath + mockStaticPost.id + '/');
|
||||
done();
|
||||
}
|
||||
};
|
||||
it('will NOT render static page via /YYYY/MM/DD/:slug', function (done) {
|
||||
var req = {
|
||||
path: '/' + ['2012/12/30', mockStaticPost.slug].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy()
|
||||
};
|
||||
|
||||
frontend.single(req, res, null);
|
||||
});
|
||||
frontend.single(req, res, function () {
|
||||
res.render.called.should.be.false;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('will NOT redirect to admin edit page for a static page accessed as a date url', function (done) {
|
||||
var req = {
|
||||
params: ['2012/12/30/', mockStaticPost.slug, 'edit']
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: sinon.spy()
|
||||
};
|
||||
it('will redirect static page to admin edit page via /:slug/edit', function (done) {
|
||||
var req = {
|
||||
path: '/' + [mockStaticPost.slug, 'edit'].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: function (arg) {
|
||||
res.render.called.should.be.false;
|
||||
arg.should.eql(adminEditPagePath + mockStaticPost.id + '/');
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
frontend.single(req, res, function () {
|
||||
res.render.called.should.be.false;
|
||||
res.redirect.called.should.be.false;
|
||||
done();
|
||||
frontend.single(req, res, failTest(done));
|
||||
});
|
||||
|
||||
it('will NOT redirect static page to admin edit page via /YYYY/MM/DD/:slug/edit', function (done) {
|
||||
var req = {
|
||||
path: '/' + ['2012/12/30', mockStaticPost.slug, 'edit'].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: sinon.spy()
|
||||
};
|
||||
|
||||
frontend.single(req, res, function () {
|
||||
res.render.called.should.be.false;
|
||||
res.redirect.called.should.be.false;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('permalink set to date', function () {
|
||||
beforeEach(function () {
|
||||
apiSettingsStub.withArgs('permalinks').returns(when({
|
||||
value: '/:year/:month/:day/:slug/'
|
||||
}));
|
||||
});
|
||||
describe('post', function () {
|
||||
describe('permalink set to slug', function () {
|
||||
beforeEach(function () {
|
||||
apiSettingsStub.withArgs('permalinks').returns(when({
|
||||
value: '/:slug'
|
||||
}));
|
||||
});
|
||||
|
||||
it('can render a static page', function (done) {
|
||||
var req = {
|
||||
params: [undefined, mockStaticPost.slug]
|
||||
},
|
||||
res = {
|
||||
render: function (view, context) {
|
||||
assert.equal(view, 'page');
|
||||
assert.equal(context.post, mockStaticPost);
|
||||
done();
|
||||
}
|
||||
};
|
||||
it('will render post via /:slug', function (done) {
|
||||
var req = {
|
||||
path: '/' + mockPost.slug
|
||||
},
|
||||
res = {
|
||||
render: function (view, context) {
|
||||
assert.equal(view, 'post');
|
||||
assert(context.post, 'Context object has post attribute');
|
||||
assert.equal(context.post, mockPost);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
frontend.single(req, res, null);
|
||||
});
|
||||
frontend.single(req, res, failTest(done));
|
||||
});
|
||||
|
||||
it('will NOT render a static page accessed as a date url', function (done) {
|
||||
var req = {
|
||||
params: ['2012/12/30/', 'test-static-page']
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy()
|
||||
};
|
||||
it('will NOT render post via /YYYY/MM/DD/:slug', function (done) {
|
||||
var req = {
|
||||
path: '/' + ['2012/12/30', mockPost.slug].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy()
|
||||
};
|
||||
|
||||
frontend.single(req, res, function () {
|
||||
res.render.called.should.be.false;
|
||||
done();
|
||||
frontend.single(req, res, function () {
|
||||
res.render.called.should.be.false;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
// Handle Edit append
|
||||
it('will redirect post to admin edit page via /:slug/edit', function (done) {
|
||||
var req = {
|
||||
path: '/' + [mockPost.slug, 'edit'].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: function(arg) {
|
||||
res.render.called.should.be.false;
|
||||
arg.should.eql(adminEditPagePath + mockPost.id + '/');
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
frontend.single(req, res, failTest(done));
|
||||
});
|
||||
|
||||
it('will NOT redirect post to admin edit page via /YYYY/MM/DD/:slug/edit', function (done) {
|
||||
var req = {
|
||||
path: '/' + ['2012/12/30', mockPost.slug, 'edit'].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: sinon.spy()
|
||||
};
|
||||
|
||||
frontend.single(req, res, function () {
|
||||
res.render.called.should.be.false;
|
||||
res.redirect.called.should.be.false;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('can render a normal post', function (done) {
|
||||
var date = moment(mockPost.published_at).format('YYYY/MM/DD/'),
|
||||
req = {
|
||||
params: [date, mockPost.slug]
|
||||
},
|
||||
res = {
|
||||
render: function (view, context) {
|
||||
assert.equal(view, 'post');
|
||||
assert(context.post, 'Context object has post attribute');
|
||||
assert.equal(context.post, mockPost);
|
||||
done();
|
||||
}
|
||||
};
|
||||
describe('permalink set to date', function () {
|
||||
beforeEach(function () {
|
||||
apiSettingsStub.withArgs('permalinks').returns(when({
|
||||
value: '/:year/:month/:day/:slug'
|
||||
}));
|
||||
});
|
||||
|
||||
frontend.single(req, res, null);
|
||||
});
|
||||
it('will render post via /YYYY/MM/DD/:slug', function (done) {
|
||||
var date = moment(mockPost.published_at).format('YYYY/MM/DD'),
|
||||
req = {
|
||||
path: '/' + [date, mockPost.slug].join('/')
|
||||
},
|
||||
res = {
|
||||
render: function (view, context) {
|
||||
assert.equal(view, 'post');
|
||||
assert(context.post, 'Context object has post attribute');
|
||||
assert.equal(context.post, mockPost);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
it('will NOT render a normal post with the wrong date', function (done) {
|
||||
var date = moment(mockPost.published_at).subtract('days', 1).format('YYYY/MM/DD/'),
|
||||
req = {
|
||||
params: [date, mockPost.slug]
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy()
|
||||
};
|
||||
frontend.single(req, res, failTest(done));
|
||||
});
|
||||
|
||||
frontend.single(req, res, function () {
|
||||
res.render.called.should.be.false;
|
||||
done();
|
||||
it('will NOT render post via /YYYY/MM/DD/:slug with non-matching date in url', function (done) {
|
||||
var date = moment(mockPost.published_at).subtract('days', 1).format('YYYY/MM/DD'),
|
||||
req = {
|
||||
path: '/' + [date, mockPost.slug].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy()
|
||||
};
|
||||
|
||||
frontend.single(req, res, function () {
|
||||
res.render.called.should.be.false;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('will NOT render post via /:slug', function (done) {
|
||||
var req = {
|
||||
path: '/' + mockPost.slug
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy()
|
||||
};
|
||||
|
||||
frontend.single(req, res, function () {
|
||||
res.render.called.should.be.false;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
// Handle Edit append
|
||||
it('will redirect post to admin edit page via /YYYY/MM/DD/:slug/edit', function (done) {
|
||||
var dateFormat = moment(mockPost.published_at).format('YYYY/MM/DD'),
|
||||
req = {
|
||||
path: '/' + [dateFormat, mockPost.slug, 'edit'].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: function (arg) {
|
||||
res.render.called.should.be.false;
|
||||
arg.should.eql(adminEditPagePath + mockPost.id + '/');
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
frontend.single(req, res, failTest(done));
|
||||
});
|
||||
|
||||
it('will NOT redirect post to admin edit page via /:slug/edit', function (done) {
|
||||
var req = {
|
||||
path: '/' + [mockPost.slug, 'edit'].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: sinon.spy()
|
||||
};
|
||||
|
||||
frontend.single(req, res, function () {
|
||||
res.render.called.should.be.false;
|
||||
res.redirect.called.should.be.false;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('will NOT render a normal post accessed as a slug url', function (done) {
|
||||
var req = {
|
||||
params: [undefined, mockPost.slug]
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy()
|
||||
};
|
||||
|
||||
frontend.single(req, res, function () {
|
||||
res.render.called.should.be.false;
|
||||
done();
|
||||
describe('permalink set to custom format', function () {
|
||||
beforeEach(function () {
|
||||
apiSettingsStub.withArgs('permalinks').returns(when({
|
||||
value: '/:year/:slug'
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
// Handle Edit append
|
||||
it('will redirect to admin edit page for a normal post', function (done) {
|
||||
var req = {
|
||||
params: [moment(mockPost.published_at).format('YYYY/MM/DD/'), mockPost.slug, 'edit']
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: function (arg) {
|
||||
res.render.called.should.be.false;
|
||||
arg.should.eql(adminEditPagePath + mockPost.id + '/');
|
||||
done();
|
||||
}
|
||||
};
|
||||
it('will render post via /:year/:slug', function (done) {
|
||||
var date = moment(mockPost.published_at).format('YYYY'),
|
||||
req = {
|
||||
path: '/' + [date, mockPost.slug].join('/')
|
||||
},
|
||||
res = {
|
||||
render: function (view, context) {
|
||||
assert.equal(view, 'post');
|
||||
assert(context.post, 'Context object has post attribute');
|
||||
assert.equal(context.post, mockPost);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
frontend.single(req, res, null);
|
||||
});
|
||||
|
||||
it('will NOT redirect to admin edit page for a normal post accessed as a slug url', function (done) {
|
||||
var req = {
|
||||
params: [undefined, mockPost.slug, 'edit']
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: sinon.spy()
|
||||
};
|
||||
|
||||
frontend.single(req, res, function () {
|
||||
res.render.called.should.be.false;
|
||||
res.redirect.called.should.be.false;
|
||||
done();
|
||||
frontend.single(req, res, failTest(done));
|
||||
});
|
||||
});
|
||||
|
||||
it('will redirect to admin edit page for a static page accessed as a slug url', function (done) {
|
||||
var req = {
|
||||
params: [undefined, mockStaticPost.slug, 'edit']
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: function (arg) {
|
||||
res.render.called.should.be.false;
|
||||
arg.should.eql(adminEditPagePath + mockStaticPost.id + '/');
|
||||
done();
|
||||
}
|
||||
};
|
||||
it('will NOT render post via /YYYY/MM/DD/:slug', function (done) {
|
||||
var date = moment(mockPost.published_at).format('YYYY/MM/DD'),
|
||||
req = {
|
||||
path: '/' + [date, mockPost.slug].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy()
|
||||
};
|
||||
|
||||
frontend.single(req, res, null);
|
||||
});
|
||||
frontend.single(req, res, function () {
|
||||
res.render.called.should.be.false;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('will NOT redirect to admin edit page for a static page accessed as a date url', function (done) {
|
||||
var req = {
|
||||
params: ['2012/12/30/', mockStaticPost.slug, 'edit']
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: sinon.spy()
|
||||
};
|
||||
it('will NOT render post via /:year/slug when year does not match post year', function (done) {
|
||||
var date = moment(mockPost.published_at).subtract('years', 1).format('YYYY'),
|
||||
req = {
|
||||
path: '/' + [date, mockPost.slug].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy()
|
||||
};
|
||||
|
||||
frontend.single(req, res, function () {
|
||||
res.render.called.should.be.false;
|
||||
res.redirect.called.should.be.false;
|
||||
done();
|
||||
frontend.single(req, res, function () {
|
||||
res.render.called.should.be.false;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('will NOT render post via /:slug', function (done) {
|
||||
var req = {
|
||||
path: '/' + mockPost.slug
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy()
|
||||
};
|
||||
|
||||
frontend.single(req, res, function () {
|
||||
res.render.called.should.be.false;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
// Handle Edit append
|
||||
it('will redirect post to admin edit page via /:year/:slug/edit', function (done) {
|
||||
var date = moment(mockPost.published_at).format('YYYY'),
|
||||
req = {
|
||||
path: '/' + [date, mockPost.slug, 'edit'].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: function (arg) {
|
||||
res.render.called.should.be.false;
|
||||
arg.should.eql(adminEditPagePath + mockPost.id + '/');
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
frontend.single(req, res, failTest(done));
|
||||
});
|
||||
|
||||
it('will NOT redirect post to admin edit page /:slug/edit', function (done) {
|
||||
var req = {
|
||||
path: '/' + [mockPost.slug, 'edit'].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: sinon.spy()
|
||||
};
|
||||
|
||||
frontend.single(req, res, function () {
|
||||
res.render.called.should.be.false;
|
||||
res.redirect.called.should.be.false;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue