mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-20 22:42:53 -05:00
8f660c3259
closes #12001 * Moved settings validation to the model This moves the settings validation out of the validation file and into the model, as it is _only_ used there. It also sets us up in the future for custom validators on individual settings. * Improved validation of stripe_plans setting - Checks `interval` is a valid string - Checks `name` & `currency` are strings * Moved stripe key validation into model The stripe key settings are all nullable and the regex validation fails when the input is `null`. Rather than reworking the entirety of how we validate with default-settings validation objects, this moves the validation into methods on the Settings model. * Added tests for new setting validations Adds tests for both valid and invalid settings, as well as helpers making future tests easier and less repetitive
179 lines
7.3 KiB
JavaScript
179 lines
7.3 KiB
JavaScript
const should = require('should');
|
|
const _ = require('lodash');
|
|
const ObjectId = require('bson-objectid');
|
|
const testUtils = require('../../../utils');
|
|
const models = require('../../../../core/server/models');
|
|
const validation = require('../../../../core/server/data/validation');
|
|
|
|
// Validate our customisations
|
|
describe('Validation', function () {
|
|
before(function () {
|
|
models.init();
|
|
});
|
|
|
|
it('should export our required functions', function () {
|
|
should.exist(validation);
|
|
|
|
validation.should.have.properties(
|
|
['validate', 'validator', 'validateSchema']
|
|
);
|
|
|
|
validation.validate.should.be.a.Function();
|
|
validation.validatePassword.should.be.a.Function();
|
|
validation.validateSchema.should.be.a.Function();
|
|
|
|
validation.validator.should.have.properties(['empty', 'notContains', 'isTimezone', 'isEmptyOrURL', 'isSlug']);
|
|
});
|
|
|
|
describe('Validate Schema', function () {
|
|
describe('models.add', function () {
|
|
it('blank model', function () {
|
|
// NOTE: Fields with `defaultTo` are getting ignored. This is handled on the DB level.
|
|
return validation.validateSchema('posts', models.Post.forge(), {method: 'insert'})
|
|
.then(function () {
|
|
throw new Error('Expected ValidationError.');
|
|
})
|
|
.catch(function (err) {
|
|
if (!_.isArray(err)) {
|
|
throw err;
|
|
}
|
|
|
|
err.length.should.eql(7);
|
|
|
|
const errorMessages = _.map(err, function (object) {
|
|
return object.message;
|
|
}).join(',');
|
|
|
|
// NOTE: Some of these fields are auto-filled in the model layer (e.g. author_id, created_at etc.)
|
|
['id', 'uuid', 'slug', 'title', 'author_id', 'created_at', 'created_by'].forEach(function (attr) {
|
|
errorMessages.should.match(new RegExp('posts.' + attr));
|
|
});
|
|
});
|
|
});
|
|
|
|
it('blank id', function () {
|
|
const postModel = models.Post.forge(testUtils.DataGenerator.forKnex.createPost({
|
|
id: null,
|
|
slug: 'test'
|
|
}));
|
|
|
|
return validation.validateSchema('posts', postModel, {method: 'insert'})
|
|
.then(function () {
|
|
throw new Error('Expected ValidationError.');
|
|
})
|
|
.catch(function (err) {
|
|
if (!_.isArray(err)) {
|
|
throw err;
|
|
}
|
|
|
|
err.length.should.eql(1);
|
|
err[0].message.should.match(/posts\.id/);
|
|
});
|
|
});
|
|
|
|
it('should pass', function () {
|
|
return validation.validateSchema(
|
|
'posts',
|
|
models.Post.forge(testUtils.DataGenerator.forKnex.createPost({slug: 'title'})),
|
|
{method: 'insert'}
|
|
);
|
|
});
|
|
|
|
it('transforms 0 and 1', function () {
|
|
const post = models.Post.forge(testUtils.DataGenerator.forKnex.createPost({slug: 'test', featured: 0}));
|
|
post.get('featured').should.eql(0);
|
|
|
|
return validation.validateSchema('posts', post, {method: 'insert'})
|
|
.then(function () {
|
|
post.get('featured').should.eql(false);
|
|
});
|
|
});
|
|
|
|
it('keeps true or false', function () {
|
|
const post = models.Post.forge(testUtils.DataGenerator.forKnex.createPost({slug: 'test', featured: true}));
|
|
post.get('featured').should.eql(true);
|
|
|
|
return validation.validateSchema('posts', post, {method: 'insert'})
|
|
.then(function () {
|
|
post.get('featured').should.eql(true);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('webhooks.add', function () {
|
|
it('event name is not lowercase', function () {
|
|
const webhook = models.Webhook.forge(testUtils.DataGenerator.forKnex.createWebhook({event: 'Test'}));
|
|
|
|
// NOTE: Fields with `defaultTo` are getting ignored. This is handled on the DB level.
|
|
return validation.validateSchema('webhooks', webhook, {method: 'insert'})
|
|
.then(function () {
|
|
throw new Error('Expected ValidationError.');
|
|
})
|
|
.catch(function (err) {
|
|
if (!_.isArray(err)) {
|
|
throw err;
|
|
}
|
|
|
|
err.length.should.eql(1);
|
|
err[0].errorType.should.eql('ValidationError');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('models.edit', function () {
|
|
it('uuid is invalid', function () {
|
|
const postModel = models.Post.forge({id: ObjectId.generate(), uuid: '1234'});
|
|
|
|
postModel.changed = {uuid: postModel.get('uuid')};
|
|
|
|
return validation.validateSchema('posts', postModel)
|
|
.then(function () {
|
|
throw new Error('Expected ValidationError.');
|
|
})
|
|
.catch(function (err) {
|
|
if (!_.isArray(err)) {
|
|
throw err;
|
|
}
|
|
|
|
err.length.should.eql(1);
|
|
err[0].message.should.match(/isUUID/);
|
|
});
|
|
});
|
|
|
|
it('date is null', function () {
|
|
const postModel = models.Post.forge({id: ObjectId.generate(), created_at: null});
|
|
|
|
postModel.changed = {created_at: postModel.get('updated_at')};
|
|
|
|
return validation.validateSchema('posts', postModel)
|
|
.then(function () {
|
|
throw new Error('Expected ValidationError.');
|
|
})
|
|
.catch(function (err) {
|
|
if (!_.isArray(err)) {
|
|
throw err;
|
|
}
|
|
|
|
err.length.should.eql(1);
|
|
err[0].message.should.match(/posts\.created_at/);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('Assert the Validator dependency', function () {
|
|
const validator = validation.validator;
|
|
|
|
it('isEmptyOrUrl filters javascript urls', function () {
|
|
validator.isEmptyOrURL('javascript:alert(0)').should.be.false();
|
|
validator.isEmptyOrURL('http://example.com/lol/<script>lalala</script>/').should.be.false();
|
|
validator.isEmptyOrURL('http://example.com/lol?somequery=<script>lalala</script>').should.be.false();
|
|
validator.isEmptyOrURL('').should.be.true();
|
|
validator.isEmptyOrURL('http://localhost:2368').should.be.true();
|
|
validator.isEmptyOrURL('http://example.com/test/').should.be.true();
|
|
validator.isEmptyOrURL('http://www.example.com/test/').should.be.true();
|
|
validator.isEmptyOrURL('http://example.com/foo?somequery=bar').should.be.true();
|
|
validator.isEmptyOrURL('example.com/test/').should.be.true();
|
|
});
|
|
});
|
|
});
|