mirror of
https://github.com/elastic/kibana.git
synced 2025-06-28 03:01:21 -04:00
[Attack Discovery][Scheduling] Cases support followup 1 (#225452)
## Summary
Summarize your PR. If it involves visual changes include a screenshot or
gif.
These changes addresses the review comment from my previous PR
36ed6b38c1 (r2150081638)
Initially I broke up rendered component into multiple memoized
sub-sections. Reverting that back and adding tests coverage for the new
functionality - Case actions UI for the Attack Discovery rule type:
* Hidden `group by` component
* Hidden `time window` component
* Hidden `reopen case` component
* Disabled `template selector` component
* Tooltip explaining why we disabled the `template selector` component
This commit is contained in:
parent
4de6f7ca2c
commit
d38801034a
2 changed files with 133 additions and 100 deletions
|
@ -19,6 +19,7 @@ import { useGetAllCaseConfigurations } from '../../../containers/configure/use_g
|
||||||
import { useGetAllCaseConfigurationsResponse } from '../../configure_cases/__mock__';
|
import { useGetAllCaseConfigurationsResponse } from '../../configure_cases/__mock__';
|
||||||
import { templatesConfigurationMock } from '../../../containers/mock';
|
import { templatesConfigurationMock } from '../../../containers/mock';
|
||||||
import * as utils from '../../../containers/configure/utils';
|
import * as utils from '../../../containers/configure/utils';
|
||||||
|
import { ATTACK_DISCOVERY_SCHEDULES_ALERT_TYPE_ID } from '@kbn/elastic-assistant-common';
|
||||||
|
|
||||||
jest.mock('@kbn/alerts-ui-shared/src/common/hooks/use_alerts_data_view');
|
jest.mock('@kbn/alerts-ui-shared/src/common/hooks/use_alerts_data_view');
|
||||||
jest.mock('../../../common/lib/kibana/use_application');
|
jest.mock('../../../common/lib/kibana/use_application');
|
||||||
|
@ -72,6 +73,7 @@ describe('CasesParamsFields renders', () => {
|
||||||
// Workaround for timeout via https://github.com/testing-library/user-event/issues/833#issuecomment-1171452841
|
// Workaround for timeout via https://github.com/testing-library/user-event/issues/833#issuecomment-1171452841
|
||||||
user = userEvent.setup({
|
user = userEvent.setup({
|
||||||
advanceTimers: jest.advanceTimersByTime,
|
advanceTimers: jest.advanceTimersByTime,
|
||||||
|
pointerEventsCheck: 0,
|
||||||
});
|
});
|
||||||
useApplicationMock.mockReturnValueOnce({ appId: 'management' });
|
useApplicationMock.mockReturnValueOnce({ appId: 'management' });
|
||||||
useAlertsDataViewMock.mockReturnValue({
|
useAlertsDataViewMock.mockReturnValue({
|
||||||
|
@ -397,4 +399,67 @@ describe('CasesParamsFields renders', () => {
|
||||||
expect(editAction.mock.calls[0][1].reopenClosedCases).toEqual(true);
|
expect(editAction.mock.calls[0][1].reopenClosedCases).toEqual(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Attack Discovery', () => {
|
||||||
|
it('does not render `group by` component', async () => {
|
||||||
|
const newProps = {
|
||||||
|
...defaultProps,
|
||||||
|
ruleTypeId: ATTACK_DISCOVERY_SCHEDULES_ALERT_TYPE_ID,
|
||||||
|
};
|
||||||
|
render(<CasesParamsFields {...newProps} />);
|
||||||
|
|
||||||
|
expect(screen.queryByTestId('group-by-alert-field-combobox')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not render `time window` component', async () => {
|
||||||
|
const newProps = {
|
||||||
|
...defaultProps,
|
||||||
|
ruleTypeId: ATTACK_DISCOVERY_SCHEDULES_ALERT_TYPE_ID,
|
||||||
|
};
|
||||||
|
render(<CasesParamsFields {...newProps} />);
|
||||||
|
|
||||||
|
expect(screen.queryByTestId('time-window-size-input')).not.toBeInTheDocument();
|
||||||
|
expect(screen.queryByTestId('time-window-unit-select')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not render `reopen case` component', async () => {
|
||||||
|
const newProps = {
|
||||||
|
...defaultProps,
|
||||||
|
ruleTypeId: ATTACK_DISCOVERY_SCHEDULES_ALERT_TYPE_ID,
|
||||||
|
};
|
||||||
|
render(<CasesParamsFields {...newProps} />);
|
||||||
|
|
||||||
|
expect(screen.queryByTestId('reopen-case')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders disabled `template selector` component', async () => {
|
||||||
|
const newProps = {
|
||||||
|
...defaultProps,
|
||||||
|
ruleTypeId: ATTACK_DISCOVERY_SCHEDULES_ALERT_TYPE_ID,
|
||||||
|
};
|
||||||
|
render(<CasesParamsFields {...newProps} />);
|
||||||
|
|
||||||
|
const templateSelectorComponent = await screen.findByTestId('create-case-template-select');
|
||||||
|
|
||||||
|
expect(templateSelectorComponent).toBeInTheDocument();
|
||||||
|
expect(templateSelectorComponent).toBeDisabled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('shows attack discovery explanation tooltip', async () => {
|
||||||
|
const newProps = {
|
||||||
|
...defaultProps,
|
||||||
|
ruleTypeId: ATTACK_DISCOVERY_SCHEDULES_ALERT_TYPE_ID,
|
||||||
|
};
|
||||||
|
render(<CasesParamsFields {...newProps} />);
|
||||||
|
|
||||||
|
await user.hover(await screen.findByTestId('create-case-template-select'));
|
||||||
|
|
||||||
|
expect(await screen.findByTestId('case-action-attack-discovery-tooltip')).toBeTruthy();
|
||||||
|
expect(
|
||||||
|
await screen.findByText(
|
||||||
|
'Attack Discovery Schedules fully manage Case actions, automatically filling in all fields for new Cases.'
|
||||||
|
)
|
||||||
|
).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -188,8 +188,26 @@ export const CasesParamsFieldsComponent: React.FunctionComponent<
|
||||||
[editSubActionProperty]
|
[editSubActionProperty]
|
||||||
);
|
);
|
||||||
|
|
||||||
const groupByComponent = useMemo(() => {
|
if (isAttackDiscoveryRuleType) {
|
||||||
return (
|
return (
|
||||||
|
<EuiToolTip
|
||||||
|
data-test-subj="case-action-attack-discovery-tooltip"
|
||||||
|
content={i18n.ATTACK_DISCOVERY_TEMPLATE_TOOLTIP}
|
||||||
|
>
|
||||||
|
<TemplateSelector
|
||||||
|
key={currentConfiguration.id}
|
||||||
|
isLoading={isLoadingCaseConfiguration}
|
||||||
|
templates={[defaultTemplate, ...currentConfiguration.templates]}
|
||||||
|
onTemplateChange={onTemplateChange}
|
||||||
|
initialTemplate={selectedTemplate}
|
||||||
|
isDisabled={true}
|
||||||
|
/>
|
||||||
|
</EuiToolTip>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
<EuiFlexGroup>
|
<EuiFlexGroup>
|
||||||
<EuiFlexItem grow={true}>
|
<EuiFlexItem grow={true}>
|
||||||
<EuiFormRow fullWidth label={i18n.GROUP_BY_ALERT} labelAppend={OptionalFieldLabel}>
|
<EuiFormRow fullWidth label={i18n.GROUP_BY_ALERT} labelAppend={OptionalFieldLabel}>
|
||||||
|
@ -207,12 +225,7 @@ export const CasesParamsFieldsComponent: React.FunctionComponent<
|
||||||
</EuiFormRow>
|
</EuiFormRow>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
</EuiFlexGroup>
|
</EuiFlexGroup>
|
||||||
);
|
<EuiSpacer size="m" />
|
||||||
}, [loadingAlertDataViews, onChangeComboBox, options, selectedOptions]);
|
|
||||||
|
|
||||||
const timeWindowComponent = useMemo(() => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<EuiFormRow
|
<EuiFormRow
|
||||||
fullWidth
|
fullWidth
|
||||||
id="timeWindow"
|
id="timeWindow"
|
||||||
|
@ -259,19 +272,7 @@ export const CasesParamsFieldsComponent: React.FunctionComponent<
|
||||||
size="s"
|
size="s"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
<EuiSpacer size="m" />
|
||||||
);
|
|
||||||
}, [
|
|
||||||
errors.timeWindow,
|
|
||||||
handleTimeWindowChange,
|
|
||||||
showTimeWindowWarning,
|
|
||||||
timeWindow,
|
|
||||||
timeWindowSize,
|
|
||||||
timeWindowUnit,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const templateSelectorComponent = useMemo(() => {
|
|
||||||
return (
|
|
||||||
<EuiFlexGroup>
|
<EuiFlexGroup>
|
||||||
<EuiFlexItem grow={true}>
|
<EuiFlexItem grow={true}>
|
||||||
<TemplateSelector
|
<TemplateSelector
|
||||||
|
@ -280,23 +281,10 @@ export const CasesParamsFieldsComponent: React.FunctionComponent<
|
||||||
templates={[defaultTemplate, ...currentConfiguration.templates]}
|
templates={[defaultTemplate, ...currentConfiguration.templates]}
|
||||||
onTemplateChange={onTemplateChange}
|
onTemplateChange={onTemplateChange}
|
||||||
initialTemplate={selectedTemplate}
|
initialTemplate={selectedTemplate}
|
||||||
isDisabled={isAttackDiscoveryRuleType}
|
|
||||||
/>
|
/>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
</EuiFlexGroup>
|
</EuiFlexGroup>
|
||||||
);
|
<EuiSpacer size="m" />
|
||||||
}, [
|
|
||||||
currentConfiguration.id,
|
|
||||||
currentConfiguration.templates,
|
|
||||||
defaultTemplate,
|
|
||||||
isAttackDiscoveryRuleType,
|
|
||||||
isLoadingCaseConfiguration,
|
|
||||||
onTemplateChange,
|
|
||||||
selectedTemplate,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const reopenClosedCasesComponent = useMemo(() => {
|
|
||||||
return (
|
|
||||||
<EuiFlexGroup>
|
<EuiFlexGroup>
|
||||||
<EuiFlexItem>
|
<EuiFlexItem>
|
||||||
<EuiCheckbox
|
<EuiCheckbox
|
||||||
|
@ -310,26 +298,6 @@ export const CasesParamsFieldsComponent: React.FunctionComponent<
|
||||||
/>
|
/>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
</EuiFlexGroup>
|
</EuiFlexGroup>
|
||||||
);
|
|
||||||
}, [editSubActionProperty, index, reopenClosedCases]);
|
|
||||||
|
|
||||||
if (isAttackDiscoveryRuleType) {
|
|
||||||
return (
|
|
||||||
<EuiToolTip content={i18n.ATTACK_DISCOVERY_TEMPLATE_TOOLTIP}>
|
|
||||||
{templateSelectorComponent}
|
|
||||||
</EuiToolTip>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{groupByComponent}
|
|
||||||
<EuiSpacer size="m" />
|
|
||||||
{timeWindowComponent}
|
|
||||||
<EuiSpacer size="m" />
|
|
||||||
{templateSelectorComponent}
|
|
||||||
<EuiSpacer size="m" />
|
|
||||||
{reopenClosedCasesComponent}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue