diff --git a/cypress/integration/1_detectors.spec.js b/cypress/integration/1_detectors.spec.js index 3d0ff2f0e..871941c82 100644 --- a/cypress/integration/1_detectors.spec.js +++ b/cypress/integration/1_detectors.spec.js @@ -6,6 +6,7 @@ import { OPENSEARCH_DASHBOARDS_URL } from '../support/constants'; import sample_index_settings from '../fixtures/sample_index_settings.json'; import dns_rule_data from '../fixtures/integration_tests/rule/create_dns_rule.json'; +import sample_dns_settings from '../fixtures/integration_tests/index/create_dns_settings.json'; const testMappings = { properties: { @@ -16,7 +17,7 @@ const testMappings = { }, }; -const cypressDNSRule = 'Cypress DNS Rule'; +const cypressDNSRule = dns_rule_data.title; describe('Detectors', () => { const indexName = 'cypress-test-dns'; @@ -24,6 +25,7 @@ describe('Detectors', () => { before(() => { cy.cleanUpTests(); + // Create test index cy.createIndex(indexName, sample_index_settings).then(() => cy @@ -41,8 +43,6 @@ describe('Detectors', () => { ); cy.createRule(dns_rule_data); - - cy.contains(detectorName).should('not.exist'); }); beforeEach(() => { @@ -57,6 +57,39 @@ describe('Detectors', () => { }); }); + it('...should show mappings warning', () => { + const indexName = 'cypress-index-windows'; + const dnsName = 'cypress-index-dns'; + cy.createIndex(indexName, sample_index_settings); + cy.createIndex(dnsName, sample_dns_settings); + + // Locate Create detector button click to start + cy.get('.euiButton').filter(':contains("Create detector")').click({ force: true }); + + // Check to ensure process started + cy.waitForPageLoad('create-detector', { + contains: 'Define detector', + }); + + // Select our pre-seeded data source (check indexName) + cy.get(`[data-test-subj="define-detector-select-data-source"]`) + .find('input') + .focus() + .realType(indexName); + + // Select threat detector type (Windows logs) + cy.get(`input[id="dns"]`).click({ force: true }); + + // Select our pre-seeded data source (check indexName) + cy.get(`[data-test-subj="define-detector-select-data-source"]`) + .find('input') + .focus() + .realType(dnsName) + .realPress('Enter'); + + cy.get('.euiCallOut').should('be.visible').contains('Detector configuration warning'); + }); + it('...can be created', () => { // Locate Create detector button click to start cy.get('.euiButton').filter(':contains("Create detector")').click({ force: true }); diff --git a/public/pages/CreateDetector/components/ConfigureFieldMapping/components/RequiredFieldMapping/FieldMappingsTable.tsx b/public/pages/CreateDetector/components/ConfigureFieldMapping/components/RequiredFieldMapping/FieldMappingsTable.tsx index 1a255ffbd..094dfc8c0 100644 --- a/public/pages/CreateDetector/components/ConfigureFieldMapping/components/RequiredFieldMapping/FieldMappingsTable.tsx +++ b/public/pages/CreateDetector/components/ConfigureFieldMapping/components/RequiredFieldMapping/FieldMappingsTable.tsx @@ -12,6 +12,7 @@ import { EuiIcon, EuiInMemoryTable, EuiText, + EuiToolTip, } from '@elastic/eui'; import { DEFAULT_EMPTY_DATA } from '../../../../../../utils/constants'; import { STATUS_ICON_PROPS } from '../../utils/constants'; @@ -140,14 +141,22 @@ export default class FieldMappingsTable extends Compo const { existingMappings: createdMappings, invalidMappingFieldNames } = this.props .mappingProps as MappingProps[MappingViewType.Edit]; let iconProps = STATUS_ICON_PROPS['unmapped']; + let iconTooltip = 'This field needs to be mapped with a field from your log source.'; if ( createdMappings[entry.ruleFieldName] && !invalidMappingFieldNames.includes(entry.ruleFieldName) ) { iconProps = STATUS_ICON_PROPS['mapped']; + iconTooltip = 'This field has been mapped.'; } - return || DEFAULT_EMPTY_DATA; + return ( + ( + + + + ) || DEFAULT_EMPTY_DATA + ); }, }); } diff --git a/public/pages/CreateDetector/components/DefineDetector/components/DetectorDataSource/DetectorDataSource.tsx b/public/pages/CreateDetector/components/DefineDetector/components/DetectorDataSource/DetectorDataSource.tsx index f0bbd221e..5592501cc 100644 --- a/public/pages/CreateDetector/components/DefineDetector/components/DetectorDataSource/DetectorDataSource.tsx +++ b/public/pages/CreateDetector/components/DefineDetector/components/DetectorDataSource/DetectorDataSource.tsx @@ -101,7 +101,6 @@ export default class DetectorDataSource extends Component< error={isInvalid && (errorMessage || 'Select an input source.')} > diff --git a/public/pages/CreateDetector/components/DefineDetector/containers/DefineDetector.tsx b/public/pages/CreateDetector/components/DefineDetector/containers/DefineDetector.tsx index 858e68250..49dded57d 100644 --- a/public/pages/CreateDetector/components/DefineDetector/containers/DefineDetector.tsx +++ b/public/pages/CreateDetector/components/DefineDetector/containers/DefineDetector.tsx @@ -5,13 +5,13 @@ import React, { Component } from 'react'; import { RouteComponentProps } from 'react-router-dom'; -import { EuiSpacer, EuiTitle, EuiText } from '@elastic/eui'; +import { EuiSpacer, EuiTitle, EuiText, EuiCallOut, EuiTextColor } from '@elastic/eui'; import { Detector, PeriodSchedule } from '../../../../../../models/interfaces'; import DetectorBasicDetailsForm from '../components/DetectorDetails'; import DetectorDataSource from '../components/DetectorDataSource'; import DetectorType from '../components/DetectorType'; import { EuiComboBoxOptionOption } from '@opensearch-project/oui'; -import { IndexService } from '../../../../../services'; +import { FieldMappingService, IndexService } from '../../../../../services'; import { MIN_NUM_DATA_SOURCES } from '../../../../Detectors/utils/constants'; import { DetectorCreationStep } from '../../../models/types'; import { DetectorSchedule } from '../components/DetectorSchedule/DetectorSchedule'; @@ -21,11 +21,13 @@ import { DetectionRules, } from '../components/DetectionRules/DetectionRules'; import { NotificationsStart } from 'opensearch-dashboards/public'; +import _ from 'lodash'; interface DefineDetectorProps extends RouteComponentProps { detector: Detector; isEdit: boolean; indexService: IndexService; + filedMappingService: FieldMappingService; rulesState: CreateDetectorRulesState; notifications: NotificationsStart; loadingRules?: boolean; @@ -36,16 +38,66 @@ interface DefineDetectorProps extends RouteComponentProps { onAllRulesToggle: (enabled: boolean) => void; } -interface DefineDetectorState {} +interface DefineDetectorState { + message: string[]; +} export default class DefineDetector extends Component { - updateDetectorCreationState(detector: Detector) { - const isDataValid = + state = { + message: [], + }; + + private indicesMappings: any = {}; + + async updateDetectorCreationState(detector: Detector) { + let isDataValid = !!detector.name && !!detector.detector_type && detector.inputs[0].detector_input.indices.length >= MIN_NUM_DATA_SOURCES && !!detector.schedule.period.interval; this.props.changeDetector(detector); + + const allIndices = detector.inputs[0].detector_input.indices; + for (let indexName in this.indicesMappings) { + if (allIndices.indexOf(indexName) === -1) { + // cleanup removed indexes + delete this.indicesMappings[indexName]; + } + } + + for (const indexName of allIndices) { + if (!this.indicesMappings[indexName]) { + const detectorType = this.props.detector.detector_type.toLowerCase(); + const result = await this.props.filedMappingService.getMappingsView( + indexName, + detectorType + ); + result.ok && (this.indicesMappings[indexName] = result.response.unmapped_field_aliases); + } + } + + if (!_.isEmpty(this.indicesMappings)) { + let firstMapping: string[] = []; + let firstMatchMappingIndex: string = ''; + let message: string[] = []; + for (let indexName in this.indicesMappings) { + if (this.indicesMappings.hasOwnProperty(indexName)) { + if (!firstMapping.length) firstMapping = this.indicesMappings[indexName]; + !firstMatchMappingIndex.length && (firstMatchMappingIndex = indexName); + if (!_.isEqual(firstMapping, this.indicesMappings[indexName])) { + message = [ + `The below log sources don't have the same fields, please consider creating separate detectors for them.`, + firstMatchMappingIndex, + indexName, + ]; + break; + } + } + } + + this.setState({ message }); + } + this.props.updateDataValidState(DetectorCreationStep.DEFINE_DETECTOR, isDataValid); } @@ -162,6 +214,7 @@ export default class DefineDetector extends Component + {message.length ? ( + <> + + {message.map((messageItem: string, index: number) => ( + + {messageItem} +
+
+ ))} +
+ + + ) : null} rule.enabled); - const options: CreateDetectorRulesOptions = enabledRules.map((rule) => ({ + return enabledRules.map((rule) => ({ id: rule._id, name: rule._source.title, severity: rule._source.level, tags: rule._source.tags.map((tag: { value: string }) => tag.value), })); - - return options; } async setupRulesState() { @@ -307,6 +305,7 @@ export default class CreateDetector extends Component () => { + return ; + } +); describe(' spec', () => { - it('renders the component', () => { - const view = render(); - expect(view).toMatchSnapshot(); + it('renders the component', async () => { + let wrapper; + await act(async () => { + UpdateAlertConditions.contextType = React.createContext(contextServicesMock); + wrapper = await mount(); + }); + wrapper.update(); + expect(wrapper).toMatchSnapshot(); }); }); diff --git a/public/pages/Detectors/components/UpdateAlertConditions/__snapshots__/UpdateAlertConditions.test.tsx.snap b/public/pages/Detectors/components/UpdateAlertConditions/__snapshots__/UpdateAlertConditions.test.tsx.snap index b8882eeb1..c991a985f 100644 --- a/public/pages/Detectors/components/UpdateAlertConditions/__snapshots__/UpdateAlertConditions.test.tsx.snap +++ b/public/pages/Detectors/components/UpdateAlertConditions/__snapshots__/UpdateAlertConditions.test.tsx.snap @@ -1,3634 +1,1153 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[` spec renders the component 1`] = ` -Object { - "asFragment": [Function], - "baseElement": -
-
-
-

- Edit alert triggers -

-
-
- Get notified when specific rule conditions are found by the detector. -
-
-
-
-
-
-
- -
- -
-
-
-
-
-
-
-
-
-
- -
-
-
-
- -
-
-
-
-
-
-

- If a detection rule matches -

-
-
-
-
- -
-
- -
-
-
-
- -
-
- -
-
-
-
- -
-
- -
-
-
-

- Alert and notify -

-
-
-
-
- -
-
- -
-
-
-
-
-
- -
-
- -
-
-
- -
-
-
-
-
- EuiIconMock - - Notifications plugin is not installed - -
-
-
-

- Install the notifications plugin in order to create and select channels to send out notifications.  - - Learn more - EuiIconMock - - . -

-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
- -
-
-
-
- -
-
-
-
-
-
-
-
- -
-
- -
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
- -
-
-
-
-
-
-
-
-
-
- -
-
-
-
- -
-
-
-
-
-
-

- If a detection rule matches -

-
-
-
-
- -
-
- -
-
-
-
- -
-
- -
-
-
-
- -
-
- -
-
-
-

- Alert and notify -

-
-
-
-
- -
-
- -
-
-
-
-
-
- -
-
- -
-
-
- -
-
-
-
-
- EuiIconMock - - Notifications plugin is not installed - -
-
-
-

- Install the notifications plugin in order to create and select channels to send out notifications.  - - Learn more - EuiIconMock - - . -

-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
- -
-
-
-
- -
-
-
-
-
-
-
-
- -
-
- -
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
- -
-
- -
-
-
-
- , - "container":
-
-
-

- Edit alert triggers -

-
+
+ + + + +
+
- Get notified when specific rule conditions are found by the detector. -
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- -
-
-
-
- -
-
-
-
-
-
-

- If a detection rule matches -

-
-
-
-
- -
-
- -
-
-
-
- -
-
- -
-
-
-
- -
-
- -
-
-
-

- Alert and notify -

-
-
-
-
- -
-
- -
-
-
-
-
-
- -
-
- -
-
-
- -
-
-
-
-
- EuiIconMock - - Notifications plugin is not installed - -
-
-
-

- Install the notifications plugin in order to create and select channels to send out notifications.  - - Learn more - EuiIconMock - - . -

-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
- -
-
-
-
- -
-
-
-
-
-
-
-
- -
-
- -
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
+ + + +
-
-
-
+ +
-
-
-
- -
-
-
-
-
-
-
-
-
-
- -
-
-
-
- -
-
-
-
-
-
-

- If a detection rule matches -

-
-
-
-
- -
-
- -
-
-
-
- -
-
- -
-
-
-
- -
-
- -
-
-
-

- Alert and notify -

-
-
-
-
- -
-
- -
-
-
-
-
-
- -
-
- -
-
-
- -
-
-
-
-
- EuiIconMock - - Notifications plugin is not installed - -
-
-
-

- Install the notifications plugin in order to create and select channels to send out notifications.  - - Learn more - EuiIconMock - - . -

-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
- -
-
-
-
- -
-
-
-
-
-
-
-
- -
-
- -
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
+ + + +
-
-
- -
-
-
- -
-
- -
+
-
-
, - "debug": [Function], - "findAllByAltText": [Function], - "findAllByDisplayValue": [Function], - "findAllByLabelText": [Function], - "findAllByPlaceholderText": [Function], - "findAllByRole": [Function], - "findAllByTestId": [Function], - "findAllByText": [Function], - "findAllByTitle": [Function], - "findByAltText": [Function], - "findByDisplayValue": [Function], - "findByLabelText": [Function], - "findByPlaceholderText": [Function], - "findByRole": [Function], - "findByTestId": [Function], - "findByText": [Function], - "findByTitle": [Function], - "getAllByAltText": [Function], - "getAllByDisplayValue": [Function], - "getAllByLabelText": [Function], - "getAllByPlaceholderText": [Function], - "getAllByRole": [Function], - "getAllByTestId": [Function], - "getAllByText": [Function], - "getAllByTitle": [Function], - "getByAltText": [Function], - "getByDisplayValue": [Function], - "getByLabelText": [Function], - "getByPlaceholderText": [Function], - "getByRole": [Function], - "getByTestId": [Function], - "getByText": [Function], - "getByTitle": [Function], - "queryAllByAltText": [Function], - "queryAllByDisplayValue": [Function], - "queryAllByLabelText": [Function], - "queryAllByPlaceholderText": [Function], - "queryAllByRole": [Function], - "queryAllByTestId": [Function], - "queryAllByText": [Function], - "queryAllByTitle": [Function], - "queryByAltText": [Function], - "queryByDisplayValue": [Function], - "queryByLabelText": [Function], - "queryByPlaceholderText": [Function], - "queryByRole": [Function], - "queryByTestId": [Function], - "queryByText": [Function], - "queryByTitle": [Function], - "rerender": [Function], - "unmount": [Function], -} + +
+ `; diff --git a/public/pages/Detectors/components/UpdateBasicDetails/UpdateDetectorBasicDetails.test.tsx b/public/pages/Detectors/components/UpdateBasicDetails/UpdateDetectorBasicDetails.test.tsx index 90269884e..004c3fa34 100644 --- a/public/pages/Detectors/components/UpdateBasicDetails/UpdateDetectorBasicDetails.test.tsx +++ b/public/pages/Detectors/components/UpdateBasicDetails/UpdateDetectorBasicDetails.test.tsx @@ -9,7 +9,12 @@ import { expect } from '@jest/globals'; import { UpdateDetectorBasicDetails } from './UpdateBasicDetails'; import { act } from 'react-dom/test-utils'; import { mount } from 'enzyme'; - +jest.mock( + '../../../CreateDetector/components/DefineDetector/components/DetectorDataSource/DetectorDataSource.tsx', + () => () => { + return ; + } +); describe(' spec', () => { it('renders the component', async () => { let wrapper; diff --git a/public/pages/Detectors/components/UpdateBasicDetails/__snapshots__/UpdateDetectorBasicDetails.test.tsx.snap b/public/pages/Detectors/components/UpdateBasicDetails/__snapshots__/UpdateDetectorBasicDetails.test.tsx.snap index 945386b73..5e033074f 100644 --- a/public/pages/Detectors/components/UpdateBasicDetails/__snapshots__/UpdateDetectorBasicDetails.test.tsx.snap +++ b/public/pages/Detectors/components/UpdateBasicDetails/__snapshots__/UpdateDetectorBasicDetails.test.tsx.snap @@ -188,7 +188,377 @@ exports[` spec renders the component 1`] = ` "location": Object { "pathname": "", }, - "replace": [MockFunction], + "replace": [MockFunction] { + "calls": Array [ + Array [ + Object { + "pathname": "/edit-detector-details/detector_id_1", + "state": Object { + "detectorHit": Object { + "_id": "detector_id_1", + "_index": ".windows", + "_source": Object { + "_id": "detector_id_1", + "_index": ".windows", + "_source": Object { + "createdBy": "someone", + "detector_type": "detector_type", + "enabled": true, + "enabled_time": 1, + "id": "detector_id_1", + "inputs": Array [ + Object { + "detector_input": Object { + "custom_rules": Array [ + Object { + "_id": "rule_id_1", + "_index": ".windows", + "_primary_term": 1, + "_source": Object { + "last_update_time": "12/12/2022", + "queries": Array [ + Object { + "value": ".windows", + }, + ], + "rule": "rule_name", + }, + "_version": 1, + "id": "rule_id_1", + }, + ], + "description": "detectorDescription", + "indices": Array [ + ".windows", + ], + "pre_packaged_rules": Array [ + Object { + "_id": "rule_id_1", + "_index": ".windows", + "_primary_term": 1, + "_source": Object { + "last_update_time": "12/12/2022", + "queries": Array [ + Object { + "value": ".windows", + }, + ], + "rule": "rule_name", + }, + "_version": 1, + "id": "rule_id_1", + }, + ], + }, + }, + ], + "last_update_time": 1, + "name": "detector_name", + "schedule": Object { + "period": Object { + "interval": 1, + "unit": "minute", + }, + }, + "triggers": Array [ + Object { + "actions": Array [ + Object { + "destination_id": "some_destination_id_1", + "id": "trigger_id_1_0", + "message_template": Object { + "lang": "some_lang", + "source": "some_source", + }, + "name": "some_name", + "subject_template": Object { + "lang": "some_lang", + "source": "some_source", + }, + "throttle": Object { + "unit": "minutes", + "value": 1, + }, + "throttle_enabled": true, + }, + Object { + "destination_id": "some_destination_id_1", + "id": "trigger_id_1_1", + "message_template": Object { + "lang": "some_lang", + "source": "some_source", + }, + "name": "some_name", + "subject_template": Object { + "lang": "some_lang", + "source": "some_source", + }, + "throttle": Object { + "unit": "minutes", + "value": 1, + }, + "throttle_enabled": true, + }, + ], + "id": "trigger_id_0", + "ids": Array [ + "rule_id_1", + ], + "name": "alert_name", + "sev_levels": Array [ + "severity_level_low", + ], + "severity": "1", + "tags": Array [ + "any.tag", + ], + "types": Array [ + "detector_type_1", + ], + }, + Object { + "actions": Array [ + Object { + "destination_id": "some_destination_id_1", + "id": "trigger_id_1_0", + "message_template": Object { + "lang": "some_lang", + "source": "some_source", + }, + "name": "some_name", + "subject_template": Object { + "lang": "some_lang", + "source": "some_source", + }, + "throttle": Object { + "unit": "minutes", + "value": 1, + }, + "throttle_enabled": true, + }, + Object { + "destination_id": "some_destination_id_1", + "id": "trigger_id_1_1", + "message_template": Object { + "lang": "some_lang", + "source": "some_source", + }, + "name": "some_name", + "subject_template": Object { + "lang": "some_lang", + "source": "some_source", + }, + "throttle": Object { + "unit": "minutes", + "value": 1, + }, + "throttle_enabled": true, + }, + ], + "id": "trigger_id_1", + "ids": Array [ + "rule_id_1", + ], + "name": "alert_name", + "sev_levels": Array [ + "severity_level_low", + ], + "severity": "1", + "tags": Array [ + "any.tag", + ], + "types": Array [ + "detector_type_1", + ], + }, + ], + "type": "detector", + }, + "createdBy": "someone", + "detector_type": "detector_type", + "enabled": true, + "enabled_time": 1, + "id": "detector_id_1", + "inputs": Array [ + Object { + "detector_input": Object { + "custom_rules": Array [ + Object { + "_id": "rule_id_1", + "_index": ".windows", + "_primary_term": 1, + "_source": Object { + "last_update_time": "12/12/2022", + "queries": Array [ + Object { + "value": ".windows", + }, + ], + "rule": "rule_name", + }, + "_version": 1, + "id": "rule_id_1", + }, + ], + "description": "detectorDescription", + "indices": Array [ + ".windows", + ], + "pre_packaged_rules": Array [ + Object { + "_id": "rule_id_1", + "_index": ".windows", + "_primary_term": 1, + "_source": Object { + "last_update_time": "12/12/2022", + "queries": Array [ + Object { + "value": ".windows", + }, + ], + "rule": "rule_name", + }, + "_version": 1, + "id": "rule_id_1", + }, + ], + }, + }, + ], + "last_update_time": 1, + "name": "detector_name", + "schedule": Object { + "period": Object { + "interval": 1, + "unit": "minute", + }, + }, + "triggers": Array [ + Object { + "actions": Array [ + Object { + "destination_id": "some_destination_id_1", + "id": "trigger_id_1_0", + "message_template": Object { + "lang": "some_lang", + "source": "some_source", + }, + "name": "some_name", + "subject_template": Object { + "lang": "some_lang", + "source": "some_source", + }, + "throttle": Object { + "unit": "minutes", + "value": 1, + }, + "throttle_enabled": true, + }, + Object { + "destination_id": "some_destination_id_1", + "id": "trigger_id_1_1", + "message_template": Object { + "lang": "some_lang", + "source": "some_source", + }, + "name": "some_name", + "subject_template": Object { + "lang": "some_lang", + "source": "some_source", + }, + "throttle": Object { + "unit": "minutes", + "value": 1, + }, + "throttle_enabled": true, + }, + ], + "id": "trigger_id_0", + "ids": Array [ + "rule_id_1", + ], + "name": "alert_name", + "sev_levels": Array [ + "severity_level_low", + ], + "severity": "1", + "tags": Array [ + "any.tag", + ], + "types": Array [ + "detector_type_1", + ], + }, + Object { + "actions": Array [ + Object { + "destination_id": "some_destination_id_1", + "id": "trigger_id_1_0", + "message_template": Object { + "lang": "some_lang", + "source": "some_source", + }, + "name": "some_name", + "subject_template": Object { + "lang": "some_lang", + "source": "some_source", + }, + "throttle": Object { + "unit": "minutes", + "value": 1, + }, + "throttle_enabled": true, + }, + Object { + "destination_id": "some_destination_id_1", + "id": "trigger_id_1_1", + "message_template": Object { + "lang": "some_lang", + "source": "some_source", + }, + "name": "some_name", + "subject_template": Object { + "lang": "some_lang", + "source": "some_source", + }, + "throttle": Object { + "unit": "minutes", + "value": 1, + }, + "throttle_enabled": true, + }, + ], + "id": "trigger_id_1", + "ids": Array [ + "rule_id_1", + ], + "name": "alert_name", + "sev_levels": Array [ + "severity_level_low", + ], + "severity": "1", + "tags": Array [ + "any.tag", + ], + "types": Array [ + "detector_type_1", + ], + }, + ], + "type": "detector", + }, + }, + }, + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": undefined, + }, + ], + }, } } location={ @@ -199,23 +569,7 @@ exports[` spec renders the component 1`] = ` notifications={ Object { "toasts": Object { - "addDanger": [MockFunction] { - "calls": Array [ - Array [ - Object { - "text": [TypeError: Cannot read property 'setBreadcrumbs' of undefined], - "title": "Failed to retrieve detector:", - "toastLifeTimeMs": 5000, - }, - ], - ], - "results": Array [ - Object { - "type": "return", - "value": undefined, - }, - ], - }, + "addDanger": [MockFunction], }, } } @@ -527,7 +881,7 @@ exports[` spec renders the component 1`] = ` className="euiSpacer euiSpacer--xl" /> - spec renders the component 1`] = ` notifications={ Object { "toasts": Object { - "addDanger": [MockFunction] { - "calls": Array [ - Array [ - Object { - "text": [TypeError: Cannot read property 'setBreadcrumbs' of undefined], - "title": "Failed to retrieve detector:", - "toastLifeTimeMs": 5000, - }, - ], - ], - "results": Array [ - Object { - "type": "return", - "value": undefined, - }, - ], - }, + "addDanger": [MockFunction], }, } } onDetectorInputIndicesChange={[Function]} > - - -
- -
- -
- -

- Data source -

-
-
-
-
-
- -
-
-
- -
- - - } - labelType="label" - > -
-
- - - -
-
- -
- - -
-
-
- - - .windows - - - -
- -
-
- -
- -
- - - - - - - - -
-
-
-
- - -
- -
-
- -
-
- - - + + @@ -1823,20 +1758,20 @@ exports[` spec renders the component 1`] = ` className="euiFlexItem euiFlexItem--flexGrowZero" >