mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
* 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
200 lines
5.9 KiB
TypeScript
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);
|
|
});
|
|
});
|