0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-03-11 02:12:21 -05:00

Splitted preview & single controllers from index (#9121)

refs #5091

- one step towards having a less confusing controller/routing system for blogs
This commit is contained in:
Hannah Wolfe 2017-10-09 12:56:44 +01:00 committed by Katharina Irrgang
parent 75fdcd168e
commit d77e000113
8 changed files with 354 additions and 296 deletions

View file

@ -1,7 +1,7 @@
var express = require('express'),
path = require('path'),
config = require('../config'),
frontend = require('../controllers/frontend'),
controllers = require('../controllers'),
channels = require('../controllers/frontend/channels'),
utils = require('../utils');
@ -23,7 +23,7 @@ module.exports = function frontendRoutes() {
});
// Post Live Preview
router.get(utils.url.urlJoin('/', routeKeywords.preview, ':uuid', ':options?'), frontend.preview);
router.get(utils.url.urlJoin('/', routeKeywords.preview, ':uuid', ':options?'), controllers.preview);
// Channels
router.use(channels.router());
@ -38,7 +38,7 @@ module.exports = function frontendRoutes() {
});
// Default
router.get('*', frontend.single);
router.get('*', controllers.single);
return router;
};

View file

@ -1,103 +0,0 @@
/**
* Main controller for Ghost frontend
*/
/*global require, module */
var debug = require('ghost-ignition').debug('channels:single'),
api = require('../../api'),
utils = require('../../utils'),
filters = require('../../filters'),
templates = require('./templates'),
handleError = require('./error'),
formatResponse = require('./format-response'),
postLookup = require('./post-lookup'),
setResponseContext = require('./context'),
setRequestIsSecure = require('./secure'),
frontendControllers;
/*
* Sets the response context around a post and renders it
* with the current theme's post view. Used by post preview
* and single post methods.
* Returns a function that takes the post to be rendered.
*/
function renderPost(req, res) {
debug('renderPost called');
return function renderPost(post) {
var view = templates.single(post),
response = formatResponse.single(post);
setResponseContext(req, res, response);
debug('Rendering view: ' + view);
res.render(view, response);
};
}
frontendControllers = {
preview: function preview(req, res, next) {
var params = {
uuid: req.params.uuid,
status: 'all',
include: 'author,tags'
};
api.posts.read(params).then(function then(result) {
var post = result.posts[0];
if (!post) {
return next();
}
if (req.params.options && req.params.options.toLowerCase() === 'edit') {
// CASE: last param is of url is /edit, redirect to admin
return res.redirect(utils.url.urlJoin(utils.url.urlFor('admin'), 'editor', post.id, '/'));
} else if (req.params.options) {
// CASE: unknown options param detected. Ignore and end in 404.
return next();
}
if (post.status === 'published') {
return res.redirect(301, utils.url.urlFor('post', {post: post}));
}
setRequestIsSecure(req, post);
filters.doFilter('prePostsRender', post, res.locals)
.then(renderPost(req, res));
}).catch(handleError(next));
},
single: function single(req, res, next) {
// Query database to find post
return postLookup(req.path).then(function then(lookup) {
var post = lookup ? lookup.post : false;
if (!post) {
return next();
}
// CASE: postlookup can detect options for example /edit, unknown options get ignored and end in 404
if (lookup.isUnknownOption) {
return next();
}
// CASE: last param is of url is /edit, redirect to admin
if (lookup.isEditURL) {
return res.redirect(utils.url.urlJoin(utils.url.urlFor('admin'), 'editor', post.id, '/'));
}
// CASE: permalink is not valid anymore, we redirect him permanently to the correct one
if (post.url !== req.path) {
return res.redirect(301, post.url);
}
setRequestIsSecure(req, post);
filters.doFilter('prePostsRender', post, res.locals)
.then(renderPost(req, res));
}).catch(handleError(next));
}
};
module.exports = frontendControllers;

View file

@ -0,0 +1,22 @@
var debug = require('ghost-ignition').debug('channels:render-post'),
templates = require('./templates'),
formatResponse = require('./format-response'),
setResponseContext = require('./context');
/*
* Sets the response context around a post and renders it
* with the current theme's post view. Used by post preview
* and single post methods.
* Returns a function that takes the post to be rendered.
*/
module.exports = function renderPost(req, res) {
debug('renderPost called');
return function renderPost(post) {
var view = templates.single(post),
response = formatResponse.single(post);
setResponseContext(req, res, response);
debug('Rendering view: ' + view);
res.render(view, response);
};
};

View file

@ -0,0 +1,4 @@
module.exports = {
preview: require('./preview'),
single: require('./single')
};

View file

@ -0,0 +1,39 @@
var api = require('../api'),
utils = require('../utils'),
filters = require('../filters'),
handleError = require('./frontend/error'),
renderPost = require('./frontend/render-post'),
setRequestIsSecure = require('./frontend/secure');
module.exports = function preview(req, res, next) {
var params = {
uuid: req.params.uuid,
status: 'all',
include: 'author,tags'
};
api.posts.read(params).then(function then(result) {
var post = result.posts[0];
if (!post) {
return next();
}
if (req.params.options && req.params.options.toLowerCase() === 'edit') {
// CASE: last param is of url is /edit, redirect to admin
return res.redirect(utils.url.urlJoin(utils.url.urlFor('admin'), 'editor', post.id, '/'));
} else if (req.params.options) {
// CASE: unknown options param detected. Ignore and end in 404.
return next();
}
if (post.status === 'published') {
return res.redirect(301, utils.url.urlFor('post', {post: post}));
}
setRequestIsSecure(req, post);
filters.doFilter('prePostsRender', post, res.locals)
.then(renderPost(req, res));
}).catch(handleError(next));
};

View file

@ -0,0 +1,37 @@
var utils = require('../utils'),
filters = require('../filters'),
handleError = require('./frontend/error'),
postLookup = require('./frontend/post-lookup'),
renderPost = require('./frontend/render-post'),
setRequestIsSecure = require('./frontend/secure');
module.exports = function single(req, res, next) {
// Query database to find post
return postLookup(req.path).then(function then(lookup) {
var post = lookup ? lookup.post : false;
if (!post) {
return next();
}
// CASE: postlookup can detect options for example /edit, unknown options get ignored and end in 404
if (lookup.isUnknownOption) {
return next();
}
// CASE: last param is of url is /edit, redirect to admin
if (lookup.isEditURL) {
return res.redirect(utils.url.urlJoin(utils.url.urlFor('admin'), 'editor', post.id, '/'));
}
// CASE: permalink is not valid anymore, we redirect him permanently to the correct one
if (post.url !== req.path) {
return res.redirect(301, post.url);
}
setRequestIsSecure(req, post);
filters.doFilter('prePostsRender', post, res.locals)
.then(renderPost(req, res));
}).catch(handleError(next));
};

View file

@ -0,0 +1,197 @@
var should = require('should'),
sinon = require('sinon'),
Promise = require('bluebird'),
_ = require('lodash'),
// Test utils
configUtils = require('../../utils/configUtils'),
markdownToMobiledoc = require('../../utils/fixtures/data-generator').markdownToMobiledoc,
// Server requires
api = require('../../../server/api'),
controllers = require('../../../server/controllers'),
themes = require('../../../server/themes'),
sandbox = sinon.sandbox.create();
describe('Controllers', function () {
var hasTemplateStub;
afterEach(function () {
sandbox.restore();
configUtils.restore();
});
// Ensure hasTemplate returns values
function setupActiveTheme() {
hasTemplateStub = sandbox.stub().returns(false);
hasTemplateStub.withArgs('post').returns(true);
hasTemplateStub.withArgs('page').returns(true);
sandbox.stub(themes, 'getActive').returns({
hasTemplate: hasTemplateStub
});
}
beforeEach(function () {
setupActiveTheme();
});
// Helper function to prevent unit tests
// from failing via timeout when they
// should just immediately fail
function failTest(done) {
return function (err) {
done(err);
};
}
describe('preview', function () {
var req, res, mockPosts = [{
posts: [{
status: 'draft',
uuid: 'abc-1234-01',
id: 1,
title: 'Test static page',
slug: 'test-static-page',
mobiledoc: markdownToMobiledoc('Test static page content'),
page: 1,
author: {
id: 1,
name: 'Test User',
slug: 'test',
email: 'test@ghost.org'
},
url: '/test-static-page/'
}]
}, {
posts: [{
status: 'draft',
uuid: 'abc-1234-02',
id: 2,
title: 'Test normal post',
slug: 'test-normal-post',
mobiledoc: markdownToMobiledoc('The test normal post content'),
page: 0,
author: {
id: 1,
name: 'Test User',
slug: 'test',
email: 'test@ghost.org'
}
}]
}, {
posts: [{
status: 'published',
uuid: 'abc-1234-03',
id: 3,
title: 'Getting started',
slug: 'about',
mobiledoc: markdownToMobiledoc('This is a blog post'),
page: 0,
published_at: new Date('2014/1/30').getTime(),
author: {
id: 1,
name: 'Test User',
slug: 'test',
email: 'test@ghost.org'
},
url: '/getting-started/'
}]
}];
beforeEach(function () {
sandbox.stub(api.posts, 'read', function (args) {
var post = _.find(mockPosts, function (mock) {
return mock.posts[0].uuid === args.uuid;
});
return Promise.resolve(post || {posts: []});
});
req = {
path: '/', params: {}, route: {}
};
res = {
locals: {},
render: sinon.spy(),
redirect: sinon.spy()
};
});
it('should render draft post', function (done) {
req.params = {uuid: 'abc-1234-02'};
res.render = function (view, context) {
view.should.equal('post');
should.exist(context.post);
context.post.should.equal(mockPosts[1].posts[0]);
done();
};
controllers.preview(req, res, failTest(done));
});
it('should render draft page', function (done) {
req.params = {uuid: 'abc-1234-01'};
res.render = function (view, context) {
view.should.equal('page');
should.exist(context.post);
context.post.should.equal(mockPosts[0].posts[0]);
done();
};
controllers.preview(req, res, failTest(done));
});
it('should call next if post is not found', function (done) {
req.params = {uuid: 'abc-1234-04'};
controllers.preview(req, res, function (err) {
should.not.exist(err);
res.render.called.should.be.false();
res.redirect.called.should.be.false();
done();
});
});
it('should call redirect if post is published', function (done) {
req.params = {uuid: 'abc-1234-03'};
res.redirect = function (status, url) {
res.render.called.should.be.false();
status.should.eql(301);
url.should.eql('/getting-started/');
done();
};
controllers.preview(req, res, failTest(done));
});
it('should call redirect if /edit/ (options param) is detected', function (done) {
req.params = {uuid: 'abc-1234-01', options: 'edit'};
res.redirect = function (url) {
res.render.called.should.be.false();
url.should.eql('/ghost/editor/1/');
done();
};
controllers.preview(req, res, failTest(done));
});
it('should call next for unknown options param detected', function (done) {
req.params = {uuid: 'abc-1234-01', options: 'asdsad'};
controllers.preview(req, res, function (err) {
should.not.exist(err);
res.render.called.should.be.false();
res.redirect.called.should.be.false();
done();
});
});
});
});

View file

@ -3,15 +3,20 @@ var should = require('should'),
moment = require('moment'),
Promise = require('bluebird'),
_ = require('lodash'),
api = require('../../../../server/api'),
frontend = require('../../../../server/controllers/frontend'),
configUtils = require('../../../utils/configUtils'),
themes = require('../../../../server/themes'),
settingsCache = require('../../../../server/settings/cache'),
markdownToMobiledoc = require('../../../utils/fixtures/data-generator').markdownToMobiledoc,
// Test utils
configUtils = require('../../utils/configUtils'),
markdownToMobiledoc = require('../../utils/fixtures/data-generator').markdownToMobiledoc,
// Server requires
api = require('../../../server/api'),
controllers = require('../../../server/controllers'),
themes = require('../../../server/themes'),
settingsCache = require('../../../server/settings/cache'),
sandbox = sinon.sandbox.create();
describe('Frontend Controller', function () {
describe('Controllers', function () {
var adminEditPagePath = '/ghost/editor/',
localSettingsCache = {},
hasTemplateStub;
@ -145,7 +150,7 @@ describe('Frontend Controller', function () {
};
mockPosts[2].posts[0].url = req.path;
frontend.single(req, res, failTest(done));
controllers.single(req, res, failTest(done));
});
it('it will use page.hbs if it exists and no page-slug template is present', function (done) {
@ -160,7 +165,7 @@ describe('Frontend Controller', function () {
};
mockPosts[2].posts[0].url = req.path;
frontend.single(req, res, failTest(done));
controllers.single(req, res, failTest(done));
});
it('defaults to post.hbs without a page.hbs or page-slug template', function (done) {
@ -176,7 +181,7 @@ describe('Frontend Controller', function () {
};
mockPosts[2].posts[0].url = req.path;
frontend.single(req, res, failTest(done));
controllers.single(req, res, failTest(done));
});
});
@ -190,13 +195,13 @@ describe('Frontend Controller', function () {
done();
};
frontend.single(req, res, failTest(done));
controllers.single(req, res, failTest(done));
});
it('will NOT render static page via /YYY/MM/DD/:slug', function (done) {
req.path = '/' + ['2012/12/30', mockPosts[0].posts[0].slug].join('/') + '/';
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
done();
});
@ -205,7 +210,7 @@ describe('Frontend Controller', function () {
it('will NOT render static page via /:author/:slug', function (done) {
req.path = '/' + ['test', mockPosts[0].posts[0].slug].join('/') + '/';
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
done();
});
@ -219,13 +224,13 @@ describe('Frontend Controller', function () {
done();
};
frontend.single(req, res, failTest(done));
controllers.single(req, res, failTest(done));
});
it('will NOT redirect static page to admin edit page via /YYYY/MM/DD/:slug/edit', function (done) {
req.path = '/' + ['2012/12/30', mockPosts[0].posts[0].slug, 'edit'].join('/') + '/';
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
res.redirect.called.should.be.false();
done();
@ -235,7 +240,7 @@ describe('Frontend Controller', function () {
it('will NOT redirect static page to admin edit page via /:author/:slug/edit', function (done) {
req.path = '/' + ['test', mockPosts[0].posts[0].slug, 'edit'].join('/') + '/';
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
res.redirect.called.should.be.false();
done();
@ -257,14 +262,14 @@ describe('Frontend Controller', function () {
done();
};
frontend.single(req, res, failTest(done));
controllers.single(req, res, failTest(done));
});
it('will NOT render static page via /YYYY/MM/DD/:slug', function (done) {
req.path = '/' + ['2012/12/30', mockPosts[0].posts[0].slug].join('/') + '/';
res.render = sinon.spy();
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
done();
});
@ -279,7 +284,7 @@ describe('Frontend Controller', function () {
done();
};
frontend.single(req, res, failTest(done));
controllers.single(req, res, failTest(done));
});
it('will NOT redirect static page to admin edit page via /YYYY/MM/DD/:slug/edit', function (done) {
@ -287,7 +292,7 @@ describe('Frontend Controller', function () {
res.render = sinon.spy();
res.redirect = sinon.spy();
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
res.redirect.called.should.be.false();
done();
@ -312,13 +317,13 @@ describe('Frontend Controller', function () {
done();
};
frontend.single(req, res, failTest(done));
controllers.single(req, res, failTest(done));
});
it('will NOT render post via /YYYY/MM/DD/:slug', function (done) {
req.path = '/' + ['2012/12/30', mockPosts[1].posts[0].slug].join('/') + '/';
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
done();
});
@ -327,7 +332,7 @@ describe('Frontend Controller', function () {
it('will NOT render post via /:author/:slug', function (done) {
req.path = '/' + ['test', mockPosts[1].posts[0].slug].join('/') + '/';
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
done();
});
@ -342,13 +347,13 @@ describe('Frontend Controller', function () {
done();
};
frontend.single(req, res, failTest(done));
controllers.single(req, res, failTest(done));
});
it('will NOT redirect post to admin edit page via /YYYY/MM/DD/:slug/edit', function (done) {
req.path = '/' + ['2012/12/30', mockPosts[1].posts[0].slug, 'edit'].join('/') + '/';
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
res.redirect.called.should.be.false();
done();
@ -358,7 +363,7 @@ describe('Frontend Controller', function () {
it('will NOT redirect post to admin edit page via /:author/:slug/edit', function (done) {
req.path = '/' + ['test', mockPosts[1].posts[0].slug, 'edit'].join('/') + '/';
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
res.redirect.called.should.be.false();
done();
@ -368,7 +373,7 @@ describe('Frontend Controller', function () {
it('should call next if post is not found', function (done) {
req.path = '/unknown/';
frontend.single(req, res, function (err) {
controllers.single(req, res, function (err) {
if (err) {
return done(err);
}
@ -401,13 +406,13 @@ describe('Frontend Controller', function () {
done();
};
frontend.single(req, res, failTest(done));
controllers.single(req, res, failTest(done));
});
it('will NOT render post via /:slug/', function (done) {
req.path = '/' + mockPosts[1].posts[0].slug + '/';
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
done();
});
@ -416,7 +421,7 @@ describe('Frontend Controller', function () {
it('will NOT render post via /:author/:slug/', function (done) {
req.path = '/' + ['test', mockPosts[1].posts[0].slug].join('/') + '/';
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
done();
});
@ -433,13 +438,13 @@ describe('Frontend Controller', function () {
done();
};
frontend.single(req, res, failTest(done));
controllers.single(req, res, failTest(done));
});
it('will NOT redirect post to admin edit page via /:slug/edit/', function (done) {
req.path = '/' + [mockPosts[1].posts[0].slug, 'edit'].join('/') + '/';
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
res.redirect.called.should.be.false();
done();
@ -449,7 +454,7 @@ describe('Frontend Controller', function () {
it('will NOT redirect post to admin edit page via /:author/:slug/edit/', function (done) {
req.path = '/' + ['test', mockPosts[1].posts[0].slug, 'edit'].join('/') + '/';
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
res.redirect.called.should.be.false();
done();
@ -475,14 +480,14 @@ describe('Frontend Controller', function () {
done();
};
frontend.single(req, res, failTest(done));
controllers.single(req, res, failTest(done));
});
it('will NOT render post via /YYYY/MM/DD/:slug/', function (done) {
var date = moment(mockPosts[1].posts[0].published_at).format('YYYY/MM/DD');
req.path = '/' + [date, mockPosts[1].posts[0].slug].join('/') + '/';
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
done();
});
@ -491,7 +496,7 @@ describe('Frontend Controller', function () {
it('will NOT render post via /:author/:slug/ when author does not match post author', function (done) {
req.path = '/' + ['test-2', mockPosts[1].posts[0].slug].join('/') + '/';
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
done();
});
@ -500,7 +505,7 @@ describe('Frontend Controller', function () {
it('will NOT render post via /:slug/', function (done) {
req.path = '/' + mockPosts[1].posts[0].slug + '/';
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
done();
});
@ -516,14 +521,14 @@ describe('Frontend Controller', function () {
done();
};
frontend.single(req, res, failTest(done));
controllers.single(req, res, failTest(done));
});
it('will NOT redirect post to admin edit page via /YYYY/MM/DD/:slug/edit/', function (done) {
var date = moment(mockPosts[1].posts[0].published_at).format('YYYY/MM/DD');
req.path = '/' + [date, mockPosts[1].posts[0].slug, 'edit'].join('/') + '/';
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
res.redirect.called.should.be.false();
done();
@ -533,7 +538,7 @@ describe('Frontend Controller', function () {
it('will NOT redirect post to admin edit page /:slug/edit/', function (done) {
req.path = '/' + [mockPosts[1].posts[0].slug, 'edit'].join('/') + '/';
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
res.redirect.called.should.be.false();
done();
@ -565,7 +570,7 @@ describe('Frontend Controller', function () {
}
};
frontend.single(req, res, failTest(done));
controllers.single(req, res, failTest(done));
});
it('will NOT render post via /YYYY/MM/DD/:slug/', function (done) {
@ -578,7 +583,7 @@ describe('Frontend Controller', function () {
render: sinon.spy()
};
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
done();
});
@ -594,7 +599,7 @@ describe('Frontend Controller', function () {
render: sinon.spy()
};
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
done();
});
@ -609,7 +614,7 @@ describe('Frontend Controller', function () {
render: sinon.spy()
};
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
done();
});
@ -631,7 +636,7 @@ describe('Frontend Controller', function () {
}
};
frontend.single(req, res, failTest(done));
controllers.single(req, res, failTest(done));
});
it('will NOT redirect post to admin edit page /:slug/edit/', function (done) {
@ -644,7 +649,7 @@ describe('Frontend Controller', function () {
redirect: sinon.spy()
};
frontend.single(req, res, function () {
controllers.single(req, res, function () {
res.render.called.should.be.false();
res.redirect.called.should.be.false();
done();
@ -676,152 +681,9 @@ describe('Frontend Controller', function () {
}
};
frontend.single(req, res, failTest(done));
controllers.single(req, res, failTest(done));
});
});
});
});
describe('preview', function () {
var req, res, mockPosts = [{
posts: [{
status: 'draft',
uuid: 'abc-1234-01',
id: 1,
title: 'Test static page',
slug: 'test-static-page',
mobiledoc: markdownToMobiledoc('Test static page content'),
page: 1,
author: {
id: 1,
name: 'Test User',
slug: 'test',
email: 'test@ghost.org'
},
url: '/test-static-page/'
}]
}, {
posts: [{
status: 'draft',
uuid: 'abc-1234-02',
id: 2,
title: 'Test normal post',
slug: 'test-normal-post',
mobiledoc: markdownToMobiledoc('The test normal post content'),
page: 0,
author: {
id: 1,
name: 'Test User',
slug: 'test',
email: 'test@ghost.org'
}
}]
}, {
posts: [{
status: 'published',
uuid: 'abc-1234-03',
id: 3,
title: 'Getting started',
slug: 'about',
mobiledoc: markdownToMobiledoc('This is a blog post'),
page: 0,
published_at: new Date('2014/1/30').getTime(),
author: {
id: 1,
name: 'Test User',
slug: 'test',
email: 'test@ghost.org'
},
url: '/getting-started/'
}]
}];
beforeEach(function () {
sandbox.stub(api.posts, 'read', function (args) {
var post = _.find(mockPosts, function (mock) {
return mock.posts[0].uuid === args.uuid;
});
return Promise.resolve(post || {posts: []});
});
req = {
path: '/', params: {}, route: {}
};
res = {
locals: {},
render: sinon.spy(),
redirect: sinon.spy()
};
});
it('should render draft post', function (done) {
req.params = {uuid: 'abc-1234-02'};
res.render = function (view, context) {
view.should.equal('post');
should.exist(context.post);
context.post.should.equal(mockPosts[1].posts[0]);
done();
};
frontend.preview(req, res, failTest(done));
});
it('should render draft page', function (done) {
req.params = {uuid: 'abc-1234-01'};
res.render = function (view, context) {
view.should.equal('page');
should.exist(context.post);
context.post.should.equal(mockPosts[0].posts[0]);
done();
};
frontend.preview(req, res, failTest(done));
});
it('should call next if post is not found', function (done) {
req.params = {uuid: 'abc-1234-04'};
frontend.preview(req, res, function (err) {
should.not.exist(err);
res.render.called.should.be.false();
res.redirect.called.should.be.false();
done();
});
});
it('should call redirect if post is published', function (done) {
req.params = {uuid: 'abc-1234-03'};
res.redirect = function (status, url) {
res.render.called.should.be.false();
status.should.eql(301);
url.should.eql('/getting-started/');
done();
};
frontend.preview(req, res, failTest(done));
});
it('should call redirect if /edit/ (options param) is detected', function (done) {
req.params = {uuid: 'abc-1234-01', options: 'edit'};
res.redirect = function (url) {
res.render.called.should.be.false();
url.should.eql('/ghost/editor/1/');
done();
};
frontend.preview(req, res, failTest(done));
});
it('should call next for unknown options param detected', function (done) {
req.params = {uuid: 'abc-1234-01', options: 'asdsad'};
frontend.preview(req, res, function (err) {
should.not.exist(err);
res.render.called.should.be.false();
res.redirect.called.should.be.false();
done();
});
});
});
});