Ghost/test/regression/site/dynamic_routing.test.js
Naz 30de0603ca Fixed dynamic routing test suite
refs https://github.com/TryGhost/Toolbox/issues/230

- Code tweaks to make test suite play nicely without single post author concept
2022-05-09 20:34:06 +08:00

544 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({
authors: [{
id: insertedUser.id
}]
})
]);
}).then(function () {
return testUtils.fixtures.insertOneUser(lockedUser);
}).then(function (insertedUser) {
return testUtils.fixtures.insertPosts([
testUtils.DataGenerator.forKnex.createPost({
authors: [{
id: insertedUser.id
}]
})
]);
}).then(() => {
return testUtils.fixtures.insertOneUser(suspendedUser);
}).then(function (insertedUser) {
return testUtils.fixtures.insertPosts([
testUtils.DataGenerator.forKnex.createPost({
authors: [{
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/#/settings/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));
});
});
});
});
});