Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[7.x] [Security Solution][Detection Alerts] Changes in-progress status to acknowledged (#107972) #109042

Merged
merged 1 commit into from
Aug 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,12 @@ export type RuleNameOverride = t.TypeOf<typeof rule_name_override>;
export const ruleNameOverrideOrUndefined = t.union([rule_name_override, t.undefined]);
export type RuleNameOverrideOrUndefined = t.TypeOf<typeof ruleNameOverrideOrUndefined>;

export const status = t.keyof({ open: null, closed: null, 'in-progress': null });
export const status = t.keyof({
open: null,
closed: null,
acknowledged: null,
'in-progress': null, // TODO: Remove after `acknowledged` migrations
});
export type Status = t.TypeOf<typeof status>;

export enum RuleExecutionStatus {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import {
waitForAlertsPanelToBeLoaded,
waitForAlerts,
waitForAlertsToBeLoaded,
markInProgressFirstAlert,
goToInProgressAlerts,
markAcknowledgedFirstAlert,
goToAcknowledgedAlerts,
waitForAlertsIndexToBeCreated,
goToOpenedAlerts,
} from '../../tasks/alerts';
Expand All @@ -26,7 +26,7 @@ import { refreshPage } from '../../tasks/security_header';

import { ALERTS_URL } from '../../urls/navigation';

describe('Marking alerts as in-progress', () => {
describe('Marking alerts as acknowledged', () => {
beforeEach(() => {
cleanKibana();
loginAndWaitForPage(ALERTS_URL);
Expand All @@ -37,30 +37,30 @@ describe('Marking alerts as in-progress', () => {
waitForAlertsToPopulate(500);
});

it('Mark one alert in progress when more than one open alerts are selected', () => {
it('Mark one alert as acknowledged when more than one open alerts are selected', () => {
cy.get(ALERTS_COUNT)
.invoke('text')
.then((alertNumberString) => {
const numberOfAlerts = alertNumberString.split(' ')[0];
const numberOfAlertsToBeMarkedInProgress = 1;
const numberOfAlertsToBeMarkedAcknowledged = 1;
const numberOfAlertsToBeSelected = 3;

cy.get(TAKE_ACTION_POPOVER_BTN).should('not.exist');
selectNumberOfAlerts(numberOfAlertsToBeSelected);
cy.get(TAKE_ACTION_POPOVER_BTN).should('exist');

markInProgressFirstAlert();
markAcknowledgedFirstAlert();
refreshPage();
waitForAlertsToBeLoaded();
goToOpenedAlerts();

const expectedNumberOfAlerts = +numberOfAlerts - numberOfAlertsToBeMarkedInProgress;
const expectedNumberOfAlerts = +numberOfAlerts - numberOfAlertsToBeMarkedAcknowledged;
cy.get(ALERTS_COUNT).should('have.text', `${expectedNumberOfAlerts} alerts`);

goToInProgressAlerts();
goToAcknowledgedAlerts();
waitForAlerts();

cy.get(ALERTS_COUNT).should('have.text', `${numberOfAlertsToBeMarkedInProgress} alert`);
cy.get(ALERTS_COUNT).should('have.text', `${numberOfAlertsToBeMarkedAcknowledged} alert`);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import {
} from '../../screens/kibana_navigation';
import { cleanKibana } from '../../tasks/common';

describe('top-level navigation common to all pages in the Security app', () => {
describe.skip('top-level navigation common to all pages in the Security app', () => {
before(() => {
cleanKibana();
loginAndWaitForPage(TIMELINES_URL);
Expand Down Expand Up @@ -111,7 +111,7 @@ describe('top-level navigation common to all pages in the Security app', () => {
});
});

describe('Kibana navigation to all pages in the Security app ', () => {
describe.skip('Kibana navigation to all pages in the Security app ', () => {
before(() => {
loginAndWaitForPage(KIBANA_HOME);
});
Expand Down
8 changes: 4 additions & 4 deletions x-pack/plugins/security_solution/cypress/screens/alerts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,16 @@ export const CLOSED_ALERTS_FILTER_BTN = '[data-test-subj="closedAlerts"]';

export const EXPAND_ALERT_BTN = '[data-test-subj="expand-event"]';

export const IN_PROGRESS_ALERTS_FILTER_BTN = '[data-test-subj="inProgressAlerts"]';
export const ACKNOWLEDGED_ALERTS_FILTER_BTN = '[data-test-subj="acknowledgedAlerts"]';

export const LOADING_ALERTS_PANEL = '[data-test-subj="loading-alerts-panel"]';

export const MANAGE_ALERT_DETECTION_RULES_BTN = '[data-test-subj="manage-alert-detection-rules"]';

export const MARK_ALERT_IN_PROGRESS_BTN = '[data-test-subj="in-progress-alert-status"]';
export const MARK_ALERT_ACKNOWLEDGED_BTN = '[data-test-subj="acknowledged-alert-status"]';

export const MARK_SELECTED_ALERTS_IN_PROGRESS_BTN =
'[data-test-subj="markSelectedAlertsInProgressButton"]';
export const MARK_SELECTED_ALERTS_ACKNOWLEDGED_BTN =
'[data-test-subj="markSelectedAlertsAcknowledgedButton"]';

export const NUMBER_OF_ALERTS =
'[data-test-subj="events-viewer-panel"] [data-test-subj="server-side-event-count"]';
Expand Down
21 changes: 12 additions & 9 deletions x-pack/plugins/security_solution/cypress/tasks/alerts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import {
CLOSE_SELECTED_ALERTS_BTN,
CLOSED_ALERTS_FILTER_BTN,
EXPAND_ALERT_BTN,
IN_PROGRESS_ALERTS_FILTER_BTN,
ACKNOWLEDGED_ALERTS_FILTER_BTN,
LOADING_ALERTS_PANEL,
MANAGE_ALERT_DETECTION_RULES_BTN,
MARK_ALERT_IN_PROGRESS_BTN,
MARK_SELECTED_ALERTS_IN_PROGRESS_BTN,
MARK_ALERT_ACKNOWLEDGED_BTN,
MARK_SELECTED_ALERTS_ACKNOWLEDGED_BTN,
OPEN_ALERT_BTN,
OPENED_ALERTS_FILTER_BTN,
SEND_ALERT_TO_TIMELINE_BTN,
Expand Down Expand Up @@ -112,18 +112,21 @@ export const openAlerts = () => {
cy.get(OPEN_ALERT_BTN).click();
};

export const goToInProgressAlerts = () => {
cy.get(IN_PROGRESS_ALERTS_FILTER_BTN).click();
export const goToAcknowledgedAlerts = () => {
cy.get(ACKNOWLEDGED_ALERTS_FILTER_BTN).click();
cy.get(REFRESH_BUTTON).should('not.have.text', 'Updating');
cy.get(REFRESH_BUTTON).should('have.text', 'Refresh');
cy.get(TIMELINE_COLUMN_SPINNER).should('not.exist');
};

export const markInProgressFirstAlert = () => {
export const markAcknowledgedFirstAlert = () => {
cy.get(TIMELINE_CONTEXT_MENU_BTN).first().click({ force: true });
cy.get(MARK_ALERT_IN_PROGRESS_BTN).click();
cy.get(MARK_ALERT_ACKNOWLEDGED_BTN).click();
};

export const markInProgressAlerts = () => {
export const markAcknowledgedAlerts = () => {
cy.get(TAKE_ACTION_POPOVER_BTN).click({ force: true });
cy.get(MARK_SELECTED_ALERTS_IN_PROGRESS_BTN).click();
cy.get(MARK_SELECTED_ALERTS_ACKNOWLEDGED_BTN).click();
};

export const selectNumberOfAlerts = (numberOfAlerts: number) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,9 @@ describe('EventsViewer', () => {
<EventsViewer
{...eventsViewerDefaultProps}
graphEventId={undefined}
headerFilterGroup={<AlertsTableFilterGroup onFilterGroupChanged={jest.fn()} />}
headerFilterGroup={
<AlertsTableFilterGroup status={'open'} onFilterGroupChanged={jest.fn()} />
}
/>
</TestProviders>
);
Expand All @@ -350,7 +352,9 @@ describe('EventsViewer', () => {
<EventsViewer
{...eventsViewerDefaultProps}
graphEventId={undefined}
headerFilterGroup={<AlertsTableFilterGroup onFilterGroupChanged={jest.fn()} />}
headerFilterGroup={
<AlertsTableFilterGroup status={'open'} onFilterGroupChanged={jest.fn()} />
}
/>
</TestProviders>
);
Expand All @@ -365,7 +369,9 @@ describe('EventsViewer', () => {
<EventsViewer
{...eventsViewerDefaultProps}
graphEventId=""
headerFilterGroup={<AlertsTableFilterGroup onFilterGroupChanged={jest.fn()} />}
headerFilterGroup={
<AlertsTableFilterGroup status={'open'} onFilterGroupChanged={jest.fn()} />
}
/>
</TestProviders>
);
Expand All @@ -380,7 +386,9 @@ describe('EventsViewer', () => {
<EventsViewer
{...eventsViewerDefaultProps}
graphEventId="a valid id"
headerFilterGroup={<AlertsTableFilterGroup onFilterGroupChanged={jest.fn()} />}
headerFilterGroup={
<AlertsTableFilterGroup status={'open'} onFilterGroupChanged={jest.fn()} />
}
/>
</TestProviders>
);
Expand All @@ -395,7 +403,9 @@ describe('EventsViewer', () => {
<EventsViewer
{...eventsViewerDefaultProps}
graphEventId="a valid id"
headerFilterGroup={<AlertsTableFilterGroup onFilterGroupChanged={jest.fn()} />}
headerFilterGroup={
<AlertsTableFilterGroup status={'open'} onFilterGroupChanged={jest.fn()} />
}
/>
</TestProviders>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import { AlertsTableFilterGroup } from './index';

describe('AlertsTableFilterGroup', () => {
it('renders correctly', () => {
const wrapper = shallow(<AlertsTableFilterGroup onFilterGroupChanged={jest.fn()} />);
const wrapper = shallow(
<AlertsTableFilterGroup status={'open'} onFilterGroupChanged={jest.fn()} />
);

expect(wrapper.find('EuiFilterButton')).toBeTruthy();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,84 +5,58 @@
* 2.0.
*/

import { EuiFilterButton, EuiFilterGroup } from '@elastic/eui';
import { rgba } from 'polished';
import React, { useCallback, useState } from 'react';
import styled from 'styled-components';
import { EuiButtonGroup, EuiButtonGroupOptionProps } from '@elastic/eui';
import React, { useCallback } from 'react';
import { Status } from '../../../../../common/detection_engine/schemas/common/schemas';
import * as i18n from '../translations';

export const FILTER_OPEN: Status = 'open';
export const FILTER_CLOSED: Status = 'closed';
export const FILTER_IN_PROGRESS: Status = 'in-progress';

const StatusFilterButton = styled(EuiFilterButton)<{ $isActive: boolean }>`
background: ${({ $isActive, theme }) => ($isActive ? theme.eui.euiColorPrimary : '')};
`;

const StatusFilterGroup = styled(EuiFilterGroup)`
background: ${({ theme }) => rgba(theme.eui.euiColorPrimary, 0.2)};
.euiButtonEmpty--ghost:enabled:focus {
background-color: ${({ theme }) => theme.eui.euiColorPrimary};
}
`;
export const FILTER_ACKNOWLEDGED: Status = 'acknowledged';

interface Props {
status: Status;
onFilterGroupChanged: (filterGroup: Status) => void;
}

const AlertsTableFilterGroupComponent: React.FC<Props> = ({ onFilterGroupChanged }) => {
const [filterGroup, setFilterGroup] = useState<Status>(FILTER_OPEN);

const onClickOpenFilterCallback = useCallback(() => {
setFilterGroup(FILTER_OPEN);
onFilterGroupChanged(FILTER_OPEN);
}, [setFilterGroup, onFilterGroupChanged]);

const onClickCloseFilterCallback = useCallback(() => {
setFilterGroup(FILTER_CLOSED);
onFilterGroupChanged(FILTER_CLOSED);
}, [setFilterGroup, onFilterGroupChanged]);

const onClickInProgressFilterCallback = useCallback(() => {
setFilterGroup(FILTER_IN_PROGRESS);
onFilterGroupChanged(FILTER_IN_PROGRESS);
}, [setFilterGroup, onFilterGroupChanged]);
const AlertsTableFilterGroupComponent: React.FC<Props> = ({
status = FILTER_OPEN,
onFilterGroupChanged,
}) => {
const options: EuiButtonGroupOptionProps[] = [
{
id: 'open',
label: i18n.OPEN_ALERTS,
'data-test-subj': 'openAlerts',
},
{
id: 'acknowledged',
label: i18n.ACKNOWLEDGED_ALERTS,
'data-test-subj': 'acknowledgedAlerts',
},
{
id: 'closed',
label: i18n.CLOSED_ALERTS,
'data-test-subj': 'closedAlerts',
},
];

const onChange = useCallback(
(id: string) => {
onFilterGroupChanged(id as Status);
},
[onFilterGroupChanged]
);

return (
<StatusFilterGroup data-test-subj="alerts-table-filter-group">
<StatusFilterButton
data-test-subj="openAlerts"
hasActiveFilters={filterGroup === FILTER_OPEN}
$isActive={filterGroup === FILTER_OPEN}
onClick={onClickOpenFilterCallback}
withNext
color={filterGroup === FILTER_OPEN ? 'ghost' : 'primary'}
>
{i18n.OPEN_ALERTS}
</StatusFilterButton>

<StatusFilterButton
data-test-subj="inProgressAlerts"
hasActiveFilters={filterGroup === FILTER_IN_PROGRESS}
$isActive={filterGroup === FILTER_IN_PROGRESS}
onClick={onClickInProgressFilterCallback}
withNext
color={filterGroup === FILTER_IN_PROGRESS ? 'ghost' : 'primary'}
>
{i18n.IN_PROGRESS_ALERTS}
</StatusFilterButton>

<StatusFilterButton
data-test-subj="closedAlerts"
hasActiveFilters={filterGroup === FILTER_CLOSED}
$isActive={filterGroup === FILTER_CLOSED}
onClick={onClickCloseFilterCallback}
color={filterGroup === FILTER_CLOSED ? 'ghost' : 'primary'}
>
{i18n.CLOSED_ALERTS}
</StatusFilterButton>
</StatusFilterGroup>
<EuiButtonGroup
legend="filter status"
color="primary"
options={options}
idSelected={status}
data-test-subj="alerts-table-filter-group"
onChange={onChange}
/>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import * as i18n from './translations';
import { useUiSetting$ } from '../../../../common/lib/kibana';
import { TimelineNonEcsData } from '../../../../../common/search_strategy/timeline';
import { UpdateAlertsStatus } from '../types';
import { FILTER_CLOSED, FILTER_IN_PROGRESS, FILTER_OPEN } from '../alerts_filter_group';
import { FILTER_CLOSED, FILTER_ACKNOWLEDGED, FILTER_OPEN } from '../alerts_filter_group';

export interface AlertsUtilityBarProps {
areEventsLoading: boolean;
Expand Down Expand Up @@ -126,18 +126,18 @@ const AlertsUtilityBarComponent: React.FC<AlertsUtilityBarProps> = ({
</EuiFlexItem>
)}

{currentFilter !== FILTER_IN_PROGRESS && (
{currentFilter !== FILTER_ACKNOWLEDGED && (
<EuiFlexItem>
<Link
aria-label="markSelectedAlertsInProgress"
aria-label="markSelectedAlertsAcknowledged"
onClick={() => {
closePopover();
handleUpdateStatus('in-progress');
handleUpdateStatus('acknowledged');
}}
color="text"
data-test-subj="markSelectedAlertsInProgressButton"
data-test-subj="markSelectedAlertsAcknowledgedButton"
>
{i18n.BATCH_ACTION_IN_PROGRESS_SELECTED}
{i18n.BATCH_ACTION_ACKNOWLEDGED_SELECTED}
</Link>
</EuiFlexItem>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ export const BATCH_ACTION_CLOSE_SELECTED = i18n.translate(
}
);

export const BATCH_ACTION_IN_PROGRESS_SELECTED = i18n.translate(
'xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.inProgressSelectedTitle',
export const BATCH_ACTION_ACKNOWLEDGED_SELECTED = i18n.translate(
'xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.acknowledgedSelectedTitle',
{
defaultMessage: 'Mark in progress',
defaultMessage: 'Mark as acknowledged',
}
);
Loading