[SIEM] Adds 'Deleting prebuilt rules' tests (#61328) (#61434)

* implements 'Deleting prebuilt rules' tests

* refactors code

* extracts the number of prebuilt riles to a constant that can be used in any test
This commit is contained in:
MadameSheema 2020-03-26 16:32:17 +01:00 committed by GitHub
parent b9e6ed44c4
commit 902871ec3e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 177 additions and 14 deletions

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { newRule } from '../objects/rule';
import { newRule, totalNumberOfPrebuiltRules } from '../objects/rule';
import {
ABOUT_FALSE_POSITIVES,
@ -83,7 +83,7 @@ describe('Signal detection rules, custom', () => {
changeToThreeHundredRowsPerPage();
waitForRulesToBeLoaded();
const expectedNumberOfRules = 93;
const expectedNumberOfRules = totalNumberOfPrebuiltRules + 1;
cy.get(RULES_TABLE).then($table => {
cy.wrap($table.find(RULES_ROW).length).should('eql', expectedNumberOfRules);
});

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { machineLearningRule } from '../objects/rule';
import { machineLearningRule, totalNumberOfPrebuiltRules } from '../objects/rule';
import {
ABOUT_FALSE_POSITIVES,
@ -88,7 +88,7 @@ describe('Signal detection rules, machine learning', () => {
changeToThreeHundredRowsPerPage();
waitForRulesToBeLoaded();
const expectedNumberOfRules = 93;
const expectedNumberOfRules = totalNumberOfPrebuiltRules + 1;
cy.get(RULES_TABLE).then($table => {
cy.wrap($table.find(RULES_ROW).length).should('eql', expectedNumberOfRules);
});

View file

@ -4,11 +4,21 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { ELASTIC_RULES_BTN, RULES_ROW, RULES_TABLE } from '../screens/signal_detection_rules';
import {
COLLAPSED_ACTION_BTN,
ELASTIC_RULES_BTN,
RELOAD_PREBUILT_RULES_BTN,
RULES_ROW,
RULES_TABLE,
} from '../screens/signal_detection_rules';
import {
changeToThreeHundredRowsPerPage,
deleteFirstRule,
deleteSelectedRules,
loadPrebuiltDetectionRules,
reloadDeletedRules,
selectNumberOfRules,
waitForLoadElasticPrebuiltDetectionRulesTableToBeLoaded,
waitForPrebuiltDetectionRulesToBeLoaded,
waitForRulesToBeLoaded,
@ -18,11 +28,18 @@ import {
waitForSignalsIndexToBeCreated,
waitForSignalsPanelToBeLoaded,
} from '../tasks/detections';
import { esArchiverLoadEmptyKibana, esArchiverUnloadEmptyKibana } from '../tasks/es_archiver';
import {
esArchiverLoad,
esArchiverLoadEmptyKibana,
esArchiverUnloadEmptyKibana,
esArchiverUnload,
} from '../tasks/es_archiver';
import { loginAndWaitForPageWithoutDateRange } from '../tasks/login';
import { DETECTIONS } from '../urls/navigation';
import { totalNumberOfPrebuiltRules } from '../objects/rule';
describe('Signal detection rules, prebuilt rules', () => {
before(() => {
esArchiverLoadEmptyKibana();
@ -33,6 +50,9 @@ describe('Signal detection rules, prebuilt rules', () => {
});
it('Loads prebuilt rules', () => {
const expectedNumberOfRules = totalNumberOfPrebuiltRules;
const expectedElasticRulesBtnText = `Elastic rules (${expectedNumberOfRules})`;
loginAndWaitForPageWithoutDateRange(DETECTIONS);
waitForSignalsPanelToBeLoaded();
waitForSignalsIndexToBeCreated();
@ -41,7 +61,6 @@ describe('Signal detection rules, prebuilt rules', () => {
loadPrebuiltDetectionRules();
waitForPrebuiltDetectionRulesToBeLoaded();
const expectedElasticRulesBtnText = 'Elastic rules (92)';
cy.get(ELASTIC_RULES_BTN)
.invoke('text')
.should('eql', expectedElasticRulesBtnText);
@ -49,9 +68,105 @@ describe('Signal detection rules, prebuilt rules', () => {
changeToThreeHundredRowsPerPage();
waitForRulesToBeLoaded();
const expectedNumberOfRules = 92;
cy.get(RULES_TABLE).then($table => {
cy.wrap($table.find(RULES_ROW).length).should('eql', expectedNumberOfRules);
});
});
});
describe('Deleting prebuilt rules', () => {
beforeEach(() => {
esArchiverLoad('prebuilt_rules_loaded');
loginAndWaitForPageWithoutDateRange(DETECTIONS);
waitForSignalsPanelToBeLoaded();
waitForSignalsIndexToBeCreated();
goToManageSignalDetectionRules();
});
afterEach(() => {
esArchiverUnload('prebuilt_rules_loaded');
});
it('Does not allow to delete one rule when more than one is selected', () => {
const numberOfRulesToBeSelected = 2;
selectNumberOfRules(numberOfRulesToBeSelected);
cy.get(COLLAPSED_ACTION_BTN).each(collapsedItemActionBtn => {
cy.wrap(collapsedItemActionBtn).should('have.attr', 'disabled');
});
});
it('Deletes and recovers one rule', () => {
const expectedNumberOfRulesAfterDeletion = totalNumberOfPrebuiltRules - 1;
const expectedNumberOfRulesAfterRecovering = totalNumberOfPrebuiltRules;
deleteFirstRule();
cy.reload();
changeToThreeHundredRowsPerPage();
waitForRulesToBeLoaded();
cy.get(ELASTIC_RULES_BTN)
.invoke('text')
.should('eql', `Elastic rules (${expectedNumberOfRulesAfterDeletion})`);
cy.get(RULES_TABLE).then($table => {
cy.wrap($table.find(RULES_ROW).length).should('eql', expectedNumberOfRulesAfterDeletion);
});
cy.get(RELOAD_PREBUILT_RULES_BTN).should('exist');
cy.get(RELOAD_PREBUILT_RULES_BTN)
.invoke('text')
.should('eql', 'Reload 1 deleted Elastic prebuilt rule ');
reloadDeletedRules();
cy.get(RELOAD_PREBUILT_RULES_BTN).should('not.exist');
cy.reload();
changeToThreeHundredRowsPerPage();
waitForRulesToBeLoaded();
cy.get(RULES_TABLE).then($table => {
cy.wrap($table.find(RULES_ROW).length).should('eql', expectedNumberOfRulesAfterRecovering);
});
cy.get(ELASTIC_RULES_BTN)
.invoke('text')
.should('eql', `Elastic rules (${expectedNumberOfRulesAfterRecovering})`);
});
it('Deletes and recovers more than one rule', () => {
const numberOfRulesToBeSelected = 2;
const expectedNumberOfRulesAfterDeletion = totalNumberOfPrebuiltRules - 2;
const expectedNumberOfRulesAfterRecovering = totalNumberOfPrebuiltRules;
selectNumberOfRules(numberOfRulesToBeSelected);
deleteSelectedRules();
cy.reload();
changeToThreeHundredRowsPerPage();
waitForRulesToBeLoaded();
cy.get(RELOAD_PREBUILT_RULES_BTN).should('exist');
cy.get(RELOAD_PREBUILT_RULES_BTN)
.invoke('text')
.should('eql', `Reload ${numberOfRulesToBeSelected} deleted Elastic prebuilt rules `);
cy.get(ELASTIC_RULES_BTN)
.invoke('text')
.should('eql', `Elastic rules (${expectedNumberOfRulesAfterDeletion})`);
cy.get(RULES_TABLE).then($table => {
cy.wrap($table.find(RULES_ROW).length).should('eql', expectedNumberOfRulesAfterDeletion);
});
reloadDeletedRules();
cy.get(RELOAD_PREBUILT_RULES_BTN).should('not.exist');
cy.reload();
changeToThreeHundredRowsPerPage();
waitForRulesToBeLoaded();
cy.get(RULES_TABLE).then($table => {
cy.wrap($table.find(RULES_ROW).length).should('eql', expectedNumberOfRulesAfterRecovering);
});
cy.get(ELASTIC_RULES_BTN)
.invoke('text')
.should('eql', `Elastic rules (${expectedNumberOfRulesAfterRecovering})`);
});
});

View file

@ -4,6 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
export const totalNumberOfPrebuiltRules = 92;
interface Mitre {
tactic: string;
techniques: string[];

View file

@ -4,10 +4,18 @@
* you may not use this file except in compliance with the Elastic License.
*/
export const BULK_ACTIONS_BTN = '[data-test-subj="bulkActions"] span';
export const CREATE_NEW_RULE_BTN = '[data-test-subj="create-new-rule"]';
export const COLLAPSED_ACTION_BTN = '[data-test-subj="euiCollapsedItemActionsButton"]';
export const CUSTOM_RULES_BTN = '[data-test-subj="show-custom-rules-filter-button"]';
export const DELETE_RULE_ACTION_BTN = '[data-test-subj="deleteRuleAction"]';
export const DELETE_RULE_BULK_BTN = '[data-test-subj="deleteRuleBulk"]';
export const ELASTIC_RULES_BTN = '[data-test-subj="show-elastic-rules-filter-button"]';
export const LOAD_PREBUILT_RULES_BTN = '[data-test-subj="load-prebuilt-rules"]';
@ -21,6 +29,10 @@ export const PAGINATION_POPOVER_BTN = '[data-test-subj="tablePaginationPopoverBu
export const RISK_SCORE = '[data-test-subj="riskScore"]';
export const RELOAD_PREBUILT_RULES_BTN = '[data-test-subj="reloadPrebuiltRulesBtn"]';
export const RULE_CHECKBOX = '.euiTableRow .euiCheckbox__input';
export const RULE_NAME = '[data-test-subj="ruleName"]';
export const RULE_SWITCH = '[data-test-subj="rule-switch"]';

View file

@ -5,13 +5,21 @@
*/
import {
BULK_ACTIONS_BTN,
COLLAPSED_ACTION_BTN,
CREATE_NEW_RULE_BTN,
CUSTOM_RULES_BTN,
DELETE_RULE_ACTION_BTN,
DELETE_RULE_BULK_BTN,
LOAD_PREBUILT_RULES_BTN,
LOADING_INITIAL_PREBUILT_RULES_TABLE,
LOADING_SPINNER,
PAGINATION_POPOVER_BTN,
RULE_CHECKBOX,
RULE_NAME,
RULES_TABLE,
THREE_HUNDRED_ROWS,
RELOAD_PREBUILT_RULES_BTN,
} from '../screens/signal_detection_rules';
export const changeToThreeHundredRowsPerPage = () => {
@ -19,10 +27,22 @@ export const changeToThreeHundredRowsPerPage = () => {
cy.get(THREE_HUNDRED_ROWS).click();
};
export const deleteFirstRule = () => {
cy.get(COLLAPSED_ACTION_BTN)
.first()
.click({ force: true });
cy.get(DELETE_RULE_ACTION_BTN).click();
};
export const deleteSelectedRules = () => {
cy.get(BULK_ACTIONS_BTN).click({ force: true });
cy.get(DELETE_RULE_BULK_BTN).click();
};
export const filterByCustomRules = () => {
cy.get('[data-test-subj="show-custom-rules-filter-button"]').click({ force: true });
cy.get('[data-test-subj="loading-spinner"]').should('exist');
cy.get('[data-test-subj="loading-spinner"]').should('not.exist');
cy.get(CUSTOM_RULES_BTN).click({ force: true });
cy.get(LOADING_SPINNER).should('exist');
cy.get(LOADING_SPINNER).should('not.exist');
};
export const goToCreateNewRule = () => {
@ -30,9 +50,7 @@ export const goToCreateNewRule = () => {
};
export const goToRuleDetails = () => {
cy.get('[data-test-subj="ruleName"]').click({ force: true });
cy.get('.euiLoadingSpinner').should('exist');
cy.get('.euiLoadingSpinner').should('not.exist');
cy.get(RULE_NAME).click({ force: true });
};
export const loadPrebuiltDetectionRules = () => {
@ -41,6 +59,18 @@ export const loadPrebuiltDetectionRules = () => {
.click({ force: true });
};
export const reloadDeletedRules = () => {
cy.get(RELOAD_PREBUILT_RULES_BTN).click({ force: true });
};
export const selectNumberOfRules = (numberOfRules: number) => {
for (let i = 0; i < numberOfRules; i++) {
cy.get(RULE_CHECKBOX)
.eq(i)
.click({ force: true });
}
};
export const waitForLoadElasticPrebuiltDetectionRulesTableToBeLoaded = () => {
cy.get(LOADING_INITIAL_PREBUILT_RULES_TABLE).should('exist');
cy.get(LOADING_INITIAL_PREBUILT_RULES_TABLE).should('not.exist');

View file

@ -108,6 +108,7 @@ export const getBatchItems = ({
{i18n.BATCH_ACTION_DUPLICATE_SELECTED}
</EuiContextMenuItem>,
<EuiContextMenuItem
data-test-subj="deleteRuleBulk"
key={i18n.BATCH_ACTION_DELETE_SELECTED}
icon="trash"
title={containsImmutable ? i18n.BATCH_ACTION_DELETE_SELECTED_IMMUTABLE : undefined}

View file

@ -70,6 +70,7 @@ export const getActions = (
enabled: (rowItem: Rule) => !rowItem.immutable,
},
{
'data-test-subj': 'deleteRuleAction',
description: i18n.DELETE_RULE,
type: 'icon',
icon: 'trash',

View file

@ -307,6 +307,7 @@ export const AllRules = React.memo<AllRulesProps>(
<UtilityBarText>{i18n.SELECTED_RULES(selectedRuleIds.length)}</UtilityBarText>
{!hasNoPermissions && (
<UtilityBarAction
dataTestSubj="bulkActions"
iconSide="right"
iconType="arrowDown"
popoverContent={getBatchItemsPopoverContent}

View file

@ -135,6 +135,7 @@ const RulesPageComponent: React.FC = () => {
{prePackagedRuleStatus === 'someRuleUninstall' && (
<EuiFlexItem grow={false}>
<EuiButton
data-test-subj="reloadPrebuiltRulesBtn"
iconType="plusInCircle"
isLoading={loadingCreatePrePackagedRules}
isDisabled={userHasNoPermissions || loading}