0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-10 23:36:14 -05:00

Merge pull request #3230 from jaswilli/issue-3226

Fix active theme selector.  Add validation to API.
This commit is contained in:
Hannah Wolfe 2014-07-10 12:52:01 +01:00
commit b69b5e7638
5 changed files with 59 additions and 9 deletions

View file

@ -24,7 +24,7 @@ var SettingsGeneralController = Ember.ObjectController.extend({
return themes;
}, []);
}.property('availableThemes').readOnly(),
}.property().readOnly(),
actions: {
save: function () {

View file

@ -3,10 +3,15 @@ var schema = require('../schema').tables,
validator = require('validator'),
when = require('when'),
errors = require('../../errors'),
config = require('../../config'),
requireTree = require('../../require-tree').readAll,
validateSchema,
validateSettings,
validate;
validateActiveTheme,
validate,
availableThemes;
// Provide a few custom validators
//
@ -89,6 +94,27 @@ validateSettings = function (defaultSettings, model) {
return when.resolve();
};
// A Promise that will resolve to an object with a property for each installed theme.
// This is necessary because certain configuration data is only available while Ghost
// is running and at times the validations are used when it's not (e.g. tests)
availableThemes = requireTree(config().paths.themePath);
validateActiveTheme = function (themeName) {
// If Ghost is running and its availableThemes collection exists
// give it priority.
if (Object.keys(config().paths.availableThemes).length > 0) {
availableThemes = when(config().paths.availableThemes);
}
return availableThemes.then(function (themes) {
if (!themes.hasOwnProperty(themeName)) {
return when.reject(new errors.ValidationError(themeName + ' cannot be activated because it is not currently installed.', 'activeTheme'));
}
return when.resolve();
});
};
// Validate default settings using the validator module.
// Each validation's key is a method name and its value is an array of options
//
@ -134,5 +160,6 @@ validate = function (value, key, validations) {
module.exports = {
validateSchema: validateSchema,
validateSettings: validateSettings
validateSettings: validateSettings,
validateActiveTheme: validateActiveTheme
};

View file

@ -48,9 +48,19 @@ Settings = ghostBookshelf.Model.extend({
},
validate: function () {
var self = this;
return validation.validateSchema(self.tableName, self.toJSON()).then(function () {
var self = this,
setting = this.toJSON();
return validation.validateSchema(self.tableName, setting).then(function () {
return validation.validateSettings(getDefaultSettings(), self);
}).then(function () {
var themeName = setting.value || '';
if (setting.key !== 'activeTheme') {
return when.resolve();
}
return validation.validateActiveTheme(themeName);
});
},

View file

@ -208,4 +208,17 @@ describe('Settings API', function () {
done();
}).catch(done);
});
it('does not allow an active theme which is not installed', function (done) {
return callApiWithContext(defaultContext, 'edit', 'activeTheme', { settings: [{ key: 'activeTheme', value: 'rasper' }] })
.then(function (response) {
done(new Error('Allowed to set an active theme which is not installed'));
}).catch(function (err) {
should.exist(err);
err.type.should.eql('ValidationError');
done();
}).catch(done);
});
});

View file

@ -87,15 +87,15 @@ describe('Themes API', function () {
_.extend(configStub, config);
ThemeAPI.__set__('config', configStub);
ThemeAPI.edit({themes: [{uuid: 'rasper', active: true }]}, {context: {user: 1}}).then(function (result) {
ThemeAPI.edit({themes: [{uuid: 'casper', active: true }]}, {context: {user: 1}}).then(function (result) {
should.exist(result);
should.exist(result.themes);
result.themes.length.should.be.above(0);
testUtils.API.checkResponse(result.themes[0], 'theme');
result.themes[0].uuid.should.equal('rasper');
result.themes[0].uuid.should.equal('casper');
done();
}).catch(function (error) {
done(new Error(JSON.stringify(error)));
}).catch(done);
})
});
});
});