mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-01 13:54:35 +03:00
9dc096cb15
refs 3c7a8dead4
- The tests needed adjustments with the native boot mechanism.
- The number of returned posts changed in the test resutls because duing native boot we also insert fixtures which add to the number of initial posts
- The vhost regression suite is still failing and I had no strength to figure out why. The redirect it fails with makes no sense, the clue here is that the test doesn't fail when running in isolation, so probably has to do with some leftover overrides from the previous test cases.
1636 lines
56 KiB
JavaScript
1636 lines
56 KiB
JavaScript
const should = require('should');
|
|
const sinon = require('sinon');
|
|
const _ = require('lodash');
|
|
const cheerio = require('cheerio');
|
|
const testUtils = require('../../../utils');
|
|
const localUtils = require('../utils');
|
|
const configUtils = require('../../../utils/configUtils');
|
|
const urlUtils = require('../../../utils/urlUtils');
|
|
|
|
const routeSettingsService = require('../../../../core/server/services/route-settings');
|
|
const themeEngine = require('../../../../core/frontend/services/theme-engine');
|
|
|
|
describe('Integration - Web - Site v3', function () {
|
|
let app;
|
|
|
|
before(localUtils.urlService.resetGenerators);
|
|
before(testUtils.teardownDb);
|
|
before(testUtils.setup('users:roles', 'posts'));
|
|
|
|
let postSpy;
|
|
|
|
describe('default routes.yaml', function () {
|
|
before(async function () {
|
|
localUtils.urlService.resetGenerators();
|
|
localUtils.defaultMocks(sinon, {amp: true});
|
|
localUtils.overrideGhostConfig(configUtils);
|
|
|
|
app = await localUtils.initGhost();
|
|
});
|
|
|
|
before(function () {
|
|
configUtils.set('url', 'http://example.com');
|
|
urlUtils.stubUrlUtilsFromConfig();
|
|
});
|
|
|
|
beforeEach(function () {
|
|
sinon.stub(themeEngine.getActive(), 'engine').withArgs('ghost-api').returns('v3');
|
|
sinon.stub(themeEngine.getActive(), 'config').withArgs('posts_per_page').returns(2);
|
|
const postsAPI = require('../../../../core/server/api/v3/posts-public');
|
|
postSpy = sinon.spy(postsAPI.browse, 'query');
|
|
});
|
|
|
|
afterEach(function () {
|
|
postSpy.restore();
|
|
sinon.restore();
|
|
});
|
|
|
|
after(function () {
|
|
configUtils.restore();
|
|
urlUtils.restore();
|
|
sinon.restore();
|
|
});
|
|
|
|
describe('behaviour: default cases', function () {
|
|
it('serve post', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/html-ipsum/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('post');
|
|
});
|
|
});
|
|
|
|
it('serve amp', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/html-ipsum/amp/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.match(/amp\.hbs/);
|
|
response.body.should.match(/<h1>HTML Ipsum Presents<\/h1>/);
|
|
});
|
|
});
|
|
|
|
it('post not found', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/not-found/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(404);
|
|
response.template.should.eql('error-404');
|
|
});
|
|
});
|
|
|
|
it('serve static page', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/static-page-test/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('page');
|
|
});
|
|
});
|
|
|
|
it('serve author', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/author/joe-bloggs/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
const $ = cheerio.load(response.body);
|
|
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('author');
|
|
|
|
$('.author-bio').length.should.equal(1);
|
|
});
|
|
});
|
|
|
|
it('serve tag', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/tag/bacon/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('tag');
|
|
|
|
postSpy.args[0][0].options.filter.should.eql('(tags:\'bacon\'+tags.visibility:public)+type:post');
|
|
postSpy.args[0][0].options.page.should.eql(1);
|
|
postSpy.args[0][0].options.limit.should.eql(2);
|
|
});
|
|
});
|
|
|
|
it('serve tag rss', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/tag/bacon/rss/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
});
|
|
});
|
|
|
|
it('serve collection', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
const $ = cheerio.load(response.body);
|
|
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('index');
|
|
|
|
$('.post-card').length.should.equal(2);
|
|
|
|
should.exist(response.res.locals.context);
|
|
should.exist(response.res.locals.version);
|
|
should.exist(response.res.locals.safeVersion);
|
|
should.exist(response.res.locals.safeVersion);
|
|
should.exist(response.res.locals.relativeUrl);
|
|
should.exist(response.res.locals.secure);
|
|
should.exist(response.res.routerOptions);
|
|
});
|
|
});
|
|
|
|
it('serve collection: page 2', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/page/2/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
const $ = cheerio.load(response.body);
|
|
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('index');
|
|
|
|
$('.post-card').length.should.equal(2);
|
|
});
|
|
});
|
|
|
|
it('serve theme asset', function () {
|
|
//configUtils.set('url', 'https://example.com');
|
|
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/assets/css/screen.css',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('behaviour: prettify', function () {
|
|
it('url without slash', function () {
|
|
const req = {
|
|
secure: false,
|
|
method: 'GET',
|
|
url: '/prettify-me',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(301);
|
|
response.headers.location.should.eql('/prettify-me/');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('behaviour: url redirects', function () {
|
|
describe('pagination', function () {
|
|
it('redirect /page/1/ to /', function () {
|
|
const req = {
|
|
secure: false,
|
|
host: 'example.com',
|
|
method: 'GET',
|
|
url: '/page/1/'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(301);
|
|
response.headers.location.should.eql('/');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('rss', function () {
|
|
it('redirect /feed/ to /rss/', function () {
|
|
const req = {
|
|
secure: false,
|
|
host: 'example.com',
|
|
method: 'GET',
|
|
url: '/feed/'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(301);
|
|
response.headers.location.should.eql('/rss/');
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('https', function () {
|
|
before(function () {
|
|
configUtils.set('url', 'https://example.com');
|
|
urlUtils.stubUrlUtilsFromConfig();
|
|
});
|
|
|
|
after(function () {
|
|
urlUtils.restore();
|
|
configUtils.restore();
|
|
});
|
|
|
|
describe('protocol', function () {
|
|
it('blog is https, request is http', function () {
|
|
const req = {
|
|
secure: false,
|
|
host: 'example.com',
|
|
method: 'GET',
|
|
url: '/html-ipsum'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(301);
|
|
response.headers.location.should.eql('https://example.com/html-ipsum/');
|
|
});
|
|
});
|
|
|
|
it('blog is https, request is http, trailing slash exists already', function () {
|
|
const req = {
|
|
secure: false,
|
|
method: 'GET',
|
|
url: '/html-ipsum/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(301);
|
|
response.headers.location.should.eql('https://example.com/html-ipsum/');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('assets', function () {
|
|
it('blog is https, request is http', function () {
|
|
const req = {
|
|
secure: false,
|
|
method: 'GET',
|
|
url: '/favicon.png',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(301);
|
|
response.headers.location.should.eql('https://example.com/favicon.png');
|
|
});
|
|
});
|
|
|
|
it('blog is https, request is http', function () {
|
|
const req = {
|
|
secure: false,
|
|
method: 'GET',
|
|
url: '/assets/css/main.css',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(301);
|
|
response.headers.location.should.eql('https://example.com/assets/css/main.css');
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('extended routes.yaml: collections', function () {
|
|
describe('2 collections', function () {
|
|
before(async function () {
|
|
sinon.stub(routeSettingsService, 'loadRouteSettings').get(() => () => ({
|
|
routes: {
|
|
'/': {
|
|
templates: ['home']
|
|
}
|
|
},
|
|
|
|
collections: {
|
|
'/podcast/': {
|
|
permalink: '/podcast/:slug/',
|
|
filter: 'featured:true'
|
|
},
|
|
|
|
'/something/': {
|
|
permalink: '/something/:slug/',
|
|
filter: 'featured:false'
|
|
}
|
|
},
|
|
|
|
taxonomies: {
|
|
tag: '/categories/:slug/',
|
|
author: '/authors/:slug/'
|
|
}
|
|
}));
|
|
|
|
localUtils.urlService.resetGenerators();
|
|
localUtils.defaultMocks(sinon, {theme: 'test-theme'});
|
|
|
|
app = await localUtils.initGhost();
|
|
});
|
|
|
|
beforeEach(function () {
|
|
localUtils.overrideGhostConfig(configUtils);
|
|
});
|
|
|
|
afterEach(function () {
|
|
configUtils.restore();
|
|
urlUtils.restore();
|
|
});
|
|
|
|
after(function () {
|
|
sinon.restore();
|
|
});
|
|
|
|
it('serve static route', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('home');
|
|
});
|
|
});
|
|
|
|
it('serve rss', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/podcast/rss/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
});
|
|
});
|
|
|
|
it('serve post', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/something/html-ipsum/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('post');
|
|
});
|
|
});
|
|
|
|
it('serve collection: podcast', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/podcast/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
const $ = cheerio.load(response.body);
|
|
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('index');
|
|
|
|
$('.post-card').length.should.equal(2);
|
|
});
|
|
});
|
|
|
|
it('serve collection: something with custom template', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/something/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
const $ = cheerio.load(response.body);
|
|
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('something');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('no collections', function () {
|
|
before(async function () {
|
|
sinon.stub(routeSettingsService, 'loadRouteSettings').get(() => () => ({
|
|
routes: {
|
|
'/something/': {templates: ['something']}
|
|
},
|
|
collections: {},
|
|
taxonomies: {}
|
|
}));
|
|
|
|
localUtils.urlService.resetGenerators();
|
|
localUtils.defaultMocks(sinon, {theme: 'test-theme'});
|
|
|
|
app = await localUtils.initGhost();
|
|
});
|
|
|
|
beforeEach(function () {
|
|
localUtils.overrideGhostConfig(configUtils);
|
|
});
|
|
|
|
afterEach(function () {
|
|
configUtils.restore();
|
|
urlUtils.restore();
|
|
});
|
|
|
|
after(function () {
|
|
sinon.restore();
|
|
});
|
|
|
|
it('serve route', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/something/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('something');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('static permalink route', function () {
|
|
before(async function () {
|
|
sinon.stub(routeSettingsService, 'loadRouteSettings').get(() => () => ({
|
|
routes: {},
|
|
|
|
collections: {
|
|
'/podcast/': {
|
|
permalink: '/featured/',
|
|
filter: 'featured:true'
|
|
},
|
|
|
|
'/': {
|
|
permalink: '/:slug/'
|
|
}
|
|
},
|
|
|
|
taxonomies: {}
|
|
}));
|
|
|
|
localUtils.urlService.resetGenerators();
|
|
localUtils.defaultMocks(sinon);
|
|
|
|
app = await localUtils.initGhost();
|
|
});
|
|
|
|
beforeEach(function () {
|
|
localUtils.overrideGhostConfig(configUtils);
|
|
});
|
|
|
|
afterEach(function () {
|
|
configUtils.restore();
|
|
urlUtils.restore();
|
|
});
|
|
|
|
after(function () {
|
|
sinon.restore();
|
|
});
|
|
|
|
it('serve post', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/featured/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
// We can't find a post with the slug "featured"
|
|
response.statusCode.should.eql(404);
|
|
response.template.should.eql('error-404');
|
|
});
|
|
});
|
|
|
|
it('serve post', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/html-ipsum/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('post');
|
|
});
|
|
});
|
|
|
|
it('serve author', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/author/joe-bloggs/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(404);
|
|
response.template.should.eql('error-404');
|
|
});
|
|
});
|
|
|
|
it('serve tag', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/tag/bacon/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(404);
|
|
response.template.should.eql('error-404');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('primary author permalink', function () {
|
|
before(async function () {
|
|
sinon.stub(routeSettingsService, 'loadRouteSettings').get(() => () => ({
|
|
routes: {},
|
|
|
|
collections: {
|
|
'/something/': {
|
|
permalink: '/:primary_author/:slug/'
|
|
}
|
|
},
|
|
|
|
taxonomies: {}
|
|
}));
|
|
|
|
localUtils.urlService.resetGenerators();
|
|
localUtils.defaultMocks(sinon);
|
|
|
|
app = await localUtils.initGhost();
|
|
});
|
|
|
|
beforeEach(function () {
|
|
localUtils.overrideGhostConfig(configUtils);
|
|
});
|
|
|
|
afterEach(function () {
|
|
configUtils.restore();
|
|
urlUtils.restore();
|
|
});
|
|
|
|
after(function () {
|
|
sinon.restore();
|
|
});
|
|
|
|
it('serve post', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/joe-bloggs/html-ipsum/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('post');
|
|
});
|
|
});
|
|
|
|
it('post without author', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/html-ipsum/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(404);
|
|
response.template.should.eql('error-404');
|
|
});
|
|
});
|
|
|
|
it('page', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/static-page-test/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('page');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('primary tag permalink', function () {
|
|
before(async function () {
|
|
sinon.stub(routeSettingsService, 'loadRouteSettings').get(() => () => ({
|
|
routes: {},
|
|
|
|
collections: {
|
|
'/something/': {
|
|
permalink: '/something/:primary_tag/:slug/'
|
|
}
|
|
},
|
|
|
|
taxonomies: {}
|
|
}));
|
|
|
|
localUtils.urlService.resetGenerators();
|
|
localUtils.defaultMocks(sinon);
|
|
app = await localUtils.initGhost();
|
|
});
|
|
|
|
beforeEach(function () {
|
|
localUtils.overrideGhostConfig(configUtils);
|
|
});
|
|
|
|
afterEach(function () {
|
|
configUtils.restore();
|
|
urlUtils.restore();
|
|
});
|
|
|
|
after(function () {
|
|
sinon.restore();
|
|
});
|
|
|
|
it('serve post', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/something/kitchen-sink/html-ipsum/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('post');
|
|
});
|
|
});
|
|
|
|
it('post without tag', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/something/html-ipsum/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(404);
|
|
response.template.should.eql('error-404');
|
|
});
|
|
});
|
|
|
|
it('post without tag', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/html-ipsum/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(404);
|
|
response.template.should.eql('error-404');
|
|
});
|
|
});
|
|
|
|
it('page', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/static-page-test/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('page');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('collection/routes with data key', function () {
|
|
before(async function () {
|
|
sinon.stub(routeSettingsService, 'loadRouteSettings').get(() => () => ({
|
|
routes: {
|
|
'/my-page/': {
|
|
data: {
|
|
query: {
|
|
page: {
|
|
controller: 'pagesPublic',
|
|
resource: 'pages',
|
|
type: 'read',
|
|
options: {
|
|
slug: 'static-page-test'
|
|
}
|
|
}
|
|
},
|
|
router: {
|
|
pages: [{redirect: true, slug: 'static-page-test'}]
|
|
}
|
|
},
|
|
templates: ['page']
|
|
}
|
|
},
|
|
|
|
collections: {
|
|
'/food/': {
|
|
permalink: '/food/:slug/',
|
|
filter: 'tag:bacon+tag:-chorizo',
|
|
data: {
|
|
query: {
|
|
tag: {
|
|
controller: 'tagsPublic',
|
|
resource: 'tags',
|
|
type: 'read',
|
|
options: {
|
|
slug: 'bacon'
|
|
}
|
|
}
|
|
},
|
|
router: {
|
|
tags: [{redirect: true, slug: 'bacon'}]
|
|
}
|
|
}
|
|
},
|
|
'/sport/': {
|
|
permalink: '/sport/:slug/',
|
|
filter: 'tag:chorizo+tag:-bacon',
|
|
data: {
|
|
query: {
|
|
apollo: {
|
|
controller: 'tagsPublic',
|
|
resource: 'tags',
|
|
type: 'read',
|
|
options: {
|
|
slug: 'chorizo'
|
|
}
|
|
}
|
|
},
|
|
router: {
|
|
tags: [{redirect: false, slug: 'chorizo'}]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
taxonomies: {
|
|
tag: '/categories/:slug/',
|
|
author: '/authors/:slug/'
|
|
}
|
|
}));
|
|
|
|
localUtils.urlService.resetGenerators();
|
|
localUtils.defaultMocks(sinon);
|
|
|
|
app = await localUtils.initGhost();
|
|
});
|
|
|
|
beforeEach(function () {
|
|
localUtils.overrideGhostConfig(configUtils);
|
|
});
|
|
|
|
afterEach(function () {
|
|
configUtils.restore();
|
|
urlUtils.restore();
|
|
});
|
|
|
|
after(function () {
|
|
sinon.restore();
|
|
});
|
|
|
|
it('serve /food/', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/food/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('index');
|
|
});
|
|
});
|
|
|
|
it('serve bacon tag', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/categories/bacon/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(301);
|
|
});
|
|
});
|
|
|
|
it('serve /sport/', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/sport/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('index');
|
|
});
|
|
});
|
|
|
|
it('serve chorizo tag', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/categories/chorizo/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
});
|
|
});
|
|
|
|
it('serve my-page', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/my-page/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('extended routes.yaml: templates', function () {
|
|
describe('default template, no template', function () {
|
|
before(async function () {
|
|
sinon.stub(routeSettingsService, 'loadRouteSettings').get(() => () => ({
|
|
routes: {},
|
|
|
|
collections: {
|
|
'/': {
|
|
permalink: '/:slug/',
|
|
templates: ['default']
|
|
},
|
|
'/magic/': {
|
|
permalink: '/magic/:slug/'
|
|
}
|
|
}
|
|
}));
|
|
|
|
localUtils.urlService.resetGenerators();
|
|
localUtils.defaultMocks(sinon);
|
|
|
|
app = await localUtils.initGhost();
|
|
});
|
|
|
|
beforeEach(function () {
|
|
localUtils.overrideGhostConfig(configUtils);
|
|
});
|
|
|
|
afterEach(function () {
|
|
configUtils.restore();
|
|
urlUtils.restore();
|
|
});
|
|
|
|
after(function () {
|
|
sinon.restore();
|
|
});
|
|
|
|
it('serve collection', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('default');
|
|
});
|
|
});
|
|
|
|
it('serve second collectiom', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/magic/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('index');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('two templates', function () {
|
|
before(async function () {
|
|
sinon.stub(routeSettingsService, 'loadRouteSettings').get(() => () => ({
|
|
routes: {},
|
|
|
|
collections: {
|
|
'/': {
|
|
permalink: '/:slug/',
|
|
templates: ['something', 'default']
|
|
}
|
|
}
|
|
}));
|
|
|
|
localUtils.urlService.resetGenerators();
|
|
localUtils.defaultMocks(sinon);
|
|
|
|
app = await localUtils.initGhost();
|
|
});
|
|
|
|
beforeEach(function () {
|
|
localUtils.overrideGhostConfig(configUtils);
|
|
});
|
|
|
|
afterEach(function () {
|
|
configUtils.restore();
|
|
urlUtils.restore();
|
|
});
|
|
|
|
after(function () {
|
|
sinon.restore();
|
|
});
|
|
|
|
it('serve collection', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('default');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('home.hbs priority', function () {
|
|
before(async function () {
|
|
sinon.stub(routeSettingsService, 'loadRouteSettings').get(() => () => ({
|
|
routes: {},
|
|
|
|
collections: {
|
|
'/': {
|
|
permalink: '/:slug/',
|
|
templates: ['something', 'default']
|
|
},
|
|
'/magic/': {
|
|
permalink: '/magic/:slug/',
|
|
templates: ['something', 'default']
|
|
}
|
|
}
|
|
}));
|
|
|
|
localUtils.urlService.resetGenerators();
|
|
localUtils.defaultMocks(sinon, {theme: 'test-theme'});
|
|
|
|
app = await localUtils.initGhost();
|
|
});
|
|
|
|
beforeEach(function () {
|
|
localUtils.overrideGhostConfig(configUtils);
|
|
});
|
|
|
|
afterEach(function () {
|
|
configUtils.restore();
|
|
urlUtils.restore();
|
|
});
|
|
|
|
after(function () {
|
|
sinon.restore();
|
|
});
|
|
|
|
it('serve collection', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('home');
|
|
});
|
|
});
|
|
|
|
it('serve second page collection: should use index.hbs', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/magic/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('something');
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('extended routes.yaml: routes', function () {
|
|
describe('channels', function () {
|
|
before(localUtils.urlService.resetGenerators);
|
|
before(testUtils.teardownDb);
|
|
before(testUtils.setup('users:roles', 'posts'));
|
|
|
|
before(async function () {
|
|
localUtils.defaultMocks(sinon, {theme: 'test-theme-channels'});
|
|
|
|
sinon.stub(routeSettingsService, 'loadRouteSettings').get(() => () => ({
|
|
routes: {
|
|
'/channel1/': {
|
|
controller: 'channel',
|
|
filter: 'tag:kitchen-sink',
|
|
data: {
|
|
query: {
|
|
tag: {
|
|
controller: 'tagsPublic',
|
|
resource: 'tags',
|
|
type: 'read',
|
|
options: {
|
|
slug: 'kitchen-sink'
|
|
}
|
|
}
|
|
},
|
|
router: {
|
|
tags: [{redirect: true, slug: 'kitchen-sink'}]
|
|
}
|
|
}
|
|
},
|
|
|
|
'/channel2/': {
|
|
controller: 'channel',
|
|
filter: 'tag:bacon',
|
|
data: {
|
|
query: {
|
|
tag: {
|
|
controller: 'tagsPublic',
|
|
resource: 'tags',
|
|
type: 'read',
|
|
options: {
|
|
slug: 'bacon'
|
|
}
|
|
}
|
|
},
|
|
router: {
|
|
tags: [{redirect: true, slug: 'bacon'}]
|
|
}
|
|
},
|
|
templates: ['default']
|
|
},
|
|
|
|
'/channel3/': {
|
|
controller: 'channel',
|
|
filter: 'author:joe-bloggs',
|
|
data: {
|
|
query: {
|
|
joe: {
|
|
controller: 'authorsPublic',
|
|
resource: 'authors',
|
|
type: 'read',
|
|
options: {
|
|
slug: 'joe-bloggs',
|
|
redirect: false
|
|
}
|
|
}
|
|
},
|
|
router: {
|
|
authors: [{redirect: false, slug: 'joe-bloggs'}]
|
|
}
|
|
}
|
|
},
|
|
|
|
'/channel4/': {
|
|
controller: 'channel',
|
|
filter: 'author:joe-bloggs'
|
|
},
|
|
|
|
'/channel5/': {
|
|
controller: 'channel',
|
|
data: {
|
|
query: {
|
|
tag: {
|
|
controller: 'authorsPublic',
|
|
resource: 'authors',
|
|
type: 'read',
|
|
options: {
|
|
slug: 'joe-bloggs',
|
|
redirect: false
|
|
}
|
|
}
|
|
},
|
|
router: {
|
|
authors: [{redirect: false, slug: 'joe-bloggs'}]
|
|
}
|
|
}
|
|
},
|
|
|
|
'/channel6/': {
|
|
controller: 'channel',
|
|
data: {
|
|
query: {
|
|
post: {
|
|
controller: 'postsPublic',
|
|
resource: 'posts',
|
|
type: 'read',
|
|
options: {
|
|
slug: 'html-ipsum',
|
|
redirect: true
|
|
}
|
|
}
|
|
},
|
|
router: {
|
|
posts: [{redirect: true, slug: 'html-ipsum'}]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
collections: {
|
|
'/': {
|
|
permalink: '/:slug/'
|
|
}
|
|
},
|
|
|
|
taxonomies: {
|
|
tag: '/tag/:slug/',
|
|
author: '/author/:slug/'
|
|
}
|
|
}));
|
|
|
|
app = await localUtils.initGhost();
|
|
|
|
sinon.stub(themeEngine.getActive(), 'config').withArgs('posts_per_page').returns(10);
|
|
});
|
|
|
|
beforeEach(function () {
|
|
localUtils.overrideGhostConfig(configUtils);
|
|
});
|
|
|
|
afterEach(function () {
|
|
configUtils.restore();
|
|
urlUtils.restore();
|
|
});
|
|
|
|
after(function () {
|
|
sinon.restore();
|
|
});
|
|
|
|
it('serve channel 1', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/channel1/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
const $ = cheerio.load(response.body);
|
|
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('index');
|
|
|
|
$('.post-card').length.should.equal(2);
|
|
});
|
|
});
|
|
|
|
it('serve channel 1: rss', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/channel1/rss/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
response.headers['content-type'].should.eql('text/xml; charset=UTF-8');
|
|
});
|
|
});
|
|
|
|
it('serve channel 2', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/channel2/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
const $ = cheerio.load(response.body);
|
|
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('default');
|
|
|
|
// default template does not list posts
|
|
$('.post-card').length.should.equal(0);
|
|
});
|
|
});
|
|
|
|
it('serve channel 3', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/channel3/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
const $ = cheerio.load(response.body);
|
|
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('channel3');
|
|
});
|
|
});
|
|
|
|
it('serve channel 4', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/channel4/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
const $ = cheerio.load(response.body);
|
|
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('index');
|
|
|
|
$('.post-card').length.should.equal(4);
|
|
});
|
|
});
|
|
|
|
it('serve channel 5', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/channel5/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
const $ = cheerio.load(response.body);
|
|
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('index');
|
|
|
|
$('.post-card').length.should.equal(10);
|
|
});
|
|
});
|
|
|
|
it('serve channel 6', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/channel6/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
const $ = cheerio.load(response.body);
|
|
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('index');
|
|
|
|
$('.post-card').length.should.equal(10);
|
|
});
|
|
});
|
|
|
|
it('serve kitching-sink: redirect', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/tag/kitchen-sink/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(301);
|
|
response.headers.location.should.eql('/channel1/');
|
|
});
|
|
});
|
|
|
|
it('serve html-ipsum: redirect', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/html-ipsum/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(301);
|
|
response.headers.location.should.eql('/channel6/');
|
|
});
|
|
});
|
|
|
|
it('serve chorizo: no redirect', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/tag/chorizo/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
});
|
|
});
|
|
|
|
it('serve joe-bloggs', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/author/joe-bloggs/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('extended routes.yaml (5): rss override', function () {
|
|
before(async function () {
|
|
sinon.stub(routeSettingsService, 'loadRouteSettings').get(() => () => ({
|
|
routes: {
|
|
'/about/': 'about',
|
|
'/podcast/rss/': {
|
|
templates: ['podcast/rss'],
|
|
content_type: 'text/xml'
|
|
},
|
|
'/cooking/': {
|
|
controller: 'channel',
|
|
rss: false
|
|
},
|
|
'/flat/': {
|
|
controller: 'channel'
|
|
}
|
|
},
|
|
|
|
collections: {
|
|
'/podcast/': {
|
|
permalink: '/:slug/',
|
|
filter: 'featured:true',
|
|
templates: ['home'],
|
|
rss: false
|
|
},
|
|
'/music/': {
|
|
permalink: '/:slug/',
|
|
rss: false
|
|
},
|
|
'/': {
|
|
permalink: '/:slug/'
|
|
}
|
|
},
|
|
|
|
taxonomies: {}
|
|
}));
|
|
|
|
localUtils.urlService.resetGenerators();
|
|
localUtils.defaultMocks(sinon, {theme: 'test-theme'});
|
|
|
|
app = await localUtils.initGhost();
|
|
});
|
|
|
|
beforeEach(function () {
|
|
localUtils.overrideGhostConfig(configUtils);
|
|
});
|
|
|
|
afterEach(function () {
|
|
configUtils.restore();
|
|
urlUtils.restore();
|
|
});
|
|
|
|
after(function () {
|
|
sinon.restore();
|
|
});
|
|
|
|
it('serve /rss/', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/rss/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
});
|
|
});
|
|
|
|
it('serve /music/rss/', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/music/rss/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(404);
|
|
});
|
|
});
|
|
|
|
it('serve /cooking/rss/', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/cooking/rss/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(404);
|
|
});
|
|
});
|
|
|
|
it('serve /flat/rss/', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/flat/rss/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
});
|
|
});
|
|
|
|
it('serve /podcast/rss/', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/podcast/rss/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
response.statusCode.should.eql(200);
|
|
response.template.should.eql('podcast/rss');
|
|
response.headers['content-type'].should.eql('text/xml; charset=utf-8');
|
|
response.body.match(/<link>/g).length.should.eql(2);
|
|
});
|
|
});
|
|
|
|
it('serve /podcast/', function () {
|
|
const req = {
|
|
secure: true,
|
|
method: 'GET',
|
|
url: '/podcast/',
|
|
host: 'example.com'
|
|
};
|
|
|
|
return localUtils.mockExpress.invoke(app, req)
|
|
.then(function (response) {
|
|
const $ = cheerio.load(response.body);
|
|
response.statusCode.should.eql(200);
|
|
$('head link')[1].attribs.href.should.eql('https://127.0.0.1:2369/rss/');
|
|
});
|
|
});
|
|
});
|
|
});
|