grafana/public/app/features/alerting/unified/AlertsFolderView.test.tsx
Sonia Aguilar 64ee42d01e
Alerting: Add limits and move state and label matching filters to the BE (#66267)
* WIP

* Add instance totals to combined rule. Use totals to display instances stats in the UI

* WIP

* add global summaries, fix TS errors

* fix useCombined test

* fix test

* use activeAt from rule when available

* Fix NaN in global stats

* Add no data total to global summary

* Add totals recalculation for filtered rules

* Fix instances totals, remove instances filtering from alert list view

* Update tests

* Fetch alerts considering filtering label matchers

* WIP - Fetch alerts appending state filter to endpoint

* Fix multiple values for state in request being applyied

* fix test

* Calculate hidden by for grafana managed alerts

* Use INSTANCES_DISPLAY_LIMIT constant for limiting alert instances instead of 1

* Rename matchers parameter according to API changes

* Fix calculating total number of grafana instances

* Rename matcher prop after previous change

* Display button to remove max instances limit

* Change matcher query param to be an array of strings

* Add test for paramsWithMatcherAndState method

* Refactor matcher to be an string array to be consistent with state

* Use matcher query string as matcher object type (encoded JSON)

* Avoind encoding matcher parameters twice

* fix tests

* Enable toggle for the limit/show all button and restore limit and filters when we come back from custom view

* Move getMatcherListFromString method to utils/alertmanager.ts

* Fix limit toggle button being shown when it's not necessary

* Use filteredTotals from be response to calculate hidden by count

* Fix variables not being replaced correctly

* Fix total shown to be all the instances filtered without limits

* Adress some PR review comments

* Move paramsWithMatcherAndState inside prometheusUrlBuilder method

---------

Co-authored-by: Gilles De Mey <gilles.de.mey@gmail.com>
Co-authored-by: Konrad Lalik <konrad.lalik@grafana.com>
Co-authored-by: Virginia Cepeda <virginia.cepeda@grafana.com>
2023-04-25 11:19:20 +02:00

194 lines
5.2 KiB
TypeScript

import { render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { TestProvider } from 'test/helpers/TestProvider';
import { byTestId } from 'testing-library-selector';
import { FolderState } from 'app/types';
import { CombinedRuleNamespace } from 'app/types/unified-alerting';
import { AlertsFolderView } from './AlertsFolderView';
import { mockCombinedRule } from './mocks';
import { GRAFANA_RULES_SOURCE_NAME } from './utils/datasource';
const ui = {
filter: {
name: byTestId('name-filter'),
label: byTestId('label-filter'),
},
ruleList: {
row: byTestId('alert-card-row'),
},
};
const combinedNamespaceMock = jest.fn<CombinedRuleNamespace[], any>();
jest.mock('./hooks/useCombinedRuleNamespaces', () => ({
useCombinedRuleNamespaces: () => combinedNamespaceMock(),
}));
const mockFolder = (folderOverride: Partial<FolderState> = {}): FolderState => {
return {
id: 1,
title: 'Folder with alerts',
uid: 'folder-1',
hasChanged: false,
canSave: false,
url: '/folder-1',
version: 1,
permissions: [],
canViewFolderPermissions: false,
canDelete: false,
...folderOverride,
};
};
describe('AlertsFolderView tests', () => {
it('Should display grafana alert rules when the namespace name matches the folder name', () => {
// Arrange
const folder = mockFolder();
const grafanaNamespace: CombinedRuleNamespace = {
name: folder.title,
rulesSource: GRAFANA_RULES_SOURCE_NAME,
groups: [
{
name: 'group1',
rules: [
mockCombinedRule({ name: 'Test Alert 1' }),
mockCombinedRule({ name: 'Test Alert 2' }),
mockCombinedRule({ name: 'Test Alert 3' }),
],
totals: {},
},
{
name: 'group2',
rules: [
mockCombinedRule({ name: 'Test Alert 4' }),
mockCombinedRule({ name: 'Test Alert 5' }),
mockCombinedRule({ name: 'Test Alert 6' }),
],
totals: {},
},
],
};
combinedNamespaceMock.mockReturnValue([grafanaNamespace]);
// Act
render(
<TestProvider>
<AlertsFolderView folder={folder} />
</TestProvider>
);
// Assert
const alertRows = ui.ruleList.row.queryAll();
expect(alertRows).toHaveLength(6);
expect(alertRows[0]).toHaveTextContent('Test Alert 1');
expect(alertRows[1]).toHaveTextContent('Test Alert 2');
expect(alertRows[2]).toHaveTextContent('Test Alert 3');
expect(alertRows[3]).toHaveTextContent('Test Alert 4');
expect(alertRows[4]).toHaveTextContent('Test Alert 5');
expect(alertRows[5]).toHaveTextContent('Test Alert 6');
});
it('Should not display alert rules when the namespace name does not match the folder name', () => {
// Arrange
const folder = mockFolder();
const grafanaNamespace: CombinedRuleNamespace = {
name: 'Folder without alerts',
rulesSource: GRAFANA_RULES_SOURCE_NAME,
groups: [
{
name: 'default',
rules: [
mockCombinedRule({ name: 'Test Alert from other folder 1' }),
mockCombinedRule({ name: 'Test Alert from other folder 2' }),
],
totals: {},
},
],
};
combinedNamespaceMock.mockReturnValue([grafanaNamespace]);
// Act
render(
<TestProvider>
<AlertsFolderView folder={folder} />
</TestProvider>
);
// Assert
expect(ui.ruleList.row.queryAll()).toHaveLength(0);
});
it('Should filter alert rules by the name, case insensitive', async () => {
// Arrange
const folder = mockFolder();
const grafanaNamespace: CombinedRuleNamespace = {
name: folder.title,
rulesSource: GRAFANA_RULES_SOURCE_NAME,
groups: [
{
name: 'default',
rules: [mockCombinedRule({ name: 'CPU Alert' }), mockCombinedRule({ name: 'RAM usage alert' })],
totals: {},
},
],
};
combinedNamespaceMock.mockReturnValue([grafanaNamespace]);
// Act
render(
<TestProvider>
<AlertsFolderView folder={folder} />
</TestProvider>
);
await userEvent.type(ui.filter.name.get(), 'cpu');
// Assert
expect(ui.ruleList.row.queryAll()).toHaveLength(1);
expect(ui.ruleList.row.get()).toHaveTextContent('CPU Alert');
});
it('Should filter alert rule by labels', async () => {
// Arrange
const folder = mockFolder();
const grafanaNamespace: CombinedRuleNamespace = {
name: folder.title,
rulesSource: GRAFANA_RULES_SOURCE_NAME,
groups: [
{
name: 'default',
rules: [
mockCombinedRule({ name: 'CPU Alert', labels: {} }),
mockCombinedRule({ name: 'RAM usage alert', labels: { severity: 'critical' } }),
],
totals: {},
},
],
};
combinedNamespaceMock.mockReturnValue([grafanaNamespace]);
// Act
render(
<TestProvider>
<AlertsFolderView folder={folder} />
</TestProvider>
);
await userEvent.type(ui.filter.label.get(), 'severity=critical');
// Assert
expect(ui.ruleList.row.queryAll()).toHaveLength(1);
expect(ui.ruleList.row.get()).toHaveTextContent('RAM usage alert');
});
});