From 55feb39ad047a2cbfb499953e93ef1aa4ebf5f45 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Thu, 2 Mar 2023 17:18:39 -0500 Subject: [PATCH] adds flyout validation and edit workflow tests --- .../src/exception_item_card/meta/index.tsx | 2 +- .../add_edit_flyout/flyout_validation.cy.ts | 24 +++++++++++++++++++ .../add_edit_exception.cy.ts | 6 +++++ .../cypress/objects/exception.ts | 1 + .../cypress/screens/exceptions.ts | 6 +++++ .../cypress/tasks/api_calls/exceptions.ts | 1 + .../cypress/tasks/exceptions.ts | 20 ++++++++++++++++ .../flyout_components/expire_time/index.tsx | 8 ++++++- 8 files changed, 66 insertions(+), 2 deletions(-) diff --git a/packages/kbn-securitysolution-exception-list-components/src/exception_item_card/meta/index.tsx b/packages/kbn-securitysolution-exception-list-components/src/exception_item_card/meta/index.tsx index 2fffe08b5b091..7f2cab0920007 100644 --- a/packages/kbn-securitysolution-exception-list-components/src/exception_item_card/meta/index.tsx +++ b/packages/kbn-securitysolution-exception-list-components/src/exception_item_card/meta/index.tsx @@ -85,7 +85,7 @@ export const ExceptionItemCardMetaInfo = memo( {item.expire_time != null && ( <> - + { closeExceptionBuilderFlyout(); }); + it('Validates expire time field correctly', () => { + // open add exception modal + openExceptionFlyoutFromEmptyViewerPrompt(); + + // add exception item name + addExceptionFlyoutItemName('My item name'); + + // add an entry with a value and submit button should enable + addExceptionEntryFieldValue('agent.name', 0); + addExceptionEntryFieldValueValue('test', 0); + + // set an expiration date in the past + editExceptionFlyoutExpireTime(new Date(Date.now() - 1000000).toISOString()); + cy.get(CONFIRM_BTN).should('be.disabled'); + + // set an expiration date in the future + editExceptionFlyoutExpireTime(new Date(Date.now() + 1000000).toISOString()); + cy.get(CONFIRM_BTN).should('be.enabled'); + + closeExceptionBuilderFlyout(); + }); + // TODO - Add back in error states into modal describe.skip('flyout errors', () => { beforeEach(() => { @@ -341,6 +364,7 @@ describe('Exceptions flyout', () => { value: ['some host', 'another host'], }, ], + expire_time: undefined, }); reload(); diff --git a/x-pack/plugins/security_solution/cypress/e2e/exceptions/rule_details_flow/add_edit_exception.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/exceptions/rule_details_flow/add_edit_exception.cy.ts index 1439e5ed88210..66a98faf10403 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/exceptions/rule_details_flow/add_edit_exception.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/exceptions/rule_details_flow/add_edit_exception.cy.ts @@ -34,6 +34,7 @@ import { import { addExceptionConditions, addExceptionFlyoutItemName, + clearExceptionFlyoutExpireTime, editException, editExceptionFlyoutItemName, selectAddToRuleRadio, @@ -56,6 +57,7 @@ import { EXCEPTION_CARD_ITEM_NAME, EXCEPTION_CARD_ITEM_CONDITIONS, FIELD_INPUT_PARENT, + EXCEPTION_CARD_ITEM_META_INFO, } from '../../../screens/exceptions'; import { createExceptionList, @@ -118,6 +120,7 @@ describe('Add/edit exception from rule details', () => { value: ['foo'], }, ], + expire_time: new Date(Date.now() + 1000000).toISOString(), }); }); @@ -135,6 +138,7 @@ describe('Add/edit exception from rule details', () => { cy.get(NO_EXCEPTIONS_EXIST_PROMPT).should('not.exist'); cy.get(EXCEPTION_CARD_ITEM_NAME).should('have.text', ITEM_NAME); cy.get(EXCEPTION_CARD_ITEM_CONDITIONS).should('have.text', ' unique_value.testis one of foo'); + cy.get(EXCEPTION_CARD_ITEM_META_INFO).should('exist'); // open edit exception modal openEditException(); @@ -152,6 +156,7 @@ describe('Add/edit exception from rule details', () => { // edit conditions editException(FIELD_DIFFERENT_FROM_EXISTING_ITEM_FIELD, 0, 0); + clearExceptionFlyoutExpireTime(); // submit submitEditedExceptionItem(); @@ -162,6 +167,7 @@ describe('Add/edit exception from rule details', () => { // check that updates stuck cy.get(EXCEPTION_CARD_ITEM_NAME).should('have.text', NEW_ITEM_NAME); cy.get(EXCEPTION_CARD_ITEM_CONDITIONS).should('have.text', ' agent.nameIS foo'); + cy.get(EXCEPTION_CARD_ITEM_META_INFO).should('not.exist'); }); describe('rule with existing shared exceptions', () => { diff --git a/x-pack/plugins/security_solution/cypress/objects/exception.ts b/x-pack/plugins/security_solution/cypress/objects/exception.ts index 8427d828b6eea..5c76a0d033bcb 100644 --- a/x-pack/plugins/security_solution/cypress/objects/exception.ts +++ b/x-pack/plugins/security_solution/cypress/objects/exception.ts @@ -31,6 +31,7 @@ export interface ExceptionListItem { tags: string[]; type: 'simple'; entries: Array<{ field: string; operator: string; type: string; value: string[] }>; + expire_time: string | undefined; } export const getExceptionList = (): ExceptionList => ({ diff --git a/x-pack/plugins/security_solution/cypress/screens/exceptions.ts b/x-pack/plugins/security_solution/cypress/screens/exceptions.ts index b15c23d59cf0e..f87076145b168 100644 --- a/x-pack/plugins/security_solution/cypress/screens/exceptions.ts +++ b/x-pack/plugins/security_solution/cypress/screens/exceptions.ts @@ -99,6 +99,9 @@ export const EXCEPTION_CARD_ITEM_NAME = '[data-test-subj="exceptionItemCardHeade export const EXCEPTION_CARD_ITEM_CONDITIONS = '[data-test-subj="exceptionItemCardConditions-condition"]'; +export const EXCEPTION_CARD_ITEM_META_INFO = + '[data-test-subj="exceptionItemCardMetaInfo-expireTime-value1"]'; + // Exception flyout components export const EXCEPTION_ITEM_NAME_INPUT = 'input[data-test-subj="exceptionFlyoutNameInput"]'; @@ -123,3 +126,6 @@ export const MANAGE_EXCEPTION_CREATE_BUTTON_EXCEPTION = '[data-test-subj="manageExceptionListCreateExceptionButton"]'; export const RULE_ACTION_LINK_RULE_SWITCH = '[data-test-subj="ruleActionLinkRuleSwitch"]'; + +export const EXCEPTION_ITEM_EXPIRE_TIME_INPUT = + '[data-test-subj="exceptionExpireTimeInputRow"] input.euiDatePicker'; diff --git a/x-pack/plugins/security_solution/cypress/tasks/api_calls/exceptions.ts b/x-pack/plugins/security_solution/cypress/tasks/api_calls/exceptions.ts index fd070cfcda55e..d245d57050991 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/api_calls/exceptions.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/api_calls/exceptions.ts @@ -59,6 +59,7 @@ export const createExceptionListItem = ( value: ['some host', 'another host'], }, ], + expire_time: exceptionListItem?.expire_time, }, headers: { 'kbn-xsrf': 'cypress-creds' }, failOnStatusCode: false, diff --git a/x-pack/plugins/security_solution/cypress/tasks/exceptions.ts b/x-pack/plugins/security_solution/cypress/tasks/exceptions.ts index 78fdd20ea882b..3b03c38955d24 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/exceptions.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/exceptions.ts @@ -5,6 +5,7 @@ * 2.0. */ +import moment from 'moment'; import type { Exception } from '../objects/exception'; import { FIELD_INPUT, @@ -24,6 +25,7 @@ import { SHARED_LIST_SWITCH, OS_SELECTION_SECTION, OS_INPUT, + EXCEPTION_ITEM_EXPIRE_TIME_INPUT, } from '../screens/exceptions'; export const addExceptionEntryFieldValueOfItemX = ( @@ -93,6 +95,24 @@ export const editExceptionFlyoutItemName = (name: string) => { .should('have.value', name); }; +export const editExceptionFlyoutExpireTime = (date: string) => { + const formattedDate = moment(new Date(date).toISOString()).format('MM DD YYYY hh:mm a'); + cy.root() + .pipe(($el) => { + return $el.find(EXCEPTION_ITEM_EXPIRE_TIME_INPUT); + }) + .clear() + .type(`${formattedDate}{enter}`); +}; + +export const clearExceptionFlyoutExpireTime = () => { + cy.root() + .pipe(($el) => { + return $el.find(EXCEPTION_ITEM_EXPIRE_TIME_INPUT); + }) + .clear(); +}; + export const selectBulkCloseAlerts = () => { cy.get(CLOSE_ALERTS_CHECKBOX).should('exist'); cy.get(CLOSE_ALERTS_CHECKBOX).click({ force: true }); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/expire_time/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/expire_time/index.tsx index 1f71c7a2fe51c..4f89ac415a382 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/expire_time/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/expire_time/index.tsx @@ -56,8 +56,14 @@ const ExceptionItemExpireTime: React.FC = ({

{i18n.EXCEPTION_EXPIRE_TIME_HEADER}

- +