2
1
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2023-12-13 21:00:40 +01:00

Merge pull request #5858 from ErisDS/issue-5808

Show a single 422 error for invalid values
This commit is contained in:
Sebastian Gierlinger 2015-09-26 12:14:12 +02:00
commit dbc53dc853
9 changed files with 86 additions and 6 deletions

View file

@ -89,7 +89,8 @@ utils = {
return Promise.resolve(options);
}
return errors.logAndRejectError(validationErrors);
// For now, we can only handle showing the first validation error
return errors.logAndRejectError(validationErrors[0]);
}
// If we got an object, check that too
@ -110,6 +111,7 @@ utils = {
var globalValidations = {
id: {matches: /^\d+|me$/},
uuid: {isUUID: true},
slug: {isSlug: true},
page: {matches: /^\d+$/},
limit: {matches: /^\d+|all$/},
fields: {matches: /^[a-z0-9_,]+$/},
@ -125,8 +127,8 @@ utils = {
if (globalValidations[key]) {
errors = errors.concat(validation.validate(value, key, globalValidations[key]));
} else {
// all other keys should be an alphanumeric string + -, like slug, tag, author, status, etc
errors = errors.concat(validation.validate(value, key, {matches: /^[a-z0-9\-_]+$/}));
// all other keys should be alpha-numeric with dashes/underscores, like tag, author, status, etc
errors = errors.concat(validation.validate(value, key, globalValidations.slug));
}
}
});

View file

@ -27,6 +27,10 @@ validator.extend('isEmptyOrURL', function isEmptyOrURL(str) {
return (_.isEmpty(str) || validator.isURL(str, {require_protocol: false}));
});
validator.extend('isSlug', function isSlug(str) {
return validator.matches(str, /^[a-z0-9\-_]+$/);
});
// Validation against schema attributes
// values are checked against the validation objects from schema.js
validateSchema = function validateSchema(tableName, model) {

View file

@ -336,7 +336,7 @@ errors = {
if (!err || !(err instanceof Error)) {
next();
}
errors.renderErrorPage(err.status || 500, err, req, res, next);
errors.renderErrorPage(err.status || err.code || 500, err, req, res, next);
} else {
var statusCode = 500,
returnErrors = [];

View file

@ -63,6 +63,14 @@ describe('Frontend Routing', function () {
.end(doEnd(done));
});
it('should 404 for unknown post with invalid characters', function (done) {
request.get('/$pec+acular~/')
.expect('Cache-Control', testUtils.cacheRules['private'])
.expect(404)
.expect(/Page not found/)
.end(doEnd(done));
});
it('should 404 for unknown frontend route', function (done) {
request.get('/spectacular/marvellous/')
.expect('Cache-Control', testUtils.cacheRules['private'])
@ -102,6 +110,14 @@ describe('Frontend Routing', function () {
.expect(/Page not found/)
.end(doEnd(done));
});
it('should 404 for unknown author with invalid characters', function (done) {
request.get('/author/ghost!user^/')
.expect('Cache-Control', testUtils.cacheRules['private'])
.expect(404)
.expect(/Page not found/)
.end(doEnd(done));
});
});
describe('Home', function () {

View file

@ -219,6 +219,28 @@ describe('Post API', function () {
done();
}).catch(done);
});
it('cannot fetch all posts for a tag with invalid slug', function (done) {
PostAPI.browse({tag: 'invalid!'}).then(function () {
done(new Error('Should not return a result with invalid tag'));
}).catch(function (err) {
should.exist(err);
err.message.should.eql('Validation (isSlug) failed for tag');
err.code.should.eql(422);
done();
});
});
it('cannot fetch all posts for an author with invalid slug', function (done) {
PostAPI.browse({author: 'invalid!'}).then(function () {
done(new Error('Should not return a result with invalid author'));
}).catch(function (err) {
should.exist(err);
err.message.should.eql('Validation (isSlug) failed for author');
err.code.should.eql(422);
done();
});
});
});
describe('Read', function () {
@ -372,5 +394,17 @@ describe('Post API', function () {
done();
}).catch(done);
});
// TODO: this should be a 422?
it('cannot fetch a post with an invalid slug', function (done) {
PostAPI.read({slug: 'invalid!'}).then(function () {
done(new Error('Should not return a result with invalid slug'));
}).catch(function (err) {
should.exist(err);
err.message.should.eql('Post not found.');
done();
});
});
});
});

View file

@ -77,7 +77,7 @@ describe('Slug API', function () {
.then(function () {
done(new Error('Generate a slug for an unknown type is not rejected.'));
}).catch(function (errors) {
errors.should.have.enumerable(0).with.property('errorType', 'ValidationError');
errors.should.have.property('errorType', 'ValidationError');
done();
}).catch(done);
});

View file

@ -296,5 +296,17 @@ describe('Tags API', function () {
done();
}).catch(done);
});
// TODO: this should be a 422?
it('cannot fetch a tag with an invalid slug', function (done) {
TagAPI.read({slug: 'invalid!'}).then(function () {
done(new Error('Should not return a result with invalid slug'));
}).catch(function (err) {
should.exist(err);
err.message.should.eql('Tag not found.');
done();
});
});
});
});

View file

@ -194,6 +194,18 @@ describe('Users API', function () {
done();
}).catch(done);
});
// TODO: this should be a 422?
it('cannot fetch a user with an invalid slug', function (done) {
UserAPI.read({slug: 'invalid!'}).then(function () {
done(new Error('Should not return a result with invalid slug'));
}).catch(function (err) {
should.exist(err);
err.message.should.eql('User not found.');
done();
});
});
});
describe('Edit', function () {

View file

@ -163,7 +163,7 @@ describe('API Utils', function () {
).then(function () {
done(new Error('Should have thrown a validation error'));
}).catch(function (err) {
err.should.have.enumerable('0').with.property('errorType', 'ValidationError');
err.should.have.property('errorType', 'ValidationError');
done();
});
});