mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-21 18:01:36 +03:00
e4074286df
- e2e tests are tests that cover critical functionality by booting ghost - integration tests are more like unit tests, but need to initialise and use a db - so settings shouldn't start Ghost, url service is critical and should be in integration, and preview is critical and should be in e2e
613 lines
22 KiB
JavaScript
613 lines
22 KiB
JavaScript
const _ = require('lodash');
|
|
const should = require('should');
|
|
const sinon = require('sinon');
|
|
const rewire = require('rewire');
|
|
const testUtils = require('../utils');
|
|
const configUtils = require('../utils/configUtils');
|
|
const models = require('../../core/server/models');
|
|
const events = require('../../core/server/lib/common/events');
|
|
const UrlService = rewire('../../core/frontend/services/url/UrlService');
|
|
|
|
/**
|
|
* @NOTE
|
|
*
|
|
* If this test fails for you, you are probably modifying supported theme engines
|
|
* and thus should check if the there is a configuration added for the new API version
|
|
*
|
|
*/
|
|
describe('Integration: services/url/UrlService', function () {
|
|
let urlService;
|
|
|
|
before(function () {
|
|
models.init();
|
|
});
|
|
|
|
before(testUtils.teardownDb);
|
|
before(testUtils.setup('users:roles', 'posts'));
|
|
after(testUtils.teardownDb);
|
|
|
|
after(function () {
|
|
sinon.restore();
|
|
});
|
|
|
|
describe('functional: default routing set', function () {
|
|
let router1;
|
|
let router2;
|
|
let router3;
|
|
let router4;
|
|
|
|
before(function (done) {
|
|
urlService = new UrlService();
|
|
|
|
router1 = {
|
|
getFilter: sinon.stub(),
|
|
addListener: sinon.stub(),
|
|
getResourceType: sinon.stub(),
|
|
getPermalinks: sinon.stub(),
|
|
toString: function () {
|
|
return 'post collection';
|
|
}
|
|
};
|
|
|
|
router2 = {
|
|
getFilter: sinon.stub(),
|
|
addListener: sinon.stub(),
|
|
getResourceType: sinon.stub(),
|
|
getPermalinks: sinon.stub(),
|
|
toString: function () {
|
|
return 'authors';
|
|
}
|
|
};
|
|
|
|
router3 = {
|
|
getFilter: sinon.stub(),
|
|
addListener: sinon.stub(),
|
|
getResourceType: sinon.stub(),
|
|
getPermalinks: sinon.stub(),
|
|
toString: function () {
|
|
return 'tags';
|
|
}
|
|
};
|
|
|
|
router4 = {
|
|
getFilter: sinon.stub(),
|
|
addListener: sinon.stub(),
|
|
getResourceType: sinon.stub(),
|
|
getPermalinks: sinon.stub(),
|
|
toString: function () {
|
|
return 'static pages';
|
|
}
|
|
};
|
|
|
|
router1.getFilter.returns('featured:false');
|
|
router1.getResourceType.returns('posts');
|
|
router1.getPermalinks.returns({
|
|
getValue: function () {
|
|
return '/:slug/';
|
|
}
|
|
});
|
|
|
|
router2.getFilter.returns(false);
|
|
router2.getResourceType.returns('authors');
|
|
router2.getPermalinks.returns({
|
|
getValue: function () {
|
|
return '/author/:slug/';
|
|
}
|
|
});
|
|
|
|
router3.getFilter.returns(false);
|
|
router3.getResourceType.returns('tags');
|
|
router3.getPermalinks.returns({
|
|
getValue: function () {
|
|
return '/tag/:slug/';
|
|
}
|
|
});
|
|
|
|
router4.getFilter.returns(false);
|
|
router4.getResourceType.returns('pages');
|
|
router4.getPermalinks.returns({
|
|
getValue: function () {
|
|
return '/:slug/';
|
|
}
|
|
});
|
|
|
|
events.emit('router.created', router1);
|
|
events.emit('router.created', router2);
|
|
events.emit('router.created', router3);
|
|
events.emit('router.created', router4);
|
|
|
|
// We can't use our url service utils here, because this is a local copy of the urlService, not the singletone
|
|
urlService.init();
|
|
|
|
let timeout;
|
|
(function retry() {
|
|
clearTimeout(timeout);
|
|
|
|
if (urlService.hasFinished()) {
|
|
return done();
|
|
}
|
|
|
|
setTimeout(retry, 50);
|
|
})();
|
|
});
|
|
|
|
after(function () {
|
|
urlService.reset();
|
|
});
|
|
|
|
it('check url generators', function () {
|
|
urlService.urlGenerators.length.should.eql(4);
|
|
urlService.urlGenerators[0].router.should.eql(router1);
|
|
urlService.urlGenerators[1].router.should.eql(router2);
|
|
urlService.urlGenerators[2].router.should.eql(router3);
|
|
urlService.urlGenerators[3].router.should.eql(router4);
|
|
});
|
|
|
|
it('getUrl', function () {
|
|
urlService.urlGenerators.forEach(function (generator) {
|
|
if (generator.router.getResourceType() === 'posts') {
|
|
generator.getUrls().length.should.eql(2);
|
|
}
|
|
|
|
if (generator.router.getResourceType() === 'pages') {
|
|
generator.getUrls().length.should.eql(1);
|
|
}
|
|
|
|
if (generator.router.getResourceType() === 'tags') {
|
|
generator.getUrls().length.should.eql(3);
|
|
}
|
|
|
|
if (generator.router.getResourceType() === 'authors') {
|
|
generator.getUrls().length.should.eql(2);
|
|
}
|
|
});
|
|
|
|
let url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.posts[0].id);
|
|
url.should.eql('/html-ipsum/');
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.posts[1].id);
|
|
url.should.eql('/ghostly-kitchen-sink/');
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.posts[2].id);
|
|
url.should.eql('/404/');
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.tags[0].id);
|
|
url.should.eql('/tag/kitchen-sink/');
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.tags[1].id);
|
|
url.should.eql('/tag/bacon/');
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.tags[2].id);
|
|
url.should.eql('/tag/chorizo/');
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.tags[3].id);
|
|
url.should.eql('/404/'); // tags with no posts should not be public
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[0].id);
|
|
url.should.eql('/author/joe-bloggs/');
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[1].id);
|
|
url.should.eql('/404/'); // users with no posts should not be public
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[2].id);
|
|
url.should.eql('/404/'); // users with no posts should not be public
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[3].id);
|
|
url.should.eql('/author/slimer-mcectoplasm/');
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[4].id);
|
|
url.should.eql('/404/'); // users with no posts should not be public
|
|
});
|
|
|
|
it('getResource', function () {
|
|
let resource = urlService.getResource('/html-ipsum/');
|
|
resource.data.id.should.eql(testUtils.DataGenerator.forKnex.posts[0].id);
|
|
|
|
resource = urlService.getResource('/does-not-exist/');
|
|
should.not.exist(resource);
|
|
});
|
|
});
|
|
|
|
describe('functional: extended/modified routing set', function () {
|
|
let router1;
|
|
let router2;
|
|
let router3;
|
|
let router4;
|
|
let router5;
|
|
|
|
before(testUtils.teardownDb);
|
|
before(testUtils.setup('users:roles', 'posts'));
|
|
|
|
before(function () {
|
|
urlService.resetGenerators();
|
|
});
|
|
|
|
before(function (done) {
|
|
urlService = new UrlService();
|
|
|
|
router1 = {
|
|
getFilter: sinon.stub(),
|
|
addListener: sinon.stub(),
|
|
getResourceType: sinon.stub(),
|
|
getPermalinks: sinon.stub(),
|
|
toString: function () {
|
|
return 'post collection 1';
|
|
}
|
|
};
|
|
|
|
router2 = {
|
|
getFilter: sinon.stub(),
|
|
addListener: sinon.stub(),
|
|
getResourceType: sinon.stub(),
|
|
getPermalinks: sinon.stub(),
|
|
toString: function () {
|
|
return 'post collection 2';
|
|
}
|
|
};
|
|
|
|
router3 = {
|
|
getFilter: sinon.stub(),
|
|
addListener: sinon.stub(),
|
|
getResourceType: sinon.stub(),
|
|
getPermalinks: sinon.stub(),
|
|
toString: function () {
|
|
return 'authors';
|
|
}
|
|
};
|
|
|
|
router4 = {
|
|
getFilter: sinon.stub(),
|
|
addListener: sinon.stub(),
|
|
getResourceType: sinon.stub(),
|
|
getPermalinks: sinon.stub(),
|
|
toString: function () {
|
|
return 'tags';
|
|
}
|
|
};
|
|
|
|
router5 = {
|
|
getFilter: sinon.stub(),
|
|
addListener: sinon.stub(),
|
|
getResourceType: sinon.stub(),
|
|
getPermalinks: sinon.stub(),
|
|
toString: function () {
|
|
return 'static pages';
|
|
}
|
|
};
|
|
|
|
router1.getFilter.returns('featured:true');
|
|
router1.getResourceType.returns('posts');
|
|
router1.getPermalinks.returns({
|
|
getValue: function () {
|
|
return '/podcast/:slug/';
|
|
}
|
|
});
|
|
|
|
router2.getFilter.returns('page:false');
|
|
router2.getResourceType.returns('posts');
|
|
router2.getPermalinks.returns({
|
|
getValue: function () {
|
|
return '/collection/:year/:slug/';
|
|
}
|
|
});
|
|
|
|
router3.getFilter.returns(false);
|
|
router3.getResourceType.returns('authors');
|
|
router3.getPermalinks.returns({
|
|
getValue: function () {
|
|
return '/persons/:slug/';
|
|
}
|
|
});
|
|
|
|
router4.getFilter.returns(false);
|
|
router4.getResourceType.returns('tags');
|
|
router4.getPermalinks.returns({
|
|
getValue: function () {
|
|
return '/category/:slug/';
|
|
}
|
|
});
|
|
|
|
router5.getFilter.returns(false);
|
|
router5.getResourceType.returns('pages');
|
|
router5.getPermalinks.returns({
|
|
getValue: function () {
|
|
return '/:slug/';
|
|
}
|
|
});
|
|
|
|
events.emit('router.created', router1);
|
|
events.emit('router.created', router2);
|
|
events.emit('router.created', router3);
|
|
events.emit('router.created', router4);
|
|
events.emit('router.created', router5);
|
|
|
|
// We can't use our url service utils here, because this is a local copy of the urlService, not the singletone
|
|
urlService.init();
|
|
|
|
let timeout;
|
|
(function retry() {
|
|
clearTimeout(timeout);
|
|
|
|
if (urlService.hasFinished()) {
|
|
return done();
|
|
}
|
|
|
|
setTimeout(retry, 50);
|
|
})();
|
|
});
|
|
|
|
after(function () {
|
|
urlService.resetGenerators();
|
|
});
|
|
|
|
it('check url generators', function () {
|
|
urlService.urlGenerators.length.should.eql(5);
|
|
urlService.urlGenerators[0].router.should.eql(router1);
|
|
urlService.urlGenerators[1].router.should.eql(router2);
|
|
urlService.urlGenerators[2].router.should.eql(router3);
|
|
urlService.urlGenerators[3].router.should.eql(router4);
|
|
urlService.urlGenerators[4].router.should.eql(router5);
|
|
});
|
|
|
|
it('getUrl', function () {
|
|
urlService.urlGenerators.forEach(function (generator) {
|
|
if (generator.router.getResourceType() === 'posts' && generator.router.getFilter() === 'page:false') {
|
|
generator.getUrls().length.should.eql(2);
|
|
}
|
|
|
|
if (generator.router.getResourceType() === 'posts' && generator.router.getFilter() === 'featured:true') {
|
|
generator.getUrls().length.should.eql(2);
|
|
}
|
|
|
|
if (generator.router.getResourceType() === 'pages') {
|
|
generator.getUrls().length.should.eql(1);
|
|
}
|
|
|
|
if (generator.router.getResourceType() === 'tags') {
|
|
generator.getUrls().length.should.eql(3);
|
|
}
|
|
|
|
if (generator.router.getResourceType() === 'authors') {
|
|
generator.getUrls().length.should.eql(2);
|
|
}
|
|
});
|
|
|
|
let url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.posts[0].id);
|
|
url.should.eql('/collection/2015/html-ipsum/');
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.posts[1].id);
|
|
url.should.eql('/collection/2015/ghostly-kitchen-sink/');
|
|
|
|
// featured
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.posts[2].id);
|
|
url.should.eql('/podcast/short-and-sweet/');
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.tags[0].id);
|
|
url.should.eql('/category/kitchen-sink/');
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.tags[1].id);
|
|
url.should.eql('/category/bacon/');
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.tags[2].id);
|
|
url.should.eql('/category/chorizo/');
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.tags[3].id);
|
|
url.should.eql('/404/'); // tags with no posts should not be public
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[0].id);
|
|
url.should.eql('/persons/joe-bloggs/');
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[1].id);
|
|
url.should.eql('/404/'); // users with no posts should not be public
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[2].id);
|
|
url.should.eql('/404/'); // users with no posts should not be public
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[3].id);
|
|
url.should.eql('/persons/slimer-mcectoplasm/');
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[4].id);
|
|
url.should.eql('/404/'); // users with no posts should not be public
|
|
});
|
|
});
|
|
|
|
describe('functional: subdirectory', function () {
|
|
let router1;
|
|
let router2;
|
|
let router3;
|
|
let router4;
|
|
let router5;
|
|
|
|
beforeEach(function (done) {
|
|
configUtils.set('url', 'http://localhost:2388/blog/');
|
|
|
|
urlService = new UrlService();
|
|
|
|
router1 = {
|
|
getFilter: sinon.stub(),
|
|
addListener: sinon.stub(),
|
|
getResourceType: sinon.stub(),
|
|
getPermalinks: sinon.stub(),
|
|
toString: function () {
|
|
return 'post collection 1';
|
|
}
|
|
};
|
|
|
|
router2 = {
|
|
getFilter: sinon.stub(),
|
|
addListener: sinon.stub(),
|
|
getResourceType: sinon.stub(),
|
|
getPermalinks: sinon.stub(),
|
|
toString: function () {
|
|
return 'post collection 2';
|
|
}
|
|
};
|
|
|
|
router3 = {
|
|
getFilter: sinon.stub(),
|
|
addListener: sinon.stub(),
|
|
getResourceType: sinon.stub(),
|
|
getPermalinks: sinon.stub(),
|
|
toString: function () {
|
|
return 'authors';
|
|
}
|
|
};
|
|
|
|
router4 = {
|
|
getFilter: sinon.stub(),
|
|
addListener: sinon.stub(),
|
|
getResourceType: sinon.stub(),
|
|
getPermalinks: sinon.stub(),
|
|
toString: function () {
|
|
return 'tags';
|
|
}
|
|
};
|
|
|
|
router5 = {
|
|
getFilter: sinon.stub(),
|
|
addListener: sinon.stub(),
|
|
getResourceType: sinon.stub(),
|
|
getPermalinks: sinon.stub(),
|
|
toString: function () {
|
|
return 'static pages';
|
|
}
|
|
};
|
|
|
|
router1.getFilter.returns('featured:false');
|
|
router1.getResourceType.returns('posts');
|
|
router1.getPermalinks.returns({
|
|
getValue: function () {
|
|
return '/collection/:year/:slug/';
|
|
}
|
|
});
|
|
|
|
router2.getFilter.returns('featured:true');
|
|
router2.getResourceType.returns('posts');
|
|
router2.getPermalinks.returns({
|
|
getValue: function () {
|
|
return '/podcast/:slug/';
|
|
}
|
|
});
|
|
|
|
router3.getFilter.returns(false);
|
|
router3.getResourceType.returns('authors');
|
|
router3.getPermalinks.returns({
|
|
getValue: function () {
|
|
return '/persons/:slug/';
|
|
}
|
|
});
|
|
|
|
router4.getFilter.returns(false);
|
|
router4.getResourceType.returns('tags');
|
|
router4.getPermalinks.returns({
|
|
getValue: function () {
|
|
return '/category/:slug/';
|
|
}
|
|
});
|
|
|
|
router5.getFilter.returns(false);
|
|
router5.getResourceType.returns('pages');
|
|
router5.getPermalinks.returns({
|
|
getValue: function () {
|
|
return '/:slug/';
|
|
}
|
|
});
|
|
|
|
events.emit('router.created', router1);
|
|
events.emit('router.created', router2);
|
|
events.emit('router.created', router3);
|
|
events.emit('router.created', router4);
|
|
events.emit('router.created', router5);
|
|
|
|
// We can't use our url service utils here, because this is a local copy of the urlService, not the singletone
|
|
urlService.init();
|
|
|
|
let timeout;
|
|
(function retry() {
|
|
clearTimeout(timeout);
|
|
|
|
if (urlService.hasFinished()) {
|
|
return done();
|
|
}
|
|
|
|
setTimeout(retry, 50);
|
|
})();
|
|
});
|
|
|
|
afterEach(function () {
|
|
urlService.resetGenerators();
|
|
configUtils.restore();
|
|
});
|
|
|
|
it('check url generators', function () {
|
|
urlService.urlGenerators.length.should.eql(5);
|
|
urlService.urlGenerators[0].router.should.eql(router1);
|
|
urlService.urlGenerators[1].router.should.eql(router2);
|
|
urlService.urlGenerators[2].router.should.eql(router3);
|
|
urlService.urlGenerators[3].router.should.eql(router4);
|
|
urlService.urlGenerators[4].router.should.eql(router5);
|
|
});
|
|
|
|
it('getUrl', function () {
|
|
urlService.urlGenerators.forEach(function (generator) {
|
|
if (generator.router.getResourceType() === 'posts' && generator.router.getFilter() === 'featured:false') {
|
|
generator.getUrls().length.should.eql(2);
|
|
}
|
|
|
|
if (generator.router.getResourceType() === 'posts' && generator.router.getFilter() === 'featured:true') {
|
|
generator.getUrls().length.should.eql(2);
|
|
}
|
|
|
|
if (generator.router.getResourceType() === 'pages') {
|
|
generator.getUrls().length.should.eql(1);
|
|
}
|
|
|
|
if (generator.router.getResourceType() === 'tags') {
|
|
generator.getUrls().length.should.eql(3);
|
|
}
|
|
|
|
if (generator.router.getResourceType() === 'authors') {
|
|
generator.getUrls().length.should.eql(2);
|
|
}
|
|
});
|
|
|
|
let url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.posts[0].id);
|
|
url.should.eql('/collection/2015/html-ipsum/');
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.posts[1].id);
|
|
url.should.eql('/collection/2015/ghostly-kitchen-sink/');
|
|
|
|
// featured
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.posts[2].id);
|
|
url.should.eql('/podcast/short-and-sweet/');
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.tags[0].id);
|
|
url.should.eql('/category/kitchen-sink/');
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.tags[1].id);
|
|
url.should.eql('/category/bacon/');
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.tags[2].id);
|
|
url.should.eql('/category/chorizo/');
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.tags[3].id);
|
|
url.should.eql('/404/'); // tags with no posts should not be public
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[0].id);
|
|
url.should.eql('/persons/joe-bloggs/');
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[1].id);
|
|
url.should.eql('/404/'); // users with no posts should not be public
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[2].id);
|
|
url.should.eql('/404/'); // users with no posts should not be public
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[3].id);
|
|
url.should.eql('/persons/slimer-mcectoplasm/');
|
|
|
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[4].id);
|
|
url.should.eql('/404/'); // users with no posts should not be public
|
|
});
|
|
});
|
|
});
|