mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Security Solution] Fix alerts table grouping severity stats not showing badge (#216738)
## Summary This PR fixes an issue introduced by [this PR](https://github.com/elastic/kibana/pull/184635) back in `8.16`. I don't think anyone noticed the problem until now... In the PR linked above, the name of the property responsible to render custom components in the group stats section of the alerts table grouping was changed from `renderer` to `component` but there was (at least) one usage that had not been updated. Because that usage wasn't correctly typed and there was no unit tests to verify the behavior, the issue went unnoticed... ### Notes This whole code should be refactored eventually. This is not the purpose of this PR. This only focuses on fixing the issue, adding proper types and unit tests. | Before | After | | ------------- | ------------- | |  |  | ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios
This commit is contained in:
parent
01ef04980f
commit
c1939bb647
2 changed files with 156 additions and 41 deletions
|
@ -10,70 +10,201 @@ import { getStats } from '.';
|
|||
describe('getStats', () => {
|
||||
it('returns array of badges which corresponds to the field name', () => {
|
||||
const badgesRuleName = getStats('kibana.alert.rule.name', {
|
||||
key: ['Rule name test', 'Some description'],
|
||||
usersCountAggregation: {
|
||||
value: 10,
|
||||
},
|
||||
key: [],
|
||||
severitiesSubAggregation: { buckets: [{ key: 'medium', doc_count: 10 }] },
|
||||
countSeveritySubAggregation: { value: 1 },
|
||||
usersCountAggregation: { value: 3 },
|
||||
hostsCountAggregation: { value: 5 },
|
||||
doc_count: 10,
|
||||
});
|
||||
|
||||
expect(badgesRuleName.length).toBe(4);
|
||||
expect(
|
||||
badgesRuleName.find(
|
||||
(badge) => badge.badge != null && badge.title === 'Users:' && badge.badge.value === 10
|
||||
(badge) => badge.title === 'Severity:' && badge.component != null && badge.badge == null
|
||||
)
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
badgesRuleName.find(
|
||||
(badge) => badge.badge != null && badge.title === 'Alerts:' && badge.badge.value === 10
|
||||
(badge) =>
|
||||
badge.title === 'Users:' &&
|
||||
badge.component == null &&
|
||||
badge.badge != null &&
|
||||
badge.badge.value === 3
|
||||
)
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
badgesRuleName.find(
|
||||
(badge) =>
|
||||
badge.title === 'Hosts:' &&
|
||||
badge.component == null &&
|
||||
badge.badge != null &&
|
||||
badge.badge.value === 5
|
||||
)
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
badgesRuleName.find(
|
||||
(badge) =>
|
||||
badge.title === 'Alerts:' &&
|
||||
badge.component == null &&
|
||||
badge.badge != null &&
|
||||
badge.badge.value === 10
|
||||
)
|
||||
).toBeTruthy();
|
||||
|
||||
const badgesHostName = getStats('host.name', {
|
||||
key: 'Host',
|
||||
rulesCountAggregation: {
|
||||
value: 3,
|
||||
},
|
||||
severitiesSubAggregation: { buckets: [{ key: 'medium', doc_count: 10 }] },
|
||||
countSeveritySubAggregation: { value: 1 },
|
||||
usersCountAggregation: { value: 5 },
|
||||
rulesCountAggregation: { value: 3 },
|
||||
doc_count: 2,
|
||||
});
|
||||
|
||||
expect(badgesHostName.length).toBe(4);
|
||||
expect(
|
||||
badgesHostName.find(
|
||||
(badge) => badge.badge != null && badge.title === 'Rules:' && badge.badge.value === 3
|
||||
(badge) => badge.title === 'Severity:' && badge.component != null && badge.badge == null
|
||||
)
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
badgesHostName.find(
|
||||
(badge) =>
|
||||
badge.title === 'Users:' &&
|
||||
badge.component == null &&
|
||||
badge.badge != null &&
|
||||
badge.badge.value === 5
|
||||
)
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
badgesHostName.find(
|
||||
(badge) =>
|
||||
badge.title === 'Rules:' &&
|
||||
badge.component == null &&
|
||||
badge.badge != null &&
|
||||
badge.badge.value === 3
|
||||
)
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
badgesHostName.find(
|
||||
(badge) =>
|
||||
badge.title === 'Alerts:' &&
|
||||
badge.component == null &&
|
||||
badge.badge != null &&
|
||||
badge.badge.value === 2
|
||||
)
|
||||
).toBeTruthy();
|
||||
|
||||
const badgesUserName = getStats('user.name', {
|
||||
key: 'User test',
|
||||
hostsCountAggregation: {
|
||||
value: 1,
|
||||
},
|
||||
severitiesSubAggregation: { buckets: [{ key: 'medium', doc_count: 10 }] },
|
||||
countSeveritySubAggregation: { value: 1 },
|
||||
rulesCountAggregation: { value: 2 },
|
||||
hostsCountAggregation: { value: 1 },
|
||||
doc_count: 1,
|
||||
});
|
||||
|
||||
expect(badgesUserName.length).toBe(4);
|
||||
expect(
|
||||
badgesUserName.find(
|
||||
(badge) => badge.badge != null && badge.title === `Hosts:` && badge.badge.value === 1
|
||||
(badge) => badge.title === 'Severity:' && badge.component != null && badge.badge == null
|
||||
)
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
badgesUserName.find(
|
||||
(badge) =>
|
||||
badge.title === 'Hosts:' &&
|
||||
badge.component == null &&
|
||||
badge.badge != null &&
|
||||
badge.badge.value === 1
|
||||
)
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
badgesUserName.find(
|
||||
(badge) =>
|
||||
badge.title === 'Rules:' &&
|
||||
badge.component == null &&
|
||||
badge.badge != null &&
|
||||
badge.badge.value === 2
|
||||
)
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
badgesUserName.find(
|
||||
(badge) =>
|
||||
badge.title === 'Alerts:' &&
|
||||
badge.component == null &&
|
||||
badge.badge != null &&
|
||||
badge.badge.value === 1
|
||||
)
|
||||
).toBeTruthy();
|
||||
|
||||
const badgesSourceIp = getStats('source.ip', {
|
||||
key: 'User test',
|
||||
severitiesSubAggregation: { buckets: [{ key: 'medium', doc_count: 10 }] },
|
||||
countSeveritySubAggregation: { value: 1 },
|
||||
rulesCountAggregation: { value: 16 },
|
||||
hostsCountAggregation: { value: 17 },
|
||||
doc_count: 18,
|
||||
});
|
||||
|
||||
expect(badgesSourceIp.length).toBe(4);
|
||||
expect(
|
||||
badgesSourceIp.find(
|
||||
(badge) => badge.title === 'Severity:' && badge.component != null && badge.badge == null
|
||||
)
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
badgesSourceIp.find(
|
||||
(badge) =>
|
||||
badge.title === 'Hosts:' &&
|
||||
badge.component == null &&
|
||||
badge.badge != null &&
|
||||
badge.badge.value === 17
|
||||
)
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
badgesSourceIp.find(
|
||||
(badge) =>
|
||||
badge.title === 'Rules:' &&
|
||||
badge.component == null &&
|
||||
badge.badge != null &&
|
||||
badge.badge.value === 16
|
||||
)
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
badgesSourceIp.find(
|
||||
(badge) =>
|
||||
badge.title === 'Alerts:' &&
|
||||
badge.component == null &&
|
||||
badge.badge != null &&
|
||||
badge.badge.value === 18
|
||||
)
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
it('returns default badges if the field specific does not exist', () => {
|
||||
it('should return default badges if the field specific does not exist', () => {
|
||||
const badges = getStats('process.name', {
|
||||
key: 'process',
|
||||
rulesCountAggregation: {
|
||||
value: 3,
|
||||
},
|
||||
severitiesSubAggregation: { buckets: [{ key: 'medium', doc_count: 10 }] },
|
||||
countSeveritySubAggregation: { value: 1 },
|
||||
rulesCountAggregation: { value: 3 },
|
||||
doc_count: 10,
|
||||
});
|
||||
|
||||
expect(badges.length).toBe(2);
|
||||
expect(badges.length).toBe(3);
|
||||
expect(
|
||||
badges.find(
|
||||
(badge) => badge.badge != null && badge.title === 'Rules:' && badge.badge.value === 3
|
||||
(badge) => badge.title === 'Severity:' && badge.component != null && badge.badge == null
|
||||
)
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
badges.find(
|
||||
(badge) => badge.badge != null && badge.title === 'Alerts:' && badge.badge.value === 10
|
||||
(badge) => badge.title === 'Rules:' && badge.component == null && badge.badge?.value === 3
|
||||
)
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
badges.find(
|
||||
(badge) => badge.title === 'Alerts:' && badge.component == null && badge.badge?.value === 10
|
||||
)
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import { EuiIcon } from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import type { RawBucket, GroupStatsItem } from '@kbn/grouping';
|
||||
import type { GroupStatsItem, RawBucket } from '@kbn/grouping';
|
||||
import type { AlertsGroupingAggregation } from './types';
|
||||
import * as i18n from '../translations';
|
||||
|
||||
|
@ -77,16 +77,16 @@ export const getStats = (
|
|||
? multiSeverity
|
||||
: singleSeverityComponent;
|
||||
|
||||
const severityStat = !severityComponent
|
||||
const severityStat: GroupStatsItem[] = !severityComponent
|
||||
? []
|
||||
: [
|
||||
{
|
||||
title: i18n.STATS_GROUP_SEVERITY,
|
||||
renderer: severityComponent,
|
||||
component: severityComponent,
|
||||
},
|
||||
];
|
||||
|
||||
const defaultBadges = [
|
||||
const defaultBadges: GroupStatsItem[] = [
|
||||
{
|
||||
title: i18n.STATS_GROUP_ALERTS,
|
||||
badge: {
|
||||
|
@ -133,22 +133,6 @@ export const getStats = (
|
|||
...defaultBadges,
|
||||
];
|
||||
case 'user.name':
|
||||
return [
|
||||
...severityStat,
|
||||
{
|
||||
title: i18n.STATS_GROUP_HOSTS,
|
||||
badge: {
|
||||
value: bucket.hostsCountAggregation?.value ?? 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18n.STATS_GROUP_RULES,
|
||||
badge: {
|
||||
value: bucket.rulesCountAggregation?.value ?? 0,
|
||||
},
|
||||
},
|
||||
...defaultBadges,
|
||||
];
|
||||
case 'source.ip':
|
||||
return [
|
||||
...severityStat,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue