mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[RAM] Fix blank rule details page when displaying SIEM rules and small alignment issue (#138659)
* Fix rule details page erroring while displaying SIEM rules * Add unit test to verify fix * Address comment and add generic SIEM rule description for now Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Faisal Kanout <faisal.kanout@elastic.co>
This commit is contained in:
parent
2187087c44
commit
568c260369
3 changed files with 70 additions and 19 deletions
|
@ -46,9 +46,9 @@ export function RuleActions({ ruleActions, actionTypeRegistry }: RuleActionsProp
|
|||
}
|
||||
if (isLoadingActionConnectors) return <EuiLoadingSpinner size="s" />;
|
||||
return (
|
||||
<EuiFlexGroup direction="column">
|
||||
<EuiFlexGroup direction="column" gutterSize="none">
|
||||
{actionConnectors.map(({ actionTypeId, name }) => (
|
||||
<React.Fragment key={actionTypeId}>
|
||||
<EuiFlexItem key={actionTypeId}>
|
||||
<EuiFlexGroup alignItems="center" gutterSize="s" component="span">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiIcon size="m" type={getActionIconClass(actionTypeId) ?? 'apps'} />
|
||||
|
@ -60,7 +60,7 @@ export function RuleActions({ ruleActions, actionTypeRegistry }: RuleActionsProp
|
|||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer size="s" />
|
||||
</React.Fragment>
|
||||
</EuiFlexItem>
|
||||
))}
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
|
|
|
@ -69,19 +69,28 @@ const mockedRuleTypeIndex = new Map(
|
|||
})
|
||||
);
|
||||
|
||||
interface SetupProps {
|
||||
ruleOverwrite?: any;
|
||||
}
|
||||
|
||||
describe('Rule Definition', () => {
|
||||
let wrapper: ReactWrapper;
|
||||
async function setup() {
|
||||
async function setup({ ruleOverwrite }: SetupProps = {}) {
|
||||
const actionTypeRegistry = actionTypeRegistryMock.create();
|
||||
const ruleTypeRegistry = ruleTypeRegistryMock.create();
|
||||
const mockedRule = mockRule();
|
||||
const mockedRule = mockRule(ruleOverwrite);
|
||||
jest.mock('../../../lib/capabilities', () => ({
|
||||
hasAllPrivilege: jest.fn(() => true),
|
||||
hasSaveRulesCapability: jest.fn(() => true),
|
||||
hasExecuteActionsCapability: jest.fn(() => true),
|
||||
hasManageApiKeysCapability: jest.fn(() => true),
|
||||
}));
|
||||
ruleTypeRegistry.has.mockReturnValue(true);
|
||||
ruleTypeRegistry.has.mockImplementation((id) => {
|
||||
if (id === 'siem_rule') {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
const ruleTypeR: RuleTypeModel = {
|
||||
id: 'my-rule-type',
|
||||
iconClass: 'test',
|
||||
|
@ -93,7 +102,12 @@ describe('Rule Definition', () => {
|
|||
ruleParamsExpression: jest.fn(),
|
||||
requiresAppContext: false,
|
||||
};
|
||||
ruleTypeRegistry.get.mockReturnValue(ruleTypeR);
|
||||
ruleTypeRegistry.get.mockImplementation((id) => {
|
||||
if (id === 'siem_rule') {
|
||||
throw new Error('error');
|
||||
}
|
||||
return ruleTypeR;
|
||||
});
|
||||
actionTypeRegistry.list.mockReturnValue([
|
||||
{ id: '.server-log', iconClass: 'logsApp' },
|
||||
{ id: '.slack', iconClass: 'logoSlack' },
|
||||
|
@ -117,7 +131,10 @@ describe('Rule Definition', () => {
|
|||
});
|
||||
}
|
||||
|
||||
beforeAll(async () => await setup());
|
||||
beforeEach(async () => await setup());
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('renders rule definition ', async () => {
|
||||
expect(wrapper.find('[data-test-subj="ruleSummaryRuleDefinition"]')).toBeTruthy();
|
||||
|
@ -138,6 +155,18 @@ describe('Rule Definition', () => {
|
|||
expect(ruleDescription.find('div.euiText').text()).toEqual('Rule when testing');
|
||||
});
|
||||
|
||||
it('show SIEM rule type description "', async () => {
|
||||
await setup({
|
||||
ruleOverwrite: {
|
||||
consumer: 'siem',
|
||||
ruleTypeId: 'siem_rule',
|
||||
},
|
||||
});
|
||||
const ruleDescription = wrapper.find('[data-test-subj="ruleSummaryRuleDescription"]');
|
||||
expect(ruleDescription).toBeTruthy();
|
||||
expect(ruleDescription.find('div.euiText').text()).toEqual('Security detection rule');
|
||||
});
|
||||
|
||||
it('show rule conditions "', async () => {
|
||||
const ruleConditions = wrapper.find('[data-test-subj="ruleSummaryRuleConditions"]');
|
||||
expect(ruleConditions).toBeTruthy();
|
||||
|
@ -166,7 +195,7 @@ describe('Rule Definition', () => {
|
|||
expect(editButton).toMatchObject({});
|
||||
});
|
||||
});
|
||||
function mockRule(): Rule {
|
||||
function mockRule(overwrite = {}): Rule {
|
||||
return {
|
||||
id: '1',
|
||||
name: 'test rule',
|
||||
|
@ -175,7 +204,7 @@ function mockRule(): Rule {
|
|||
ruleTypeId: 'test_rule_type',
|
||||
schedule: { interval: '1s' },
|
||||
actions: [],
|
||||
params: { name: 'test rule type name' },
|
||||
params: { name: 'test rule type name', description: 'siem description' },
|
||||
createdBy: null,
|
||||
updatedBy: null,
|
||||
apiKeyOwner: null,
|
||||
|
@ -218,5 +247,6 @@ function mockRule(): Rule {
|
|||
},
|
||||
},
|
||||
},
|
||||
...overwrite,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import {
|
|||
EuiTitle,
|
||||
EuiLoadingSpinner,
|
||||
} from '@elastic/eui';
|
||||
import { AlertConsumers } from '@kbn/rule-data-utils';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { formatDuration } from '@kbn/alerting-plugin/common';
|
||||
import { RuleDefinitionProps } from '../../../../types';
|
||||
|
@ -83,6 +84,20 @@ export const RuleDefinition: React.FunctionComponent<RuleDefinitionProps> = ({
|
|||
: false)
|
||||
);
|
||||
}, [hideEditButton, canSaveRule, ruleTypeRegistry, rule]);
|
||||
|
||||
const ruleDescription = useMemo(() => {
|
||||
if (ruleTypeRegistry.has(rule.ruleTypeId)) {
|
||||
return ruleTypeRegistry.get(rule.ruleTypeId).description;
|
||||
}
|
||||
// TODO: Replace this generic description with proper SIEM rule descriptions
|
||||
if (rule.consumer === AlertConsumers.SIEM) {
|
||||
return i18n.translate('xpack.triggersActionsUI.ruleDetails.securityDetectionRule', {
|
||||
defaultMessage: 'Security detection rule',
|
||||
});
|
||||
}
|
||||
return '';
|
||||
}, [rule, ruleTypeRegistry]);
|
||||
|
||||
return (
|
||||
<EuiFlexItem data-test-subj="ruleSummaryRuleDefinition" grow={3}>
|
||||
<EuiPanel color="subdued" hasBorder={false} paddingSize={'m'}>
|
||||
|
@ -143,27 +158,33 @@ export const RuleDefinition: React.FunctionComponent<RuleDefinitionProps> = ({
|
|||
</ItemTitleRuleSummary>
|
||||
<ItemValueRuleSummary
|
||||
data-test-subj="ruleSummaryRuleDescription"
|
||||
itemValue={ruleTypeRegistry.get(rule.ruleTypeId).description}
|
||||
itemValue={ruleDescription}
|
||||
/>
|
||||
</EuiFlexGroup>
|
||||
|
||||
<EuiSpacer size="m" />
|
||||
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexGroup alignItems="center">
|
||||
<ItemTitleRuleSummary>
|
||||
{i18n.translate('xpack.triggersActionsUI.ruleDetails.conditionsTitle', {
|
||||
defaultMessage: 'Conditions',
|
||||
})}
|
||||
</ItemTitleRuleSummary>
|
||||
<EuiFlexItem grow={3}>
|
||||
<EuiFlexGroup data-test-subj="ruleSummaryRuleConditions" alignItems="center">
|
||||
{hasEditButton ? (
|
||||
<EuiButtonEmpty onClick={() => setEditFlyoutVisible(true)}>
|
||||
<EuiFlexGroup
|
||||
data-test-subj="ruleSummaryRuleConditions"
|
||||
alignItems="center"
|
||||
gutterSize="none"
|
||||
>
|
||||
<EuiFlexItem grow={false}>
|
||||
{hasEditButton ? (
|
||||
<EuiButtonEmpty onClick={() => setEditFlyoutVisible(true)} flush="left">
|
||||
<EuiText size="s">{getRuleConditionsWording()}</EuiText>
|
||||
</EuiButtonEmpty>
|
||||
) : (
|
||||
<EuiText size="s">{getRuleConditionsWording()}</EuiText>
|
||||
</EuiButtonEmpty>
|
||||
) : (
|
||||
<EuiText size="s">{getRuleConditionsWording()}</EuiText>
|
||||
)}
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue