| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 |
- import { StackdriverQueryCtrl } from '../query_ctrl';
- describe('StackdriverQueryCtrl', () => {
- let ctrl;
- let result;
- describe('when initializing query editor', () => {
- beforeEach(() => {
- const existingFilters = ['key1', '=', 'val1', 'AND', 'key2', '=', 'val2'];
- ctrl = createCtrlWithFakes(existingFilters);
- });
- it('should initialize filter segments using the target filter values', () => {
- expect(ctrl.filterSegments.length).toBe(8);
- expect(ctrl.filterSegments[0].type).toBe('key');
- expect(ctrl.filterSegments[1].type).toBe('operator');
- expect(ctrl.filterSegments[2].type).toBe('value');
- expect(ctrl.filterSegments[3].type).toBe('condition');
- expect(ctrl.filterSegments[4].type).toBe('key');
- expect(ctrl.filterSegments[5].type).toBe('operator');
- expect(ctrl.filterSegments[6].type).toBe('value');
- expect(ctrl.filterSegments[7].type).toBe('plus-button');
- });
- });
- describe('group bys', () => {
- beforeEach(() => {
- ctrl = createCtrlWithFakes();
- });
- describe('when labels are fetched', () => {
- beforeEach(async () => {
- ctrl.metricLabels = { 'metric-key-1': ['metric-value-1'] };
- ctrl.resourceLabels = { 'resource-key-1': ['resource-value-1'] };
- result = await ctrl.getGroupBys();
- });
- it('should populate group bys segments', () => {
- expect(result.length).toBe(3);
- expect(result[0].value).toBe('metric.label.metric-key-1');
- expect(result[1].value).toBe('resource.label.resource-key-1');
- expect(result[2].value).toBe('-- remove group by --');
- });
- });
- describe('when a group by label is selected', () => {
- beforeEach(async () => {
- ctrl.metricLabels = {
- 'metric-key-1': ['metric-value-1'],
- 'metric-key-2': ['metric-value-2'],
- };
- ctrl.resourceLabels = {
- 'resource-key-1': ['resource-value-1'],
- 'resource-key-2': ['resource-value-2'],
- };
- ctrl.target.aggregation.groupBys = ['metric.label.metric-key-1', 'resource.label.resource-key-1'];
- result = await ctrl.getGroupBys();
- });
- it('should not be used to populate group bys segments', () => {
- expect(result.length).toBe(3);
- expect(result[0].value).toBe('metric.label.metric-key-2');
- expect(result[1].value).toBe('resource.label.resource-key-2');
- expect(result[2].value).toBe('-- remove group by --');
- });
- });
- describe('when a group by is selected', () => {
- beforeEach(() => {
- const removeSegment = { fake: true, value: '-- remove group by --' };
- const segment = { value: 'groupby1' };
- ctrl.groupBySegments = [segment, removeSegment];
- ctrl.groupByChanged(segment);
- });
- it('should be added to group bys list', () => {
- expect(ctrl.target.aggregation.groupBys.length).toBe(1);
- });
- });
- describe('when a selected group by is removed', () => {
- beforeEach(() => {
- const removeSegment = { fake: true, value: '-- remove group by --' };
- const segment = { value: 'groupby1' };
- ctrl.groupBySegments = [segment, removeSegment];
- ctrl.groupByChanged(removeSegment);
- });
- it('should be added to group bys list', () => {
- expect(ctrl.target.aggregation.groupBys.length).toBe(0);
- });
- });
- });
- describe('filters', () => {
- beforeEach(() => {
- ctrl = createCtrlWithFakes();
- });
- describe('when values for a condition filter part are fetched', () => {
- beforeEach(async () => {
- const segment = { type: 'condition' };
- result = await ctrl.getFilters(segment, 0);
- });
- it('should populate group bys segments', () => {
- expect(result.length).toBe(1);
- expect(result[0].value).toBe('AND');
- });
- });
- describe('when values for a operator filter part are fetched', () => {
- beforeEach(async () => {
- const segment = { type: 'operator' };
- result = await ctrl.getFilters(segment, 0);
- });
- it('should populate group bys segments', () => {
- expect(result.length).toBe(4);
- expect(result[0].value).toBe('=');
- expect(result[1].value).toBe('!=');
- expect(result[2].value).toBe('=~');
- expect(result[3].value).toBe('!=~');
- });
- });
- describe('when values for a key filter part are fetched', () => {
- beforeEach(async () => {
- ctrl.metricLabels = {
- 'metric-key-1': ['metric-value-1'],
- 'metric-key-2': ['metric-value-2'],
- };
- ctrl.resourceLabels = {
- 'resource-key-1': ['resource-value-1'],
- 'resource-key-2': ['resource-value-2'],
- };
- const segment = { type: 'key' };
- result = await ctrl.getFilters(segment, 0);
- });
- it('should populate group bys segments', () => {
- expect(result.length).toBe(5);
- expect(result[0].value).toBe('metric.label.metric-key-1');
- expect(result[1].value).toBe('metric.label.metric-key-2');
- expect(result[2].value).toBe('resource.label.resource-key-1');
- expect(result[3].value).toBe('resource.label.resource-key-2');
- expect(result[4].value).toBe('-- remove filter --');
- });
- });
- describe('when values for a value filter part are fetched', () => {
- beforeEach(async () => {
- ctrl.metricLabels = {
- 'metric-key-1': ['metric-value-1'],
- 'metric-key-2': ['metric-value-2'],
- };
- ctrl.resourceLabels = {
- 'resource-key-1': ['resource-value-1'],
- 'resource-key-2': ['resource-value-2'],
- };
- ctrl.filterSegments = [{ type: 'key', value: 'metric.label.metric-key-1' }, { type: 'operator', value: '=' }];
- const segment = { type: 'value' };
- result = await ctrl.getFilters(segment, 2);
- });
- it('should populate group bys segments', () => {
- expect(result.length).toBe(1);
- expect(result[0].value).toBe('metric-value-1');
- });
- });
- describe('when a filter is created by clicking on plus button', () => {
- describe('and there are no other filters', () => {
- beforeEach(() => {
- const segment = { value: 'filterkey1', type: 'plus-button' };
- ctrl.filterSegments = [segment];
- ctrl.filterSegmentUpdated(segment, 0);
- });
- it('should transform the plus button segment to a key segment', () => {
- expect(ctrl.filterSegments[0].type).toBe('key');
- });
- it('should add an operator, value segment and plus button segment', () => {
- expect(ctrl.filterSegments.length).toBe(3);
- expect(ctrl.filterSegments[1].type).toBe('operator');
- expect(ctrl.filterSegments[2].type).toBe('value');
- });
- });
- });
- describe('when has one existing filter', () => {
- describe('and user clicks on key segment', () => {
- beforeEach(() => {
- const existingKeySegment = { value: 'filterkey1', type: 'key' };
- const existingOperatorSegment = { value: '=', type: 'operator' };
- const existingValueSegment = { value: 'filtervalue', type: 'value' };
- const plusSegment = { value: '', type: 'plus-button' };
- ctrl.filterSegments = [existingKeySegment, existingOperatorSegment, existingValueSegment, plusSegment];
- ctrl.filterSegmentUpdated(existingKeySegment, 0);
- });
- it('should not add any new segments', () => {
- expect(ctrl.filterSegments.length).toBe(4);
- expect(ctrl.filterSegments[0].type).toBe('key');
- expect(ctrl.filterSegments[1].type).toBe('operator');
- expect(ctrl.filterSegments[2].type).toBe('value');
- });
- });
- describe('and user clicks on value segment and value not equal to fake value', () => {
- beforeEach(() => {
- const existingKeySegment = { value: 'filterkey1', type: 'key' };
- const existingOperatorSegment = { value: '=', type: 'operator' };
- const existingValueSegment = { value: 'filtervalue', type: 'value' };
- ctrl.filterSegments = [existingKeySegment, existingOperatorSegment, existingValueSegment];
- ctrl.filterSegmentUpdated(existingValueSegment, 2);
- });
- it('should ensure that plus segment exists', () => {
- expect(ctrl.filterSegments.length).toBe(4);
- expect(ctrl.filterSegments[0].type).toBe('key');
- expect(ctrl.filterSegments[1].type).toBe('operator');
- expect(ctrl.filterSegments[2].type).toBe('value');
- expect(ctrl.filterSegments[3].type).toBe('plus-button');
- });
- });
- describe('and user clicks on value segment and value is equal to fake value', () => {
- beforeEach(() => {
- const existingKeySegment = { value: 'filterkey1', type: 'key' };
- const existingOperatorSegment = { value: '=', type: 'operator' };
- const existingValueSegment = { value: ctrl.defaultFilterValue, type: 'value' };
- ctrl.filterSegments = [existingKeySegment, existingOperatorSegment, existingValueSegment];
- ctrl.filterSegmentUpdated(existingValueSegment, 2);
- });
- it('should not add plus segment', () => {
- expect(ctrl.filterSegments.length).toBe(3);
- expect(ctrl.filterSegments[0].type).toBe('key');
- expect(ctrl.filterSegments[1].type).toBe('operator');
- expect(ctrl.filterSegments[2].type).toBe('value');
- });
- });
- describe('and user removes key segment', () => {
- beforeEach(() => {
- const existingKeySegment = { value: ctrl.defaultRemoveFilterValue, type: 'key' };
- const existingOperatorSegment = { value: '=', type: 'operator' };
- const existingValueSegment = { value: 'filtervalue', type: 'value' };
- const plusSegment = { value: '', type: 'plus-button' };
- ctrl.filterSegments = [existingKeySegment, existingOperatorSegment, existingValueSegment, plusSegment];
- ctrl.filterSegmentUpdated(existingKeySegment, 0);
- });
- it('should remove filter segments', () => {
- expect(ctrl.filterSegments.length).toBe(1);
- expect(ctrl.filterSegments[0].type).toBe('plus-button');
- });
- });
- describe('and user removes key segment and there is a previous filter', () => {
- beforeEach(() => {
- const existingKeySegment1 = { value: ctrl.defaultRemoveFilterValue, type: 'key' };
- const existingKeySegment2 = { value: ctrl.defaultRemoveFilterValue, type: 'key' };
- const existingOperatorSegment = { value: '=', type: 'operator' };
- const existingValueSegment = { value: 'filtervalue', type: 'value' };
- const conditionSegment = { value: 'AND', type: 'condition' };
- const plusSegment = { value: '', type: 'plus-button' };
- ctrl.filterSegments = [
- existingKeySegment1,
- existingOperatorSegment,
- existingValueSegment,
- conditionSegment,
- existingKeySegment2,
- Object.assign({}, existingOperatorSegment),
- Object.assign({}, existingValueSegment),
- plusSegment,
- ];
- ctrl.filterSegmentUpdated(existingKeySegment2, 4);
- });
- it('should remove filter segments and the condition segment', () => {
- expect(ctrl.filterSegments.length).toBe(4);
- expect(ctrl.filterSegments[0].type).toBe('key');
- expect(ctrl.filterSegments[1].type).toBe('operator');
- expect(ctrl.filterSegments[2].type).toBe('value');
- expect(ctrl.filterSegments[3].type).toBe('plus-button');
- });
- });
- describe('and user removes key segment and there is a filter after it', () => {
- beforeEach(() => {
- const existingKeySegment1 = { value: ctrl.defaultRemoveFilterValue, type: 'key' };
- const existingKeySegment2 = { value: ctrl.defaultRemoveFilterValue, type: 'key' };
- const existingOperatorSegment = { value: '=', type: 'operator' };
- const existingValueSegment = { value: 'filtervalue', type: 'value' };
- const conditionSegment = { value: 'AND', type: 'condition' };
- const plusSegment = { value: '', type: 'plus-button' };
- ctrl.filterSegments = [
- existingKeySegment1,
- existingOperatorSegment,
- existingValueSegment,
- conditionSegment,
- existingKeySegment2,
- Object.assign({}, existingOperatorSegment),
- Object.assign({}, existingValueSegment),
- plusSegment,
- ];
- ctrl.filterSegmentUpdated(existingKeySegment1, 0);
- });
- it('should remove filter segments and the condition segment', () => {
- expect(ctrl.filterSegments.length).toBe(4);
- expect(ctrl.filterSegments[0].type).toBe('key');
- expect(ctrl.filterSegments[1].type).toBe('operator');
- expect(ctrl.filterSegments[2].type).toBe('value');
- expect(ctrl.filterSegments[3].type).toBe('plus-button');
- });
- });
- describe('and user clicks on plus button', () => {
- beforeEach(() => {
- const existingKeySegment = { value: 'filterkey1', type: 'key' };
- const existingOperatorSegment = { value: '=', type: 'operator' };
- const existingValueSegment = { value: 'filtervalue', type: 'value' };
- const plusSegment = { value: 'filterkey2', type: 'plus-button' };
- ctrl.filterSegments = [existingKeySegment, existingOperatorSegment, existingValueSegment, plusSegment];
- ctrl.filterSegmentUpdated(plusSegment, 3);
- });
- it('should condition segment and new filter segments', () => {
- expect(ctrl.filterSegments.length).toBe(7);
- expect(ctrl.filterSegments[0].type).toBe('key');
- expect(ctrl.filterSegments[1].type).toBe('operator');
- expect(ctrl.filterSegments[2].type).toBe('value');
- expect(ctrl.filterSegments[3].type).toBe('condition');
- expect(ctrl.filterSegments[4].type).toBe('key');
- expect(ctrl.filterSegments[5].type).toBe('operator');
- expect(ctrl.filterSegments[6].type).toBe('value');
- });
- });
- });
- });
- });
- function createCtrlWithFakes(existingFilters?: string[]) {
- StackdriverQueryCtrl.prototype.panelCtrl = {
- events: { on: () => {} },
- panel: { scopedVars: [], targets: [] },
- refresh: () => {},
- };
- StackdriverQueryCtrl.prototype.target = createTarget(existingFilters);
- StackdriverQueryCtrl.prototype.getMetricTypes = () => {
- return Promise.resolve();
- };
- StackdriverQueryCtrl.prototype.getLabels = () => {
- return Promise.resolve();
- };
- const fakeSegmentServer = {
- newKey: val => {
- return { value: val, type: 'key' };
- },
- newKeyValue: val => {
- return { value: val, type: 'value' };
- },
- newSegment: obj => {
- return { value: obj.value ? obj.value : obj };
- },
- newOperators: ops => {
- return ops.map(o => {
- return { type: 'operator', value: o };
- });
- },
- newFake: (value, type, cssClass) => {
- return { value, type, cssClass };
- },
- newOperator: op => {
- return { value: op, type: 'operator' };
- },
- newPlusButton: () => {
- return { type: 'plus-button' };
- },
- newCondition: val => {
- return { type: 'condition', value: val };
- },
- };
- return new StackdriverQueryCtrl(null, null, fakeSegmentServer, null);
- }
- function createTarget(existingFilters?: string[]) {
- return {
- project: {
- id: '',
- name: '',
- },
- metricType: 'ametric',
- refId: 'A',
- aggregation: {
- crossSeriesReducer: '',
- secondaryCrossSeriesReducer: '',
- alignmentPeriod: '',
- perSeriesAligner: '',
- groupBys: [],
- },
- filters: existingFilters || [],
- };
- }
|