mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-10 23:36:14 -05:00
🔥 Removed V1 code/references in frontend resources/routing layer (#11087)
no issue - Removed v1 'author' leftover in include statement for preview controller - Removed v1 'author' leftover in include statement for preview controller - Removed v1 'author' leftover in include statement in entry lookup routing helper - Migrated related test to use v2 API controller - Removed v0.1 routing confif - Removed v0.1 url config - Fixed tests that had to do with url's in resources after removing v0.1 resources from URL cache - Removed v1 'author' leftover in include statement in static routing helper - Modified the test to use v2 API - Removed v1 specific condition with 'page' in context helper - Fixed dynamic routing spec after theme switch to v2. All tested users have to have at least one published post to be shown as an author - Fixed URL Service spec to use theme engine v2
This commit is contained in:
parent
a9050f68ea
commit
7dc38e2078
20 changed files with 143 additions and 2964 deletions
|
@ -1,70 +0,0 @@
|
||||||
/* eslint-disable */
|
|
||||||
module.exports.QUERY = {
|
|
||||||
tag: {
|
|
||||||
controller: 'tags',
|
|
||||||
type: 'read',
|
|
||||||
resource: 'tags',
|
|
||||||
options: {
|
|
||||||
slug: '%s',
|
|
||||||
visibility: 'public'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
author: {
|
|
||||||
resourceAlias: 'authors',
|
|
||||||
controller: 'users',
|
|
||||||
type: 'read',
|
|
||||||
resource: 'users',
|
|
||||||
options: {
|
|
||||||
slug: '%s',
|
|
||||||
visibility: 'public'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
user: {
|
|
||||||
resourceAlias: 'authors',
|
|
||||||
controller: 'users',
|
|
||||||
type: 'read',
|
|
||||||
resource: 'users',
|
|
||||||
options: {
|
|
||||||
slug: '%s',
|
|
||||||
visibility: 'public'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
post: {
|
|
||||||
controller: 'posts',
|
|
||||||
type: 'read',
|
|
||||||
resource: 'posts',
|
|
||||||
options: {
|
|
||||||
slug: '%s',
|
|
||||||
status: 'published',
|
|
||||||
page: 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
page: {
|
|
||||||
controller: 'posts',
|
|
||||||
type: 'read',
|
|
||||||
resource: 'posts',
|
|
||||||
options: {
|
|
||||||
slug: '%s',
|
|
||||||
status: 'published',
|
|
||||||
page: 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
preview: {
|
|
||||||
controller: 'posts',
|
|
||||||
resource: 'posts'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.TAXONOMIES = {
|
|
||||||
tag: {
|
|
||||||
filter: 'tags:\'%s\'+tags.visibility:public',
|
|
||||||
editRedirect: '#/settings/tags/:slug/',
|
|
||||||
resource: 'tags'
|
|
||||||
},
|
|
||||||
author: {
|
|
||||||
filter: 'authors:\'%s\'',
|
|
||||||
editRedirect: '#/team/:slug/',
|
|
||||||
resource: 'authors'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
/* eslint-enable */
|
|
|
@ -67,13 +67,6 @@ module.exports = function entryController(req, res, next) {
|
||||||
* @NOTE:
|
* @NOTE:
|
||||||
*
|
*
|
||||||
* Ensure we redirect to the correct post url including subdirectory.
|
* Ensure we redirect to the correct post url including subdirectory.
|
||||||
*
|
|
||||||
* @NOTE:
|
|
||||||
* Keep in mind, that the logic here is used for v0.1 and v2.
|
|
||||||
* v0.1 returns relative urls, v2 returns absolute urls.
|
|
||||||
*
|
|
||||||
* @TODO:
|
|
||||||
* Simplify if we drop v0.1.
|
|
||||||
*/
|
*/
|
||||||
if (urlUtils.absoluteToRelative(entry.url, {withoutSubdirectory: true}) !== req.path) {
|
if (urlUtils.absoluteToRelative(entry.url, {withoutSubdirectory: true}) !== req.path) {
|
||||||
debug('redirect');
|
debug('redirect');
|
||||||
|
|
|
@ -18,8 +18,7 @@ module.exports = function previewController(req, res, next) {
|
||||||
const params = {
|
const params = {
|
||||||
uuid: req.params.uuid,
|
uuid: req.params.uuid,
|
||||||
status: 'all',
|
status: 'all',
|
||||||
// @TODO: Remove "author" if we drop v0.1
|
include: 'authors,tags'
|
||||||
include: 'author,authors,tags'
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return api[res.routerOptions.query.controller]
|
return api[res.routerOptions.query.controller]
|
||||||
|
|
|
@ -14,8 +14,7 @@ function processQuery(query, locals) {
|
||||||
// We override the `include` property for now, because the full data set is required anyway.
|
// We override the `include` property for now, because the full data set is required anyway.
|
||||||
if (_.get(query, 'resource') === 'posts') {
|
if (_.get(query, 'resource') === 'posts') {
|
||||||
_.extend(query.options, {
|
_.extend(query.options, {
|
||||||
// @TODO: Remove "author" when we drop v0.1
|
include: 'authors,tags'
|
||||||
include: 'author,authors,tags'
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ function setResponseContext(req, res, data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add context 'amp' to either post or page, if we have an `*/amp` route
|
// Add context 'amp' to either post or page, if we have an `*/amp` route
|
||||||
if (ampPattern.test(res.locals.relativeUrl) && data.post) {
|
if (ampPattern.test(res.locals.relativeUrl) && (data.post || data.page)) {
|
||||||
res.locals.context.push('amp');
|
res.locals.context.push('amp');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,12 +64,7 @@ function setResponseContext(req, res, data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @TODO: remove first if condition when we drop v0.1
|
if (data && data.post) {
|
||||||
if (data && data.post && data.post.page) {
|
|
||||||
if (!res.locals.context.includes('page')) {
|
|
||||||
res.locals.context.push('page');
|
|
||||||
}
|
|
||||||
} else if (data && data.post) {
|
|
||||||
if (!res.locals.context.includes('post')) {
|
if (!res.locals.context.includes('post')) {
|
||||||
res.locals.context.push('post');
|
res.locals.context.push('post');
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,11 +40,7 @@ function entryLookup(postUrl, routerOptions, locals) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let options = {
|
let options = {
|
||||||
/**
|
include: 'authors,tags'
|
||||||
* @deprecated: `author`, will be removed in Ghost 3.0
|
|
||||||
* @TODO: Remove "author" when we drop v0.1
|
|
||||||
*/
|
|
||||||
include: 'author,authors,tags'
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (config.get('enableDeveloperExperiments')) {
|
if (config.get('enableDeveloperExperiments')) {
|
||||||
|
|
|
@ -7,7 +7,7 @@ const Promise = require('bluebird');
|
||||||
const config = require('../../../../server/config');
|
const config = require('../../../../server/config');
|
||||||
|
|
||||||
// The default settings for a default post query
|
// The default settings for a default post query
|
||||||
// @TODO: get rid of this config and use v0.1 or v2 config
|
// @TODO: get rid of this config and use v2, v3 config
|
||||||
const queryDefaults = {
|
const queryDefaults = {
|
||||||
type: 'browse',
|
type: 'browse',
|
||||||
resource: 'posts',
|
resource: 'posts',
|
||||||
|
@ -22,9 +22,8 @@ const defaultQueryOptions = {
|
||||||
options: {
|
options: {
|
||||||
/**
|
/**
|
||||||
* @deprecated: `author`, will be removed in Ghost 3.0
|
* @deprecated: `author`, will be removed in Ghost 3.0
|
||||||
* @TODO: Remove "author" when we drop v0.1
|
|
||||||
*/
|
*/
|
||||||
include: 'author,authors,tags'
|
include: 'authors,tags'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,121 +0,0 @@
|
||||||
/*
|
|
||||||
* These are the default resources and filters.
|
|
||||||
* They contain minimum filters for public accessibility of resources.
|
|
||||||
*/
|
|
||||||
|
|
||||||
module.exports = [
|
|
||||||
{
|
|
||||||
type: 'posts',
|
|
||||||
modelOptions: {
|
|
||||||
modelName: 'Post',
|
|
||||||
filter: 'visibility:public+status:published+page:false',
|
|
||||||
exclude: [
|
|
||||||
'title',
|
|
||||||
'mobiledoc',
|
|
||||||
'html',
|
|
||||||
'plaintext',
|
|
||||||
'amp',
|
|
||||||
'codeinjection_head',
|
|
||||||
'codeinjection_foot',
|
|
||||||
'meta_title',
|
|
||||||
'meta_description',
|
|
||||||
'custom_excerpt',
|
|
||||||
'og_image',
|
|
||||||
'og_title',
|
|
||||||
'og_description',
|
|
||||||
'twitter_image',
|
|
||||||
'twitter_title',
|
|
||||||
'twitter_description',
|
|
||||||
'custom_template',
|
|
||||||
'locale'
|
|
||||||
],
|
|
||||||
withRelated: ['tags', 'authors'],
|
|
||||||
withRelatedPrimary: {
|
|
||||||
primary_tag: 'tags',
|
|
||||||
primary_author: 'authors'
|
|
||||||
},
|
|
||||||
withRelatedFields: {
|
|
||||||
tags: ['tags.id', 'tags.slug'],
|
|
||||||
authors: ['users.id', 'users.slug']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
events: {
|
|
||||||
add: 'post.published',
|
|
||||||
update: 'post.published.edited',
|
|
||||||
remove: 'post.unpublished'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'pages',
|
|
||||||
modelOptions: {
|
|
||||||
modelName: 'Post',
|
|
||||||
exclude: [
|
|
||||||
'title',
|
|
||||||
'mobiledoc',
|
|
||||||
'html',
|
|
||||||
'plaintext',
|
|
||||||
'amp',
|
|
||||||
'codeinjection_head',
|
|
||||||
'codeinjection_foot',
|
|
||||||
'meta_title',
|
|
||||||
'meta_description',
|
|
||||||
'custom_excerpt',
|
|
||||||
'og_image',
|
|
||||||
'og_title',
|
|
||||||
'og_description',
|
|
||||||
'twitter_image',
|
|
||||||
'twitter_title',
|
|
||||||
'twitter_description',
|
|
||||||
'custom_template',
|
|
||||||
'locale',
|
|
||||||
'tags',
|
|
||||||
'authors',
|
|
||||||
'primary_tag',
|
|
||||||
'primary_author'
|
|
||||||
],
|
|
||||||
filter: 'visibility:public+status:published+page:true'
|
|
||||||
},
|
|
||||||
events: {
|
|
||||||
add: 'page.published',
|
|
||||||
update: 'page.published.edited',
|
|
||||||
remove: 'page.unpublished'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'tags',
|
|
||||||
keep: ['id', 'slug', 'updated_at', 'created_at'],
|
|
||||||
modelOptions: {
|
|
||||||
modelName: 'Tag',
|
|
||||||
exclude: ['description', 'meta_title', 'meta_description'],
|
|
||||||
filter: 'visibility:public'
|
|
||||||
},
|
|
||||||
events: {
|
|
||||||
add: 'tag.added',
|
|
||||||
update: 'tag.edited',
|
|
||||||
remove: 'tag.deleted'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'authors',
|
|
||||||
modelOptions: {
|
|
||||||
modelName: 'User',
|
|
||||||
exclude: [
|
|
||||||
'bio',
|
|
||||||
'website',
|
|
||||||
'location',
|
|
||||||
'facebook',
|
|
||||||
'twitter',
|
|
||||||
'accessibility',
|
|
||||||
'meta_title',
|
|
||||||
'meta_description',
|
|
||||||
'tour'
|
|
||||||
],
|
|
||||||
filter: 'visibility:public'
|
|
||||||
},
|
|
||||||
events: {
|
|
||||||
add: 'user.activated',
|
|
||||||
update: 'user.activated.edited',
|
|
||||||
remove: 'user.deleted'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
|
@ -43,7 +43,9 @@ describe('Tag API', function () {
|
||||||
jsonResponse.meta.pagination.should.have.property('next', null);
|
jsonResponse.meta.pagination.should.have.property('next', null);
|
||||||
jsonResponse.meta.pagination.should.have.property('prev', null);
|
jsonResponse.meta.pagination.should.have.property('prev', null);
|
||||||
|
|
||||||
jsonResponse.tags[0].url.should.eql(`${config.get('url')}/tag/pollo/`);
|
// returns 404 because this tag has no published posts
|
||||||
|
jsonResponse.tags[0].url.should.eql(`${config.get('url')}/404/`);
|
||||||
|
jsonResponse.tags[1].url.should.eql(`${config.get('url')}/tag/kitchen-sink/`);
|
||||||
|
|
||||||
should.exist(jsonResponse.tags[0].count.posts);
|
should.exist(jsonResponse.tags[0].count.posts);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
const should = require('should');
|
const should = require('should');
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const supertest = require('supertest');
|
const supertest = require('supertest');
|
||||||
const moment = require('moment');
|
|
||||||
const Promise = require('bluebird');
|
const Promise = require('bluebird');
|
||||||
const ObjectId = require('bson-objectid');
|
|
||||||
const testUtils = require('../../../utils');
|
const testUtils = require('../../../utils');
|
||||||
const localUtils = require('./utils');
|
const localUtils = require('./utils');
|
||||||
const config = require('../../../../server/config');
|
const config = require('../../../../server/config');
|
||||||
|
@ -13,12 +11,11 @@ const ghost = testUtils.startGhost;
|
||||||
let request;
|
let request;
|
||||||
|
|
||||||
describe('User API', function () {
|
describe('User API', function () {
|
||||||
let ghostServer, inactiveUser, admin;
|
let inactiveUser, admin;
|
||||||
|
|
||||||
before(function () {
|
before(function () {
|
||||||
return ghost()
|
return ghost()
|
||||||
.then(function (_ghostServer) {
|
.then(function () {
|
||||||
ghostServer = _ghostServer;
|
|
||||||
request = supertest.agent(config.get('url'));
|
request = supertest.agent(config.get('url'));
|
||||||
})
|
})
|
||||||
.then(function () {
|
.then(function () {
|
||||||
|
@ -82,10 +79,11 @@ describe('User API', function () {
|
||||||
testUtils.API.isISO8601(jsonResponse.users[3].created_at).should.be.true();
|
testUtils.API.isISO8601(jsonResponse.users[3].created_at).should.be.true();
|
||||||
testUtils.API.isISO8601(jsonResponse.users[3].updated_at).should.be.true();
|
testUtils.API.isISO8601(jsonResponse.users[3].updated_at).should.be.true();
|
||||||
|
|
||||||
jsonResponse.users[0].url.should.eql(`${config.get('url')}/author/admin-user/`);
|
// only "ghost" author has a published post
|
||||||
|
jsonResponse.users[0].url.should.eql(`${config.get('url')}/404/`);
|
||||||
jsonResponse.users[1].url.should.eql(`${config.get('url')}/404/`);
|
jsonResponse.users[1].url.should.eql(`${config.get('url')}/404/`);
|
||||||
jsonResponse.users[2].url.should.eql(`${config.get('url')}/author/ghost/`);
|
jsonResponse.users[2].url.should.eql(`${config.get('url')}/author/ghost/`);
|
||||||
jsonResponse.users[3].url.should.eql(`${config.get('url')}/author/joe-bloggs/`);
|
jsonResponse.users[3].url.should.eql(`${config.get('url')}/404/`);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,7 +16,7 @@ describe('Integration: services/url/UrlService', function () {
|
||||||
models.init();
|
models.init();
|
||||||
|
|
||||||
sinon.stub(themes, 'getActive').returns({
|
sinon.stub(themes, 'getActive').returns({
|
||||||
engine: () => 'v0.1'
|
engine: () => 'v2'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -148,11 +148,11 @@ describe('Integration: services/url/UrlService', function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (generator.router.getResourceType() === 'tags') {
|
if (generator.router.getResourceType() === 'tags') {
|
||||||
generator.getUrls().length.should.eql(5);
|
generator.getUrls().length.should.eql(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (generator.router.getResourceType() === 'authors') {
|
if (generator.router.getResourceType() === 'authors') {
|
||||||
generator.getUrls().length.should.eql(5);
|
generator.getUrls().length.should.eql(2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -175,25 +175,22 @@ describe('Integration: services/url/UrlService', function () {
|
||||||
url.should.eql('/tag/chorizo/');
|
url.should.eql('/tag/chorizo/');
|
||||||
|
|
||||||
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.tags[3].id);
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.tags[3].id);
|
||||||
url.should.eql('/tag/pollo/');
|
url.should.eql('/404/'); // tags with no posts should not be public
|
||||||
|
|
||||||
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.tags[4].id);
|
|
||||||
url.should.eql('/tag/injection/');
|
|
||||||
|
|
||||||
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[0].id);
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[0].id);
|
||||||
url.should.eql('/author/joe-bloggs/');
|
url.should.eql('/author/joe-bloggs/');
|
||||||
|
|
||||||
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[1].id);
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[1].id);
|
||||||
url.should.eql('/author/smith-wellingsworth/');
|
url.should.eql('/404/'); // users with no posts should not be public
|
||||||
|
|
||||||
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[2].id);
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[2].id);
|
||||||
url.should.eql('/author/jimothy-bogendath/');
|
url.should.eql('/404/'); // users with no posts should not be public
|
||||||
|
|
||||||
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[3].id);
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[3].id);
|
||||||
url.should.eql('/author/slimer-mcectoplasm/');
|
url.should.eql('/author/slimer-mcectoplasm/');
|
||||||
|
|
||||||
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[4].id);
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[4].id);
|
||||||
url.should.eql('/author/contributor/');
|
url.should.eql('/404/'); // users with no posts should not be public
|
||||||
});
|
});
|
||||||
|
|
||||||
it('getResource', function () {
|
it('getResource', function () {
|
||||||
|
@ -356,11 +353,11 @@ describe('Integration: services/url/UrlService', function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (generator.router.getResourceType() === 'tags') {
|
if (generator.router.getResourceType() === 'tags') {
|
||||||
generator.getUrls().length.should.eql(5);
|
generator.getUrls().length.should.eql(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (generator.router.getResourceType() === 'authors') {
|
if (generator.router.getResourceType() === 'authors') {
|
||||||
generator.getUrls().length.should.eql(5);
|
generator.getUrls().length.should.eql(2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -384,25 +381,22 @@ describe('Integration: services/url/UrlService', function () {
|
||||||
url.should.eql('/category/chorizo/');
|
url.should.eql('/category/chorizo/');
|
||||||
|
|
||||||
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.tags[3].id);
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.tags[3].id);
|
||||||
url.should.eql('/category/pollo/');
|
url.should.eql('/404/'); // tags with no posts should not be public
|
||||||
|
|
||||||
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.tags[4].id);
|
|
||||||
url.should.eql('/category/injection/');
|
|
||||||
|
|
||||||
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[0].id);
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[0].id);
|
||||||
url.should.eql('/persons/joe-bloggs/');
|
url.should.eql('/persons/joe-bloggs/');
|
||||||
|
|
||||||
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[1].id);
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[1].id);
|
||||||
url.should.eql('/persons/smith-wellingsworth/');
|
url.should.eql('/404/'); // users with no posts should not be public
|
||||||
|
|
||||||
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[2].id);
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[2].id);
|
||||||
url.should.eql('/persons/jimothy-bogendath/');
|
url.should.eql('/404/'); // users with no posts should not be public
|
||||||
|
|
||||||
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[3].id);
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[3].id);
|
||||||
url.should.eql('/persons/slimer-mcectoplasm/');
|
url.should.eql('/persons/slimer-mcectoplasm/');
|
||||||
|
|
||||||
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[4].id);
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[4].id);
|
||||||
url.should.eql('/persons/contributor/');
|
url.should.eql('/404/'); // users with no posts should not be public
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -553,11 +547,11 @@ describe('Integration: services/url/UrlService', function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (generator.router.getResourceType() === 'tags') {
|
if (generator.router.getResourceType() === 'tags') {
|
||||||
generator.getUrls().length.should.eql(5);
|
generator.getUrls().length.should.eql(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (generator.router.getResourceType() === 'users') {
|
if (generator.router.getResourceType() === 'authors') {
|
||||||
generator.getUrls().length.should.eql(5);
|
generator.getUrls().length.should.eql(2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -581,25 +575,22 @@ describe('Integration: services/url/UrlService', function () {
|
||||||
url.should.eql('/category/chorizo/');
|
url.should.eql('/category/chorizo/');
|
||||||
|
|
||||||
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.tags[3].id);
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.tags[3].id);
|
||||||
url.should.eql('/category/pollo/');
|
url.should.eql('/404/'); // tags with no posts should not be public
|
||||||
|
|
||||||
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.tags[4].id);
|
|
||||||
url.should.eql('/category/injection/');
|
|
||||||
|
|
||||||
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[0].id);
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[0].id);
|
||||||
url.should.eql('/persons/joe-bloggs/');
|
url.should.eql('/persons/joe-bloggs/');
|
||||||
|
|
||||||
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[1].id);
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[1].id);
|
||||||
url.should.eql('/persons/smith-wellingsworth/');
|
url.should.eql('/404/'); // users with no posts should not be public
|
||||||
|
|
||||||
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[2].id);
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[2].id);
|
||||||
url.should.eql('/persons/jimothy-bogendath/');
|
url.should.eql('/404/'); // users with no posts should not be public
|
||||||
|
|
||||||
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[3].id);
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[3].id);
|
||||||
url.should.eql('/persons/slimer-mcectoplasm/');
|
url.should.eql('/persons/slimer-mcectoplasm/');
|
||||||
|
|
||||||
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[4].id);
|
url = urlService.getUrlByResourceId(testUtils.DataGenerator.forKnex.users[4].id);
|
||||||
url.should.eql('/persons/contributor/');
|
url.should.eql('/404/'); // users with no posts should not be public
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -394,10 +394,28 @@ describe('Dynamic Routing', function () {
|
||||||
return testUtils.initData();
|
return testUtils.initData();
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return testUtils.fixtures.overrideOwnerUser(ownerSlug);
|
return testUtils.fixtures.overrideOwnerUser(ownerSlug);
|
||||||
|
}).then(function (insertedUser) {
|
||||||
|
return testUtils.fixtures.insertPosts([
|
||||||
|
testUtils.DataGenerator.forKnex.createPost({
|
||||||
|
author_id: insertedUser.id
|
||||||
|
})
|
||||||
|
]);
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return testUtils.fixtures.insertOneUser(lockedUser);
|
return testUtils.fixtures.insertOneUser(lockedUser);
|
||||||
}).then(function () {
|
}).then(function (insertedUser) {
|
||||||
|
return testUtils.fixtures.insertPosts([
|
||||||
|
testUtils.DataGenerator.forKnex.createPost({
|
||||||
|
author_id: insertedUser.id
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
}).then(() => {
|
||||||
return testUtils.fixtures.insertOneUser(suspendedUser);
|
return testUtils.fixtures.insertOneUser(suspendedUser);
|
||||||
|
}).then(function (insertedUser) {
|
||||||
|
return testUtils.fixtures.insertPosts([
|
||||||
|
testUtils.DataGenerator.forKnex.createPost({
|
||||||
|
author_id: insertedUser.id
|
||||||
|
})
|
||||||
|
]);
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -27,119 +27,6 @@ describe('Unit - services/routing/controllers/preview', function () {
|
||||||
configUtils.restore();
|
configUtils.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('v0.1', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
post = testUtils.DataGenerator.forKnex.createPost({status: 'draft'});
|
|
||||||
|
|
||||||
apiResponse = {
|
|
||||||
posts: [post]
|
|
||||||
};
|
|
||||||
|
|
||||||
req = {
|
|
||||||
path: '/',
|
|
||||||
params: {
|
|
||||||
uuid: 'something'
|
|
||||||
},
|
|
||||||
route: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
res = {
|
|
||||||
routerOptions: {
|
|
||||||
query: {controller: 'posts', resource: 'posts'}
|
|
||||||
},
|
|
||||||
locals: {
|
|
||||||
apiVersion: 'v0.1'
|
|
||||||
},
|
|
||||||
render: sinon.spy(),
|
|
||||||
redirect: sinon.spy(),
|
|
||||||
set: sinon.spy()
|
|
||||||
};
|
|
||||||
|
|
||||||
secureStub = sinon.stub();
|
|
||||||
|
|
||||||
sinon.stub(urlUtils, 'redirectToAdmin');
|
|
||||||
sinon.stub(urlUtils, 'redirect301');
|
|
||||||
sinon.stub(urlService, 'getUrlByResourceId');
|
|
||||||
|
|
||||||
sinon.stub(helpers, 'secure').get(function () {
|
|
||||||
return secureStub;
|
|
||||||
});
|
|
||||||
|
|
||||||
renderStub = sinon.stub();
|
|
||||||
sinon.stub(helpers, 'renderEntry').get(function () {
|
|
||||||
return function () {
|
|
||||||
return renderStub;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
sinon.stub(api.posts, 'read').withArgs({
|
|
||||||
uuid: req.params.uuid,
|
|
||||||
status: 'all',
|
|
||||||
include: 'author,authors,tags'
|
|
||||||
}).callsFake(function () {
|
|
||||||
return Promise.resolve(apiResponse);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render post', function (done) {
|
|
||||||
controllers.preview(req, res, failTest(done)).then(function () {
|
|
||||||
secureStub.called.should.be.true();
|
|
||||||
renderStub.called.should.be.true();
|
|
||||||
done();
|
|
||||||
}).catch(done);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call next if post is not found', function (done) {
|
|
||||||
apiResponse = {posts: []};
|
|
||||||
|
|
||||||
controllers.preview(req, res, function (err) {
|
|
||||||
should.not.exist(err);
|
|
||||||
renderStub.called.should.be.false();
|
|
||||||
secureStub.called.should.be.false();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call redirect if post is published', function (done) {
|
|
||||||
post.status = 'published';
|
|
||||||
urlService.getUrlByResourceId.withArgs(post.id).returns('/something/');
|
|
||||||
|
|
||||||
urlUtils.redirect301.callsFake(function (res, postUrl) {
|
|
||||||
postUrl.should.eql('/something/');
|
|
||||||
renderStub.called.should.be.false();
|
|
||||||
secureStub.called.should.be.false();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
controllers.preview(req, res, failTest(done));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call redirect if /edit/ (options param) is detected', function (done) {
|
|
||||||
req.params.options = 'edit';
|
|
||||||
|
|
||||||
urlUtils.redirectToAdmin.callsFake(function (statusCode, res, editorUrl) {
|
|
||||||
statusCode.should.eql(302);
|
|
||||||
editorUrl.should.eql(EDITOR_URL + post.id);
|
|
||||||
renderStub.called.should.be.false();
|
|
||||||
secureStub.called.should.be.false();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
controllers.preview(req, res, failTest(done));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call next for unknown options param detected', function (done) {
|
|
||||||
req.params.options = 'abcde';
|
|
||||||
|
|
||||||
controllers.preview(req, res, function (err) {
|
|
||||||
should.not.exist(err);
|
|
||||||
renderStub.called.should.be.false();
|
|
||||||
secureStub.called.should.be.false();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('v2', function () {
|
describe('v2', function () {
|
||||||
let previewStub;
|
let previewStub;
|
||||||
|
|
||||||
|
@ -191,7 +78,7 @@ describe('Unit - services/routing/controllers/preview', function () {
|
||||||
previewStub.withArgs({
|
previewStub.withArgs({
|
||||||
uuid: req.params.uuid,
|
uuid: req.params.uuid,
|
||||||
status: 'all',
|
status: 'all',
|
||||||
include: 'author,authors,tags'
|
include: 'authors,tags'
|
||||||
}).resolves(apiResponse);
|
}).resolves(apiResponse);
|
||||||
|
|
||||||
sinon.stub(api.v2, 'preview').get(() => {
|
sinon.stub(api.v2, 'preview').get(() => {
|
||||||
|
@ -261,7 +148,7 @@ describe('Unit - services/routing/controllers/preview', function () {
|
||||||
previewStub.withArgs({
|
previewStub.withArgs({
|
||||||
uuid: req.params.uuid,
|
uuid: req.params.uuid,
|
||||||
status: 'all',
|
status: 'all',
|
||||||
include: 'author,authors,tags'
|
include: 'authors,tags'
|
||||||
}).resolves(apiResponse);
|
}).resolves(apiResponse);
|
||||||
|
|
||||||
sinon.stub(api.canary, 'preview').get(() => {
|
sinon.stub(api.canary, 'preview').get(() => {
|
||||||
|
@ -331,7 +218,7 @@ describe('Unit - services/routing/controllers/preview', function () {
|
||||||
previewStub.withArgs({
|
previewStub.withArgs({
|
||||||
uuid: req.params.uuid,
|
uuid: req.params.uuid,
|
||||||
status: 'all',
|
status: 'all',
|
||||||
include: 'author,authors,tags'
|
include: 'authors,tags'
|
||||||
}).resolves(apiResponse);
|
}).resolves(apiResponse);
|
||||||
|
|
||||||
sinon.stub(api.v3, 'preview').get(() => {
|
sinon.stub(api.v3, 'preview').get(() => {
|
||||||
|
|
|
@ -14,22 +14,30 @@ function failTest(done) {
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('Unit - services/routing/controllers/static', function () {
|
describe('Unit - services/routing/controllers/static', function () {
|
||||||
let req, res, secureStub, renderStub, handleErrorStub, formatResponseStub, posts, postsPerPage;
|
let req,
|
||||||
|
res,
|
||||||
|
secureStub,
|
||||||
|
renderStub,
|
||||||
|
handleErrorStub,
|
||||||
|
formatResponseStub,
|
||||||
|
postsPerPage,
|
||||||
|
tagsReadStub;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
postsPerPage = 5;
|
postsPerPage = 5;
|
||||||
|
|
||||||
posts = [
|
|
||||||
testUtils.DataGenerator.forKnex.createPost()
|
|
||||||
];
|
|
||||||
|
|
||||||
secureStub = sinon.stub();
|
secureStub = sinon.stub();
|
||||||
renderStub = sinon.stub();
|
renderStub = sinon.stub();
|
||||||
handleErrorStub = sinon.stub();
|
handleErrorStub = sinon.stub();
|
||||||
formatResponseStub = sinon.stub();
|
formatResponseStub = sinon.stub();
|
||||||
formatResponseStub.entries = sinon.stub();
|
formatResponseStub.entries = sinon.stub();
|
||||||
|
|
||||||
sinon.stub(api.tags, 'read');
|
tagsReadStub = sinon.stub().resolves();
|
||||||
|
sinon.stub(api.v2, 'tagsPublic').get(() => {
|
||||||
|
return {
|
||||||
|
read: tagsReadStub
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
sinon.stub(helpers, 'secure').get(function () {
|
sinon.stub(helpers, 'secure').get(function () {
|
||||||
return secureStub;
|
return secureStub;
|
||||||
|
@ -66,7 +74,7 @@ describe('Unit - services/routing/controllers/static', function () {
|
||||||
render: sinon.spy(),
|
render: sinon.spy(),
|
||||||
redirect: sinon.spy(),
|
redirect: sinon.spy(),
|
||||||
locals: {
|
locals: {
|
||||||
apiVersion: 'v0.1'
|
apiVersion: 'v2'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -78,7 +86,7 @@ describe('Unit - services/routing/controllers/static', function () {
|
||||||
it('no extra data to fetch', function (done) {
|
it('no extra data to fetch', function (done) {
|
||||||
helpers.renderer.callsFake(function () {
|
helpers.renderer.callsFake(function () {
|
||||||
helpers.formatResponse.entries.calledOnce.should.be.true();
|
helpers.formatResponse.entries.calledOnce.should.be.true();
|
||||||
api.tags.read.called.should.be.false();
|
tagsReadStub.called.should.be.false();
|
||||||
helpers.secure.called.should.be.false();
|
helpers.secure.called.should.be.false();
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
@ -89,7 +97,7 @@ describe('Unit - services/routing/controllers/static', function () {
|
||||||
it('extra data to fetch', function (done) {
|
it('extra data to fetch', function (done) {
|
||||||
res.routerOptions.data = {
|
res.routerOptions.data = {
|
||||||
tag: {
|
tag: {
|
||||||
controller: 'tags',
|
controller: 'tagsPublic',
|
||||||
resource: 'tags',
|
resource: 'tags',
|
||||||
type: 'read',
|
type: 'read',
|
||||||
options: {
|
options: {
|
||||||
|
@ -98,10 +106,10 @@ describe('Unit - services/routing/controllers/static', function () {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
api.tags.read.resolves({tags: [{slug: 'bacon'}]});
|
tagsReadStub = sinon.stub().resolves({tags: [{slug: 'bacon'}]});
|
||||||
|
|
||||||
helpers.renderer.callsFake(function () {
|
helpers.renderer.callsFake(function () {
|
||||||
api.tags.read.called.should.be.true();
|
tagsReadStub.called.should.be.true();
|
||||||
helpers.formatResponse.entries.calledOnce.should.be.true();
|
helpers.formatResponse.entries.calledOnce.should.be.true();
|
||||||
helpers.secure.calledOnce.should.be.true();
|
helpers.secure.calledOnce.should.be.true();
|
||||||
done();
|
done();
|
||||||
|
|
|
@ -286,7 +286,7 @@ describe('Contexts', function () {
|
||||||
|
|
||||||
it('should correctly identify AMP page', function () {
|
it('should correctly identify AMP page', function () {
|
||||||
res.locals.relativeUrl = '/welcome-to-ghost/amp/';
|
res.locals.relativeUrl = '/welcome-to-ghost/amp/';
|
||||||
data.post = testUtils.DataGenerator.forKnex.createPost({page: true});
|
data.page = testUtils.DataGenerator.forKnex.createPost({page: true});
|
||||||
|
|
||||||
delete res.routerOptions;
|
delete res.routerOptions;
|
||||||
helpers.context(req, res, data);
|
helpers.context(req, res, data);
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
const should = require('should'),
|
const should = require('should');
|
||||||
sinon = require('sinon'),
|
const sinon = require('sinon');
|
||||||
api = require('../../../../../server/api')['v0.1'],
|
const api = require('../../../../../server/api').v2;
|
||||||
helpers = require('../../../../../frontend/services/routing/helpers'),
|
const helpers = require('../../../../../frontend/services/routing/helpers');
|
||||||
testUtils = require('../../../../utils');
|
const testUtils = require('../../../../utils');
|
||||||
|
|
||||||
describe('Unit - services/routing/helpers/fetch-data', function () {
|
describe('Unit - services/routing/helpers/fetch-data', function () {
|
||||||
let posts, tags, locals;
|
let posts, tags, locals;
|
||||||
|
let browsePostsStub, readTagsStub;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
posts = [
|
posts = [
|
||||||
|
@ -22,19 +23,28 @@ describe('Unit - services/routing/helpers/fetch-data', function () {
|
||||||
testUtils.DataGenerator.forKnex.createTag()
|
testUtils.DataGenerator.forKnex.createTag()
|
||||||
];
|
];
|
||||||
|
|
||||||
sinon.stub(api.posts, 'browse')
|
browsePostsStub = sinon.stub().resolves({
|
||||||
.resolves({
|
posts: posts,
|
||||||
posts: posts,
|
meta: {
|
||||||
meta: {
|
pagination: {
|
||||||
pagination: {
|
pages: 2
|
||||||
pages: 2
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
sinon.stub(api, 'postsPublic').get(() => {
|
||||||
|
return {
|
||||||
|
browse: browsePostsStub
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
sinon.stub(api.tags, 'read').resolves({tags: tags});
|
readTagsStub = sinon.stub().resolves({tags: tags});
|
||||||
|
sinon.stub(api, 'tagsPublic').get(() => {
|
||||||
|
return {
|
||||||
|
read: readTagsStub
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
locals = {apiVersion: 'v0.1'};
|
locals = {apiVersion: 'v2'};
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
|
@ -47,10 +57,10 @@ describe('Unit - services/routing/helpers/fetch-data', function () {
|
||||||
result.should.be.an.Object().with.properties('posts', 'meta');
|
result.should.be.an.Object().with.properties('posts', 'meta');
|
||||||
result.should.not.have.property('data');
|
result.should.not.have.property('data');
|
||||||
|
|
||||||
api.posts.browse.calledOnce.should.be.true();
|
browsePostsStub.calledOnce.should.be.true();
|
||||||
api.posts.browse.firstCall.args[0].should.be.an.Object();
|
browsePostsStub.firstCall.args[0].should.be.an.Object();
|
||||||
api.posts.browse.firstCall.args[0].should.have.property('include');
|
browsePostsStub.firstCall.args[0].should.have.property('include');
|
||||||
api.posts.browse.firstCall.args[0].should.not.have.property('filter');
|
browsePostsStub.firstCall.args[0].should.not.have.property('filter');
|
||||||
|
|
||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
|
@ -64,11 +74,11 @@ describe('Unit - services/routing/helpers/fetch-data', function () {
|
||||||
|
|
||||||
result.posts.length.should.eql(posts.length);
|
result.posts.length.should.eql(posts.length);
|
||||||
|
|
||||||
api.posts.browse.calledOnce.should.be.true();
|
browsePostsStub.calledOnce.should.be.true();
|
||||||
api.posts.browse.firstCall.args[0].should.be.an.Object();
|
browsePostsStub.firstCall.args[0].should.be.an.Object();
|
||||||
api.posts.browse.firstCall.args[0].should.have.property('include');
|
browsePostsStub.firstCall.args[0].should.have.property('include');
|
||||||
api.posts.browse.firstCall.args[0].should.have.property('limit', 10);
|
browsePostsStub.firstCall.args[0].should.have.property('limit', 10);
|
||||||
api.posts.browse.firstCall.args[0].should.have.property('page', 2);
|
browsePostsStub.firstCall.args[0].should.have.property('page', 2);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
|
@ -102,11 +112,10 @@ describe('Unit - services/routing/helpers/fetch-data', function () {
|
||||||
// @TODO v3 will deprecate this style (featured.posts)
|
// @TODO v3 will deprecate this style (featured.posts)
|
||||||
result.data.featured.posts.length.should.eql(posts.length);
|
result.data.featured.posts.length.should.eql(posts.length);
|
||||||
|
|
||||||
api.posts.browse.calledTwice.should.be.true();
|
browsePostsStub.calledTwice.should.be.true();
|
||||||
api.posts.browse.firstCall.args[0].should.have.property('include', 'author,authors,tags');
|
browsePostsStub.firstCall.args[0].should.have.property('include', 'authors,tags');
|
||||||
|
browsePostsStub.secondCall.args[0].should.have.property('filter', 'featured:true');
|
||||||
api.posts.browse.secondCall.args[0].should.have.property('filter', 'featured:true');
|
browsePostsStub.secondCall.args[0].should.have.property('limit', 3);
|
||||||
api.posts.browse.secondCall.args[0].should.have.property('limit', 3);
|
|
||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
});
|
});
|
||||||
|
@ -139,11 +148,11 @@ describe('Unit - services/routing/helpers/fetch-data', function () {
|
||||||
// @TODO v3 will deprecate this style (featured.posts)
|
// @TODO v3 will deprecate this style (featured.posts)
|
||||||
result.data.featured.posts.length.should.eql(posts.length);
|
result.data.featured.posts.length.should.eql(posts.length);
|
||||||
|
|
||||||
api.posts.browse.calledTwice.should.be.true();
|
browsePostsStub.calledTwice.should.be.true();
|
||||||
api.posts.browse.firstCall.args[0].should.have.property('include', 'author,authors,tags');
|
browsePostsStub.firstCall.args[0].should.have.property('include', 'authors,tags');
|
||||||
api.posts.browse.firstCall.args[0].should.have.property('page', 2);
|
browsePostsStub.firstCall.args[0].should.have.property('page', 2);
|
||||||
api.posts.browse.secondCall.args[0].should.have.property('filter', 'featured:true');
|
browsePostsStub.secondCall.args[0].should.have.property('filter', 'featured:true');
|
||||||
api.posts.browse.secondCall.args[0].should.have.property('limit', 3);
|
browsePostsStub.secondCall.args[0].should.have.property('limit', 3);
|
||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
});
|
});
|
||||||
|
@ -157,7 +166,7 @@ describe('Unit - services/routing/helpers/fetch-data', function () {
|
||||||
filter: 'tags:%s',
|
filter: 'tags:%s',
|
||||||
data: {
|
data: {
|
||||||
tag: {
|
tag: {
|
||||||
controller: 'tags',
|
controller: 'tagsPublic',
|
||||||
type: 'read',
|
type: 'read',
|
||||||
resource: 'tags',
|
resource: 'tags',
|
||||||
options: {slug: '%s'}
|
options: {slug: '%s'}
|
||||||
|
@ -173,11 +182,11 @@ describe('Unit - services/routing/helpers/fetch-data', function () {
|
||||||
result.posts.length.should.eql(posts.length);
|
result.posts.length.should.eql(posts.length);
|
||||||
result.data.tag.length.should.eql(tags.length);
|
result.data.tag.length.should.eql(tags.length);
|
||||||
|
|
||||||
api.posts.browse.calledOnce.should.be.true();
|
browsePostsStub.calledOnce.should.be.true();
|
||||||
api.posts.browse.firstCall.args[0].should.have.property('include');
|
browsePostsStub.firstCall.args[0].should.have.property('include');
|
||||||
api.posts.browse.firstCall.args[0].should.have.property('filter', 'tags:testing');
|
browsePostsStub.firstCall.args[0].should.have.property('filter', 'tags:testing');
|
||||||
api.posts.browse.firstCall.args[0].should.not.have.property('slug');
|
browsePostsStub.firstCall.args[0].should.not.have.property('slug');
|
||||||
api.tags.read.firstCall.args[0].should.have.property('slug', 'testing');
|
readTagsStub.firstCall.args[0].should.have.property('slug', 'testing');
|
||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
});
|
});
|
||||||
|
|
|
@ -21,787 +21,6 @@ describe('UNIT: services/settings/validate', function () {
|
||||||
sinon.restore();
|
sinon.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('v0.1', function () {
|
|
||||||
before(function () {
|
|
||||||
apiVersion = 'v0.1';
|
|
||||||
});
|
|
||||||
|
|
||||||
it('no type definitions / empty yaml file', function () {
|
|
||||||
const object = validate({});
|
|
||||||
|
|
||||||
object.should.eql({collections: {}, routes: {}, taxonomies: {}});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('throws error when using :\w+ notiation in collection', function () {
|
|
||||||
try {
|
|
||||||
validate({
|
|
||||||
collections: {
|
|
||||||
'/magic/': {
|
|
||||||
permalink: '/magic/{slug}/'
|
|
||||||
},
|
|
||||||
'/': {
|
|
||||||
permalink: '/:slug/'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
(err instanceof common.errors.ValidationError).should.be.true();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('should fail');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('throws error when using :\w+ notiation in taxonomies', function () {
|
|
||||||
try {
|
|
||||||
validate({
|
|
||||||
taxonomies: {
|
|
||||||
tag: '/categories/:slug/'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
(err instanceof common.errors.ValidationError).should.be.true();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('should fail');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('throws error when using an undefined taxonomy', function () {
|
|
||||||
try {
|
|
||||||
validate({
|
|
||||||
taxonomies: {
|
|
||||||
sweet_baked_good: '/patisserie/{slug}'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
(err instanceof common.errors.ValidationError).should.be.true();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('should fail');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('throws error when permalink is missing (collection)', function () {
|
|
||||||
try {
|
|
||||||
validate({
|
|
||||||
collections: {
|
|
||||||
permalink: '/{slug}/'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
(err instanceof common.errors.ValidationError).should.be.true();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('should fail');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('throws error without leading or trailing slashes', function () {
|
|
||||||
try {
|
|
||||||
validate({
|
|
||||||
routes: {
|
|
||||||
about: 'about'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
(err instanceof common.errors.ValidationError).should.be.true();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('should fail');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('throws error without trailing slash', function () {
|
|
||||||
try {
|
|
||||||
validate({
|
|
||||||
routes: {
|
|
||||||
'/about': 'about'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
(err instanceof common.errors.ValidationError).should.be.true();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('should fail');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('throws error without leading slashe', function () {
|
|
||||||
try {
|
|
||||||
validate({
|
|
||||||
routes: {
|
|
||||||
'about/': 'about'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
(err instanceof common.errors.ValidationError).should.be.true();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('should fail');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('throws error without leading slash with permalink', function () {
|
|
||||||
try {
|
|
||||||
validate({
|
|
||||||
collections: {
|
|
||||||
'magic/': {
|
|
||||||
permalink: '/{slug}/'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
(err instanceof common.errors.ValidationError).should.be.true();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('should fail');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('throws error without leading or trailing slashes with permalink', function () {
|
|
||||||
try {
|
|
||||||
validate({
|
|
||||||
collections: {
|
|
||||||
magic: {
|
|
||||||
permalink: '/{slug}/'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
(err instanceof common.errors.ValidationError).should.be.true();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('should fail');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('throws error without trailing slash with permalink', function () {
|
|
||||||
try {
|
|
||||||
validate({
|
|
||||||
collections: {
|
|
||||||
'/magic': {
|
|
||||||
permalink: '/{slug}/'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
(err instanceof common.errors.ValidationError).should.be.true();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('should fail');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('throws error without trailing slash in permalink', function () {
|
|
||||||
try {
|
|
||||||
validate({
|
|
||||||
collections: {
|
|
||||||
'/magic/': {
|
|
||||||
permalink: '/{slug}'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
(err instanceof common.errors.ValidationError).should.be.true();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('should fail');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('throws error without leading or trailing slashes in permalink', function () {
|
|
||||||
try {
|
|
||||||
validate({
|
|
||||||
collections: {
|
|
||||||
'/magic/': {
|
|
||||||
permalink: '{slug}'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
(err instanceof common.errors.ValidationError).should.be.true();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('should fail');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('no validation error for routes', function () {
|
|
||||||
validate({
|
|
||||||
routes: {
|
|
||||||
'/': 'home'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('no validation error for / collection', function () {
|
|
||||||
validate({
|
|
||||||
collections: {
|
|
||||||
'/': {
|
|
||||||
permalink: '/{primary_tag}/{slug}/'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('transforms {.*} notation into :\w+', function () {
|
|
||||||
const object = validate({
|
|
||||||
collections: {
|
|
||||||
'/magic/': {
|
|
||||||
permalink: '/magic/{year}/{slug}/'
|
|
||||||
},
|
|
||||||
'/': {
|
|
||||||
permalink: '/{slug}/'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
taxonomies: {
|
|
||||||
tag: '/tags/{slug}/',
|
|
||||||
author: '/authors/{slug}/'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
object.should.eql({
|
|
||||||
routes: {},
|
|
||||||
taxonomies: {
|
|
||||||
tag: '/tags/:slug/',
|
|
||||||
author: '/authors/:slug/'
|
|
||||||
},
|
|
||||||
collections: {
|
|
||||||
'/magic/': {
|
|
||||||
permalink: '/magic/:year/:slug/',
|
|
||||||
templates: []
|
|
||||||
},
|
|
||||||
'/': {
|
|
||||||
permalink: '/:slug/',
|
|
||||||
templates: []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('template definitions', function () {
|
|
||||||
it('single value', function () {
|
|
||||||
const object = validate({
|
|
||||||
routes: {
|
|
||||||
'/about/': 'about',
|
|
||||||
'/me/': {
|
|
||||||
template: 'me'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
collections: {
|
|
||||||
'/': {
|
|
||||||
permalink: '/{slug}/',
|
|
||||||
template: 'test'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
object.should.eql({
|
|
||||||
taxonomies: {},
|
|
||||||
routes: {
|
|
||||||
'/about/': {
|
|
||||||
templates: ['about']
|
|
||||||
},
|
|
||||||
'/me/': {
|
|
||||||
templates: ['me']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
collections: {
|
|
||||||
'/': {
|
|
||||||
permalink: '/:slug/',
|
|
||||||
templates: ['test']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('array', function () {
|
|
||||||
const object = validate({
|
|
||||||
routes: {
|
|
||||||
'/about/': 'about',
|
|
||||||
'/me/': {
|
|
||||||
template: ['me']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
collections: {
|
|
||||||
'/': {
|
|
||||||
permalink: '/{slug}/',
|
|
||||||
template: ['test']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
object.should.eql({
|
|
||||||
taxonomies: {},
|
|
||||||
routes: {
|
|
||||||
'/about/': {
|
|
||||||
templates: ['about']
|
|
||||||
},
|
|
||||||
'/me/': {
|
|
||||||
templates: ['me']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
collections: {
|
|
||||||
'/': {
|
|
||||||
permalink: '/:slug/',
|
|
||||||
templates: ['test']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('data definitions', function () {
|
|
||||||
it('shortform', function () {
|
|
||||||
const object = validate({
|
|
||||||
routes: {
|
|
||||||
'/food/': {
|
|
||||||
data: 'tag.food'
|
|
||||||
},
|
|
||||||
'/music/': {
|
|
||||||
data: 'tag.music'
|
|
||||||
},
|
|
||||||
'/ghost/': {
|
|
||||||
data: 'user.ghost'
|
|
||||||
},
|
|
||||||
'/sleep/': {
|
|
||||||
data: {
|
|
||||||
bed: 'tag.bed',
|
|
||||||
dream: 'tag.dream'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'/lala/': {
|
|
||||||
data: 'author.carsten'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
collections: {
|
|
||||||
'/more/': {
|
|
||||||
permalink: '/{slug}/',
|
|
||||||
data: {
|
|
||||||
home: 'page.home'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'/podcast/': {
|
|
||||||
permalink: '/podcast/{slug}/',
|
|
||||||
data: {
|
|
||||||
something: 'tag.something'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'/': {
|
|
||||||
permalink: '/{slug}/',
|
|
||||||
data: 'tag.sport'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
object.should.eql({
|
|
||||||
taxonomies: {},
|
|
||||||
routes: {
|
|
||||||
'/food/': {
|
|
||||||
data: {
|
|
||||||
query: {
|
|
||||||
tag: {
|
|
||||||
controller: 'tags',
|
|
||||||
resource: 'tags',
|
|
||||||
type: 'read',
|
|
||||||
options: {
|
|
||||||
slug: 'food',
|
|
||||||
visibility: 'public'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
router: {
|
|
||||||
tags: [{redirect: true, slug: 'food'}]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
templates: []
|
|
||||||
},
|
|
||||||
'/ghost/': {
|
|
||||||
data: {
|
|
||||||
query: {
|
|
||||||
user: {
|
|
||||||
controller: 'users',
|
|
||||||
resource: 'users',
|
|
||||||
type: 'read',
|
|
||||||
options: {
|
|
||||||
slug: 'ghost',
|
|
||||||
visibility: 'public'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
router: {
|
|
||||||
authors: [{redirect: true, slug: 'ghost'}]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
templates: []
|
|
||||||
},
|
|
||||||
'/music/': {
|
|
||||||
data: {
|
|
||||||
query: {
|
|
||||||
tag: {
|
|
||||||
controller: 'tags',
|
|
||||||
resource: 'tags',
|
|
||||||
type: 'read',
|
|
||||||
options: {
|
|
||||||
slug: 'music',
|
|
||||||
visibility: 'public'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
router: {
|
|
||||||
tags: [{redirect: true, slug: 'music'}]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
templates: []
|
|
||||||
},
|
|
||||||
'/sleep/': {
|
|
||||||
data: {
|
|
||||||
query: {
|
|
||||||
bed: {
|
|
||||||
controller: 'tags',
|
|
||||||
resource: 'tags',
|
|
||||||
type: 'read',
|
|
||||||
options: {
|
|
||||||
slug: 'bed',
|
|
||||||
visibility: 'public'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dream: {
|
|
||||||
controller: 'tags',
|
|
||||||
resource: 'tags',
|
|
||||||
type: 'read',
|
|
||||||
options: {
|
|
||||||
slug: 'dream',
|
|
||||||
visibility: 'public'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
router: {
|
|
||||||
tags: [{redirect: true, slug: 'bed'}, {redirect: true, slug: 'dream'}]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
templates: []
|
|
||||||
},
|
|
||||||
'/lala/': {
|
|
||||||
data: {
|
|
||||||
query: {
|
|
||||||
author: {
|
|
||||||
controller: 'users',
|
|
||||||
resource: 'users',
|
|
||||||
type: 'read',
|
|
||||||
options: {
|
|
||||||
slug: 'carsten',
|
|
||||||
visibility: 'public'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
router: {
|
|
||||||
authors: [{redirect: true, slug: 'carsten'}]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
templates: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
collections: {
|
|
||||||
'/more/': {
|
|
||||||
permalink: '/:slug/',
|
|
||||||
data: {
|
|
||||||
query: {
|
|
||||||
home: {
|
|
||||||
controller: 'posts',
|
|
||||||
resource: 'posts',
|
|
||||||
type: 'read',
|
|
||||||
options: {
|
|
||||||
page: 1,
|
|
||||||
slug: 'home',
|
|
||||||
status: 'published'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
router: {
|
|
||||||
posts: [{redirect: true, slug: 'home'}]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
templates: []
|
|
||||||
},
|
|
||||||
'/podcast/': {
|
|
||||||
permalink: '/podcast/:slug/',
|
|
||||||
data: {
|
|
||||||
query: {
|
|
||||||
something: {
|
|
||||||
controller: 'tags',
|
|
||||||
resource: 'tags',
|
|
||||||
type: 'read',
|
|
||||||
options: {
|
|
||||||
slug: 'something',
|
|
||||||
visibility: 'public'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
router: {
|
|
||||||
tags: [{redirect: true, slug: 'something'}]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
templates: []
|
|
||||||
},
|
|
||||||
'/': {
|
|
||||||
permalink: '/:slug/',
|
|
||||||
data: {
|
|
||||||
query: {
|
|
||||||
tag: {
|
|
||||||
controller: 'tags',
|
|
||||||
resource: 'tags',
|
|
||||||
type: 'read',
|
|
||||||
options: {
|
|
||||||
slug: 'sport',
|
|
||||||
visibility: 'public'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
router: {
|
|
||||||
tags: [{redirect: true, slug: 'sport'}]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
templates: []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('longform', function () {
|
|
||||||
const object = validate({
|
|
||||||
routes: {
|
|
||||||
'/food/': {
|
|
||||||
data: {
|
|
||||||
food: {
|
|
||||||
resource: 'posts',
|
|
||||||
type: 'browse'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'/wellness/': {
|
|
||||||
data: {
|
|
||||||
posts: {
|
|
||||||
resource: 'posts',
|
|
||||||
type: 'read',
|
|
||||||
redirect: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'/partyparty/': {
|
|
||||||
data: {
|
|
||||||
people: {
|
|
||||||
resource: 'users',
|
|
||||||
type: 'read',
|
|
||||||
slug: 'djgutelaune',
|
|
||||||
redirect: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
collections: {
|
|
||||||
'/yoga/': {
|
|
||||||
permalink: '/{slug}/',
|
|
||||||
data: {
|
|
||||||
gym: {
|
|
||||||
resource: 'posts',
|
|
||||||
type: 'read',
|
|
||||||
slug: 'ups',
|
|
||||||
status: 'draft'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
object.should.eql({
|
|
||||||
taxonomies: {},
|
|
||||||
routes: {
|
|
||||||
'/food/': {
|
|
||||||
data: {
|
|
||||||
query: {
|
|
||||||
food: {
|
|
||||||
controller: 'posts',
|
|
||||||
resource: 'posts',
|
|
||||||
type: 'browse',
|
|
||||||
options: {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
router: {
|
|
||||||
posts: [{redirect: true}]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
templates: []
|
|
||||||
},
|
|
||||||
'/wellness/': {
|
|
||||||
data: {
|
|
||||||
query: {
|
|
||||||
posts: {
|
|
||||||
controller: 'posts',
|
|
||||||
resource: 'posts',
|
|
||||||
type: 'read',
|
|
||||||
options: {
|
|
||||||
status: 'published',
|
|
||||||
slug: '%s',
|
|
||||||
page: 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
router: {
|
|
||||||
posts: [{redirect: false}]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
templates: []
|
|
||||||
},
|
|
||||||
'/partyparty/': {
|
|
||||||
data: {
|
|
||||||
query: {
|
|
||||||
people: {
|
|
||||||
controller: 'users',
|
|
||||||
resource: 'users',
|
|
||||||
type: 'read',
|
|
||||||
options: {
|
|
||||||
slug: 'djgutelaune',
|
|
||||||
visibility: 'public'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
router: {
|
|
||||||
authors: [{redirect: true, slug: 'djgutelaune'}]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
templates: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
collections: {
|
|
||||||
'/yoga/': {
|
|
||||||
permalink: '/:slug/',
|
|
||||||
data: {
|
|
||||||
query: {
|
|
||||||
gym: {
|
|
||||||
controller: 'posts',
|
|
||||||
resource: 'posts',
|
|
||||||
type: 'read',
|
|
||||||
options: {
|
|
||||||
page: 0,
|
|
||||||
slug: 'ups',
|
|
||||||
status: 'draft'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
router: {
|
|
||||||
posts: [{redirect: true, slug: 'ups'}]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
templates: []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('errors: data shortform incorrect', function () {
|
|
||||||
try {
|
|
||||||
validate({
|
|
||||||
collections: {
|
|
||||||
'/magic/': {
|
|
||||||
permalink: '/{slug}/',
|
|
||||||
data: 'tag:test'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
(err instanceof common.errors.ValidationError).should.be.true();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('should fail');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('errors: data longform resource is missing', function () {
|
|
||||||
try {
|
|
||||||
validate({
|
|
||||||
collections: {
|
|
||||||
'/magic/': {
|
|
||||||
permalink: '/{slug}/',
|
|
||||||
data: {
|
|
||||||
type: 'edit'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
(err instanceof common.errors.ValidationError).should.be.true();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('should fail');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('errors: data longform type is missing', function () {
|
|
||||||
try {
|
|
||||||
validate({
|
|
||||||
collections: {
|
|
||||||
'/magic/': {
|
|
||||||
permalink: '/{slug}/',
|
|
||||||
data: {
|
|
||||||
resource: 'subscribers'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
(err instanceof common.errors.ValidationError).should.be.true();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('should fail');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('errors: data longform name is author', function () {
|
|
||||||
try {
|
|
||||||
validate({
|
|
||||||
collections: {
|
|
||||||
'/magic/': {
|
|
||||||
permalink: '/{slug}/',
|
|
||||||
data: {
|
|
||||||
author: {
|
|
||||||
resource: 'users'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
(err instanceof common.errors.ValidationError).should.be.true();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('should fail');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('errors: data longform does not use a custom name at all', function () {
|
|
||||||
try {
|
|
||||||
validate({
|
|
||||||
collections: {
|
|
||||||
'/magic/': {
|
|
||||||
permalink: '/{slug}/',
|
|
||||||
data: {
|
|
||||||
resource: 'users'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
(err instanceof common.errors.ValidationError).should.be.true();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('should fail');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('v2', function () {
|
describe('v2', function () {
|
||||||
before(function () {
|
before(function () {
|
||||||
apiVersion = 'v2';
|
apiVersion = 'v2';
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
"demo": "https://demo.ghost.io",
|
"demo": "https://demo.ghost.io",
|
||||||
"version": "2.4.2",
|
"version": "2.4.2",
|
||||||
"engines": {
|
"engines": {
|
||||||
"ghost": ">=2.0.0"
|
"ghost": ">=2.0.0",
|
||||||
|
"ghost-api": "v2"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"screenshots": {
|
"screenshots": {
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
"demo": "https://demo.ghost.io",
|
"demo": "https://demo.ghost.io",
|
||||||
"version": "2.4.2",
|
"version": "2.4.2",
|
||||||
"engines": {
|
"engines": {
|
||||||
"ghost": ">=2.0.0"
|
"ghost": ">=2.0.0",
|
||||||
|
"ghost-api": "v2"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"screenshots": {
|
"screenshots": {
|
||||||
|
|
Loading…
Add table
Reference in a new issue