grafana_bak/public/app/features/alerting/unified/hooks/ruleGroup/useDeleteRuleFromGroup.test.tsx
2025-04-01 10:38:02 +09:00

160 lines
4.7 KiB
TypeScript

import { HttpResponse } from 'msw';
import { render } from 'test/test-utils';
import { byRole, byText } from 'testing-library-selector';
import { AccessControlAction } from 'app/types';
import { CombinedRule } from 'app/types/unified-alerting';
import server, { setupMswServer } from '../../mockApi';
import {
grantUserPermissions,
mockCombinedRule,
mockGrafanaRulerRule,
mockRulerAlertingRule,
mockRulerRecordingRule,
mockRulerRuleGroup,
} from '../../mocks';
import { grafanaRulerRule } from '../../mocks/grafanaRulerApi';
import { setRulerRuleGroupHandler, setUpdateRulerRuleNamespaceHandler } from '../../mocks/server/configure';
import { captureRequests, serializeRequests } from '../../mocks/server/events';
import { rulerRuleGroupHandler, updateRulerRuleNamespaceHandler } from '../../mocks/server/handlers/mimirRuler';
import { fromRulerRuleAndRuleGroupIdentifier } from '../../utils/rule-id';
import { getRuleGroupLocationFromCombinedRule } from '../../utils/rules';
import { SerializeState } from '../useAsync';
import { useDeleteRuleFromGroup } from './useDeleteRuleFromGroup';
setupMswServer();
beforeAll(() => {
grantUserPermissions([AccessControlAction.AlertingRuleExternalRead, AccessControlAction.AlertingRuleRead]);
});
describe('delete rule', () => {
it('should be able to delete a Grafana managed rule', async () => {
const rules = [
mockCombinedRule({
name: 'r1',
rulerRule: mockGrafanaRulerRule({ uid: 'r1' }),
}),
mockCombinedRule({
name: 'r2',
rulerRule: mockGrafanaRulerRule({ uid: 'r2' }),
}),
];
const group = mockRulerRuleGroup({
name: 'group-1',
rules: [rules[0].rulerRule!, rules[1].rulerRule!],
});
const getGroup = rulerRuleGroupHandler({
delay: 0,
response: HttpResponse.json(group),
});
const updateNamespace = updateRulerRuleNamespaceHandler({
response: new HttpResponse(undefined, { status: 200 }),
});
server.use(getGroup, updateNamespace);
const capture = captureRequests();
const { user } = render(<DeleteTestComponent rule={rules[1]} />);
await user.click(byRole('button').get());
expect(await byText(/success/i).find()).toBeInTheDocument();
const requests = await capture;
const serializedRequests = await serializeRequests(requests);
expect(serializedRequests).toMatchSnapshot();
});
it('should be able to delete a Data source managed rule', async () => {
setUpdateRulerRuleNamespaceHandler({
response: new HttpResponse(undefined, { status: 200 }),
});
const rules = [
mockCombinedRule({
name: 'r1',
rulerRule: mockRulerAlertingRule({ alert: 'r1', labels: { foo: 'bar' } }),
}),
mockCombinedRule({
name: 'r2',
rulerRule: mockRulerRecordingRule({ record: 'r2', labels: { bar: 'baz' } }),
}),
];
const group = mockRulerRuleGroup({
name: 'group-1',
rules: [rules[0].rulerRule!, rules[1].rulerRule!],
});
setRulerRuleGroupHandler({
delay: 0,
response: HttpResponse.json(group),
});
const capture = captureRequests();
const { user } = render(<DeleteTestComponent rule={rules[1]} />);
await user.click(byRole('button').get());
expect(await byText(/success/i).find()).toBeInTheDocument();
const requests = await capture;
const serializedRequests = await serializeRequests(requests);
expect(serializedRequests).toMatchSnapshot();
});
it('should delete the entire group if no more rules are left', async () => {
const rule = mockCombinedRule({
rulerRule: grafanaRulerRule,
});
const group = mockRulerRuleGroup({
name: 'group-1',
rules: [rule.rulerRule!],
});
setRulerRuleGroupHandler({
response: HttpResponse.json(group),
});
const capture = captureRequests();
const { user } = render(<DeleteTestComponent rule={rule} />);
await user.click(byRole('button').get());
expect(await byText(/success/i).find()).toBeInTheDocument();
const requests = await capture;
const serializedRequests = await serializeRequests(requests);
expect(serializedRequests).toMatchSnapshot();
});
});
type DeleteTestComponentProps = {
rule: CombinedRule;
};
const DeleteTestComponent = ({ rule }: DeleteTestComponentProps) => {
const [deleteRuleFromGroup, requestState] = useDeleteRuleFromGroup();
// always handle your errors!
const ruleGroupID = getRuleGroupLocationFromCombinedRule(rule);
const ruleID = fromRulerRuleAndRuleGroupIdentifier(ruleGroupID, rule.rulerRule!);
const onClick = () => {
deleteRuleFromGroup.execute(ruleGroupID, ruleID);
};
return (
<>
<button onClick={() => onClick()} />
<SerializeState state={requestState} />
</>
);
};