mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-26 12:21:36 +03:00
Merge pull request #2814 from lennerd/issue-2601
Refactore slug API for generating tag and post slugs
This commit is contained in:
commit
97011e5eca
@ -13,13 +13,14 @@ var _ = require('lodash'),
|
||||
tags = require('./tags'),
|
||||
themes = require('./themes'),
|
||||
users = require('./users'),
|
||||
slugs = require('./slugs'),
|
||||
|
||||
http,
|
||||
formatHttpErrors,
|
||||
cacheInvalidationHeader,
|
||||
locationHeader,
|
||||
contentDispositionHeader,
|
||||
init,
|
||||
init;
|
||||
|
||||
/**
|
||||
* ### Init
|
||||
@ -247,5 +248,6 @@ module.exports = {
|
||||
settings: settings,
|
||||
tags: tags,
|
||||
themes: themes,
|
||||
users: users
|
||||
users: users,
|
||||
slugs: slugs
|
||||
};
|
||||
|
@ -168,26 +168,6 @@ posts = {
|
||||
}, function () {
|
||||
return when.reject(new errors.NoPermissionError('You do not have permission to remove posts.'));
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* ## Generate Slug
|
||||
* Create a unique slug for a given post title
|
||||
* @param {{title (required), transacting}} options
|
||||
* @returns {Promise(String)} Unique string
|
||||
*/
|
||||
generateSlug: function generateSlug(options) {
|
||||
return canThis(options.context).slug.post().then(function () {
|
||||
return dataProvider.Base.Model.generateSlug(dataProvider.Post, options.title, {status: 'all'})
|
||||
.then(function (slug) {
|
||||
if (slug) {
|
||||
return slug;
|
||||
}
|
||||
return when.reject(new errors.InternalServerError('Could not generate slug'));
|
||||
});
|
||||
}, function () {
|
||||
return when.reject(new errors.NoPermissionError('You do not have permission.'));
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
46
core/server/api/slugs.js
Normal file
46
core/server/api/slugs.js
Normal file
@ -0,0 +1,46 @@
|
||||
var canThis = require('../permissions').canThis,
|
||||
dataProvider = require('../models'),
|
||||
errors = require('../errors'),
|
||||
when = require('when'),
|
||||
|
||||
slugs,
|
||||
// `allowedTypes` is used to define allowed slug types and map them against it's model class counterpart
|
||||
allowedTypes = {
|
||||
post: dataProvider.Post,
|
||||
tag: dataProvider.Tag
|
||||
};
|
||||
|
||||
/**
|
||||
* ## Generate Slug
|
||||
* Create a unique slug for a given post title
|
||||
* @param {{type (required), context}} options
|
||||
* @param {{title (required), transacting}} options
|
||||
* @returns {Promise(String)} Unique string
|
||||
*/
|
||||
slugs = {
|
||||
|
||||
// #### Generate slug
|
||||
// **takes:** a string to generate the slug from
|
||||
generate: function (options) {
|
||||
options = options || {};
|
||||
|
||||
return canThis(options.context).generate.slug().then(function () {
|
||||
if (allowedTypes[options.type] === undefined) {
|
||||
return when.reject(new errors.BadRequestError('Unknown slug type \'' + options.type + '\'.'));
|
||||
}
|
||||
|
||||
return dataProvider.Base.Model.generateSlug(allowedTypes[options.type], options.title, {status: 'all'}).then(function (slug) {
|
||||
if (!slug) {
|
||||
return when.reject(new errors.InternalServerError('Could not generate slug.'));
|
||||
}
|
||||
|
||||
return { slugs: [{ slug: slug }] };
|
||||
});
|
||||
}, function () {
|
||||
return when.reject(new errors.NoPermissionError('You do not have permission to generate a slug.'));
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
module.exports = slugs;
|
@ -71,9 +71,14 @@ var fixtures = {
|
||||
|
||||
permissions003: [
|
||||
{
|
||||
"name": "Get slug",
|
||||
"action_type": "slug",
|
||||
"object_type": "post"
|
||||
"name": "Generate post slug",
|
||||
"action_type": "generate",
|
||||
"object_type": "slug"
|
||||
},
|
||||
{
|
||||
"name": "Generate tag slug",
|
||||
"action_type": "generate",
|
||||
"object_type": "slug"
|
||||
},
|
||||
{
|
||||
"name": "Export database",
|
||||
@ -185,7 +190,7 @@ populateFixtures = function () {
|
||||
Role.forge({name: 'Editor'}).fetch({withRelated: ['permissions']}).then(function (role) {
|
||||
Permissions.forge().fetch().then(function (perms) {
|
||||
var editor_perm = _.map(perms.toJSON(), function (perm) {
|
||||
if (perm.object_type === 'post' || perm.object_type === 'user') {
|
||||
if (perm.object_type === 'post' || perm.object_type === 'user' || perm.object_type === 'slug') {
|
||||
return perm.id;
|
||||
}
|
||||
if (perm.object_type === 'setting' &&
|
||||
@ -198,12 +203,14 @@ populateFixtures = function () {
|
||||
});
|
||||
});
|
||||
|
||||
// author gets access to post.add, post.slug, settings.browse, settings.read, users.browse and users.read
|
||||
// author gets access to post.add, slug.generate, settings.browse, settings.read, users.browse and users.read
|
||||
Role.forge({name: 'Author'}).fetch({withRelated: ['permissions']}).then(function (role) {
|
||||
Permissions.forge().fetch().then(function (perms) {
|
||||
var author_perm = _.map(perms.toJSON(), function (perm) {
|
||||
if (perm.object_type === 'post' &&
|
||||
(perm.action_type === 'add' || perm.action_type === 'slug')) {
|
||||
if (perm.object_type === 'post' && perm.action_type === 'add') {
|
||||
return perm.id;
|
||||
}
|
||||
if (perm.object_type === 'slug' && perm.action_type === 'generate') {
|
||||
return perm.id;
|
||||
}
|
||||
if (perm.object_type === 'setting' &&
|
||||
@ -272,8 +279,10 @@ updateFixtures = function () {
|
||||
Role.forge({name: 'Author'}).fetch({withRelated: ['permissions']}).then(function (role) {
|
||||
Permissions.forge().fetch().then(function (perms) {
|
||||
var author_perm = _.map(perms.toJSON(), function (perm) {
|
||||
if (perm.object_type === 'post' &&
|
||||
(perm.action_type === 'add' || perm.action_type === 'slug')) {
|
||||
if (perm.object_type === 'post' && perm.action_type === 'add') {
|
||||
return perm.id;
|
||||
}
|
||||
if (perm.object_type === 'slug' && perm.action_type === 'generate') {
|
||||
return perm.id;
|
||||
}
|
||||
if (perm.object_type === 'setting' &&
|
||||
|
@ -38,6 +38,8 @@ apiRoutes = function (server) {
|
||||
// ## Mail
|
||||
server.post('/ghost/api/v0.1/mail', api.http(api.mail.send));
|
||||
server.post('/ghost/api/v0.1/mail/test', api.http(api.mail.sendTest));
|
||||
// #### Slugs
|
||||
server.get('/ghost/api/v0.1/slugs/:type/:title', api.http(api.slugs.generate));
|
||||
};
|
||||
|
||||
module.exports = apiRoutes;
|
||||
module.exports = apiRoutes;
|
||||
|
@ -5,8 +5,8 @@ var testUtils = require('../../utils'),
|
||||
// Stuff we are testing
|
||||
permissions = require('../../../server/permissions'),
|
||||
DataGenerator = require('../../utils/fixtures/data-generator'),
|
||||
dbAPI = require('../../../server/api/db');
|
||||
TagsAPI = require('../../../server/api/tags');
|
||||
dbAPI = require('../../../server/api/db'),
|
||||
TagsAPI = require('../../../server/api/tags'),
|
||||
PostAPI = require('../../../server/api/posts');
|
||||
|
||||
describe('DB API', function () {
|
||||
|
66
core/test/integration/api/api_slugs_spec.js
Normal file
66
core/test/integration/api/api_slugs_spec.js
Normal file
@ -0,0 +1,66 @@
|
||||
var testUtils = require('../../utils'),
|
||||
should = require('should'),
|
||||
|
||||
permissions = require('../../../server/permissions'),
|
||||
slugAPI = require('../../../server/api/slugs');
|
||||
|
||||
describe('Slug API', function () {
|
||||
|
||||
before(function (done) {
|
||||
testUtils.clearData().then(function () {
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
beforeEach(function (done) {
|
||||
testUtils.initData().then(function () {
|
||||
return testUtils.insertDefaultFixtures();
|
||||
}).then(function () {
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
afterEach(function (done) {
|
||||
testUtils.clearData().then(function () {
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can generate post slug', function (done) {
|
||||
permissions.init().then(function () {
|
||||
return slugAPI.generate({ context: {user: 1}, type: 'post', title: 'A fancy Title'});
|
||||
}).then(function (results) {
|
||||
should.exist(results);
|
||||
testUtils.API.checkResponse(results, 'slugs');
|
||||
results.slugs.length.should.be.above(0);
|
||||
testUtils.API.checkResponse(results.slugs[0], 'slug');
|
||||
results.slugs[0].slug.should.equal('a-fancy-title');
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can generate tag slug', function (done) {
|
||||
permissions.init().then(function () {
|
||||
return slugAPI.generate({ context: {user: 1}, type: 'tag', title: 'A fancy Title'});
|
||||
}).then(function (results) {
|
||||
should.exist(results);
|
||||
testUtils.API.checkResponse(results, 'slugs');
|
||||
results.slugs.length.should.be.above(0);
|
||||
testUtils.API.checkResponse(results.slugs[0], 'slug');
|
||||
results.slugs[0].slug.should.equal('a-fancy-title');
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('reject unknown type', function (done) {
|
||||
permissions.init().then(function () {
|
||||
return slugAPI.generate({ context: {user: 1}, type: 'unknown type', title: 'A fancy Title'});
|
||||
}).then(function () {
|
||||
done(new Error('Generate a slug for a unknown type is not rejected.'));
|
||||
}, function (error) {
|
||||
error.type.should.eql('BadRequestError');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
@ -18,7 +18,9 @@ var url = require('url'),
|
||||
user: ['id', 'uuid', 'name', 'slug', 'email', 'image', 'cover', 'bio', 'website',
|
||||
'location', 'accessibility', 'status', 'language', 'meta_title', 'meta_description', 'last_login',
|
||||
'created_at', 'created_by', 'updated_at', 'updated_by'],
|
||||
notification: ['type', 'message', 'status', 'id', 'dismissable', 'location']
|
||||
notification: ['type', 'message', 'status', 'id', 'dismissable', 'location'],
|
||||
slugs: ['slugs'],
|
||||
slug: ['slug']
|
||||
};
|
||||
|
||||
function getApiQuery(route) {
|
||||
|
Loading…
Reference in New Issue
Block a user