Files
grafana/public/app/plugins/datasource/prometheus/querybuilder/shared/operationUtils.test.ts
Gareth Dawson c5ed9391b6 Loki: Display error with label filter conflicts (#63109)
* feat: add logic to check for conflicting operator

* feat: display error if there is a conflict

* feat: check if label filter conflicts with other filters

* fix: remove capitalisation from "no data"

* test: add tests for isConflictingFilter function

* feat(labels): add validation for label matchers

* test(labels): add tests for isConflictingSelector

* refactor(labels): add suggestions from code review

* test(labels): add case for labels without op

* refactor(operations): add suggestions from code review

* feat(operations): display tooltip when you have conflicts

* fix: remove unused props from test

* fix: remove old test

* fix(labels): error message now displays in the correct location

* fix(operations): operations can be dragged, even with error

* fix: remove unused vars

* fix: failing tests

* fix(operations): hide error message whilst dragging

* refactor: use more appropriate variable naming

* refactor: add suggestions from code review

* perf: use array.some instead of array.find
2023-02-22 09:56:20 +00:00

200 lines
5.9 KiB
TypeScript

import {
createAggregationOperation,
createAggregationOperationWithParam,
isConflictingSelector,
} from './operationUtils';
describe('createAggregationOperation', () => {
it('returns correct aggregation definitions with overrides', () => {
expect(createAggregationOperation('test_aggregation', { category: 'test_category' })).toMatchObject([
{
addOperationHandler: {},
alternativesKey: 'plain aggregations',
category: 'test_category',
defaultParams: [],
explainHandler: {},
id: 'test_aggregation',
name: 'Test aggregation',
paramChangedHandler: {},
params: [
{
name: 'By label',
optional: true,
restParam: true,
type: 'string',
},
],
renderer: {},
},
{
alternativesKey: 'aggregations by',
category: 'test_category',
defaultParams: [''],
explainHandler: {},
hideFromList: true,
id: '__test_aggregation_by',
name: 'Test aggregation by',
paramChangedHandler: {},
params: [
{
editor: {},
name: 'Label',
optional: true,
restParam: true,
type: 'string',
},
],
renderer: {},
},
{
alternativesKey: 'aggregations by',
category: 'test_category',
defaultParams: [''],
explainHandler: {},
hideFromList: true,
id: '__test_aggregation_without',
name: 'Test aggregation without',
paramChangedHandler: {},
params: [
{
name: 'Label',
optional: true,
restParam: true,
type: 'string',
},
],
renderer: {},
},
]);
});
});
describe('createAggregationOperationWithParams', () => {
it('returns correct aggregation definitions with overrides and params', () => {
expect(
createAggregationOperationWithParam(
'test_aggregation',
{
params: [{ name: 'K-value', type: 'number' }],
defaultParams: [5],
},
{ category: 'test_category' }
)
).toMatchObject([
{
addOperationHandler: {},
alternativesKey: 'plain aggregations',
category: 'test_category',
defaultParams: [5],
explainHandler: {},
id: 'test_aggregation',
name: 'Test aggregation',
paramChangedHandler: {},
params: [
{ name: 'K-value', type: 'number' },
{ name: 'By label', optional: true, restParam: true, type: 'string' },
],
renderer: {},
},
{
alternativesKey: 'aggregations by',
category: 'test_category',
defaultParams: [5, ''],
explainHandler: {},
hideFromList: true,
id: '__test_aggregation_by',
name: 'Test aggregation by',
paramChangedHandler: {},
params: [
{ name: 'K-value', type: 'number' },
{ editor: {}, name: 'Label', optional: true, restParam: true, type: 'string' },
],
renderer: {},
},
{
alternativesKey: 'aggregations by',
category: 'test_category',
defaultParams: [5, ''],
explainHandler: {},
hideFromList: true,
id: '__test_aggregation_without',
name: 'Test aggregation without',
paramChangedHandler: {},
params: [
{ name: 'K-value', type: 'number' },
{ name: 'Label', optional: true, restParam: true, type: 'string' },
],
renderer: {},
},
]);
});
it('returns correct query string using aggregation definitions with overrides and number type param', () => {
const def = createAggregationOperationWithParam(
'test_aggregation',
{
params: [{ name: 'K-value', type: 'number' }],
defaultParams: [5],
},
{ category: 'test_category' }
);
const topKByDefinition = def[1];
expect(
topKByDefinition.renderer(
{ id: '__topk_by', params: ['5', 'source', 'place'] },
def[1],
'rate({place="luna"} |= `` [5m])'
)
).toBe('test_aggregation by(source, place) (5, rate({place="luna"} |= `` [5m]))');
});
it('returns correct query string using aggregation definitions with overrides and string type param', () => {
const def = createAggregationOperationWithParam(
'test_aggregation',
{
params: [{ name: 'Identifier', type: 'string' }],
defaultParams: ['count'],
},
{ category: 'test_category' }
);
const countValueDefinition = def[1];
expect(
countValueDefinition.renderer(
{ id: 'count_values', params: ['5', 'source', 'place'] },
def[1],
'rate({place="luna"} |= `` [5m])'
)
).toBe('test_aggregation by(source, place) ("5", rate({place="luna"} |= `` [5m]))');
});
});
describe('isConflictingSelector', () => {
it('returns true if selector is conflicting', () => {
const newLabel = { label: 'job', op: '!=', value: 'tns/app' };
const labels = [
{ label: 'job', op: '=', value: 'tns/app' },
{ label: 'job', op: '!=', value: 'tns/app' },
];
expect(isConflictingSelector(newLabel, labels)).toBe(true);
});
it('returns false if selector is not complete', () => {
const newLabel = { label: 'job', op: '', value: 'tns/app' };
const labels = [
{ label: 'job', op: '=', value: 'tns/app' },
{ label: 'job', op: '', value: 'tns/app' },
];
expect(isConflictingSelector(newLabel, labels)).toBe(false);
});
it('returns false if selector is not conflicting', () => {
const newLabel = { label: 'host', op: '=', value: 'docker-desktop' };
const labels = [
{ label: 'job', op: '=', value: 'tns/app' },
{ label: 'host', op: '=', value: 'docker-desktop' },
];
expect(isConflictingSelector(newLabel, labels)).toBe(false);
});
});