UNPKG

kibana-with-account

Version:

kibana-with-account is develop based kibana project

506 lines (435 loc) 19.3 kB
describe('index pattern', function () { var _ = require('lodash'); var sinon = require('auto-release-sinon'); var ngMock = require('ngMock'); var expect = require('expect.js'); var Promise = require('bluebird'); var errors = require('ui/errors'); var IndexedArray = require('ui/IndexedArray'); var IndexPattern; var mapper; var mappingSetup; var mockLogstashFields; var DocSource; var config; var docSourceResponse; var indexPatternId = 'test-pattern'; var indexPattern; var calculateIndices; var $rootScope; var intervals; beforeEach(ngMock.module('kibana')); beforeEach(ngMock.inject(function (Private, $injector, _config_) { $rootScope = $injector.get('$rootScope'); config = _config_; mockLogstashFields = Private(require('fixtures/logstash_fields')); docSourceResponse = Private(require('fixtures/stubbed_doc_source_response')); DocSource = Private(require('ui/courier/data_source/doc_source')); sinon.stub(DocSource.prototype, 'doIndex'); sinon.stub(DocSource.prototype, 'fetch'); // stub mapper mapper = Private(require('ui/index_patterns/_mapper')); sinon.stub(mapper, 'getFieldsForIndexPattern', function () { return Promise.resolve(_.filter(mockLogstashFields, { scripted: false })); }); // stub mappingSetup mappingSetup = Private(require('ui/utils/mapping_setup')); sinon.stub(mappingSetup, 'isDefined', function () { return Promise.resolve(true); }); // stub calculateIndices calculateIndices = sinon.spy(function () { return $injector.get('Promise').resolve([ { index: 'foo', max: Infinity, min: -Infinity }, { index: 'bar', max: Infinity, min: -Infinity } ]); }); Private.stub(require('ui/index_patterns/_calculate_indices'), calculateIndices); // spy on intervals intervals = Private(require('ui/index_patterns/_intervals')); sinon.stub(intervals, 'toIndexList').returns([ { index: 'foo', max: Infinity, min: -Infinity }, { index: 'bar', max: Infinity, min: -Infinity } ]); IndexPattern = Private(require('ui/index_patterns/_index_pattern')); })); // create an indexPattern instance for each test beforeEach(function () { return create(indexPatternId).then(function (pattern) { indexPattern = pattern; }); }); // helper function to create index patterns function create(id, payload) { var indexPattern = new IndexPattern(id); DocSource.prototype.doIndex.returns(Promise.resolve(id)); payload = _.defaults(payload || {}, docSourceResponse(id)); setDocsourcePayload(payload); return indexPattern.init(); } function setDocsourcePayload(payload) { DocSource.prototype.fetch.returns(Promise.resolve(payload)); } describe('api', function () { it('should have expected properties', function () { return create('test-pattern').then(function (indexPattern) { // methods expect(indexPattern).to.have.property('refreshFields'); expect(indexPattern).to.have.property('popularizeField'); expect(indexPattern).to.have.property('getScriptedFields'); expect(indexPattern).to.have.property('getNonScriptedFields'); expect(indexPattern).to.have.property('getInterval'); expect(indexPattern).to.have.property('addScriptedField'); expect(indexPattern).to.have.property('removeScriptedField'); expect(indexPattern).to.have.property('toString'); expect(indexPattern).to.have.property('toJSON'); expect(indexPattern).to.have.property('save'); // properties expect(indexPattern).to.have.property('fields'); }); }); }); describe('init', function () { it('should append the found fields', function () { expect(DocSource.prototype.fetch.callCount).to.be(1); expect(indexPattern.fields).to.have.length(mockLogstashFields.length); expect(indexPattern.fields).to.be.an(IndexedArray); }); }); describe('fields', function () { it('should have expected properties on fields', function () { expect(indexPattern.fields[0]).to.have.property('bucketable'); expect(indexPattern.fields[0]).to.have.property('displayName'); expect(indexPattern.fields[0]).to.have.property('filterable'); expect(indexPattern.fields[0]).to.have.property('format'); expect(indexPattern.fields[0]).to.have.property('sortable'); expect(indexPattern.fields[0]).to.have.property('scripted'); }); }); describe('getScriptedFields', function () { it('should return all scripted fields', function () { var scriptedNames = _(mockLogstashFields).where({ scripted: true }).pluck('name').value(); var respNames = _.pluck(indexPattern.getScriptedFields(), 'name'); expect(respNames).to.eql(scriptedNames); }); }); describe('getNonScriptedFields', function () { it('should return all non-scripted fields', function () { var notScriptedNames = _(mockLogstashFields).where({ scripted: false }).pluck('name').value(); var respNames = _.pluck(indexPattern.getNonScriptedFields(), 'name'); expect(respNames).to.eql(notScriptedNames); }); }); describe('refresh fields', function () { // override the default indexPattern, with a truncated field list require('testUtils/noDigestPromises').activateForSuite(); var indexPatternId = 'test-pattern'; var indexPattern; var fieldLength; var truncatedFields; beforeEach(function () { fieldLength = mockLogstashFields.length; truncatedFields = mockLogstashFields.slice(3); return create(indexPatternId, { _source: { customFormats: '{}', fields: JSON.stringify(truncatedFields) } }).then(function (pattern) { indexPattern = pattern; }); }); it('should fetch fields from the doc source', function () { // ensure that we don't have all the fields expect(truncatedFields.length).to.not.equal(mockLogstashFields.length); expect(indexPattern.fields).to.have.length(truncatedFields.length); // ensure that all fields will be included in the returned docSource setDocsourcePayload(docSourceResponse(indexPatternId)); return Promise.all([ // read fields from elasticsearch mapper.getFieldsForIndexPattern(), // tell the index pattern to do the same indexPattern.refreshFields(), ]) .then(function (data) { var expected = data[0]; // just the fields in the index var fields = indexPattern.getNonScriptedFields(); // get all but scripted fields expect(_.pluck(fields, 'name')).to.eql(_.pluck(expected, 'name')); }); }); it('should preserve the scripted fields', function () { // ensure that all fields will be included in the returned docSource setDocsourcePayload(docSourceResponse(indexPatternId)); // add spy to indexPattern.getScriptedFields var scriptedFieldsSpy = sinon.spy(indexPattern, 'getScriptedFields'); // refresh fields, which will fetch return indexPattern.refreshFields().then(function () { // called to append scripted fields to the response from mapper.getFieldsForIndexPattern expect(scriptedFieldsSpy.callCount).to.equal(1); var scripted = _.where(mockLogstashFields, { scripted: true }); var expected = _.filter(indexPattern.fields, { scripted: true }); expect(_.pluck(expected, 'name')).to.eql(_.pluck(scripted, 'name')); }); }); }); describe('add and remove scripted fields', function () { it('should append the scripted field', function () { // keep a copy of the current scripted field count var saveSpy = sinon.spy(indexPattern, 'save'); var oldCount = indexPattern.getScriptedFields().length; // add a new scripted field var scriptedField = { name: 'new scripted field', script: 'false', type: 'boolean' }; indexPattern.addScriptedField(scriptedField.name, scriptedField.script, scriptedField.type); indexPattern._indexFields(); // normally triggered by docSource.onUpdate() var scriptedFields = indexPattern.getScriptedFields(); expect(saveSpy.callCount).to.equal(1); expect(scriptedFields).to.have.length(oldCount + 1); expect(indexPattern.fields.byName[scriptedField.name].displayName).to.equal(scriptedField.name); }); it('should remove scripted field, by name', function () { var saveSpy = sinon.spy(indexPattern, 'save'); var scriptedFields = indexPattern.getScriptedFields(); var oldCount = scriptedFields.length; var scriptedField = _.last(scriptedFields); indexPattern.removeScriptedField(scriptedField.name); expect(saveSpy.callCount).to.equal(1); expect(indexPattern.getScriptedFields().length).to.equal(oldCount - 1); expect(indexPattern.fields.byName[scriptedField.name]).to.equal(undefined); }); it('should not allow duplicate names', function () { var scriptedFields = indexPattern.getScriptedFields(); var scriptedField = _.last(scriptedFields); expect(function () { indexPattern.addScriptedField(scriptedField.name, '\'new script\'', 'string'); }).to.throwError(function (e) { expect(e).to.be.a(errors.DuplicateField); }); }); }); describe('popularizeField', function () { it('should increment the poplarity count by default', function () { var saveSpy = sinon.stub(indexPattern, 'save'); indexPattern.fields.forEach(function (field, i) { var oldCount = field.count; indexPattern.popularizeField(field.name); expect(saveSpy.callCount).to.equal(i + 1); expect(field.count).to.equal(oldCount + 1); }); }); it('should increment the poplarity count', function () { var saveSpy = sinon.stub(indexPattern, 'save'); indexPattern.fields.forEach(function (field, i) { var oldCount = field.count; var incrementAmount = 4; indexPattern.popularizeField(field.name, incrementAmount); expect(saveSpy.callCount).to.equal(i + 1); expect(field.count).to.equal(oldCount + incrementAmount); }); }); it('should decrement the poplarity count', function () { indexPattern.fields.forEach(function (field, i) { var oldCount = field.count; var incrementAmount = 4; var decrementAmount = -2; indexPattern.popularizeField(field.name, incrementAmount); indexPattern.popularizeField(field.name, decrementAmount); expect(field.count).to.equal(oldCount + incrementAmount + decrementAmount); }); }); it('should not go below 0', function () { indexPattern.fields.forEach(function (field) { var decrementAmount = -Number.MAX_VALUE; indexPattern.popularizeField(field.name, decrementAmount); expect(field.count).to.equal(0); }); }); }); describe('#toDetailedIndexList', function () { require('testUtils/noDigestPromises').activateForSuite(); context('when index pattern is an interval', function () { var interval; beforeEach(function () { interval = 'result:getInterval'; sinon.stub(indexPattern, 'getInterval').returns(interval); }); it('invokes interval toDetailedIndexList with given start/stop times', async function () { await indexPattern.toDetailedIndexList(1, 2); var id = indexPattern.id; expect(intervals.toIndexList.calledWith(id, interval, 1, 2)).to.be(true); }); it('is fulfilled by the result of interval toDetailedIndexList', async function () { var indexList = await indexPattern.toDetailedIndexList(); expect(indexList[0].index).to.equal('foo'); expect(indexList[1].index).to.equal('bar'); }); context('with sort order', function () { it('passes the sort order to the intervals module', function () { return indexPattern.toDetailedIndexList(1, 2, 'SORT_DIRECTION') .then(function () { expect(intervals.toIndexList.callCount).to.be(1); expect(intervals.toIndexList.getCall(0).args[4]).to.be('SORT_DIRECTION'); }); }); }); }); context('when index pattern is a time-base wildcard', function () { beforeEach(function () { sinon.stub(indexPattern, 'getInterval').returns(false); sinon.stub(indexPattern, 'hasTimeField').returns(true); sinon.stub(indexPattern, 'isWildcard').returns(true); }); it('invokes calculateIndices with given start/stop times and sortOrder', async function () { await indexPattern.toDetailedIndexList(1, 2, 'sortOrder'); var id = indexPattern.id; var field = indexPattern.timeFieldName; expect(calculateIndices.calledWith(id, field, 1, 2, 'sortOrder')).to.be(true); }); it('is fulfilled by the result of calculateIndices', async function () { var indexList = await indexPattern.toDetailedIndexList(); expect(indexList[0].index).to.equal('foo'); expect(indexList[1].index).to.equal('bar'); }); }); context('when index pattern is a time-base wildcard that is configured not to expand', function () { beforeEach(function () { sinon.stub(indexPattern, 'getInterval').returns(false); sinon.stub(indexPattern, 'hasTimeField').returns(true); sinon.stub(indexPattern, 'isWildcard').returns(true); sinon.stub(indexPattern, 'canExpandIndices').returns(false); }); it('is fulfilled by id', async function () { var indexList = await indexPattern.toDetailedIndexList(); expect(indexList.index).to.equal(indexPattern.id); }); }); context('when index pattern is neither an interval nor a time-based wildcard', function () { beforeEach(function () { sinon.stub(indexPattern, 'getInterval').returns(false); }); it('is fulfilled by id', async function () { var indexList = await indexPattern.toDetailedIndexList(); expect(indexList.index).to.equal(indexPattern.id); }); }); }); describe('#toIndexList', function () { context('when index pattern is an interval', function () { require('testUtils/noDigestPromises').activateForSuite(); var interval; beforeEach(function () { interval = 'result:getInterval'; sinon.stub(indexPattern, 'getInterval').returns(interval); }); it('invokes interval toIndexList with given start/stop times', async function () { await indexPattern.toIndexList(1, 2); var id = indexPattern.id; expect(intervals.toIndexList.calledWith(id, interval, 1, 2)).to.be(true); }); it('is fulfilled by the result of interval toIndexList', async function () { var indexList = await indexPattern.toIndexList(); expect(indexList[0]).to.equal('foo'); expect(indexList[1]).to.equal('bar'); }); context('with sort order', function () { it('passes the sort order to the intervals module', function () { return indexPattern.toIndexList(1, 2, 'SORT_DIRECTION') .then(function () { expect(intervals.toIndexList.callCount).to.be(1); expect(intervals.toIndexList.getCall(0).args[4]).to.be('SORT_DIRECTION'); }); }); }); }); context('when index pattern is a time-base wildcard', function () { require('testUtils/noDigestPromises').activateForSuite(); beforeEach(function () { sinon.stub(indexPattern, 'getInterval').returns(false); sinon.stub(indexPattern, 'hasTimeField').returns(true); sinon.stub(indexPattern, 'isWildcard').returns(true); }); it('invokes calculateIndices with given start/stop times and sortOrder', async function () { await indexPattern.toIndexList(1, 2, 'sortOrder'); var id = indexPattern.id; var field = indexPattern.timeFieldName; expect(calculateIndices.calledWith(id, field, 1, 2, 'sortOrder')).to.be(true); }); it('is fulfilled by the result of calculateIndices', async function () { var indexList = await indexPattern.toIndexList(); expect(indexList[0]).to.equal('foo'); expect(indexList[1]).to.equal('bar'); }); }); context('when index pattern is a time-base wildcard that is configured not to expand', function () { require('testUtils/noDigestPromises').activateForSuite(); beforeEach(function () { sinon.stub(indexPattern, 'getInterval').returns(false); sinon.stub(indexPattern, 'hasTimeField').returns(true); sinon.stub(indexPattern, 'isWildcard').returns(true); sinon.stub(indexPattern, 'canExpandIndices').returns(false); }); it('is fulfilled by id', async function () { var indexList = await indexPattern.toIndexList(); expect(indexList).to.equal(indexPattern.id); }); }); context('when index pattern is neither an interval nor a time-based wildcard', function () { beforeEach(function () { sinon.stub(indexPattern, 'getInterval').returns(false); }); it('is fulfilled by id', function () { var indexList; indexPattern.toIndexList().then(function (val) { indexList = val; }); $rootScope.$apply(); expect(indexList).to.equal(indexPattern.id); }); }); }); describe('#canExpandIndices()', function () { it('returns true if notExpandable is false', function () { indexPattern.notExpandable = false; expect(indexPattern.canExpandIndices()).to.be(true); }); it('returns true if notExpandable is not defined', function () { delete indexPattern.notExpandable; expect(indexPattern.canExpandIndices()).to.be(true); }); it('returns false if notExpandable is true', function () { indexPattern.notExpandable = true; expect(indexPattern.canExpandIndices()).to.be(false); }); }); describe('#hasTimeField()', function () { beforeEach(function () { // for the sake of these tests, it doesn't much matter what type of field // this is so long as it exists indexPattern.timeFieldName = 'bytes'; }); it('returns false if no time field', function () { delete indexPattern.timeFieldName; expect(indexPattern.hasTimeField()).to.be(false); }); it('returns false if time field does not actually exist in fields', function () { indexPattern.timeFieldName = 'does not exist'; expect(indexPattern.hasTimeField()).to.be(false); }); it('returns true if valid time field is configured', function () { expect(indexPattern.hasTimeField()).to.be(true); }); }); describe('#isWildcard()', function () { it('returns true if id has an *', function () { indexPattern.id = 'foo*'; expect(indexPattern.isWildcard()).to.be(true); }); it('returns false if id has no *', function () { indexPattern.id = 'foo'; expect(indexPattern.isWildcard()).to.be(false); }); }); });