diff --git a/src/kibana/components/validate_query/lib/from_user.js b/src/kibana/components/validate_query/lib/from_user.js new file mode 100644 index 0000000000000..b1982a35d205d --- /dev/null +++ b/src/kibana/components/validate_query/lib/from_user.js @@ -0,0 +1,35 @@ +define(function (require) { + var _ = require('lodash'); + + /** + * Take text from the user and make it into a query object + * @param {text} user's query input + * @returns {object} + */ + return function (text) { + var matchAll = {query_string: {query: '*'}}; + + // If we get an empty object, treat it as a * + if (_.isObject(text)) { + if (Object.keys(text).length) { + return text; + } else { + return matchAll; + } + } + + // Nope, not an object. + text = (text || '').trim(); + if (text.length === 0) return matchAll; + + if (text[0] === '{') { + try { + return JSON.parse(text); + } catch (e) { + return {query_string: {query: text}}; + } + } else { + return {query_string: {query: text}}; + } + }; +}); diff --git a/src/kibana/components/validate_query/lib/to_user.js b/src/kibana/components/validate_query/lib/to_user.js new file mode 100644 index 0000000000000..44d4c81ec15b9 --- /dev/null +++ b/src/kibana/components/validate_query/lib/to_user.js @@ -0,0 +1,17 @@ +define(function (require) { + var _ = require('lodash'); + + /** + * Take text from the model and present it to the user as a string + * @param {text} model value + * @returns {string} + */ + return function (text) { + if (_.isString(text)) return text; + if (_.isObject(text)) { + if (text.query_string) return text.query_string.query; + return JSON.stringify(text); + } + return text.toString(); + }; +}); diff --git a/src/kibana/directives/validate_query.js b/src/kibana/components/validate_query/validate_query.js similarity index 77% rename from src/kibana/directives/validate_query.js rename to src/kibana/components/validate_query/validate_query.js index dd09c4a2352fd..ce4a329c743f6 100644 --- a/src/kibana/directives/validate_query.js +++ b/src/kibana/components/validate_query/validate_query.js @@ -1,6 +1,9 @@ define(function (require) { var _ = require('lodash'); var $ = require('jquery'); + var fromUser = require('components/validate_query/lib/from_user'); + var toUser = require('components/validate_query/lib/to_user'); + require('services/debounce'); require('modules') @@ -105,37 +108,6 @@ define(function (require) { trailing: true }); - // What should I make with the input from the user? - var fromUser = function (text) { - - // If we get an empty object, treat it as a * - if (_.isObject(text)) { - if (Object.keys(text).length) { - return text; - } else { - return {query_string: {query: '*'}}; - } - } - - // Nope, not an object. - text = (text || '').trim(); - try { - return JSON.parse(text); - } catch (e) { - return {query_string: {query: text || '*'}}; - } - }; - - // How should I present the data back to the user in the input field? - var toUser = function (text) { - if (_.isString(text)) return text; - if (_.isObject(text)) { - if (text.query_string) return text.query_string.query; - return JSON.stringify(text); - } - return undefined; - }; - ngModel.$parsers.push(fromUser); ngModel.$formatters.push(toUser); diff --git a/src/kibana/plugins/discover/controllers/discover.js b/src/kibana/plugins/discover/controllers/discover.js index 32e7b706ce935..c5bc1ae2ab7ba 100644 --- a/src/kibana/plugins/discover/controllers/discover.js +++ b/src/kibana/plugins/discover/controllers/discover.js @@ -13,7 +13,7 @@ define(function (require) { require('components/timepicker/timepicker'); require('directives/fixed_scroll'); require('directives/validate_json'); - require('directives/validate_query'); + require('components/validate_query/validate_query'); require('filters/moment'); require('components/courier/courier'); require('components/index_patterns/index_patterns'); diff --git a/test/unit/specs/directives/validate_query.js b/test/unit/specs/directives/validate_query.js index f1c15e8f22e62..c847b1cff5fae 100644 --- a/test/unit/specs/directives/validate_query.js +++ b/test/unit/specs/directives/validate_query.js @@ -3,7 +3,7 @@ define(function (require) { var sinon = require('test_utils/auto_release_sinon'); // Load the kibana app dependencies. - require('directives/validate_query'); + require('components/validate_query/validate_query'); var $rootScope; var $timeout; @@ -16,6 +16,9 @@ define(function (require) { var cycleIndex = 0; var mockValidateQuery; var markup = ''; + var fromUser = require('components/validate_query/lib/from_user'); + var toUser = require('components/validate_query/lib/to_user'); + var validEsResponse = function () { return Promise.resolve({ valid: true }); @@ -152,5 +155,45 @@ define(function (require) { checkClass('ng-valid'); }); }); + + describe('user input parser', function () { + it('should return the input if passed an object', function () { + expect(fromUser({foo: 'bar'})).to.eql({foo: 'bar'}); + }); + + it('unless the object is empty, that implies a *', function () { + expect(fromUser({})).to.eql({query_string: {query: '*'}}); + }); + + it('should treat an empty string as a *', function () { + expect(fromUser('')).to.eql({query_string: {query: '*'}}); + }); + + it('should treat input that does not start with { as a query string', function () { + expect(fromUser('foo')).to.eql({query_string: {query: 'foo'}}); + expect(fromUser('400')).to.eql({query_string: {query: '400'}}); + expect(fromUser('true')).to.eql({query_string: {query: 'true'}}); + }); + + it('should parse valid JSON', function () { + expect(fromUser('{}')).to.eql({}); + expect(fromUser('{a:b}')).to.eql({query_string: {query: '{a:b}'}}); + }); + }); + + describe('model presentation formatter', function () { + it('should present objects as strings', function () { + expect(toUser({foo: 'bar'})).to.be('{"foo":"bar"}'); + }); + + it('should present string as strings', function () { + expect(toUser('foo')).to.be('foo'); + }); + + it('should present numbers as strings', function () { + expect(toUser(400)).to.be('400'); + }); + }); + }); });