Ghost/test/unit/services/routing/CollectionRouter_spec.js
Hannah Wolfe bd597db829
Moved settings/cache to shared/settings-cache
- This is part of the quest to separate the frontend and server & get rid of all the places where there are cross-requires
- At the moment the settings cache is one big shared cache used by the frontend and server liberally
- This change doesn't really solve the fundamental problems, as we still depend on events, and requires from inside frontend
- However it allows us to control the misuse slightly better by getting rid of restricted requires and turning on that eslint ruleset
2021-06-30 15:49:10 +01:00

244 lines
9.8 KiB
JavaScript

const should = require('should');
const sinon = require('sinon');
const express = require('../../../../core/shared/express')._express;
const settingsCache = require('../../../../core/shared/settings-cache');
const events = require('../../../../core/server/lib/common/events');
const controllers = require('../../../../core/frontend/services/routing/controllers');
const CollectionRouter = require('../../../../core/frontend/services/routing/CollectionRouter');
const RESOURCE_CONFIG = {QUERY: {post: {controller: 'posts', resource: 'posts'}}};
describe('UNIT - services/routing/CollectionRouter', function () {
let req;
let res;
let next;
beforeEach(function () {
sinon.stub(events, 'emit');
sinon.stub(events, 'on');
sinon.spy(CollectionRouter.prototype, 'mountRoute');
sinon.spy(CollectionRouter.prototype, 'mountRouter');
sinon.spy(CollectionRouter.prototype, 'unmountRoute');
sinon.spy(express.Router, 'param');
req = sinon.stub();
res = sinon.stub();
next = sinon.stub();
res.locals = {};
});
afterEach(function () {
sinon.restore();
});
describe('instantiate', function () {
it('default', function () {
const collectionRouter = new CollectionRouter('/', {permalink: '/:slug/'}, RESOURCE_CONFIG);
should.exist(collectionRouter.router);
should.not.exist(collectionRouter.getFilter());
collectionRouter.getResourceType().should.eql('posts');
collectionRouter.templates.should.eql([]);
collectionRouter.getPermalinks().getValue().should.eql('/:slug/');
events.emit.calledOnce.should.be.true();
events.emit.calledWith('router.created', collectionRouter).should.be.true();
events.on.calledTwice.should.be.false();
collectionRouter.mountRoute.callCount.should.eql(3);
express.Router.param.callCount.should.eql(2);
// parent route
collectionRouter.mountRoute.args[0][0].should.eql('/');
collectionRouter.mountRoute.args[0][1].should.eql(controllers.collection);
// pagination feature
collectionRouter.mountRoute.args[1][0].should.eql('/page/:page(\\d+)');
collectionRouter.mountRoute.args[1][1].should.eql(controllers.collection);
// permalinks
collectionRouter.mountRoute.args[2][0].should.eql('/:slug/:options(edit)?/');
collectionRouter.mountRoute.args[2][1].should.eql(controllers.entry);
collectionRouter.mountRouter.callCount.should.eql(1);
collectionRouter.mountRouter.args[0][0].should.eql('/');
collectionRouter.mountRouter.args[0][1].should.eql(collectionRouter.rssRouter.router());
});
it('router name', function () {
const collectionRouter1 = new CollectionRouter('/', {permalink: '/:slug/'}, RESOURCE_CONFIG);
const collectionRouter2 = new CollectionRouter('/podcast/', {permalink: '/:slug/'}, RESOURCE_CONFIG);
const collectionRouter3 = new CollectionRouter('/hello/world/', {permalink: '/:slug/'}, RESOURCE_CONFIG);
collectionRouter1.routerName.should.eql('index');
collectionRouter2.routerName.should.eql('podcast');
collectionRouter3.routerName.should.eql('helloworld');
collectionRouter1.context.should.eql(['index']);
collectionRouter2.context.should.eql(['podcast']);
collectionRouter3.context.should.eql(['helloworld']);
});
it('collection lives under /blog/', function () {
const collectionRouter = new CollectionRouter('/blog/', {permalink: '/blog/:year/:slug/'}, RESOURCE_CONFIG);
should.exist(collectionRouter.router);
should.not.exist(collectionRouter.getFilter());
collectionRouter.getResourceType().should.eql('posts');
collectionRouter.templates.should.eql([]);
collectionRouter.getPermalinks().getValue().should.eql('/blog/:year/:slug/');
events.emit.calledOnce.should.be.true();
events.emit.calledWith('router.created', collectionRouter).should.be.true();
events.on.calledTwice.should.be.false();
collectionRouter.mountRoute.callCount.should.eql(3);
// parent route
collectionRouter.mountRoute.args[0][0].should.eql('/blog/');
collectionRouter.mountRoute.args[0][1].should.eql(controllers.collection);
// pagination feature
collectionRouter.mountRoute.args[1][0].should.eql('/blog/page/:page(\\d+)');
collectionRouter.mountRoute.args[1][1].should.eql(controllers.collection);
// permalinks
collectionRouter.mountRoute.args[2][0].should.eql('/blog/:year/:slug/:options(edit)?/');
collectionRouter.mountRoute.args[2][1].should.eql(controllers.entry);
collectionRouter.mountRouter.callCount.should.eql(1);
collectionRouter.mountRouter.args[0][0].should.eql('/blog/');
collectionRouter.mountRouter.args[0][1].should.eql(collectionRouter.rssRouter.router());
});
it('with custom filter', function () {
const collectionRouter = new CollectionRouter('/', {permalink: '/:slug/', filter: 'featured:true'}, RESOURCE_CONFIG);
collectionRouter.getFilter().should.eql('featured:true');
});
it('with templates', function () {
const collectionRouter = new CollectionRouter('/magic/', {permalink: '/:slug/', templates: ['home', 'index']}, RESOURCE_CONFIG);
// they are getting reversed because we unshift the templates in the helper
collectionRouter.templates.should.eql(['index', 'home']);
});
});
describe('fn: _prepareEntriesContext', function () {
it('index collection', function () {
const collectionRouter = new CollectionRouter('/', {permalink: '/:slug/'}, RESOURCE_CONFIG);
collectionRouter._prepareEntriesContext(req, res, next);
next.calledOnce.should.be.true();
res.routerOptions.should.eql({
type: 'collection',
filter: undefined,
permalinks: '/:slug/:options(edit)?/',
query: {controller: 'posts', resource: 'posts'},
frontPageTemplate: 'home',
templates: [],
identifier: collectionRouter.identifier,
context: ['index'],
name: 'index',
resourceType: 'posts',
data: {},
order: undefined,
limit: undefined
});
});
it('with templates, with order + limit, no index collection', function () {
const collectionRouter = new CollectionRouter('/magic/', {
permalink: '/:slug/',
order: 'published asc',
limit: 19,
templates: ['home', 'index']
}, RESOURCE_CONFIG);
collectionRouter._prepareEntriesContext(req, res, next);
next.calledOnce.should.be.true();
res.routerOptions.should.eql({
type: 'collection',
filter: undefined,
permalinks: '/:slug/:options(edit)?/',
query: {controller: 'posts', resource: 'posts'},
frontPageTemplate: 'home',
templates: ['index', 'home'],
identifier: collectionRouter.identifier,
context: ['magic'],
name: 'magic',
resourceType: 'posts',
data: {},
order: 'published asc',
limit: 19
});
});
});
describe('timezone changes', function () {
describe('no dated permalink', function () {
it('default', function () {
const collectionRouter = new CollectionRouter('/magic/', {permalink: '/:slug/'}, RESOURCE_CONFIG);
sinon.stub(collectionRouter, 'emit');
events.on.args[0][1]({
attributes: {value: 'America/Los_Angeles'},
_previousAttributes: {value: 'Europe/London'}
});
collectionRouter.emit.called.should.be.false();
});
it('tz has not changed', function () {
const collectionRouter = new CollectionRouter('/magic/', {permalink: '/:slug/'}, RESOURCE_CONFIG);
sinon.stub(collectionRouter, 'emit');
events.on.args[0][1]({
attributes: {value: 'America/Los_Angeles'},
_previousAttributes: {value: 'America/Los_Angeles'}
});
collectionRouter.emit.called.should.be.false();
});
});
describe('with dated permalink', function () {
it('default', function () {
const collectionRouter = new CollectionRouter('/magic/', {permalink: '/:year/:slug/'}, RESOURCE_CONFIG);
sinon.stub(collectionRouter, 'emit');
events.on.args[0][1]({
attributes: {value: 'America/Los_Angeles'},
_previousAttributes: {value: 'Europe/London'}
});
collectionRouter.emit.calledOnce.should.be.true();
});
it('tz has not changed', function () {
const collectionRouter = new CollectionRouter('/magic/', {permalink: '/:year/:slug/'}, RESOURCE_CONFIG);
sinon.stub(collectionRouter, 'emit');
events.on.args[0][1]({
attributes: {value: 'America/Los_Angeles'},
_previousAttributes: {value: 'America/Los_Angeles'}
});
collectionRouter.emit.called.should.be.false();
});
});
});
});