Submit
Path:
~
/
/
usr
/
share
/
grafana
/
public
/
app
/
features
/
alerting
/
unified
/
components
/
rules
/
File Content:
EditRuleGroupModal.test.tsx
import { render } from '@testing-library/react'; import React from 'react'; import { Provider } from 'react-redux'; import { byLabelText, byTestId, byText, byTitle } from 'testing-library-selector'; import { CombinedRuleNamespace } from 'app/types/unified-alerting'; import { mockCombinedRule, mockCombinedRuleNamespace, mockDataSource, mockPromAlertingRule, mockPromRecordingRule, mockRulerAlertingRule, mockRulerRecordingRule, mockRulerRuleGroup, mockStore, } from '../../mocks'; import { GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource'; import { EditCloudGroupModal } from './EditRuleGroupModal'; const ui = { input: { namespace: byLabelText(/^Folder|^Namespace/, { exact: true }), group: byLabelText(/Evaluation group/), interval: byLabelText(/Evaluation interval/), }, folderLink: byTitle(/Go to folder/), // <a> without a href has the generic role table: byTestId('dynamic-table'), tableRows: byTestId('row'), noRulesText: byText('This group does not contain alert rules.'), }; mockRulerRuleGroup({ name: 'group1', rules: [ mockRulerRecordingRule({ record: 'instance:node_num_cpu:sum', expr: 'count without (cpu) (count without (mode) (node_cpu_seconds_total{job="integrations/node_exporter"}))', labels: { type: 'cpu' }, }), mockRulerAlertingRule({ alert: 'nonRecordingRule' }), ], }); jest.mock('app/types', () => ({ ...jest.requireActual('app/types'), useDispatch: () => jest.fn(), })); function getProvidersWrapper() { return function Wrapper({ children }: React.PropsWithChildren<{}>) { const store = mockStore(() => null); return <Provider store={store}>{children}</Provider>; }; } describe('EditGroupModal', () => { it('Should disable all inputs but interval when intervalEditOnly is set', () => { const namespace = mockCombinedRuleNamespace({ name: 'my-alerts', rulesSource: mockDataSource(), groups: [{ name: 'default-group', interval: '90s', rules: [], totals: {} }], }); const group = namespace.groups[0]; render(<EditCloudGroupModal namespace={namespace} group={group} intervalEditOnly onClose={() => jest.fn()} />, { wrapper: getProvidersWrapper(), }); expect(ui.input.namespace.get()).toHaveAttribute('readonly'); expect(ui.input.group.get()).toHaveAttribute('readonly'); expect(ui.input.interval.get()).not.toHaveAttribute('readonly'); }); }); describe('EditGroupModal component on cloud alert rules', () => { const promDsSettings = mockDataSource({ name: 'Prometheus-1', uid: 'Prometheus-1' }); const alertingRule = mockCombinedRule({ namespace: undefined, promRule: mockPromAlertingRule({ name: 'alerting-rule-cpu' }), rulerRule: mockRulerAlertingRule({ alert: 'alerting-rule-cpu' }), }); const recordingRule1 = mockCombinedRule({ namespace: undefined, promRule: mockPromRecordingRule({ name: 'recording-rule-memory' }), rulerRule: mockRulerRecordingRule({ record: 'recording-rule-memory' }), }); const recordingRule2 = mockCombinedRule({ namespace: undefined, promRule: mockPromRecordingRule({ name: 'recording-rule-cpu' }), rulerRule: mockRulerRecordingRule({ record: 'recording-rule-cpu' }), }); it('Should show alert table in case of having some non-recording rules in the group', () => { const promNs = mockCombinedRuleNamespace({ name: 'prometheus-ns', rulesSource: promDsSettings, groups: [ { name: 'default-group', interval: '90s', rules: [alertingRule, recordingRule1, recordingRule2], totals: {} }, ], }); const group = promNs.groups[0]; render(<EditCloudGroupModal namespace={promNs} group={group} onClose={() => jest.fn()} />, { wrapper: getProvidersWrapper(), }); expect(ui.input.namespace.get()).toHaveValue('prometheus-ns'); expect(ui.input.namespace.get()).not.toHaveAttribute('readonly'); expect(ui.input.group.get()).toHaveValue('default-group'); expect(ui.tableRows.getAll()).toHaveLength(1); // Only one rule is non-recording expect(ui.tableRows.getAll()[0]).toHaveTextContent('alerting-rule-cpu'); }); it('Should not show alert table in case of having exclusively recording rules in the group', () => { const promNs = mockCombinedRuleNamespace({ name: 'prometheus-ns', rulesSource: promDsSettings, groups: [{ name: 'default-group', interval: '90s', rules: [recordingRule1, recordingRule2], totals: {} }], }); const group = promNs.groups[0]; render(<EditCloudGroupModal namespace={promNs} group={group} onClose={jest.fn()} />, { wrapper: getProvidersWrapper(), }); expect(ui.table.query()).not.toBeInTheDocument(); expect(ui.noRulesText.get()).toBeInTheDocument(); }); }); describe('EditGroupModal component on grafana-managed alert rules', () => { const grafanaNamespace: CombinedRuleNamespace = { name: 'namespace1', rulesSource: GRAFANA_RULES_SOURCE_NAME, groups: [ { name: 'grafanaGroup1', interval: '30s', rules: [ mockCombinedRule({ namespace: undefined, promRule: mockPromAlertingRule({ name: 'high-cpu-1' }), rulerRule: mockRulerAlertingRule({ alert: 'high-cpu-1' }), }), mockCombinedRule({ namespace: undefined, promRule: mockPromAlertingRule({ name: 'high-memory' }), rulerRule: mockRulerAlertingRule({ alert: 'high-memory' }), }), ], totals: {}, }, ], }; const grafanaGroup1 = grafanaNamespace.groups[0]; it('Should show alert table', () => { render(<EditCloudGroupModal namespace={grafanaNamespace} group={grafanaGroup1} onClose={jest.fn()} />, { wrapper: getProvidersWrapper(), }); expect(ui.input.namespace.get()).toHaveValue('namespace1'); expect(ui.input.group.get()).toHaveValue('grafanaGroup1'); expect(ui.input.interval.get()).toHaveValue('30s'); expect(ui.tableRows.getAll()).toHaveLength(2); expect(ui.tableRows.getAll()[0]).toHaveTextContent('high-cpu-1'); expect(ui.tableRows.getAll()[1]).toHaveTextContent('high-memory'); }); it('Should have folder input in readonly mode', () => { render(<EditCloudGroupModal namespace={grafanaNamespace} group={grafanaGroup1} onClose={jest.fn()} />, { wrapper: getProvidersWrapper(), }); expect(ui.input.namespace.get()).toHaveAttribute('readonly'); }); it('Should not display folder link if no folderUrl provided', () => { render(<EditCloudGroupModal namespace={grafanaNamespace} group={grafanaGroup1} onClose={jest.fn()} />, { wrapper: getProvidersWrapper(), }); expect(ui.folderLink.query()).not.toBeInTheDocument(); }); });
Submit
FILE
FOLDER
INFO
Name
Size
Permission
Action
state-history
---
0755
ActionButton.tsx
656 bytes
0644
ActionIcon.tsx
1221 bytes
0644
AlertInstanceDetails.tsx
890 bytes
0644
AlertInstanceStateFilter.tsx
2279 bytes
0644
AlertInstancesTable.tsx
3137 bytes
0644
AlertStateTag.tsx
798 bytes
0644
CloneRule.tsx
2736 bytes
0644
CloudRules.tsx
4731 bytes
0644
EditRuleGroupModal.test.tsx
6785 bytes
0644
EditRuleGroupModal.tsx
13135 bytes
0644
GrafanaRules.tsx
4432 bytes
0644
MultipleDataSourcePicker.tsx
5591 bytes
0644
NoRulesCTA.tsx
1878 bytes
0644
ReorderRuleGroupModal.test.tsx
341 bytes
0644
ReorderRuleGroupModal.tsx
6809 bytes
0644
RuleActionsButtons.tsx
7169 bytes
0644
RuleConfigStatus.tsx
1410 bytes
0644
RuleDetails.test.tsx
5891 bytes
0644
RuleDetails.tsx
4376 bytes
0644
RuleDetailsActionButtons.tsx
11094 bytes
0644
RuleDetailsAnnotations.tsx
880 bytes
0644
RuleDetailsDataSources.tsx
2159 bytes
0644
RuleDetailsExpression.tsx
927 bytes
0644
RuleDetailsFederatedSources.tsx
541 bytes
0644
RuleDetailsMatchingInstances.test.tsx
6494 bytes
0644
RuleDetailsMatchingInstances.tsx
6532 bytes
0644
RuleHealth.tsx
949 bytes
0644
RuleListErrors.tsx
5247 bytes
0644
RuleListGroupView.test.tsx
4198 bytes
0644
RuleListGroupView.tsx
1485 bytes
0644
RuleListStateSection.tsx
1413 bytes
0644
RuleListStateView.tsx
2178 bytes
0644
RuleState.tsx
2363 bytes
0644
RuleStats.tsx
3651 bytes
0644
RulesFilter.test.tsx
2591 bytes
0644
RulesFilter.tsx
10765 bytes
0644
RulesGroup.test.tsx
7427 bytes
0644
RulesGroup.tsx
12418 bytes
0644
RulesTable.test.tsx
4684 bytes
0644
RulesTable.tsx
8979 bytes
0644
useCombinedGroupNamespace.tsx
378 bytes
0644
N4ST4R_ID | Naxtarrr