Added v2 controller for slugs (#9978)

- Added slugs controller to v2 API
- Added slugs tests to v2 API
- Updated generic validation error message in shared validator to return validation error with sub-message
This commit is contained in:
Rishabh Garg 2018-10-12 17:55:20 +05:30 committed by GitHub
parent 2da74a614b
commit 5683204371
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 208 additions and 2 deletions

View File

@ -55,7 +55,12 @@ const validate = (config, attrs) => {
});
if (unallowedValues.length) {
errors.push(new common.errors.ValidationError());
errors.push(new common.errors.ValidationError({
message: common.i18n.t('notices.data.validation.index.validationFailed', {
validationName: 'AllowedValues',
key: key
})
}));
}
}
}

View File

@ -17,5 +17,9 @@ module.exports = {
get roles() {
return shared.pipeline(require('./roles'), localUtils);
},
get slugs() {
return shared.pipeline(require('./slugs'), localUtils);
}
};

View File

@ -0,0 +1,47 @@
const models = require('../../models');
const common = require('../../lib/common');
const allowedTypes = {
post: models.Post,
tag: models.Tag,
user: models.User,
app: models.App
};
module.exports = {
docName: 'slugs',
generate: {
options: [
'include',
'type'
],
data: [
'name'
],
permissions: true,
validation: {
options: {
type: {
required: true,
values: Object.keys(allowedTypes)
}
},
data: {
name: {
required: true
}
}
},
query(frame) {
return models.Base.Model.generateSlug(allowedTypes[frame.options.type], frame.data.name, {status: 'all'})
.then((slug) => {
if (!slug) {
return Promise.reject(new common.errors.GhostError({
message: common.i18n.t('errors.api.slugs.couldNotGenerateSlug')
}));
}
return slug;
});
}
}
};

View File

@ -5,5 +5,9 @@ module.exports = {
get roles() {
return require('./roles');
},
get slugs() {
return require('./slugs');
}
};

View File

@ -0,0 +1,13 @@
const debug = require('ghost-ignition').debug('api:v2:utils:serializers:output:slugs');
module.exports = {
all(slug, apiConfig, frame) {
debug('all');
frame.response = {
slugs: [{slug}]
};
debug(frame.response);
}
};

View File

@ -97,7 +97,7 @@ module.exports = function apiRoutes() {
router.get('/clients/slug/:slug', api.http(api.clients.read));
// ## Slugs
router.get('/slugs/:type/:name', mw.authAdminAPI, api.http(api.slugs.generate));
router.get('/slugs/:type/:name', mw.authAdminAPI, apiv2.http(apiv2.slugs.generate));
// ## Themes
router.get('/themes/', mw.authAdminAPI, api.http(api.themes.browse));

View File

@ -0,0 +1,133 @@
var should = require('should'),
supertest = require('supertest'),
testUtils = require('../../../../utils'),
localUtils = require('./utils'),
config = require('../../../../../server/config'),
ghost = testUtils.startGhost,
request;
describe('Slug API', function () {
let ghostServer;
before(function () {
return ghost()
.then(function (_ghostServer) {
ghostServer = _ghostServer;
request = supertest.agent(config.get('url'));
})
.then(function () {
return localUtils.doAuth(request);
});
});
it('should be able to get a post slug', function (done) {
request.get(localUtils.API.getApiQuery('slugs/post/a post title/'))
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(200)
.end(function (err, res) {
if (err) {
return done(err);
}
should.not.exist(res.headers['x-cache-invalidate']);
var jsonResponse = res.body;
should.exist(jsonResponse);
should.exist(jsonResponse.slugs);
jsonResponse.slugs.should.have.length(1);
testUtils.API.checkResponse(jsonResponse.slugs[0], 'slug');
jsonResponse.slugs[0].slug.should.equal('a-post-title');
done();
});
});
it('should be able to get a tag slug', function (done) {
request.get(localUtils.API.getApiQuery('slugs/post/atag/'))
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(200)
.end(function (err, res) {
if (err) {
return done(err);
}
should.not.exist(res.headers['x-cache-invalidate']);
var jsonResponse = res.body;
should.exist(jsonResponse);
should.exist(jsonResponse.slugs);
jsonResponse.slugs.should.have.length(1);
testUtils.API.checkResponse(jsonResponse.slugs[0], 'slug');
jsonResponse.slugs[0].slug.should.equal('atag');
done();
});
});
it('should be able to get a user slug', function (done) {
request.get(localUtils.API.getApiQuery('slugs/user/user name/'))
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(200)
.end(function (err, res) {
if (err) {
return done(err);
}
should.not.exist(res.headers['x-cache-invalidate']);
var jsonResponse = res.body;
should.exist(jsonResponse);
should.exist(jsonResponse.slugs);
jsonResponse.slugs.should.have.length(1);
testUtils.API.checkResponse(jsonResponse.slugs[0], 'slug');
jsonResponse.slugs[0].slug.should.equal('user-name');
done();
});
});
it('should be able to get an app slug', function (done) {
request.get(localUtils.API.getApiQuery('slugs/app/cool app/'))
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(200)
.end(function (err, res) {
if (err) {
return done(err);
}
should.not.exist(res.headers['x-cache-invalidate']);
var jsonResponse = res.body;
should.exist(jsonResponse);
should.exist(jsonResponse.slugs);
jsonResponse.slugs.should.have.length(1);
testUtils.API.checkResponse(jsonResponse.slugs[0], 'slug');
jsonResponse.slugs[0].slug.should.equal('cool-app');
done();
});
});
it('should not be able to get a slug for an unknown type', function (done) {
request.get(localUtils.API.getApiQuery('slugs/unknown/who knows/'))
.set('Origin', config.get('url'))
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(422)
.end(function (err, res) {
if (err) {
return done(err);
}
var jsonResponse = res.body;
should.exist(jsonResponse.errors);
done();
});
});
});