Skip to content

Commit

Permalink
[Security Solution] Adds prebuilt rule customization cypress tests (e…
Browse files Browse the repository at this point in the history
…lastic#212170)

**Partially addresses:** elastic#202068

## Summary

Adds tests in accordance to
elastic#204888

Follow-up to elastic#207016

Adds cypress tests for the prebuilt rule customization features

### Checklist

Check the PR satisfies following conditions.

Reviewers should verify this PR satisfies this list as well.

- [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
- [x] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed
- [x] 🟢 ESS x50:
https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/7925
- [x] 🟢 Serverless x50:
https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/7926

(cherry picked from commit ca6cc75)
  • Loading branch information
dplumlee committed Feb 24, 2025
1 parent 4552bd4 commit 5d99d03
Show file tree
Hide file tree
Showing 7 changed files with 388 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,9 @@ export const CustomizedPrebuiltRuleBadge: React.FC<CustomizedPrebuiltRuleBadgePr
return null;
}

return <EuiBadge color="hollow">{i18n.MODIFIED_PREBUILT_RULE_LABEL}</EuiBadge>;
return (
<EuiBadge data-test-subj="modified-prebuilt-rule-badge" color="hollow">
{i18n.MODIFIED_PREBUILT_RULE_LABEL}
</EuiBadge>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,348 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { clickRuleUpdatesTab } from '../../../../tasks/prebuilt_rules';
import {
clickUpdateScheduleMenuItem,
openBulkEditAddIndexPatternsForm,
openBulkEditAddInvestigationFieldsForm,
openBulkEditAddTagsForm,
openBulkEditDeleteIndexPatternsForm,
openBulkEditDeleteInvestigationFieldsForm,
openBulkEditDeleteTagsForm,
setScheduleIntervalTimeUnit,
setScheduleLookbackTimeUnit,
submitBulkEditForm,
typeIndexPatterns,
typeInvestigationFields,
typeScheduleInterval,
typeScheduleLookback,
typeTags,
waitForBulkEditActionToFinish,
} from '../../../../tasks/rules_bulk_actions';
import {
ABOUT_EDIT_TAB,
ACTIONS_EDIT_TAB,
DEFINITION_EDIT_TAB,
SCHEDULE_EDIT_TAB,
} from '../../../../screens/create_new_rule';
import { ABOUT_RULE_DESCRIPTION } from '../../../../screens/rule_details';
import { goToRuleEditSettings } from '../../../../tasks/rule_details';
import { getIndexPatterns, getNewRule } from '../../../../objects/rule';
import {
editFirstRule,
expectModifiedBadgeToBeDisplayed,
expectModifiedBadgeToNotBeDisplayed,
expectToContainModifiedBadge,
expectToNotContainModifiedBadge,
filterByCustomRules,
filterByElasticRules,
selectAllRules,
} from '../../../../tasks/alerts_detection_rules';
import { MODIFIED_RULE_BADGE, RULE_NAME } from '../../../../screens/alerts_detection_rules';
import { createRuleAssetSavedObject } from '../../../../helpers/rules';
import {
deleteAlertsAndRules,
deletePrebuiltRulesAssets,
} from '../../../../tasks/api_calls/common';
import {
createAndInstallMockedPrebuiltRules,
installPrebuiltRuleAssets,
preventPrebuiltRulesPackageInstallation,
} from '../../../../tasks/api_calls/prebuilt_rules';
import { createRule, patchRule } from '../../../../tasks/api_calls/rules';

import { login } from '../../../../tasks/login';

import { visitRulesManagementTable } from '../../../../tasks/rules_management';
import { fillDescription, goToAboutStepTab } from '../../../../tasks/create_new_rule';
import { saveEditedRule } from '../../../../tasks/edit_rule';
describe(
'Detection rules, Prebuilt Rules Customization workflow',
{
tags: ['@ess', '@serverless', '@skipInServerlessMKI'],
env: {
ftrConfig: {
kbnServerArgs: [
`--xpack.securitySolution.enableExperimental=${JSON.stringify([
'prebuiltRulesCustomizationEnabled',
])}`,
],
},
},
},

() => {
describe('Customizing prebuilt rules', () => {
const testTags = ['tag 1', 'tag 2'];
const PREBUILT_RULE = createRuleAssetSavedObject({
name: 'Non-customized prebuilt rule',
rule_id: 'rule_1',
version: 1,
index: getIndexPatterns(),
tags: testTags,
investigation_fields: { field_names: ['source.ip'] },
});

beforeEach(() => {
login();
deleteAlertsAndRules();
deletePrebuiltRulesAssets();
preventPrebuiltRulesPackageInstallation();
/* Create a new rule and install it */
createAndInstallMockedPrebuiltRules([PREBUILT_RULE]);
visitRulesManagementTable();
createRule(
getNewRule({
name: 'Custom rule',
index: getIndexPatterns(),
tags: testTags,
enabled: false,
})
);
});

it('user can navigate to rule editing page from the rule details page', function () {
cy.get(RULE_NAME).contains('Non-customized prebuilt rule').click();

goToRuleEditSettings();
cy.get(DEFINITION_EDIT_TAB).should('be.enabled');
cy.get(ABOUT_EDIT_TAB).should('be.enabled');
cy.get(SCHEDULE_EDIT_TAB).should('be.enabled');
cy.get(ACTIONS_EDIT_TAB).should('be.enabled');
});

it('user can edit a non-customized prebuilt rule from the rule edit page', function () {
const newDescriptionValue = 'New rule description';
cy.get(RULE_NAME).contains('Non-customized prebuilt rule').click();

goToRuleEditSettings();
goToAboutStepTab();
fillDescription(newDescriptionValue);
saveEditedRule();

expectModifiedBadgeToBeDisplayed();
cy.get(ABOUT_RULE_DESCRIPTION).should('have.text', newDescriptionValue);
});

it('user can edit a customized prebuilt rule from the rule edit page', function () {
const newDescriptionValue = 'New rule description';
patchRule('rule_1', { name: 'Customized prebuilt rule' }); // We want to make this a customized prebuilt rule
visitRulesManagementTable();

cy.get(RULE_NAME).contains('Customized prebuilt rule').click();
expectModifiedBadgeToBeDisplayed(); // Expect modified badge to already be displayed

goToRuleEditSettings();
goToAboutStepTab();
fillDescription(newDescriptionValue);
saveEditedRule();

expectModifiedBadgeToBeDisplayed();
cy.get(ABOUT_RULE_DESCRIPTION).should('have.text', newDescriptionValue);
});

it('user can navigate to rule editing page from the rule management page', function () {
filterByElasticRules();
editFirstRule();

cy.get(DEFINITION_EDIT_TAB).should('be.enabled');
cy.get(ABOUT_EDIT_TAB).should('be.enabled');
cy.get(SCHEDULE_EDIT_TAB).should('be.enabled');
cy.get(ACTIONS_EDIT_TAB).should('be.enabled');
});

describe('user can bulk edit prebuilt rules from rules management page', () => {
it('add index patterns', () => {
filterByElasticRules();
selectAllRules();

openBulkEditAddIndexPatternsForm();
typeIndexPatterns(['test-pattern']);
submitBulkEditForm();

waitForBulkEditActionToFinish({
updatedCount: 1,
});

expectToContainModifiedBadge('Non-customized prebuilt rule');
});

it('delete index patterns', () => {
filterByElasticRules();
selectAllRules();

openBulkEditDeleteIndexPatternsForm();
typeIndexPatterns([getIndexPatterns()[0]]);
submitBulkEditForm();

waitForBulkEditActionToFinish({
updatedCount: 1,
});

expectToContainModifiedBadge('Non-customized prebuilt rule');
});

it('add tags', () => {
filterByElasticRules();
selectAllRules();

openBulkEditAddTagsForm();
typeTags(['custom-tag']);
submitBulkEditForm();

waitForBulkEditActionToFinish({
updatedCount: 1,
});

expectToContainModifiedBadge('Non-customized prebuilt rule');
});

it('delete tags', () => {
filterByElasticRules();
selectAllRules();

openBulkEditDeleteTagsForm();
typeTags([testTags[0]]);
submitBulkEditForm();

waitForBulkEditActionToFinish({
updatedCount: 1,
});

expectToContainModifiedBadge('Non-customized prebuilt rule');
});

it('add custom highlighted fields', () => {
filterByElasticRules();
selectAllRules();

openBulkEditAddInvestigationFieldsForm();
typeInvestigationFields(['host.name']);
submitBulkEditForm();

waitForBulkEditActionToFinish({
updatedCount: 1,
});

expectToContainModifiedBadge('Non-customized prebuilt rule');
});

it('delete custom highlighted fields', () => {
filterByElasticRules();
selectAllRules();

openBulkEditDeleteInvestigationFieldsForm();
typeInvestigationFields(['source.ip']);
submitBulkEditForm();

waitForBulkEditActionToFinish({
updatedCount: 1,
});

expectToContainModifiedBadge('Non-customized prebuilt rule');
});

it('modify rule schedules', () => {
filterByElasticRules();
selectAllRules();

clickUpdateScheduleMenuItem();

typeScheduleInterval('20');
setScheduleIntervalTimeUnit('Hours');

typeScheduleLookback('10');
setScheduleLookbackTimeUnit('Minutes');

submitBulkEditForm();

waitForBulkEditActionToFinish({
updatedCount: 1,
});

expectToContainModifiedBadge('Non-customized prebuilt rule');
});
});

describe('calculating the Modified badge', () => {
it('modified badge should appear on the rule details page when prebuilt rule is customized', function () {
patchRule('rule_1', { name: 'Customized prebuilt rule' }); // We want to make this a customized prebuilt rule
visitRulesManagementTable();

cy.get(RULE_NAME).contains('Customized prebuilt rule').click();
expectModifiedBadgeToBeDisplayed(); // Expect modified badge to be displayed
});

it("modified badge should not appear on the rule details page when prebuilt rule isn't customized", function () {
visitRulesManagementTable();

cy.get(RULE_NAME).contains('Non-customized prebuilt rule').click();
expectModifiedBadgeToNotBeDisplayed(); // Expect modified badge to not be displayed
});

it("modified badge should not appear on a custom rule's rule details page", function () {
visitRulesManagementTable();

cy.get(RULE_NAME).contains('Custom rule').click();
expectModifiedBadgeToNotBeDisplayed(); // Expect modified badge to not be displayed
});

it('modified badge should appear on the rule management table when prebuilt rule is modified', function () {
patchRule('rule_1', { name: 'Customized prebuilt rule' }); // We want to make this a customized prebuilt rule
visitRulesManagementTable();

filterByElasticRules();
expectToContainModifiedBadge('Customized prebuilt rule');
});

it("modified badge should not appear on the rule management table when prebuilt rule isn't customized", function () {
visitRulesManagementTable();

filterByElasticRules();
expectToNotContainModifiedBadge('Non-customized prebuilt rule');
});

it('modified badge should not appear on the rule management table when row is a custom rule', function () {
visitRulesManagementTable();

filterByCustomRules();
expectToNotContainModifiedBadge('Custom rule');
});

it('modified badge should appear on the rule updates table when prebuilt rule is customized', function () {
// Create a new version of the rule to trigger the rule update logic
installPrebuiltRuleAssets([
{
...PREBUILT_RULE,
'security-rule': { ...PREBUILT_RULE['security-rule'], version: 2 },
},
]);
patchRule('rule_1', { name: 'Customized prebuilt rule' }); // We want to make this a customized prebuilt rule
visitRulesManagementTable();
clickRuleUpdatesTab();

cy.get(MODIFIED_RULE_BADGE).should('exist');
});

it("Modified badge should not appear on the rule updates table when prebuilt rule isn't customized", function () {
// Create a new version of the rule to trigger the rule update logic
installPrebuiltRuleAssets([
{
...PREBUILT_RULE,
'security-rule': { ...PREBUILT_RULE['security-rule'], version: 2 },
},
]);
visitRulesManagementTable();
clickRuleUpdatesTab();

cy.get(MODIFIED_RULE_BADGE).should('not.exist');
});
});
});
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -351,3 +351,5 @@ export const PER_FIELD_DIFF_WRAPPER = '[data-test-subj="ruleUpgradePerFieldDiffW
export const PER_FIELD_DIFF_DEFINITION_SECTION = '[data-test-subj="perFieldDiffDefinitionSection"]';

export const MODIFIED_RULE_BADGE = '[data-test-subj="upgradeRulesTableModifiedColumnBadge"]';

export const RULES_TABLE_MODIFIED_RULE_BADGE = '[data-test-subj="rulesTableModifiedColumnBadge"]';
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ export const ABOUT_CONTINUE_BTN = '[data-test-subj="about-continue"]';

export const ABOUT_EDIT_BUTTON = '[data-test-subj="edit-about-rule"]';

export const DEFINITION_EDIT_TAB = '[data-test-subj="edit-rule-define-tab"]';

export const ABOUT_EDIT_TAB = '[data-test-subj="edit-rule-about-tab"]';

export const ACTIONS_EDIT_TAB = '[data-test-subj="edit-rule-actions-tab"]';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,3 +201,5 @@ export const RULE_GAPS_FILL_TOOLTIP = '[data-test-subj="rule-gaps-fill-gap-toolt
export const RULE_GAPS_PROGRESS_BAR = '[data-test-subj="rule-gaps-progress-bar"]';
export const RULE_GAPS_DATE_PICKER = '[data-test-subj="rule-gaps-date-picker"]';
export const RULE_GAPS_DATE_PICKER_APPLY_REFRESH = `${RULE_GAPS_DATE_PICKER} .euiSuperUpdateButton`;

export const MODIFIED_PREBUILT_RULE_BADGE = '[data-test-subj="modified-prebuilt-rule-badge"]';
Loading

0 comments on commit 5d99d03

Please sign in to comment.