Move to new API format for Settings.

refs #2606
- Use new API format when updating settings from the client side
- Add additional test to test new API format
- Adjust functional tests to work with the new format
This commit is contained in:
Fabian Becker 2014-05-06 18:52:11 +00:00
parent 7de8025bed
commit 2795e723e1
4 changed files with 56 additions and 60 deletions

View File

@ -1,4 +1,4 @@
/*global Ghost, _ */ /*global Backbone, Ghost, _ */
(function () { (function () {
'use strict'; 'use strict';
//id:0 is used to issue PUT requests //id:0 is used to issue PUT requests
@ -14,6 +14,19 @@
}, {}); }, {});
return result; return result;
},
sync: function (method, model, options) {
var settings = _.map(this.attributes, function (value, key) {
return { key: key, value: value };
});
//wrap settings in {settings: [{...}]}
if (method === 'update') {
options.data = JSON.stringify({settings: settings});
options.contentType = 'application/json';
}
return Backbone.Model.prototype.sync.apply(this, arguments);
} }
}); });

View File

@ -1,10 +1,8 @@
var _ = require('lodash'), var _ = require('lodash'),
dataProvider = require('../models'), dataProvider = require('../models'),
when = require('when'), when = require('when'),
errors = require('../errorHandling'),
config = require('../config'), config = require('../config'),
settings, settings,
settingsCollection,
settingsFilter, settingsFilter,
updateSettingsCache, updateSettingsCache,
readSettingsResult, readSettingsResult,
@ -14,12 +12,6 @@ var _ = require('lodash'),
settingsCache = {}; settingsCache = {};
// ### Helpers // ### Helpers
// Turn an object into a collection
settingsCollection = function (settings) {
return _.map(settings, function (value, key) {
return { key: key, value: value };
});
};
// Filters an object based on a given filter object // Filters an object based on a given filter object
settingsFilter = function (settings, filter) { settingsFilter = function (settings, filter) {
@ -185,15 +177,21 @@ settings = {
var self = this, var self = this,
type; type;
// Check for passing a collection of settings first // Allow shorthand syntax
if (_.isObject(key)) { if (_.isString(key)) {
//clean data key = { settings: [{ key: key, value: value }]};
type = key.type; }
delete key.type;
delete key.availableThemes; //clean data
delete key.availableApps; type = _.find(key.settings, function (setting) { return setting.key === 'type'; });
if (_.isObject(type)) {
type = type.value;
}
key = _.reject(key.settings, function (setting) {
return setting.key === 'type' || setting.key === 'availableThemes' || setting.key === 'availableApps';
});
key = settingsCollection(key);
return dataProvider.Settings.edit(key, {user: self.user}).then(function (result) { return dataProvider.Settings.edit(key, {user: self.user}).then(function (result) {
var readResult = readSettingsResult(result); var readResult = readSettingsResult(result);
@ -203,38 +201,9 @@ settings = {
return settingsResult(readResult, type); return settingsResult(readResult, type);
}); });
}).otherwise(function (error) { }).otherwise(function (error) {
return dataProvider.Settings.findOne(key.key).then(function (result) { // In case something goes wrong it is most likely because of an invalid key
if (!result) { // or because of a badly formatted request.
return when.reject({type: 'NotFound', message: 'Unable to find setting: ' + key + '.'}); return when.reject({type: 'BadRequest', message: error.message});
}
return when.reject({type: 'InternalServerError', message: error.message});
});
});
}
return dataProvider.Settings.findOne(key).then(function (setting) {
if (!setting) {
return when.reject({type: 'NotFound', message: 'Unable to find setting: ' + key + '.'});
}
if (!_.isString(value)) {
value = JSON.stringify(value);
}
setting.set('value', value);
return dataProvider.Settings.edit(setting, {user: self.user}).then(function (result) {
var updatedSetting = _.first(result).attributes;
settingsCache[updatedSetting.key].value = updatedSetting.value;
return updatedSetting;
}).then(function (updatedSetting) {
return config.theme.update(settings, config().url).then(function () {
return updatedSetting;
});
}).then(function (updatedSetting) {
var result = {};
result[updatedSetting.key] = updatedSetting;
return settingsResult(result);
}).otherwise(errors.logAndThrowError);
}); });
} }
}; };

View File

@ -148,7 +148,9 @@ describe('Settings API', function () {
var jsonResponse = res.body, var jsonResponse = res.body,
changedValue = 'Ghost changed', changedValue = 'Ghost changed',
settingToChange = { settingToChange = {
title: changedValue settings: [
{ key: 'title', value: changedValue }
]
}; };
jsonResponse.should.exist; jsonResponse.should.exist;
@ -175,7 +177,7 @@ describe('Settings API', function () {
}); });
it('can\'t edit settings with invalid CSRF token', function (done) { it('can\'t edit settings with invalid CSRF token', function (done) {
request.get(testUtils.API.getApiQuery('settings')) request.get(testUtils.API.getApiQuery('settings/'))
.end(function (err, res) { .end(function (err, res) {
if (err) { if (err) {
return done(err); return done(err);
@ -202,7 +204,7 @@ describe('Settings API', function () {
it('can\'t edit non existent setting', function (done) { it('can\'t edit non existent setting', function (done) {
request.get(testUtils.API.getApiQuery('settings')) request.get(testUtils.API.getApiQuery('settings/'))
.end(function (err, res) { .end(function (err, res) {
if (err) { if (err) {
return done(err); return done(err);
@ -211,12 +213,13 @@ describe('Settings API', function () {
var jsonResponse = res.body, var jsonResponse = res.body,
newValue = 'new value'; newValue = 'new value';
jsonResponse.should.exist; jsonResponse.should.exist;
jsonResponse.testvalue = newValue; should.exist(jsonResponse.settings);
jsonResponse.settings.push({ key: 'testvalue', value: newValue });
request.put(testUtils.API.getApiQuery('settings/')) request.put(testUtils.API.getApiQuery('settings/'))
.set('X-CSRF-Token', csrfToken) .set('X-CSRF-Token', csrfToken)
.send(jsonResponse) .send(jsonResponse)
.expect(404) .expect(400)
.end(function (err, res) { .end(function (err, res) {
if (err) { if (err) {
return done(err); return done(err);

View File

@ -67,6 +67,17 @@ describe('Settings API', function () {
}); });
it('can edit', function (done) { it('can edit', function (done) {
return SettingsAPI.edit({ settings: [{ key: 'title', value: 'UpdatedGhost'}]}).then(function (response) {
should.exist(response);
testUtils.API.checkResponse(response, 'settings');
response.settings.length.should.equal(1);
testUtils.API.checkResponse(response.settings[0], 'setting');
done();
}).catch(done);
})
it('can edit, by key/value', function (done) {
return SettingsAPI.edit('title', 'UpdatedGhost').then(function (response) { return SettingsAPI.edit('title', 'UpdatedGhost').then(function (response) {
should.exist(response); should.exist(response);
testUtils.API.checkResponse(response, 'settings'); testUtils.API.checkResponse(response, 'settings');