mirror of
https://github.com/grafana/grafana.git
synced 2026-09-05 04:40:13 -05:00
* Keybindings: No global keybindings on chromeless pages * simplify condition * Refactoring * Align name and file * Move logic into AppChrome * minor fix * Update Page.tsx * Fixing test * Fixed tests * More fixes * Fixed more tests * Fixing final test * Fixed search in old nav
199 lines
6.9 KiB
TypeScript
199 lines
6.9 KiB
TypeScript
import { render, waitFor, waitForElementToBeRemoved } from '@testing-library/react';
|
|
import { setupServer } from 'msw/node';
|
|
import React from 'react';
|
|
import { FormProvider, useForm } from 'react-hook-form';
|
|
import { TestProvider } from 'test/helpers/TestProvider';
|
|
import { byRole, byTestId, byText } from 'testing-library-selector';
|
|
|
|
import { selectors } from '@grafana/e2e-selectors/src';
|
|
import { config, setBackendSrv, setDataSourceSrv } from '@grafana/runtime';
|
|
import { backendSrv } from 'app/core/services/backend_srv';
|
|
import 'whatwg-fetch';
|
|
|
|
import { RulerGrafanaRuleDTO } from '../../../types/unified-alerting-dto';
|
|
|
|
import { CloneRuleEditor } from './CloneRuleEditor';
|
|
import { ExpressionEditorProps } from './components/rule-editor/ExpressionEditor';
|
|
import { mockDataSource, MockDataSourceSrv, mockRulerAlertingRule, mockRulerGrafanaRule, mockStore } from './mocks';
|
|
import { mockSearchApiResponse } from './mocks/grafanaApi';
|
|
import { mockRulerRulesApiResponse, mockRulerRulesGroupApiResponse } from './mocks/rulerApi';
|
|
import { RuleFormValues } from './types/rule-form';
|
|
import { Annotation } from './utils/constants';
|
|
import { getDefaultFormValues } from './utils/rule-form';
|
|
import { hashRulerRule } from './utils/rule-id';
|
|
|
|
jest.mock('./components/rule-editor/ExpressionEditor', () => ({
|
|
// eslint-disable-next-line react/display-name
|
|
ExpressionEditor: ({ value, onChange }: ExpressionEditorProps) => (
|
|
<input value={value} data-testid="expr" onChange={(e) => onChange(e.target.value)} />
|
|
),
|
|
}));
|
|
|
|
const server = setupServer();
|
|
|
|
beforeAll(() => {
|
|
setBackendSrv(backendSrv);
|
|
server.listen({ onUnhandledRequest: 'error' });
|
|
});
|
|
|
|
beforeEach(() => {
|
|
server.resetHandlers();
|
|
});
|
|
|
|
afterAll(() => {
|
|
server.close();
|
|
});
|
|
|
|
const ui = {
|
|
inputs: {
|
|
name: byRole('textbox', { name: /rule name name for the alert rule\./i }),
|
|
expr: byTestId('expr'),
|
|
folderContainer: byTestId(selectors.components.FolderPicker.containerV2),
|
|
namespace: byTestId('namespace-picker'),
|
|
group: byTestId('group-picker'),
|
|
annotationValue: (idx: number) => byTestId(`annotation-value-${idx}`),
|
|
labelValue: (idx: number) => byTestId(`label-value-${idx}`),
|
|
},
|
|
loadingIndicator: byText('Loading the rule'),
|
|
loadingGroupIndicator: byText('Loading...'),
|
|
};
|
|
|
|
function getProvidersWrapper() {
|
|
return function Wrapper({ children }: React.PropsWithChildren<{}>) {
|
|
const store = mockStore((store) => {
|
|
store.unifiedAlerting.dataSources['grafana'] = {
|
|
loading: false,
|
|
dispatched: true,
|
|
result: {
|
|
id: 'grafana',
|
|
name: 'grafana',
|
|
rulerConfig: {
|
|
dataSourceName: 'grafana',
|
|
apiVersion: 'legacy',
|
|
},
|
|
},
|
|
};
|
|
store.unifiedAlerting.dataSources['my-prom-ds'] = {
|
|
loading: false,
|
|
dispatched: true,
|
|
result: {
|
|
id: 'my-prom-ds',
|
|
name: 'my-prom-ds',
|
|
rulerConfig: {
|
|
dataSourceName: 'my-prom-ds',
|
|
apiVersion: 'config',
|
|
},
|
|
},
|
|
};
|
|
});
|
|
|
|
const formApi = useForm<RuleFormValues>({ defaultValues: getDefaultFormValues() });
|
|
|
|
return (
|
|
<TestProvider store={store}>
|
|
<FormProvider {...formApi}>{children}</FormProvider>
|
|
</TestProvider>
|
|
);
|
|
};
|
|
}
|
|
|
|
describe('CloneRuleEditor', function () {
|
|
describe('Grafana-managed rules', function () {
|
|
it('should populate form values from the existing alert rule', async function () {
|
|
setDataSourceSrv(new MockDataSourceSrv({}));
|
|
|
|
const originRule: RulerGrafanaRuleDTO = mockRulerGrafanaRule(
|
|
{
|
|
for: '1m',
|
|
labels: { severity: 'critical', region: 'nasa' },
|
|
annotations: { [Annotation.summary]: 'This is a very important alert rule' },
|
|
},
|
|
{ uid: 'grafana-rule-1', title: 'First Grafana Rule', data: [] }
|
|
);
|
|
|
|
mockRulerRulesApiResponse(server, 'grafana', {
|
|
'folder-one': [{ name: 'group1', interval: '20s', rules: [originRule] }],
|
|
});
|
|
|
|
mockSearchApiResponse(server, []);
|
|
|
|
render(<CloneRuleEditor sourceRuleId={{ uid: 'grafana-rule-1', ruleSourceName: 'grafana' }} />, {
|
|
wrapper: getProvidersWrapper(),
|
|
});
|
|
|
|
await waitForElementToBeRemoved(ui.loadingIndicator.query());
|
|
await waitForElementToBeRemoved(ui.loadingGroupIndicator.query(), { container: ui.inputs.group.get() });
|
|
|
|
await waitFor(() => {
|
|
expect(ui.inputs.name.get()).toHaveValue('First Grafana Rule (copy)');
|
|
expect(ui.inputs.folderContainer.get()).toHaveTextContent('folder-one');
|
|
expect(ui.inputs.group.get()).toHaveTextContent('group1');
|
|
expect(ui.inputs.labelValue(0).get()).toHaveTextContent('critical');
|
|
expect(ui.inputs.labelValue(1).get()).toHaveTextContent('nasa');
|
|
expect(ui.inputs.annotationValue(0).get()).toHaveTextContent('This is a very important alert rule');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('Cloud rules', function () {
|
|
it('should populate form values from the existing alert rule', async function () {
|
|
const dsSettings = mockDataSource({
|
|
name: 'my-prom-ds',
|
|
uid: 'my-prom-ds',
|
|
});
|
|
config.datasources = {
|
|
'my-prom-ds': dsSettings,
|
|
};
|
|
|
|
setDataSourceSrv(new MockDataSourceSrv({ 'my-prom-ds': dsSettings }));
|
|
|
|
const originRule = mockRulerAlertingRule({
|
|
for: '1m',
|
|
alert: 'First Ruler Rule',
|
|
expr: 'vector(1) > 0',
|
|
labels: { severity: 'critical', region: 'nasa' },
|
|
annotations: { [Annotation.summary]: 'This is a very important alert rule' },
|
|
});
|
|
|
|
mockRulerRulesApiResponse(server, 'my-prom-ds', {
|
|
'namespace-one': [{ name: 'group1', interval: '20s', rules: [originRule] }],
|
|
});
|
|
|
|
mockRulerRulesGroupApiResponse(server, 'my-prom-ds', 'namespace-one', 'group1', {
|
|
name: 'group1',
|
|
interval: '20s',
|
|
rules: [originRule],
|
|
});
|
|
|
|
mockSearchApiResponse(server, []);
|
|
|
|
render(
|
|
<CloneRuleEditor
|
|
sourceRuleId={{
|
|
uid: 'prom-rule-1',
|
|
ruleSourceName: 'my-prom-ds',
|
|
namespace: 'namespace-one',
|
|
groupName: 'group1',
|
|
rulerRuleHash: hashRulerRule(originRule),
|
|
}}
|
|
/>,
|
|
{
|
|
wrapper: getProvidersWrapper(),
|
|
}
|
|
);
|
|
|
|
await waitForElementToBeRemoved(ui.loadingIndicator.query());
|
|
|
|
await waitFor(() => {
|
|
expect(ui.inputs.name.get()).toHaveValue('First Ruler Rule (copy)');
|
|
expect(ui.inputs.expr.get()).toHaveValue('vector(1) > 0');
|
|
expect(ui.inputs.namespace.get()).toHaveTextContent('namespace-one');
|
|
expect(ui.inputs.group.get()).toHaveTextContent('group1');
|
|
expect(ui.inputs.labelValue(0).get()).toHaveTextContent('critical');
|
|
expect(ui.inputs.labelValue(1).get()).toHaveTextContent('nasa');
|
|
expect(ui.inputs.annotationValue(0).get()).toHaveTextContent('This is a very important alert rule');
|
|
});
|
|
});
|
|
});
|
|
});
|