Skip to content

Commit

Permalink
[Security Solution] Adds Cypress test for index action in detection r…
Browse files Browse the repository at this point in the history
…ules (#141069)

Co-authored-by: Dmitrii Shevchenko <[email protected]>
Co-authored-by: Kibana Machine <[email protected]>
  • Loading branch information
3 people authored Sep 29, 2022
1 parent b2ab340 commit db6a825
Show file tree
Hide file tree
Showing 17 changed files with 533 additions and 196 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
*/

import { formatMitreAttackDescription } from '../../helpers/rules';
import type { Mitre } from '../../objects/rule';
import {
getNewRule,
getExistingRule,
getIndexPatterns,
getEditedRule,
getNewOverrideRule,
} from '../../objects/rule';
import type { CompleteTimeline } from '../../objects/timeline';
import { ALERT_GRID_CELL, NUMBER_OF_ALERTS } from '../../screens/alerts';

import {
Expand Down Expand Up @@ -46,6 +48,7 @@ import {
FROM_VALIDATION_ERROR,
EMAIL_ACTION_TO_INPUT,
EMAIL_ACTION_SUBJECT_INPUT,
SCHEDULE_CONTINUE_BUTTON,
} from '../../screens/create_new_rule';
import {
ADDITIONAL_LOOK_BACK_DETAILS,
Expand Down Expand Up @@ -87,7 +90,7 @@ import {
createAndEnableRule,
fillAboutRule,
fillAboutRuleAndContinue,
fillDefineCustomRuleWithImportedQueryAndContinue,
fillDefineCustomRuleAndContinue,
fillEmailConnectorForm,
fillScheduleRuleAndContinue,
goToAboutStepTab,
Expand All @@ -108,19 +111,21 @@ describe('Custom query rules', () => {
login();
});
describe('Custom detection rules creation', () => {
const expectedUrls = getNewRule().referenceUrls.join('');
const expectedFalsePositives = getNewRule().falsePositivesExamples.join('');
const expectedTags = getNewRule().tags.join('');
const expectedMitre = formatMitreAttackDescription(getNewRule().mitre);
const expectedUrls = getNewRule().referenceUrls?.join('');
const expectedFalsePositives = getNewRule().falsePositivesExamples?.join('');
const expectedTags = getNewRule().tags?.join('');
const mitreAttack = getNewRule().mitre as Mitre[];
const expectedMitre = formatMitreAttackDescription(mitreAttack);
const expectedNumberOfRules = 1;

beforeEach(() => {
const timeline = getNewRule().timeline as CompleteTimeline;
deleteAlertsAndRules();
createTimeline(getNewRule().timeline).then((response) => {
createTimeline(timeline).then((response) => {
cy.wrap({
...getNewRule(),
timeline: {
...getNewRule().timeline,
...timeline,
id: response.body.data.persistTimeline.timeline.savedObjectId,
},
}).as('rule');
Expand All @@ -129,7 +134,7 @@ describe('Custom query rules', () => {

it('Creates and enables a new rule', function () {
visit(RULE_CREATION);
fillDefineCustomRuleWithImportedQueryAndContinue(this.rule);
fillDefineCustomRuleAndContinue(this.rule);
fillAboutRuleAndContinue(this.rule);
fillScheduleRuleAndContinue(this.rule);

Expand All @@ -144,6 +149,7 @@ describe('Custom query rules', () => {
cy.get(RULE_NAME_INPUT).invoke('val').should('eql', this.rule.name);
cy.get(ABOUT_CONTINUE_BTN).should('exist').click({ force: true });
cy.get(ABOUT_CONTINUE_BTN).should('not.exist');
cy.get(SCHEDULE_CONTINUE_BUTTON).click({ force: true });

createAndEnableRule();

Expand Down Expand Up @@ -182,11 +188,11 @@ describe('Custom query rules', () => {
cy.get(SCHEDULE_DETAILS).within(() => {
getDetails(RUNS_EVERY_DETAILS).should(
'have.text',
`${getNewRule().runsEvery.interval}${getNewRule().runsEvery.type}`
`${getNewRule().runsEvery?.interval}${getNewRule().runsEvery?.type}`
);
getDetails(ADDITIONAL_LOOK_BACK_DETAILS).should(
'have.text',
`${getNewRule().lookBack.interval}${getNewRule().lookBack.type}`
`${getNewRule().lookBack?.interval}${getNewRule().lookBack?.type}`
);
});

Expand Down Expand Up @@ -299,7 +305,7 @@ describe('Custom query rules', () => {

context('Edition', () => {
const rule = getEditedRule();
const expectedEditedtags = rule.tags.join('');
const expectedEditedtags = rule.tags?.join('');
const expectedEditedIndexPatterns =
rule.dataSource.type === 'indexPatterns' &&
rule.dataSource.index &&
Expand Down Expand Up @@ -349,7 +355,7 @@ describe('Custom query rules', () => {
// expect about step to populate
cy.get(RULE_NAME_INPUT).invoke('val').should('eql', existingRule.name);
cy.get(RULE_DESCRIPTION_INPUT).should('have.text', existingRule.description);
cy.get(TAGS_FIELD).should('have.text', existingRule.tags.join(''));
cy.get(TAGS_FIELD).should('have.text', existingRule.tags?.join(''));
cy.get(SEVERITY_DROPDOWN).should('have.text', existingRule.severity);
cy.get(DEFAULT_RISK_SCORE_INPUT).invoke('val').should('eql', existingRule.riskScore);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
*/

import { formatMitreAttackDescription } from '../../helpers/rules';
import type { Mitre } from '../../objects/rule';
import { getDataViewRule } from '../../objects/rule';
import type { CompleteTimeline } from '../../objects/timeline';
import { ALERT_GRID_CELL, NUMBER_OF_ALERTS } from '../../screens/alerts';

import {
Expand Down Expand Up @@ -50,7 +52,7 @@ import { postDataView } from '../../tasks/common';
import {
createAndEnableRule,
fillAboutRuleAndContinue,
fillDefineCustomRuleWithImportedQueryAndContinue,
fillDefineCustomRuleAndContinue,
fillScheduleRuleAndContinue,
waitForAlertsToPopulate,
waitForTheRuleToBeExecuted,
Expand All @@ -69,23 +71,25 @@ describe('Custom query rules', () => {

describe('Custom detection rules creation with data views', () => {
const rule = getDataViewRule();
const expectedUrls = rule.referenceUrls.join('');
const expectedFalsePositives = rule.falsePositivesExamples.join('');
const expectedTags = rule.tags.join('');
const expectedMitre = formatMitreAttackDescription(rule.mitre);
const expectedUrls = rule.referenceUrls?.join('');
const expectedFalsePositives = rule.falsePositivesExamples?.join('');
const expectedTags = rule.tags?.join('');
const mitreAttack = rule.mitre as Mitre[];
const expectedMitre = formatMitreAttackDescription(mitreAttack);
const expectedNumberOfRules = 1;

beforeEach(() => {
/* We don't call cleanKibana method on the before hook, instead we call esArchiverReseKibana on the before each. This is because we
are creating a data view we'll use after and cleanKibana does not delete all the data views created, esArchiverReseKibana does.
We don't use esArchiverReseKibana in all the tests because is a time-consuming method and we don't need to perform an exhaustive
cleaning in all the other tests. */
const timeline = rule.timeline as CompleteTimeline;
esArchiverResetKibana();
createTimeline(rule.timeline).then((response) => {
createTimeline(timeline).then((response) => {
cy.wrap({
...rule,
timeline: {
...rule.timeline,
...timeline,
id: response.body.data.persistTimeline.timeline.savedObjectId,
},
}).as('rule');
Expand All @@ -97,7 +101,7 @@ describe('Custom query rules', () => {

it('Creates and enables a new rule', function () {
visit(RULE_CREATION);
fillDefineCustomRuleWithImportedQueryAndContinue(this.rule);
fillDefineCustomRuleAndContinue(this.rule);
fillAboutRuleAndContinue(this.rule);
fillScheduleRuleAndContinue(this.rule);
createAndEnableRule();
Expand Down Expand Up @@ -138,11 +142,11 @@ describe('Custom query rules', () => {
cy.get(SCHEDULE_DETAILS).within(() => {
getDetails(RUNS_EVERY_DETAILS).should(
'have.text',
`${getDataViewRule().runsEvery.interval}${getDataViewRule().runsEvery.type}`
`${getDataViewRule().runsEvery?.interval}${getDataViewRule().runsEvery?.type}`
);
getDetails(ADDITIONAL_LOOK_BACK_DETAILS).should(
'have.text',
`${getDataViewRule().lookBack.interval}${getDataViewRule().lookBack.type}`
`${getDataViewRule().lookBack?.interval}${getDataViewRule().lookBack?.type}`
);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { getDetails } from '../../tasks/rule_details';
import { createSavedQueryRule, createCustomRule } from '../../tasks/api_calls/rules';

import { RULE_CREATION, SECURITY_DETECTIONS_RULES_URL } from '../../urls/navigation';
import type { CompleteTimeline } from '../../objects/timeline';

const savedQueryName = 'custom saved query';
const savedQueryQuery = 'process.name: test';
Expand All @@ -56,11 +57,12 @@ describe('Custom saved_query rules', () => {
beforeEach(() => {
deleteAlertsAndRules();
deleteSavedQueries();
createTimeline(getNewRule().timeline).then((response) => {
const timeline = getNewRule().timeline as CompleteTimeline;
createTimeline(timeline).then((response) => {
cy.wrap({
...getNewRule(),
timeline: {
...getNewRule().timeline,
...timeline,
id: response.body.data.persistTimeline.timeline.savedObjectId,
},
}).as('rule');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

import { formatMitreAttackDescription } from '../../helpers/rules';
import type { Mitre } from '../../objects/rule';
import { getEqlRule, getEqlSequenceRule, getIndexPatterns } from '../../objects/rule';

import { ALERT_DATA_GRID, NUMBER_OF_ALERTS } from '../../screens/alerts';
Expand Down Expand Up @@ -59,6 +60,7 @@ import { login, visit } from '../../tasks/login';

import { RULE_CREATION } from '../../urls/navigation';
import { esArchiverLoad, esArchiverUnload } from '../../tasks/es_archiver';
import type { CompleteTimeline } from '../../objects/timeline';

describe('EQL rules', () => {
before(() => {
Expand All @@ -67,19 +69,21 @@ describe('EQL rules', () => {
deleteAlertsAndRules();
});
describe('Detection rules, EQL', () => {
const expectedUrls = getEqlRule().referenceUrls.join('');
const expectedFalsePositives = getEqlRule().falsePositivesExamples.join('');
const expectedTags = getEqlRule().tags.join('');
const expectedMitre = formatMitreAttackDescription(getEqlRule().mitre);
const expectedUrls = getEqlRule().referenceUrls?.join('');
const expectedFalsePositives = getEqlRule().falsePositivesExamples?.join('');
const expectedTags = getEqlRule().tags?.join('');
const mitreAttack = getEqlRule().mitre as Mitre[];
const expectedMitre = formatMitreAttackDescription(mitreAttack);
const expectedNumberOfRules = 1;
const expectedNumberOfAlerts = '2 alerts';

beforeEach(() => {
createTimeline(getEqlRule().timeline).then((response) => {
const timeline = getEqlRule().timeline as CompleteTimeline;
createTimeline(timeline).then((response) => {
cy.wrap({
...getEqlRule(),
timeline: {
...getEqlRule().timeline,
...timeline,
id: response.body.data.persistTimeline.timeline.savedObjectId,
},
}).as('rule');
Expand Down Expand Up @@ -161,11 +165,12 @@ describe('EQL rules', () => {
esArchiverLoad('auditbeat_big');
});
beforeEach(() => {
createTimeline(getEqlSequenceRule().timeline).then((response) => {
const timeline = getEqlSequenceRule().timeline as CompleteTimeline;
createTimeline(timeline).then((response) => {
cy.wrap({
...getEqlSequenceRule(),
timeline: {
...getEqlSequenceRule().timeline,
...timeline,
id: response.body.data.persistTimeline.timeline.savedObjectId,
},
}).as('rule');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

import { formatMitreAttackDescription } from '../../helpers/rules';
import type { Mitre } from '../../objects/rule';
import {
getIndexPatterns,
getNewThreatIndicatorRule,
Expand Down Expand Up @@ -109,10 +110,11 @@ const DEFAULT_THREAT_MATCH_QUERY = '@timestamp >= "now-30d/d"';

describe('indicator match', () => {
describe('Detection rules, Indicator Match', () => {
const expectedUrls = getNewThreatIndicatorRule().referenceUrls.join('');
const expectedFalsePositives = getNewThreatIndicatorRule().falsePositivesExamples.join('');
const expectedTags = getNewThreatIndicatorRule().tags.join('');
const expectedMitre = formatMitreAttackDescription(getNewThreatIndicatorRule().mitre);
const expectedUrls = getNewThreatIndicatorRule().referenceUrls?.join('');
const expectedFalsePositives = getNewThreatIndicatorRule().falsePositivesExamples?.join('');
const expectedTags = getNewThreatIndicatorRule().tags?.join('');
const mitreAttack = getNewThreatIndicatorRule().mitre as Mitre[];
const expectedMitre = formatMitreAttackDescription(mitreAttack);
const expectedNumberOfRules = 1;
const expectedNumberOfAlerts = '1 alert';

Expand Down Expand Up @@ -479,11 +481,11 @@ describe('indicator match', () => {
cy.get(SCHEDULE_DETAILS).within(() => {
getDetails(RUNS_EVERY_DETAILS).should(
'have.text',
`${rule.runsEvery.interval}${rule.runsEvery.type}`
`${rule.runsEvery?.interval}${rule.runsEvery?.type}`
);
getDetails(ADDITIONAL_LOOK_BACK_DETAILS).should(
'have.text',
`${rule.lookBack.interval}${rule.lookBack.type}`
`${rule.lookBack?.interval}${rule.lookBack?.type}`
);
});

Expand All @@ -492,7 +494,7 @@ describe('indicator match', () => {

cy.get(NUMBER_OF_ALERTS).should('have.text', expectedNumberOfAlerts);
cy.get(ALERT_RULE_NAME).first().should('have.text', rule.name);
cy.get(ALERT_SEVERITY).first().should('have.text', rule.severity.toLowerCase());
cy.get(ALERT_SEVERITY).first().should('have.text', rule.severity?.toLowerCase());
cy.get(ALERT_RISK_SCORE).first().should('have.text', rule.riskScore);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

import { formatMitreAttackDescription } from '../../helpers/rules';
import type { Mitre } from '../../objects/rule';
import { getNewTermsRule, getIndexPatterns } from '../../objects/rule';

import { ALERT_DATA_GRID } from '../../screens/alerts';
Expand Down Expand Up @@ -60,26 +61,29 @@ import {
import { login, visit } from '../../tasks/login';

import { RULE_CREATION } from '../../urls/navigation';
import type { CompleteTimeline } from '../../objects/timeline';

describe('New Terms rules', () => {
before(() => {
cleanKibana();
login();
});
describe('Detection rules, New Terms', () => {
const expectedUrls = getNewTermsRule().referenceUrls.join('');
const expectedFalsePositives = getNewTermsRule().falsePositivesExamples.join('');
const expectedTags = getNewTermsRule().tags.join('');
const expectedMitre = formatMitreAttackDescription(getNewTermsRule().mitre);
const expectedUrls = getNewTermsRule().referenceUrls?.join('');
const expectedFalsePositives = getNewTermsRule().falsePositivesExamples?.join('');
const expectedTags = getNewTermsRule().tags?.join('');
const mitreAttack = getNewTermsRule().mitre as Mitre[];
const expectedMitre = formatMitreAttackDescription(mitreAttack);
const expectedNumberOfRules = 1;

beforeEach(() => {
const timeline = getNewTermsRule().timeline as CompleteTimeline;
deleteAlertsAndRules();
createTimeline(getNewTermsRule().timeline).then((response) => {
createTimeline(timeline).then((response) => {
cy.wrap({
...getNewTermsRule(),
timeline: {
...getNewTermsRule().timeline,
...timeline,
id: response.body.data.persistTimeline.timeline.savedObjectId,
},
}).as('rule');
Expand Down
Loading

0 comments on commit db6a825

Please sign in to comment.