From 62bbd4bd5c285d38090b670711daa1f73bbe2afe Mon Sep 17 00:00:00 2001 From: Matthew Bargar Date: Wed, 25 Nov 2015 19:22:32 -0500 Subject: [PATCH] Use snake_case in API payloads --- .../lib/schemas/index_pattern_schema.js | 12 +++++----- .../routes/api/index_patterns/register_get.js | 15 ++++++++++++- .../routes/api/index_patterns/register_put.js | 2 +- test/unit/api/index_patterns/_get.js | 22 +++++++++++++++++++ test/unit/api/index_patterns/_post.js | 8 +++++++ test/unit/api/index_patterns/_put.js | 10 +++++++-- test/unit/api/index_patterns/data.js | 2 +- 7 files changed, 60 insertions(+), 11 deletions(-) diff --git a/src/plugins/kibana/server/lib/schemas/index_pattern_schema.js b/src/plugins/kibana/server/lib/schemas/index_pattern_schema.js index 8896ff0e6493..aea9f9b5cfa4 100644 --- a/src/plugins/kibana/server/lib/schemas/index_pattern_schema.js +++ b/src/plugins/kibana/server/lib/schemas/index_pattern_schema.js @@ -3,8 +3,8 @@ var Joi = require('joi'); module.exports = { post: Joi.object({ title: Joi.string().required(), - timeFieldName: Joi.string(), - intervalName: Joi.string(), + time_field_name: Joi.string(), + interval_name: Joi.string(), fields: Joi.array().items(Joi.object({ name: Joi.string().required(), count: Joi.number().integer(), @@ -13,19 +13,19 @@ module.exports = { type: Joi.string().required() }).unknown() })), - fieldFormatMap: Joi.object() + field_format_map: Joi.object() }), put: Joi.object({ title: Joi.string(), - timeFieldName: Joi.string(), - intervalName: Joi.string(), + time_field_name: Joi.string(), + interval_name: Joi.string(), fields: Joi.array().items(Joi.object({ name: Joi.string().required(), count: Joi.number().integer(), scripted: Joi.boolean(), mapping: Joi.any().forbidden() })), - fieldFormatMap: Joi.object() + field_format_map: Joi.object() }) }; diff --git a/src/plugins/kibana/server/routes/api/index_patterns/register_get.js b/src/plugins/kibana/server/routes/api/index_patterns/register_get.js index c5768c04b35c..e66f4d1446b2 100644 --- a/src/plugins/kibana/server/routes/api/index_patterns/register_get.js +++ b/src/plugins/kibana/server/routes/api/index_patterns/register_get.js @@ -7,6 +7,12 @@ const handleESError = require('../../../lib/handle_es_error'); module.exports = function registerGet(server) { + function convertToSnakeCase(object) { + return _.mapKeys(object, (value, key) => { + return _.snakeCase(key); + }); + } + server.route({ path: '/api/kibana/index_patterns', method: 'GET', @@ -41,6 +47,9 @@ module.exports = function registerGet(server) { }); }) .then(removeDeprecatedFieldProps) + .then((patterns) => { + return _.map(patterns, convertToSnakeCase); + }) .then((patterns) => { reply(patterns); }, function (error) { @@ -71,8 +80,12 @@ module.exports = function registerGet(server) { getMappings(pattern, req), stitchPatternAndMappings) .then(removeDeprecatedFieldProps) + .then((pattern) => { + return _.isArray(pattern) ? pattern[0] : pattern; + }) + .then(convertToSnakeCase) .then(function (pattern) { - reply(_.isArray(pattern) ? pattern[0] : pattern); + reply(pattern); }, function (error) { reply(handleESError(error)); }); diff --git a/src/plugins/kibana/server/routes/api/index_patterns/register_put.js b/src/plugins/kibana/server/routes/api/index_patterns/register_put.js index 2e59a352132e..5667d46383ec 100644 --- a/src/plugins/kibana/server/routes/api/index_patterns/register_put.js +++ b/src/plugins/kibana/server/routes/api/index_patterns/register_put.js @@ -12,7 +12,7 @@ module.exports = function registerPut(server) { if (_.isEmpty(req.payload)) { return reply(Boom.badRequest('Payload required')); } - if (req.payload.title !== req.params.id) { + if (req.payload.title && req.payload.title !== req.params.id) { return reply(Boom.badRequest('Updates to title not supported')); } const validation = Joi.validate(req.payload, indexPatternSchema.put); diff --git a/test/unit/api/index_patterns/_get.js b/test/unit/api/index_patterns/_get.js index 25eae6bf4abc..3aa721ed2d7e 100644 --- a/test/unit/api/index_patterns/_get.js +++ b/test/unit/api/index_patterns/_get.js @@ -6,6 +6,12 @@ define(function (require) { var indexPatternSchema = require('intern/dojo/node!../../../../src/plugins/kibana/server/lib/schemas/index_pattern_schema'); var Joi = require('intern/dojo/node!joi'); + function expectSnakeCase(object) { + _.forEach(object, function (value, key) { + expect(key).to.be(_.snakeCase(key)); + }); + } + return function (bdd, scenarioManager, request) { bdd.describe('GET index_patterns', function getIndexPatterns() { @@ -44,6 +50,14 @@ define(function (require) { }); }); + bdd.it('should use snake_case in the response body', function () { + return request.get('/kibana/index_patterns') + .expect(200) + .then(function (res) { + _.forEach(res.body, expectSnakeCase); + }); + }); + bdd.describe('GET index_pattern by ID', function getIndexPatternByID() { bdd.it('should return 200 with the valid index pattern requested', function () { @@ -55,6 +69,14 @@ define(function (require) { }); }); + bdd.it('should use snake_case in the response body', function () { + return request.get('/kibana/index_patterns/logstash-*') + .expect(200) + .then(function (res) { + expectSnakeCase(res.body); + }); + }); + bdd.it('should return mappings info from the indices if there is no template', function () { var pattern = createTestData().indexPatternWithMappings; pattern.fields = _.map(pattern.fields, function (field) { diff --git a/test/unit/api/index_patterns/_post.js b/test/unit/api/index_patterns/_post.js index 24e17bf9f780..6839d131187d 100644 --- a/test/unit/api/index_patterns/_post.js +++ b/test/unit/api/index_patterns/_post.js @@ -148,6 +148,14 @@ define(function (require) { .expect(201); }); + bdd.it('should enforce snake_case in the request body', function () { + return request.post('/kibana/index_patterns') + .send(_.mapKeys(createTestData().indexPatternWithMappings, function (value, key) { + return _.camelCase(key); + })) + .expect(400); + }); + }); }; diff --git a/test/unit/api/index_patterns/_put.js b/test/unit/api/index_patterns/_put.js index 0de7331e82c4..d808ceefaf0b 100644 --- a/test/unit/api/index_patterns/_put.js +++ b/test/unit/api/index_patterns/_put.js @@ -23,7 +23,7 @@ define(function (require) { pattern.fields = _.map(pattern.fields, function (field) { return _.omit(field, 'mapping'); }); - pattern.timeFieldName = 'foo'; + pattern.time_field_name = 'foo'; pattern.fields[0].count = 5; return request.put('/kibana/index_patterns/logstash-*') @@ -33,7 +33,7 @@ define(function (require) { return request.get('/kibana/index_patterns/logstash-*'); }) .then(function (res) { - expect(res.body.timeFieldName).to.be('foo'); + expect(res.body.time_field_name).to.be('foo'); expect(res.body.fields[0].count).to.be(5); }); }); @@ -95,6 +95,12 @@ define(function (require) { .expect(404); }); + bdd.it('should enforce snake_case in the request body', function () { + return request.put('/kibana/index_patterns/logstash-*') + .send({timeFieldName: 'foo'}) + .expect(400); + }); + }); }; diff --git a/test/unit/api/index_patterns/data.js b/test/unit/api/index_patterns/data.js index 752e8da79a9d..54c3d39ac648 100644 --- a/test/unit/api/index_patterns/data.js +++ b/test/unit/api/index_patterns/data.js @@ -2,7 +2,7 @@ module.exports = function createTestData() { return { indexPatternWithMappings: { 'title': 'logstash-*', - 'timeFieldName': '@timestamp', + 'time_field_name': '@timestamp', 'fields': [{ 'name': 'geo.coordinates', 'count': 0,