AlertGroups.test.tsx 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import { render, waitFor } from '@testing-library/react';
  2. import userEvent from '@testing-library/user-event';
  3. import React from 'react';
  4. import { Provider } from 'react-redux';
  5. import { Router } from 'react-router-dom';
  6. import { byRole, byTestId, byText } from 'testing-library-selector';
  7. import { locationService, setDataSourceSrv } from '@grafana/runtime';
  8. import { configureStore } from 'app/store/configureStore';
  9. import AlertGroups from './AlertGroups';
  10. import { fetchAlertGroups } from './api/alertmanager';
  11. import { mockAlertGroup, mockAlertmanagerAlert, mockDataSource, MockDataSourceSrv } from './mocks';
  12. import { DataSourceType } from './utils/datasource';
  13. jest.mock('./api/alertmanager');
  14. jest.mock('app/core/services/context_srv', () => ({
  15. contextSrv: {
  16. isEditor: true,
  17. hasAccess: () => true,
  18. hasPermission: () => true,
  19. },
  20. }));
  21. const mocks = {
  22. api: {
  23. fetchAlertGroups: jest.mocked(fetchAlertGroups),
  24. },
  25. };
  26. const renderAmNotifications = () => {
  27. const store = configureStore();
  28. return render(
  29. <Provider store={store}>
  30. <Router history={locationService.getHistory()}>
  31. <AlertGroups />
  32. </Router>
  33. </Provider>
  34. );
  35. };
  36. const dataSources = {
  37. am: mockDataSource({
  38. name: 'Alertmanager',
  39. type: DataSourceType.Alertmanager,
  40. }),
  41. };
  42. const ui = {
  43. group: byTestId('alert-group'),
  44. groupCollapseToggle: byTestId('alert-group-collapse-toggle'),
  45. groupTable: byTestId('alert-group-table'),
  46. row: byTestId('row'),
  47. collapseToggle: byTestId('collapse-toggle'),
  48. silenceButton: byText('Silence'),
  49. sourceButton: byText('See source'),
  50. matcherInput: byTestId('search-query-input'),
  51. groupByContainer: byTestId('group-by-container'),
  52. groupByInput: byRole('combobox', { name: /group by label keys/i }),
  53. clearButton: byRole('button', { name: 'Clear filters' }),
  54. };
  55. describe('AlertGroups', () => {
  56. beforeAll(() => {
  57. mocks.api.fetchAlertGroups.mockImplementation(() => {
  58. return Promise.resolve([
  59. mockAlertGroup({ labels: {}, alerts: [mockAlertmanagerAlert({ labels: { foo: 'bar' } })] }),
  60. mockAlertGroup(),
  61. ]);
  62. });
  63. });
  64. beforeEach(() => {
  65. setDataSourceSrv(new MockDataSourceSrv(dataSources));
  66. });
  67. it('loads and shows groups', async () => {
  68. renderAmNotifications();
  69. await waitFor(() => expect(mocks.api.fetchAlertGroups).toHaveBeenCalled());
  70. const groups = ui.group.getAll();
  71. expect(groups).toHaveLength(2);
  72. expect(groups[0]).toHaveTextContent('No grouping');
  73. expect(groups[1]).toHaveTextContent('severity=warningregion=US-Central');
  74. await userEvent.click(ui.groupCollapseToggle.get(groups[0]));
  75. expect(ui.groupTable.get()).toBeDefined();
  76. await userEvent.click(ui.collapseToggle.get(ui.groupTable.get()));
  77. expect(ui.silenceButton.get(ui.groupTable.get())).toBeDefined();
  78. expect(ui.sourceButton.get(ui.groupTable.get())).toBeDefined();
  79. });
  80. it('should group by custom grouping', async () => {
  81. const regions = ['NASA', 'EMEA', 'APAC'];
  82. mocks.api.fetchAlertGroups.mockImplementation(() => {
  83. const groups = regions.map((region) =>
  84. mockAlertGroup({
  85. labels: { region },
  86. alerts: [
  87. mockAlertmanagerAlert({ labels: { region, appName: 'billing', env: 'production' } }),
  88. mockAlertmanagerAlert({ labels: { region, appName: 'auth', env: 'staging', uniqueLabel: 'true' } }),
  89. mockAlertmanagerAlert({ labels: { region, appName: 'frontend', env: 'production' } }),
  90. ],
  91. })
  92. );
  93. return Promise.resolve(groups);
  94. });
  95. renderAmNotifications();
  96. await waitFor(() => expect(mocks.api.fetchAlertGroups).toHaveBeenCalled());
  97. let groups = ui.group.getAll();
  98. const groupByInput = ui.groupByInput.get();
  99. const groupByWrapper = ui.groupByContainer.get();
  100. expect(groups).toHaveLength(3);
  101. expect(groups[0]).toHaveTextContent('region=NASA');
  102. expect(groups[1]).toHaveTextContent('region=EMEA');
  103. expect(groups[2]).toHaveTextContent('region=APAC');
  104. await userEvent.type(groupByInput, 'appName{enter}');
  105. await waitFor(() => expect(groupByWrapper).toHaveTextContent('appName'));
  106. groups = ui.group.getAll();
  107. await waitFor(() => expect(ui.clearButton.get()).toBeInTheDocument());
  108. expect(groups).toHaveLength(3);
  109. expect(groups[0]).toHaveTextContent('appName=billing');
  110. expect(groups[1]).toHaveTextContent('appName=auth');
  111. expect(groups[2]).toHaveTextContent('appName=frontend');
  112. await userEvent.click(ui.clearButton.get());
  113. await waitFor(() => expect(groupByWrapper).not.toHaveTextContent('appName'));
  114. await userEvent.type(groupByInput, 'env{enter}');
  115. await waitFor(() => expect(groupByWrapper).toHaveTextContent('env'));
  116. groups = ui.group.getAll();
  117. expect(groups).toHaveLength(2);
  118. expect(groups[0]).toHaveTextContent('env=production');
  119. expect(groups[1]).toHaveTextContent('env=staging');
  120. await userEvent.click(ui.clearButton.get());
  121. await waitFor(() => expect(groupByWrapper).not.toHaveTextContent('env'));
  122. await userEvent.type(groupByInput, 'uniqueLabel{enter}');
  123. await waitFor(() => expect(groupByWrapper).toHaveTextContent('uniqueLabel'));
  124. groups = ui.group.getAll();
  125. expect(groups).toHaveLength(2);
  126. expect(groups[0]).toHaveTextContent('No grouping');
  127. expect(groups[1]).toHaveTextContent('uniqueLabel=true');
  128. });
  129. it('should combine multiple ungrouped groups', async () => {
  130. mocks.api.fetchAlertGroups.mockImplementation(() => {
  131. const groups = [
  132. mockAlertGroup({ labels: {} }),
  133. mockAlertGroup({ labels: {}, alerts: [mockAlertmanagerAlert({ labels: { foo: 'bar' } })] }),
  134. ];
  135. return Promise.resolve(groups);
  136. });
  137. renderAmNotifications();
  138. await waitFor(() => expect(mocks.api.fetchAlertGroups).toHaveBeenCalled());
  139. const groups = ui.group.getAll();
  140. expect(groups).toHaveLength(1);
  141. });
  142. });