mirror of
https://github.com/elastic/kibana.git
synced 2025-04-25 02:09:32 -04:00
[Security Solution][Exceptions] - Fix stale linked rules count on manage rules save (#155108)
## Summary Addresses https://github.com/elastic/kibana/issues/153195
This commit is contained in:
parent
dd46350cac
commit
ada91f9a5e
7 changed files with 68 additions and 15 deletions
|
@ -14,7 +14,7 @@ import { login, visitWithoutDateRange, waitForPageWithoutDateRange } from '../..
|
||||||
|
|
||||||
import { EXCEPTIONS_URL } from '../../../urls/navigation';
|
import { EXCEPTIONS_URL } from '../../../urls/navigation';
|
||||||
import {
|
import {
|
||||||
deleteExceptionListWithRuleReference,
|
deleteExceptionListWithRuleReferenceByListId,
|
||||||
deleteExceptionListWithoutRuleReference,
|
deleteExceptionListWithoutRuleReference,
|
||||||
exportExceptionList,
|
exportExceptionList,
|
||||||
searchForExceptionList,
|
searchForExceptionList,
|
||||||
|
@ -79,7 +79,7 @@ describe('Exceptions Table', () => {
|
||||||
|
|
||||||
visitWithoutDateRange(EXCEPTIONS_URL);
|
visitWithoutDateRange(EXCEPTIONS_URL);
|
||||||
waitForExceptionsTableToBeLoaded();
|
waitForExceptionsTableToBeLoaded();
|
||||||
exportExceptionList();
|
exportExceptionList(getExceptionList1().list_id);
|
||||||
|
|
||||||
cy.wait('@export').then(({ response }) => {
|
cy.wait('@export').then(({ response }) => {
|
||||||
cy.wrap(response?.body).should(
|
cy.wrap(response?.body).should(
|
||||||
|
@ -168,7 +168,7 @@ describe('Exceptions Table', () => {
|
||||||
// just checking number of lists shown
|
// just checking number of lists shown
|
||||||
cy.contains(EXCEPTIONS_TABLE_SHOWING_LISTS, '2');
|
cy.contains(EXCEPTIONS_TABLE_SHOWING_LISTS, '2');
|
||||||
|
|
||||||
deleteExceptionListWithRuleReference();
|
deleteExceptionListWithRuleReferenceByListId(getExceptionList2().list_id);
|
||||||
|
|
||||||
// Using cy.contains because we do not care about the exact text,
|
// Using cy.contains because we do not care about the exact text,
|
||||||
// just checking number of lists shown
|
// just checking number of lists shown
|
||||||
|
|
|
@ -14,11 +14,13 @@ import { login, visitWithoutDateRange, waitForPageWithoutDateRange } from '../..
|
||||||
|
|
||||||
import { EXCEPTIONS_URL } from '../../../urls/navigation';
|
import { EXCEPTIONS_URL } from '../../../urls/navigation';
|
||||||
import {
|
import {
|
||||||
deleteExceptionListWithRuleReference,
|
deleteExceptionListWithRuleReferenceByListId,
|
||||||
deleteExceptionListWithoutRuleReference,
|
deleteExceptionListWithoutRuleReference,
|
||||||
exportExceptionList,
|
exportExceptionList,
|
||||||
waitForExceptionsTableToBeLoaded,
|
waitForExceptionsTableToBeLoaded,
|
||||||
createSharedExceptionList,
|
createSharedExceptionList,
|
||||||
|
linkRulesToExceptionList,
|
||||||
|
assertNumberLinkedRules,
|
||||||
} from '../../../tasks/exceptions_table';
|
} from '../../../tasks/exceptions_table';
|
||||||
import {
|
import {
|
||||||
EXCEPTIONS_LIST_MANAGEMENT_NAME,
|
EXCEPTIONS_LIST_MANAGEMENT_NAME,
|
||||||
|
@ -46,6 +48,8 @@ describe('Manage shared exception list', () => {
|
||||||
esArchiverResetKibana();
|
esArchiverResetKibana();
|
||||||
login();
|
login();
|
||||||
|
|
||||||
|
createRule(getNewRule({ name: 'Another rule' }));
|
||||||
|
|
||||||
// Create exception list associated with a rule
|
// Create exception list associated with a rule
|
||||||
createExceptionList(getExceptionList2(), getExceptionList2().list_id).then((response) =>
|
createExceptionList(getExceptionList2(), getExceptionList2().list_id).then((response) =>
|
||||||
createRule(
|
createRule(
|
||||||
|
@ -76,7 +80,7 @@ describe('Manage shared exception list', () => {
|
||||||
it('Export exception list', function () {
|
it('Export exception list', function () {
|
||||||
cy.intercept(/(\/api\/exception_lists\/_export)/).as('export');
|
cy.intercept(/(\/api\/exception_lists\/_export)/).as('export');
|
||||||
|
|
||||||
exportExceptionList();
|
exportExceptionList(getExceptionList1().list_id);
|
||||||
|
|
||||||
cy.wait('@export').then(({ response }) => {
|
cy.wait('@export').then(({ response }) => {
|
||||||
cy.wrap(response?.body).should(
|
cy.wrap(response?.body).should(
|
||||||
|
@ -91,6 +95,12 @@ describe('Manage shared exception list', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Link rules to shared exception list', function () {
|
||||||
|
assertNumberLinkedRules(getExceptionList2().list_id, '1');
|
||||||
|
linkRulesToExceptionList(getExceptionList2().list_id, 1);
|
||||||
|
assertNumberLinkedRules(getExceptionList2().list_id, '2');
|
||||||
|
});
|
||||||
|
|
||||||
it('Create exception list', function () {
|
it('Create exception list', function () {
|
||||||
createSharedExceptionList({ name: EXCEPTION_LIST_NAME, description: 'This is my list.' }, true);
|
createSharedExceptionList({ name: EXCEPTION_LIST_NAME, description: 'This is my list.' }, true);
|
||||||
|
|
||||||
|
@ -118,7 +128,7 @@ describe('Manage shared exception list', () => {
|
||||||
// just checking number of lists shown
|
// just checking number of lists shown
|
||||||
cy.contains(EXCEPTIONS_TABLE_SHOWING_LISTS, '3');
|
cy.contains(EXCEPTIONS_TABLE_SHOWING_LISTS, '3');
|
||||||
|
|
||||||
deleteExceptionListWithRuleReference();
|
deleteExceptionListWithRuleReferenceByListId(getExceptionList2().list_id);
|
||||||
|
|
||||||
// Using cy.contains because we do not care about the exact text,
|
// Using cy.contains because we do not care about the exact text,
|
||||||
// just checking number of lists shown
|
// just checking number of lists shown
|
||||||
|
|
|
@ -49,6 +49,9 @@ export const EXCEPTIONS_TABLE_SHOWING_LISTS = '[data-test-subj="showingException
|
||||||
export const EXCEPTIONS_TABLE_DELETE_BTN =
|
export const EXCEPTIONS_TABLE_DELETE_BTN =
|
||||||
'[data-test-subj="sharedListOverflowCardActionItemDelete"]';
|
'[data-test-subj="sharedListOverflowCardActionItemDelete"]';
|
||||||
|
|
||||||
|
export const EXCEPTIONS_TABLE_LINK_RULES_BTN =
|
||||||
|
'[data-test-subj="sharedListOverflowCardActionItemLinkRules"]';
|
||||||
|
|
||||||
export const EXCEPTIONS_TABLE_EXPORT_MODAL_BTN =
|
export const EXCEPTIONS_TABLE_EXPORT_MODAL_BTN =
|
||||||
'[data-test-subj="sharedListOverflowCardActionItemExport"]';
|
'[data-test-subj="sharedListOverflowCardActionItemExport"]';
|
||||||
|
|
||||||
|
@ -149,6 +152,13 @@ export const CREATE_SHARED_EXCEPTION_LIST_DESCRIPTION_INPUT =
|
||||||
export const CREATE_SHARED_EXCEPTION_LIST_BTN =
|
export const CREATE_SHARED_EXCEPTION_LIST_BTN =
|
||||||
'button[data-test-subj="exception-lists-form-create-shared"]';
|
'button[data-test-subj="exception-lists-form-create-shared"]';
|
||||||
|
|
||||||
|
export const exceptionsTableListManagementListContainerByListId = (listId: string) =>
|
||||||
|
`[data-test-subj="exceptionsManagementListCard-${listId}"]`;
|
||||||
|
|
||||||
|
export const LINKED_RULES_BADGE = '[data-test-subj="exceptionListCardLinkedRulesBadge"]';
|
||||||
|
|
||||||
|
export const MANAGE_RULES_SAVE = '[data-test-subj="manageListRulesSaveButton"]';
|
||||||
|
|
||||||
// Exception list management
|
// Exception list management
|
||||||
export const EXCEPTIONS_LIST_MANAGEMENT_NAME =
|
export const EXCEPTIONS_LIST_MANAGEMENT_NAME =
|
||||||
'[data-test-subj="exceptionListManagementTitleText"]';
|
'[data-test-subj="exceptionListManagementTitleText"]';
|
||||||
|
|
|
@ -26,6 +26,11 @@ import {
|
||||||
EXCEPTIONS_LIST_MANAGEMENT_EDIT_MODAL_DESCRIPTION_INPUT,
|
EXCEPTIONS_LIST_MANAGEMENT_EDIT_MODAL_DESCRIPTION_INPUT,
|
||||||
EXCEPTIONS_LIST_EDIT_DETAILS_SAVE_BTN,
|
EXCEPTIONS_LIST_EDIT_DETAILS_SAVE_BTN,
|
||||||
EXCEPTIONS_LIST_DETAILS_HEADER,
|
EXCEPTIONS_LIST_DETAILS_HEADER,
|
||||||
|
exceptionsTableListManagementListContainerByListId,
|
||||||
|
EXCEPTIONS_TABLE_LINK_RULES_BTN,
|
||||||
|
RULE_ACTION_LINK_RULE_SWITCH,
|
||||||
|
LINKED_RULES_BADGE,
|
||||||
|
MANAGE_RULES_SAVE,
|
||||||
} from '../screens/exceptions';
|
} from '../screens/exceptions';
|
||||||
|
|
||||||
export const clearSearchSelection = () => {
|
export const clearSearchSelection = () => {
|
||||||
|
@ -36,12 +41,30 @@ export const expandExceptionActions = () => {
|
||||||
cy.get(EXCEPTIONS_OVERFLOW_ACTIONS_BTN).first().click();
|
cy.get(EXCEPTIONS_OVERFLOW_ACTIONS_BTN).first().click();
|
||||||
};
|
};
|
||||||
|
|
||||||
export const exportExceptionList = () => {
|
export const exportExceptionList = (listId: string) => {
|
||||||
cy.get(EXCEPTIONS_OVERFLOW_ACTIONS_BTN).first().click();
|
cy.get(exceptionsTableListManagementListContainerByListId(listId))
|
||||||
|
.find(EXCEPTIONS_OVERFLOW_ACTIONS_BTN)
|
||||||
|
.click();
|
||||||
cy.get(EXCEPTIONS_TABLE_EXPORT_MODAL_BTN).first().click();
|
cy.get(EXCEPTIONS_TABLE_EXPORT_MODAL_BTN).first().click();
|
||||||
cy.get(EXCEPTIONS_TABLE_EXPORT_CONFIRM_BTN).first().click();
|
cy.get(EXCEPTIONS_TABLE_EXPORT_CONFIRM_BTN).first().click();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const assertNumberLinkedRules = (listId: string, numberOfRulesAsString: string) => {
|
||||||
|
cy.get(exceptionsTableListManagementListContainerByListId(listId))
|
||||||
|
.find(LINKED_RULES_BADGE)
|
||||||
|
.contains(numberOfRulesAsString);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const linkRulesToExceptionList = (listId: string, ruleSwitch: number = 0) => {
|
||||||
|
cy.log(`Open link rules flyout for list_id: '${listId}'`);
|
||||||
|
cy.get(exceptionsTableListManagementListContainerByListId(listId))
|
||||||
|
.find(EXCEPTIONS_OVERFLOW_ACTIONS_BTN)
|
||||||
|
.click();
|
||||||
|
cy.get(EXCEPTIONS_TABLE_LINK_RULES_BTN).first().click();
|
||||||
|
cy.get(RULE_ACTION_LINK_RULE_SWITCH).eq(ruleSwitch).find('button').click();
|
||||||
|
cy.get(MANAGE_RULES_SAVE).first().click();
|
||||||
|
};
|
||||||
|
|
||||||
export const deleteExceptionListWithoutRuleReference = () => {
|
export const deleteExceptionListWithoutRuleReference = () => {
|
||||||
cy.get(EXCEPTIONS_OVERFLOW_ACTIONS_BTN).first().click();
|
cy.get(EXCEPTIONS_OVERFLOW_ACTIONS_BTN).first().click();
|
||||||
cy.get(EXCEPTIONS_TABLE_DELETE_BTN).first().click();
|
cy.get(EXCEPTIONS_TABLE_DELETE_BTN).first().click();
|
||||||
|
@ -50,8 +73,10 @@ export const deleteExceptionListWithoutRuleReference = () => {
|
||||||
cy.get(EXCEPTIONS_TABLE_MODAL).should('not.exist');
|
cy.get(EXCEPTIONS_TABLE_MODAL).should('not.exist');
|
||||||
};
|
};
|
||||||
|
|
||||||
export const deleteExceptionListWithRuleReference = () => {
|
export const deleteExceptionListWithRuleReferenceByListId = (listId: string) => {
|
||||||
cy.get(EXCEPTIONS_OVERFLOW_ACTIONS_BTN).last().click();
|
cy.get(exceptionsTableListManagementListContainerByListId(listId))
|
||||||
|
.find(EXCEPTIONS_OVERFLOW_ACTIONS_BTN)
|
||||||
|
.click();
|
||||||
cy.get(EXCEPTIONS_TABLE_DELETE_BTN).last().click();
|
cy.get(EXCEPTIONS_TABLE_DELETE_BTN).last().click();
|
||||||
cy.get(EXCEPTIONS_TABLE_MODAL).should('exist');
|
cy.get(EXCEPTIONS_TABLE_MODAL).should('exist');
|
||||||
cy.get(EXCEPTIONS_TABLE_MODAL_CONFIRM_BTN).first().click();
|
cy.get(EXCEPTIONS_TABLE_MODAL_CONFIRM_BTN).first().click();
|
||||||
|
|
|
@ -102,7 +102,6 @@ export const ExceptionsListCard = memo<ExceptionsListCardProps>(
|
||||||
toggleAccordion,
|
toggleAccordion,
|
||||||
openAccordionId,
|
openAccordionId,
|
||||||
menuActionItems,
|
menuActionItems,
|
||||||
listRulesCount,
|
|
||||||
listDescription,
|
listDescription,
|
||||||
exceptionItemsCount,
|
exceptionItemsCount,
|
||||||
onEditExceptionItem,
|
onEditExceptionItem,
|
||||||
|
@ -184,8 +183,11 @@ export const ExceptionsListCard = memo<ExceptionsListCardProps>(
|
||||||
<EuiFlexItem>
|
<EuiFlexItem>
|
||||||
<TitleBadge title={i18n.EXCEPTIONS} badgeString={exceptionItemsCount} />
|
<TitleBadge title={i18n.EXCEPTIONS} badgeString={exceptionItemsCount} />
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
<EuiFlexItem>
|
<EuiFlexItem data-test-subj="exceptionListCardLinkedRulesBadge">
|
||||||
<TitleBadge title={i18n.RULES} badgeString={listRulesCount} />
|
<TitleBadge
|
||||||
|
title={i18n.RULES}
|
||||||
|
badgeString={linkedRules.length.toString()}
|
||||||
|
/>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
<EuiFlexItem>
|
<EuiFlexItem>
|
||||||
<HeaderMenu
|
<HeaderMenu
|
||||||
|
@ -199,6 +201,7 @@ export const ExceptionsListCard = memo<ExceptionsListCardProps>(
|
||||||
</ListHeaderContainer>
|
</ListHeaderContainer>
|
||||||
</EuiPanel>
|
</EuiPanel>
|
||||||
}
|
}
|
||||||
|
data-test-subj={`exceptionsManagementListCard-${listId}`}
|
||||||
>
|
>
|
||||||
<ExceptionPanel hasBorder>
|
<ExceptionPanel hasBorder>
|
||||||
<ListExceptionItems
|
<ListExceptionItems
|
||||||
|
|
|
@ -77,6 +77,7 @@ export const ManageRules: FC<ManageRulesProps> = memo(
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
<EuiFlexItem grow={false}>
|
<EuiFlexItem grow={false}>
|
||||||
<EuiButton
|
<EuiButton
|
||||||
|
data-test-subj="manageListRulesSaveButton"
|
||||||
isLoading={showButtonLoader}
|
isLoading={showButtonLoader}
|
||||||
disabled={saveIsDisabled}
|
disabled={saveIsDisabled}
|
||||||
onClick={onSave}
|
onClick={onSave}
|
||||||
|
|
|
@ -340,6 +340,9 @@ export const useListDetailsView = (exceptionListId: string) => {
|
||||||
i18n.EXCEPTION_MANAGE_RULES_ERROR_DESCRIPTION
|
i18n.EXCEPTION_MANAGE_RULES_ERROR_DESCRIPTION
|
||||||
);
|
);
|
||||||
setShowManageButtonLoader(false);
|
setShowManageButtonLoader(false);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
initializeList();
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
handleErrorStatus(err);
|
handleErrorStatus(err);
|
||||||
|
@ -348,10 +351,11 @@ export const useListDetailsView = (exceptionListId: string) => {
|
||||||
list,
|
list,
|
||||||
getRulesToAdd,
|
getRulesToAdd,
|
||||||
getRulesToRemove,
|
getRulesToRemove,
|
||||||
exceptionListId,
|
|
||||||
resetManageRulesAfterSaving,
|
resetManageRulesAfterSaving,
|
||||||
handleErrorStatus,
|
exceptionListId,
|
||||||
invalidateFetchRuleByIdQuery,
|
invalidateFetchRuleByIdQuery,
|
||||||
|
handleErrorStatus,
|
||||||
|
initializeList,
|
||||||
]);
|
]);
|
||||||
const onCancelManageRules = useCallback(() => {
|
const onCancelManageRules = useCallback(() => {
|
||||||
setShowManageRulesFlyout(false);
|
setShowManageRulesFlyout(false);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue