mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-03 23:00:14 -05:00
2768f5bb72
refs: https://github.com/TryGhost/Toolbox/issues/168 - The fixture represented Casper at Ghost version 1.0 which pre-dated the introduction of the posts_per_page config in package.json - When Casper was upgraded to 2.0 in the fixtures, the lack of pagination broke the e2e tests for pagination - This change introduces proper code to stub and override posts_per_page rather than keeping and using the old casper-1.4 fixture - It also required me to remove a handful of CSS-based checks which are no longer true in the new theme version, but also didn't really add anything to the tests
537 lines
21 KiB
JavaScript
537 lines
21 KiB
JavaScript
// # Dynamic Routing Tests
|
|
// As it stands, these tests depend on the database, and as such are integration tests.
|
|
// These tests are here to cover the headers sent with requests and high-level redirects that can't be
|
|
// tested with the unit tests
|
|
const should = require('should');
|
|
const supertest = require('supertest');
|
|
const sinon = require('sinon');
|
|
const moment = require('moment');
|
|
const testUtils = require('../../utils');
|
|
const configUtils = require('../../utils/configUtils');
|
|
const cheerio = require('cheerio');
|
|
const config = require('../../../core/shared/config');
|
|
const themeEngine = require('../../../core/frontend/services/theme-engine');
|
|
|
|
let request;
|
|
|
|
describe('Dynamic Routing', function () {
|
|
function doEnd(done) {
|
|
return function (err, res) {
|
|
if (err) {
|
|
return done(err);
|
|
}
|
|
|
|
should.not.exist(res.headers['x-cache-invalidate']);
|
|
should.not.exist(res.headers['X-CSRF-Token']);
|
|
should.not.exist(res.headers['set-cookie']);
|
|
should.exist(res.headers.date);
|
|
|
|
done();
|
|
};
|
|
}
|
|
|
|
before(function () {
|
|
return testUtils.startGhost()
|
|
.then(function () {
|
|
sinon.stub(themeEngine.getActive(), 'config').withArgs('posts_per_page').returns(5);
|
|
request = supertest.agent(config.get('url'));
|
|
});
|
|
});
|
|
|
|
after(function () {
|
|
sinon.restore();
|
|
});
|
|
|
|
describe('Collection Index', function () {
|
|
it('should respond with html', function (done) {
|
|
request.get('/')
|
|
.expect('Content-Type', /html/)
|
|
.expect('Cache-Control', testUtils.cacheRules.public)
|
|
.expect(200)
|
|
.end(function (err, res) {
|
|
if (err) {
|
|
return done(err);
|
|
}
|
|
|
|
const $ = cheerio.load(res.text);
|
|
|
|
should.not.exist(res.headers['x-cache-invalidate']);
|
|
should.not.exist(res.headers['X-CSRF-Token']);
|
|
should.not.exist(res.headers['set-cookie']);
|
|
should.exist(res.headers.date);
|
|
|
|
$('title').text().should.equal('Ghost');
|
|
$('body.home-template').length.should.equal(1);
|
|
$('article.post').length.should.equal(5);
|
|
$('article.tag-getting-started').length.should.equal(5);
|
|
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should not have a third page', function (done) {
|
|
request.get('/page/3/')
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(404)
|
|
.expect(/Page not found/)
|
|
.end(doEnd(done));
|
|
});
|
|
});
|
|
|
|
describe('Collection Entry', function () {
|
|
before(function () {
|
|
return testUtils.initData().then(function () {
|
|
return testUtils.fixtures.overrideOwnerUser();
|
|
}).then(function () {
|
|
return testUtils.fixtures.insertPostsAndTags();
|
|
});
|
|
});
|
|
|
|
it('should render page with slug permalink', function (done) {
|
|
request.get('/static-page-test/')
|
|
.expect('Content-Type', /html/)
|
|
.expect('Cache-Control', testUtils.cacheRules.public)
|
|
.expect(200)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
it('should not render page with dated permalink', function (done) {
|
|
const date = moment().format('YYYY/MM/DD');
|
|
|
|
request.get('/' + date + '/static-page-test/')
|
|
.expect('Content-Type', /html/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(404)
|
|
.end(doEnd(done));
|
|
});
|
|
});
|
|
|
|
describe('Tag', function () {
|
|
before(function (done) {
|
|
testUtils.clearData().then(function () {
|
|
// we initialise data, but not a user. No user should be required for navigating the frontend
|
|
return testUtils.initData();
|
|
}).then(function () {
|
|
return testUtils.fixtures.overrideOwnerUser('ghost-owner');
|
|
}).then(function () {
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
after(testUtils.teardownDb);
|
|
|
|
it('should return HTML for valid route', function (done) {
|
|
request.get('/tag/getting-started/')
|
|
.expect(200)
|
|
.expect('Content-Type', /html/)
|
|
.expect('Content-Type', /html/)
|
|
.expect('Cache-Control', testUtils.cacheRules.public)
|
|
.expect(200)
|
|
.end(function (err, res) {
|
|
if (err) {
|
|
return done(err);
|
|
}
|
|
|
|
const $ = cheerio.load(res.text);
|
|
|
|
should.not.exist(res.headers['x-cache-invalidate']);
|
|
should.not.exist(res.headers['X-CSRF-Token']);
|
|
should.not.exist(res.headers['set-cookie']);
|
|
should.exist(res.headers.date);
|
|
|
|
$('body').attr('class').should.eql('tag-template tag-getting-started');
|
|
$('article.post').length.should.equal(5);
|
|
$('article.tag-getting-started').length.should.equal(5);
|
|
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should 404 for /tag/ route', function (done) {
|
|
request.get('/tag/')
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(404)
|
|
.expect(/Page not found/)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
it('should 404 for unknown tag', function (done) {
|
|
request.get('/tag/spectacular/')
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(404)
|
|
.expect(/Page not found/)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
it('should 404 for unknown tag with invalid characters', function (done) {
|
|
request.get('/tag/~$pectacular~/')
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(404)
|
|
.expect(/Page not found/)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
describe('RSS', function () {
|
|
it('should redirect without slash', function (done) {
|
|
request.get('/tag/getting-started/rss')
|
|
.expect('Location', '/tag/getting-started/rss/')
|
|
.expect('Cache-Control', testUtils.cacheRules.year)
|
|
.expect(301)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
it('should respond with xml', function (done) {
|
|
request.get('/tag/getting-started/rss/')
|
|
.expect('Content-Type', /xml/)
|
|
.expect('Cache-Control', testUtils.cacheRules.public)
|
|
.expect(200)
|
|
.end(doEnd(done));
|
|
});
|
|
});
|
|
|
|
describe('Edit', function () {
|
|
it('should redirect without slash', function (done) {
|
|
request.get('/tag/getting-started/edit')
|
|
.expect('Location', '/tag/getting-started/edit/')
|
|
.expect('Cache-Control', testUtils.cacheRules.year)
|
|
.expect(301)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
it('should redirect to tag settings', function (done) {
|
|
request.get('/tag/getting-started/edit/')
|
|
.expect('Location', 'http://127.0.0.1:2369/ghost/#/tags/getting-started/')
|
|
.expect('Cache-Control', testUtils.cacheRules.public)
|
|
.expect(302)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
it('should 404 for non-edit parameter', function (done) {
|
|
request.get('/tag/getting-started/notedit/')
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(404)
|
|
.expect(/Page not found/)
|
|
.end(doEnd(done));
|
|
});
|
|
});
|
|
|
|
describe('Edit with admin redirects disabled', function () {
|
|
before(function () {
|
|
configUtils.set('admin:redirects', false);
|
|
|
|
return testUtils.startGhost({forceStart: true})
|
|
.then(function () {
|
|
sinon.stub(themeEngine.getActive(), 'config').withArgs('posts_per_page').returns(5);
|
|
request = supertest.agent(config.get('url'));
|
|
});
|
|
});
|
|
|
|
after(function () {
|
|
configUtils.restore();
|
|
|
|
return testUtils.startGhost({forceStart: true})
|
|
.then(function () {
|
|
sinon.stub(themeEngine.getActive(), 'config').withArgs('posts_per_page').returns(5);
|
|
request = supertest.agent(config.get('url'));
|
|
});
|
|
});
|
|
|
|
it('should redirect without slash', function (done) {
|
|
request.get('/tag/getting-started/edit')
|
|
.expect('Location', '/tag/getting-started/edit/')
|
|
.expect('Cache-Control', testUtils.cacheRules.year)
|
|
.expect(301)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
it('should not redirect to admin', function (done) {
|
|
request.get('/tag/getting-started/edit/')
|
|
.expect(404)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.end(doEnd(done));
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('Author', function () {
|
|
const lockedUser = {
|
|
name: 'Locked so what',
|
|
slug: 'locked-so-what',
|
|
email: 'locked@example.com',
|
|
status: 'locked'
|
|
};
|
|
|
|
const suspendedUser = {
|
|
name: 'Suspended meeh',
|
|
slug: 'suspended-meeh',
|
|
email: 'suspended@example.com',
|
|
status: 'inactive'
|
|
};
|
|
|
|
const ownerSlug = 'ghost-owner';
|
|
|
|
before(function (done) {
|
|
testUtils.clearData().then(function () {
|
|
// we initialise data, but not a user. No user should be required for navigating the frontend
|
|
return testUtils.initData();
|
|
}).then(function () {
|
|
return testUtils.fixtures.overrideOwnerUser(ownerSlug);
|
|
}).then(function (insertedUser) {
|
|
return testUtils.fixtures.insertPosts([
|
|
testUtils.DataGenerator.forKnex.createPost({
|
|
author_id: insertedUser.id
|
|
})
|
|
]);
|
|
}).then(function () {
|
|
return testUtils.fixtures.insertOneUser(lockedUser);
|
|
}).then(function (insertedUser) {
|
|
return testUtils.fixtures.insertPosts([
|
|
testUtils.DataGenerator.forKnex.createPost({
|
|
author_id: insertedUser.id
|
|
})
|
|
]);
|
|
}).then(() => {
|
|
return testUtils.fixtures.insertOneUser(suspendedUser);
|
|
}).then(function (insertedUser) {
|
|
return testUtils.fixtures.insertPosts([
|
|
testUtils.DataGenerator.forKnex.createPost({
|
|
author_id: insertedUser.id
|
|
})
|
|
]);
|
|
}).then(function () {
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
after(testUtils.teardownDb);
|
|
|
|
it('should 404 for /author/ route', function (done) {
|
|
request.get('/author/')
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(404)
|
|
.expect(/Page not found/)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
it('should 404 for unknown author', function (done) {
|
|
request.get('/author/spectacular/')
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(404)
|
|
.expect(/Page not found/)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
it('should 404 for unknown author with invalid characters', function (done) {
|
|
request.get('/author/ghost!user^/')
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(404)
|
|
.expect(/Page not found/)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
it('[success] author is locked', function (done) {
|
|
request.get('/author/' + lockedUser.slug + '/')
|
|
.expect('Cache-Control', testUtils.cacheRules.public)
|
|
.expect(200)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
it('[success] author is suspended', function (done) {
|
|
request.get('/author/' + suspendedUser.slug + '/')
|
|
.expect('Cache-Control', testUtils.cacheRules.public)
|
|
.expect(200)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
it('[failure] ghost owner before blog setup', function (done) {
|
|
testUtils.fixtures.changeOwnerUserStatus({
|
|
slug: ownerSlug,
|
|
status: 'inactive'
|
|
}).then(function () {
|
|
request.get('/author/ghost-owner/')
|
|
.expect('Cache-Control', testUtils.cacheRules.public)
|
|
.expect(200)
|
|
.end(doEnd(done));
|
|
}).catch(done);
|
|
});
|
|
|
|
it('[success] ghost owner after blog setup', function (done) {
|
|
testUtils.fixtures.changeOwnerUserStatus({
|
|
slug: ownerSlug,
|
|
status: 'active'
|
|
}).then(function () {
|
|
request.get('/author/ghost-owner/')
|
|
.expect('Cache-Control', testUtils.cacheRules.public)
|
|
.expect(200)
|
|
.end(doEnd(done));
|
|
});
|
|
});
|
|
|
|
describe('RSS', function () {
|
|
it('should redirect without slash', function (done) {
|
|
request.get('/author/ghost-owner/rss')
|
|
.expect('Location', '/author/ghost-owner/rss/')
|
|
.expect('Cache-Control', testUtils.cacheRules.year)
|
|
.expect(301)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
it('should respond with xml', function (done) {
|
|
request.get('/author/ghost-owner/rss/')
|
|
.expect('Content-Type', /xml/)
|
|
.expect('Cache-Control', testUtils.cacheRules.public)
|
|
.expect(200)
|
|
.end(doEnd(done));
|
|
});
|
|
});
|
|
|
|
describe('Edit', function () {
|
|
it('should redirect without slash', function (done) {
|
|
request.get('/author/ghost-owner/edit')
|
|
.expect('Location', '/author/ghost-owner/edit/')
|
|
.expect('Cache-Control', testUtils.cacheRules.year)
|
|
.expect(301)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
it('should redirect to editor', function (done) {
|
|
request.get('/author/ghost-owner/edit/')
|
|
.expect('Location', 'http://127.0.0.1:2369/ghost/#/staff/ghost-owner/')
|
|
.expect('Cache-Control', testUtils.cacheRules.public)
|
|
.expect(302)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
it('should 404 for something that isn\'t edit', function (done) {
|
|
request.get('/author/ghost-owner/notedit/')
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(404)
|
|
.expect(/Page not found/)
|
|
.end(doEnd(done));
|
|
});
|
|
});
|
|
|
|
describe('Edit with admin redirects disabled', function () {
|
|
before(function () {
|
|
configUtils.set('admin:redirects', false);
|
|
|
|
return testUtils.startGhost({forceStart: true})
|
|
.then(function () {
|
|
sinon.stub(themeEngine.getActive(), 'config').withArgs('posts_per_page').returns(5);
|
|
request = supertest.agent(config.get('url'));
|
|
});
|
|
});
|
|
|
|
after(function () {
|
|
configUtils.restore();
|
|
|
|
return testUtils.startGhost({forceStart: true})
|
|
.then(function () {
|
|
sinon.stub(themeEngine.getActive(), 'config').withArgs('posts_per_page').returns(5);
|
|
request = supertest.agent(config.get('url'));
|
|
});
|
|
});
|
|
|
|
it('should redirect without slash', function (done) {
|
|
request.get('/author/ghost-owner/edit')
|
|
.expect('Location', '/author/ghost-owner/edit/')
|
|
.expect('Cache-Control', testUtils.cacheRules.year)
|
|
.expect(301)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
it('should not redirect to admin', function (done) {
|
|
request.get('/author/ghost-owner/edit/')
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(404)
|
|
.end(doEnd(done));
|
|
});
|
|
});
|
|
|
|
describe('Paged', function () {
|
|
// Add enough posts to trigger pages
|
|
before(function (done) {
|
|
testUtils.clearData().then(function () {
|
|
// we initialize data, but not a user. No user should be required for navigating the frontend
|
|
return testUtils.initData();
|
|
}).then(function () {
|
|
return testUtils.fixtures.insertPostsAndTags();
|
|
}).then(function () {
|
|
return testUtils.fixtures.insertExtraPosts(9);
|
|
}).then(function () {
|
|
return testUtils.fixtures.overrideOwnerUser('ghost-owner');
|
|
}).then(function () {
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
after(testUtils.teardownDb);
|
|
|
|
it('should redirect without slash', function (done) {
|
|
request.get('/author/ghost-owner/page/2')
|
|
.expect('Location', '/author/ghost-owner/page/2/')
|
|
.expect('Cache-Control', testUtils.cacheRules.year)
|
|
.expect(301)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
it('should respond with html', function (done) {
|
|
request.get('/author/ghost-owner/page/2/')
|
|
.expect('Content-Type', /html/)
|
|
.expect('Cache-Control', testUtils.cacheRules.public)
|
|
.expect(200)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
it('should redirect page 1', function (done) {
|
|
request.get('/author/ghost-owner/page/1/')
|
|
.expect('Location', '/author/ghost-owner/')
|
|
.expect('Cache-Control', testUtils.cacheRules.year)
|
|
.expect(301)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
it('should 404 if page too high', function (done) {
|
|
request.get('/author/ghost-owner/page/6/')
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(404)
|
|
.expect(/Page not found/)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
it('should 404 if page too low', function (done) {
|
|
request.get('/author/ghost-owner/page/0/')
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(404)
|
|
.expect(/Page not found/)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
describe('RSS', function () {
|
|
it('should 404 if index attempted with 0', function (done) {
|
|
request.get('/author/ghost-owner/rss/0/')
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(404)
|
|
.expect(/Page not found/)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
it('should 404 if index attempted with 1', function (done) {
|
|
request.get('/author/ghost-owner/rss/1/')
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(404)
|
|
.expect(/Page not found/)
|
|
.end(doEnd(done));
|
|
});
|
|
|
|
it('should 404 for other pages', function (done) {
|
|
request.get('/author/ghost-owner/rss/2/')
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(404)
|
|
.expect(/Page not found/)
|
|
.end(doEnd(done));
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|