diff --git a/x-pack/plugins/cases/public/common/lib/kibana/kibana_react.mock.ts b/x-pack/plugins/cases/public/common/lib/kibana/kibana_react.mock.ts index 326163f6cdc035..ff03782447846f 100644 --- a/x-pack/plugins/cases/public/common/lib/kibana/kibana_react.mock.ts +++ b/x-pack/plugins/cases/public/common/lib/kibana/kibana_react.mock.ts @@ -12,9 +12,15 @@ import { coreMock } from '../../../../../../../src/core/public/mocks'; import { KibanaContextProvider } from '../../../../../../../src/plugins/kibana_react/public'; import { StartServices } from '../../../types'; import { EuiTheme } from '../../../../../../../src/plugins/kibana_react/common'; +import { securityMock } from '../../../../../security/public/mocks'; +import { triggersActionsUiMock } from '../../../../../triggers_actions_ui/public/mocks'; export const createStartServicesMock = (): StartServices => - (coreMock.createStart() as unknown) as StartServices; + (({ + ...coreMock.createStart(), + security: securityMock.createStart(), + triggersActionsUi: triggersActionsUiMock.createStart(), + } as unknown) as StartServices); export const createWithKibanaMock = () => { const services = createStartServicesMock(); diff --git a/x-pack/plugins/cases/public/components/case_view/index.test.tsx b/x-pack/plugins/cases/public/components/case_view/index.test.tsx index d13e3978ce618c..f89218d5407eb2 100644 --- a/x-pack/plugins/cases/public/components/case_view/index.test.tsx +++ b/x-pack/plugins/cases/public/components/case_view/index.test.tsx @@ -28,6 +28,7 @@ import { useConnectors } from '../../containers/configure/use_connectors'; import { connectorsMock } from '../../containers/configure/mock'; import { usePostPushToService } from '../../containers/use_post_push_to_service'; import { CaseType, ConnectorTypes } from '../../../common'; +import { useKibana } from '../../common/lib/kibana'; jest.mock('../../containers/use_update_case'); jest.mock('../../containers/use_get_case_user_actions'); @@ -35,11 +36,13 @@ jest.mock('../../containers/use_get_case'); jest.mock('../../containers/configure/use_connectors'); jest.mock('../../containers/use_post_push_to_service'); jest.mock('../user_action_tree/user_action_timestamp'); +jest.mock('../../common/lib/kibana'); const useUpdateCaseMock = useUpdateCase as jest.Mock; const useGetCaseUserActionsMock = useGetCaseUserActions as jest.Mock; const useConnectorsMock = useConnectors as jest.Mock; const usePostPushToServiceMock = usePostPushToService as jest.Mock; +const useKibanaMock = useKibana as jest.Mocked; const alertsHit = [ { @@ -160,6 +163,10 @@ describe('CaseView ', () => { pushCaseToExternalService, })); useConnectorsMock.mockImplementation(() => ({ connectors: connectorsMock, loading: false })); + useKibanaMock().services.triggersActionsUi.actionTypeRegistry.get = jest.fn().mockReturnValue({ + actionTypeTitle: '.servicenow', + iconClass: 'logoSecurity', + }); }); it('should render CaseComponent', async () => { diff --git a/x-pack/plugins/cases/public/components/configure_cases/connectors.test.tsx b/x-pack/plugins/cases/public/components/configure_cases/connectors.test.tsx index d5b9a885f2c6d9..e5b1c66d01e1a0 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/connectors.test.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/connectors.test.tsx @@ -13,6 +13,10 @@ import { TestProviders } from '../../common/mock'; import { ConnectorsDropdown } from './connectors_dropdown'; import { connectors } from './__mock__'; import { ConnectorTypes } from '../../../common'; +import { useKibana } from '../../common/lib/kibana'; + +jest.mock('../../common/lib/kibana'); +const useKibanaMock = useKibana as jest.Mocked; describe('Connectors', () => { let wrapper: ReactWrapper; @@ -31,6 +35,10 @@ describe('Connectors', () => { }; beforeAll(() => { + useKibanaMock().services.triggersActionsUi.actionTypeRegistry.get = jest.fn().mockReturnValue({ + actionTypeTitle: 'test', + iconClass: 'logoSecurity', + }); wrapper = mount(, { wrappingComponent: TestProviders }); }); diff --git a/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.test.tsx b/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.test.tsx index 86f80f772944aa..141be31a093f1e 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.test.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.test.tsx @@ -12,6 +12,10 @@ import { EuiSuperSelect } from '@elastic/eui'; import { ConnectorsDropdown, Props } from './connectors_dropdown'; import { TestProviders } from '../../common/mock'; import { connectors } from './__mock__'; +import { useKibana } from '../../common/lib/kibana'; + +jest.mock('../../common/lib/kibana'); +const useKibanaMock = useKibana as jest.Mocked; describe('ConnectorsDropdown', () => { let wrapper: ReactWrapper; @@ -24,6 +28,10 @@ describe('ConnectorsDropdown', () => { }; beforeAll(() => { + useKibanaMock().services.triggersActionsUi.actionTypeRegistry.get = jest.fn().mockReturnValue({ + actionTypeTitle: '.servicenow', + iconClass: 'logoSecurity', + }); wrapper = mount(, { wrappingComponent: TestProviders }); }); @@ -73,14 +81,7 @@ describe('ConnectorsDropdown', () => { > @@ -103,14 +104,7 @@ describe('ConnectorsDropdown', () => { > @@ -133,14 +127,7 @@ describe('ConnectorsDropdown', () => { > @@ -163,14 +150,7 @@ describe('ConnectorsDropdown', () => { > @@ -210,9 +190,13 @@ describe('ConnectorsDropdown', () => { wrappingComponent: TestProviders, }); - expect(newWrapper.find('button span:not([data-euiicon-type])').at(1).text()).toBe( - 'My Connector' - ); + expect( + newWrapper + .find('[data-test-subj="dropdown-connectors"]') + .first() + .text() + .includes('My Connector, is selected') + ).toBeTruthy(); }); test('if the props hideConnectorServiceNowSir is true, the connector should not be part of the list of options ', () => { diff --git a/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.tsx b/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.tsx index 8c3a0f7ae19618..d26ec06d696fcf 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.tsx @@ -11,8 +11,8 @@ import styled from 'styled-components'; import { ConnectorTypes } from '../../../common'; import { ActionConnector } from '../../containers/configure/types'; -import { connectorsConfiguration } from '../connectors'; import * as i18n from './translations'; +import { useKibana } from '../../common/lib/kibana'; export interface Props { connectors: ActionConnector[]; @@ -65,6 +65,7 @@ const ConnectorsDropdownComponent: React.FC = ({ appendAddConnectorButton = false, hideConnectorServiceNowSir = false, }) => { + const { triggersActionsUi } = useKibana().services; const connectorsAsOptions = useMemo(() => { const connectorsFormatted = connectors.reduce( (acc, connector) => { @@ -80,7 +81,10 @@ const ConnectorsDropdownComponent: React.FC = ({ diff --git a/x-pack/plugins/cases/public/components/configure_cases/field_mapping.test.tsx b/x-pack/plugins/cases/public/components/configure_cases/field_mapping.test.tsx index 8c2a66ad7ee535..73f48654b22995 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/field_mapping.test.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/field_mapping.test.tsx @@ -12,6 +12,10 @@ import { FieldMapping, FieldMappingProps } from './field_mapping'; import { mappings } from './__mock__'; import { TestProviders } from '../../common/mock'; import { FieldMappingRowStatic } from './field_mapping_row_static'; +import { useKibana } from '../../common/lib/kibana'; + +jest.mock('../../common/lib/kibana'); +const useKibanaMock = useKibana as jest.Mocked; describe('FieldMappingRow', () => { let wrapper: ReactWrapper; @@ -22,8 +26,13 @@ describe('FieldMappingRow', () => { }; beforeAll(() => { + useKibanaMock().services.triggersActionsUi.actionTypeRegistry.get = jest.fn().mockReturnValue({ + actionTypeTitle: '.servicenow', + iconClass: 'logoSecurity', + }); wrapper = mount(, { wrappingComponent: TestProviders }); }); + test('it renders', () => { expect( wrapper.find('[data-test-subj="case-configure-field-mappings-row-wrapper"]').first().exists() diff --git a/x-pack/plugins/cases/public/components/configure_cases/field_mapping.tsx b/x-pack/plugins/cases/public/components/configure_cases/field_mapping.tsx index 7d5b72b583fae2..b5ce978a1b481a 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/field_mapping.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/field_mapping.tsx @@ -13,7 +13,7 @@ import { FieldMappingRowStatic } from './field_mapping_row_static'; import * as i18n from './translations'; import { CaseConnectorMapping } from '../../containers/configure/types'; -import { connectorsConfiguration } from '../connectors'; +import { useKibana } from '../../common/lib/kibana'; const FieldRowWrapper = styled.div` margin: 10px 0; @@ -31,8 +31,10 @@ const FieldMappingComponent: React.FC = ({ isLoading, mappings, }) => { + const { triggersActionsUi } = useKibana().services; const selectedConnector = useMemo( - () => connectorsConfiguration[connectorActionTypeId] ?? { fields: {} }, + () => triggersActionsUi.actionTypeRegistry.get(connectorActionTypeId) ?? { fields: {} }, + // eslint-disable-next-line react-hooks/exhaustive-deps [connectorActionTypeId] ); return mappings.length ? ( @@ -45,7 +47,7 @@ const FieldMappingComponent: React.FC = ({ - {i18n.FIELD_MAPPING_SECOND_COL(selectedConnector.name)} + {i18n.FIELD_MAPPING_SECOND_COL(selectedConnector.actionTypeTitle ?? '')} diff --git a/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx b/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx index 0d9ede9bb7de89..7212a195f79119 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx @@ -7,18 +7,12 @@ import React from 'react'; import { ReactWrapper, mount } from 'enzyme'; +import { waitFor } from '@testing-library/react'; import { ConfigureCases } from '.'; import { TestProviders } from '../../common/mock'; import { Connectors } from './connectors'; import { ClosureOptions } from './closure_options'; -import { - ActionConnector, - ConnectorAddFlyout, - ConnectorEditFlyout, - TriggersAndActionsUIPublicPluginStart, -} from '../../../../triggers_actions_ui/public'; -import { actionTypeRegistryMock } from '../../../../triggers_actions_ui/public/application/action_type_registry.mock'; import { useKibana } from '../../common/lib/kibana'; import { useConnectors } from '../../containers/configure/use_connectors'; @@ -33,6 +27,7 @@ import { useActionTypesResponse, } from './__mock__'; import { ConnectorTypes, SECURITY_SOLUTION_OWNER } from '../../../common'; +import { actionTypeRegistryMock } from '../../../../triggers_actions_ui/public/application/action_type_registry.mock'; jest.mock('../../common/lib/kibana'); jest.mock('../../containers/configure/use_connectors'); @@ -46,52 +41,13 @@ const useGetUrlSearchMock = jest.fn(); const useActionTypesMock = useActionTypes as jest.Mock; describe('ConfigureCases', () => { + beforeAll(() => { + useKibanaMock().services.triggersActionsUi.actionTypeRegistry.get = jest.fn().mockReturnValue({ + actionTypeTitle: '.servicenow', + iconClass: 'logoSecurity', + }); + }); beforeEach(() => { - useKibanaMock().services.triggersActionsUi = ({ - actionTypeRegistry: actionTypeRegistryMock.create(), - getAddConnectorFlyout: jest.fn().mockImplementation(() => ( - {}} - actionTypeRegistry={actionTypeRegistryMock.create()} - actionTypes={[ - { - id: '.servicenow', - name: 'servicenow', - enabled: true, - enabledInConfig: true, - enabledInLicense: true, - minimumLicenseRequired: 'gold', - }, - { - id: '.jira', - name: 'jira', - enabled: true, - enabledInConfig: true, - enabledInLicense: true, - minimumLicenseRequired: 'gold', - }, - { - id: '.resilient', - name: 'resilient', - enabled: true, - enabledInConfig: true, - enabledInLicense: true, - minimumLicenseRequired: 'gold', - }, - ]} - /> - )), - getEditConnectorFlyout: jest - .fn() - .mockImplementation(() => ( - {}} - actionTypeRegistry={actionTypeRegistryMock.create()} - initialConnector={connectors[1] as ActionConnector} - /> - )), - } as unknown) as TriggersAndActionsUIPublicPluginStart; - useActionTypesMock.mockImplementation(() => useActionTypesResponse); }); @@ -116,13 +72,11 @@ describe('ConfigureCases', () => { }); test('it does NOT render the ConnectorAddFlyout', () => { - // Components from triggersActionsUi do not have a data-test-subj - expect(wrapper.find(ConnectorAddFlyout).exists()).toBeFalsy(); + expect(wrapper.find('ConnectorAddFlyout').exists()).toBeFalsy(); }); test('it does NOT render the ConnectorEditFlyout', () => { - // Components from triggersActionsUi do not have a data-test-subj - expect(wrapper.find(ConnectorEditFlyout).exists()).toBeFalsy(); + expect(wrapper.find('ConnectorEditFlyout').exists()).toBeFalsy(); }); test('it does NOT render the EuiCallOut', () => { @@ -221,8 +175,8 @@ describe('ConfigureCases', () => { expect(wrapper.find(ClosureOptions).prop('closureTypeSelected')).toBe('close-by-user'); // Flyouts - expect(wrapper.find(ConnectorAddFlyout).exists()).toBe(false); - expect(wrapper.find(ConnectorEditFlyout).exists()).toBe(false); + expect(wrapper.find('ConnectorAddFlyout').exists()).toBe(false); + expect(wrapper.find('ConnectorEditFlyout').exists()).toBe(false); }); test('it disables correctly when the user cannot crud', () => { @@ -577,40 +531,67 @@ describe('user interactions', () => { useGetUrlSearchMock.mockImplementation(() => searchURL); }); - test('it show the add flyout when pressing the add connector button', () => { + test('it show the add flyout when pressing the add connector button', async () => { const wrapper = mount(, { wrappingComponent: TestProviders, }); + wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); - wrapper.update(); wrapper.find('button[data-test-subj="dropdown-connector-add-connector"]').simulate('click'); - wrapper.update(); - expect(wrapper.find(ConnectorAddFlyout).exists()).toBe(true); - expect(wrapper.find(ConnectorAddFlyout).prop('actionTypes')).toEqual([ - expect.objectContaining({ - id: '.servicenow', - }), - expect.objectContaining({ - id: '.jira', - }), - expect.objectContaining({ - id: '.resilient', - }), - ]); + await waitFor(() => { + wrapper.update(); + expect(wrapper.find('ConnectorAddFlyout').exists()).toBe(true); + expect(wrapper.find('ConnectorAddFlyout').prop('actionTypes')).toEqual([ + expect.objectContaining({ + id: '.servicenow', + }), + expect.objectContaining({ + id: '.jira', + }), + expect.objectContaining({ + id: '.resilient', + }), + expect.objectContaining({ + id: '.servicenow-sir', + }), + ]); + }); }); - test('it show the edit flyout when pressing the update connector button', () => { + test('it show the edit flyout when pressing the update connector button', async () => { + const actionType = actionTypeRegistryMock.createMockActionTypeModel({ + id: '.resilient', + validateConnector: () => { + return Promise.resolve({}); + }, + validateParams: () => { + const validationResult = { errors: {} }; + return Promise.resolve(validationResult); + }, + actionConnectorFields: null, + }); + + useKibanaMock().services.triggersActionsUi.actionTypeRegistry.get = jest + .fn() + .mockReturnValue(actionType); + useKibanaMock().services.triggersActionsUi.actionTypeRegistry.has = jest + .fn() + .mockReturnValue(true); + const wrapper = mount(, { wrappingComponent: TestProviders, }); wrapper .find('button[data-test-subj="case-configure-update-selected-connector-button"]') .simulate('click'); - wrapper.update(); - expect(wrapper.find(ConnectorEditFlyout).exists()).toBe(true); - expect(wrapper.find(ConnectorEditFlyout).prop('initialConnector')).toEqual(connectors[1]); + await waitFor(() => { + wrapper.update(); + expect(wrapper.find('ConnectorEditFlyout').exists()).toBe(true); + expect(wrapper.find('ConnectorEditFlyout').prop('initialConnector')).toEqual(connectors[1]); + }); + expect( wrapper.find('[data-test-subj="case-configure-action-bottom-bar"]').exists() ).toBeFalsy(); diff --git a/x-pack/plugins/cases/public/components/configure_cases/mapping.test.tsx b/x-pack/plugins/cases/public/components/configure_cases/mapping.test.tsx index 75b2410dde957f..0a1da1219342ed 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/mapping.test.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/mapping.test.tsx @@ -11,6 +11,10 @@ import { mount } from 'enzyme'; import { TestProviders } from '../../common/mock'; import { Mapping, MappingProps } from './mapping'; import { mappings } from './__mock__'; +import { useKibana } from '../../common/lib/kibana'; + +jest.mock('../../common/lib/kibana'); +const useKibanaMock = useKibana as jest.Mocked; describe('Mapping', () => { const props: MappingProps = { @@ -21,7 +25,12 @@ describe('Mapping', () => { beforeEach(() => { jest.clearAllMocks(); + useKibanaMock().services.triggersActionsUi.actionTypeRegistry.get = jest.fn().mockReturnValue({ + actionTypeTitle: 'ServiceNow ITSM', + iconClass: 'logoSecurity', + }); }); + test('it shows mapping form group', () => { const wrapper = mount(, { wrappingComponent: TestProviders }); expect(wrapper.find('[data-test-subj="static-mappings"]').first().exists()).toBe(true); diff --git a/x-pack/plugins/cases/public/components/configure_cases/mapping.tsx b/x-pack/plugins/cases/public/components/configure_cases/mapping.tsx index 5ec6a33f48b6aa..16c02606ae90b8 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/mapping.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/mapping.tsx @@ -14,7 +14,7 @@ import * as i18n from './translations'; import { FieldMapping } from './field_mapping'; import { CaseConnectorMapping } from '../../containers/configure/types'; -import { connectorsConfiguration } from '../connectors'; +import { useKibana } from '../../common/lib/kibana'; export interface MappingProps { connectorActionTypeId: string; @@ -27,21 +27,29 @@ const MappingComponent: React.FC = ({ isLoading, mappings, }) => { - const selectedConnector = useMemo(() => connectorsConfiguration[connectorActionTypeId], [ - connectorActionTypeId, - ]); + const { triggersActionsUi } = useKibana().services; + const selectedConnector = useMemo( + () => triggersActionsUi.actionTypeRegistry.get(connectorActionTypeId), + [connectorActionTypeId, triggersActionsUi] + ); const fieldMappingDesc: { desc: string; color: TextColor } = useMemo( () => mappings.length > 0 || isLoading - ? { desc: i18n.FIELD_MAPPING_DESC(selectedConnector.name), color: 'subdued' } - : { desc: i18n.FIELD_MAPPING_DESC_ERR(selectedConnector.name), color: 'danger' }, - [isLoading, mappings.length, selectedConnector.name] + ? { + desc: i18n.FIELD_MAPPING_DESC(selectedConnector.actionTypeTitle ?? ''), + color: 'subdued', + } + : { + desc: i18n.FIELD_MAPPING_DESC_ERR(selectedConnector.actionTypeTitle ?? ''), + color: 'danger', + }, + [isLoading, mappings.length, selectedConnector.actionTypeTitle] ); return ( -

{i18n.FIELD_MAPPING_TITLE(selectedConnector.name)}

+

{i18n.FIELD_MAPPING_TITLE(selectedConnector.actionTypeTitle ?? '')}

{fieldMappingDesc.desc} diff --git a/x-pack/plugins/cases/public/components/connector_selector/form.test.tsx b/x-pack/plugins/cases/public/components/connector_selector/form.test.tsx index ec136989dd9379..ea25fce2d4f7c4 100644 --- a/x-pack/plugins/cases/public/components/connector_selector/form.test.tsx +++ b/x-pack/plugins/cases/public/components/connector_selector/form.test.tsx @@ -11,17 +11,23 @@ import { UseField, Form, useForm, FormHook } from '../../common/shared_imports'; import { ConnectorSelector } from './form'; import { connectorsMock } from '../../containers/mock'; import { getFormMock } from '../__mock__/form'; +import { useKibana } from '../../common/lib/kibana'; jest.mock('../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form'); +jest.mock('../../common/lib/kibana'); +const useKibanaMock = useKibana as jest.Mocked; const useFormMock = useForm as jest.Mock; describe('ConnectorSelector', () => { const formHookMock = getFormMock({ connectorId: connectorsMock[0].id }); beforeEach(() => { - jest.resetAllMocks(); useFormMock.mockImplementation(() => ({ form: formHookMock })); + useKibanaMock().services.triggersActionsUi.actionTypeRegistry.get = jest.fn().mockReturnValue({ + actionTypeTitle: 'test', + iconClass: 'logoSecurity', + }); }); it('it should render', async () => { diff --git a/x-pack/plugins/cases/public/components/connectors/card.tsx b/x-pack/plugins/cases/public/components/connectors/card.tsx index 82a508ccf34329..b27c7207e7b8a3 100644 --- a/x-pack/plugins/cases/public/components/connectors/card.tsx +++ b/x-pack/plugins/cases/public/components/connectors/card.tsx @@ -9,8 +9,8 @@ import React, { memo, useMemo } from 'react'; import { EuiCard, EuiIcon, EuiLoadingSpinner } from '@elastic/eui'; import styled from 'styled-components'; -import { connectorsConfiguration } from '.'; import { ConnectorTypes } from '../../../common'; +import { useKibana } from '../../common/lib/kibana'; interface ConnectorCardProps { connectorType: ConnectorTypes; @@ -31,6 +31,8 @@ const ConnectorCardDisplay: React.FC = ({ listItems, isLoading, }) => { + const { triggersActionsUi } = useKibana().services; + const description = useMemo( () => ( @@ -46,7 +48,13 @@ const ConnectorCardDisplay: React.FC = ({ [listItems] ); const icon = useMemo( - () => , + () => ( + + ), + // eslint-disable-next-line react-hooks/exhaustive-deps [connectorType] ); return ( diff --git a/x-pack/plugins/cases/public/components/connectors/config.ts b/x-pack/plugins/cases/public/components/connectors/config.ts deleted file mode 100644 index e8d87511c7e17d..00000000000000 --- a/x-pack/plugins/cases/public/components/connectors/config.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 { - getResilientActionType, - getServiceNowITSMActionType, - getServiceNowSIRActionType, - getJiraActionType, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../triggers_actions_ui/public/common'; -import { ConnectorConfiguration } from './types'; - -const resilient = getResilientActionType(); -const serviceNowITSM = getServiceNowITSMActionType(); -const serviceNowSIR = getServiceNowSIRActionType(); -const jira = getJiraActionType(); - -export const connectorsConfiguration: Record = { - '.servicenow': { - name: serviceNowITSM.actionTypeTitle ?? '', - logo: serviceNowITSM.iconClass, - }, - '.servicenow-sir': { - name: serviceNowSIR.actionTypeTitle ?? '', - logo: serviceNowSIR.iconClass, - }, - '.jira': { - name: jira.actionTypeTitle ?? '', - logo: jira.iconClass, - }, - '.resilient': { - name: resilient.actionTypeTitle ?? '', - logo: resilient.iconClass, - }, -}; diff --git a/x-pack/plugins/cases/public/components/connectors/index.ts b/x-pack/plugins/cases/public/components/connectors/index.ts index 71ba161eb63c9f..2a7d59ca7b0409 100644 --- a/x-pack/plugins/cases/public/components/connectors/index.ts +++ b/x-pack/plugins/cases/public/components/connectors/index.ts @@ -19,7 +19,6 @@ import { export { getActionType as getCaseConnectorUi } from './case'; -export * from './config'; export * from './types'; interface GetCaseConnectorsReturn { diff --git a/x-pack/plugins/cases/public/components/connectors/jira/case_fields.test.tsx b/x-pack/plugins/cases/public/components/connectors/jira/case_fields.test.tsx index 38a1e30616200c..ae9245534c78a1 100644 --- a/x-pack/plugins/cases/public/components/connectors/jira/case_fields.test.tsx +++ b/x-pack/plugins/cases/public/components/connectors/jira/case_fields.test.tsx @@ -9,6 +9,7 @@ import React from 'react'; import { mount } from 'enzyme'; import { omit } from 'lodash/fp'; +import { useKibana } from '../../../common/lib/kibana'; import { connector, issues } from '../mock'; import { useGetIssueTypes } from './use_get_issue_types'; import { useGetFieldsByIssueType } from './use_get_fields_by_issue_type'; @@ -27,6 +28,7 @@ const useGetIssueTypesMock = useGetIssueTypes as jest.Mock; const useGetFieldsByIssueTypeMock = useGetFieldsByIssueType as jest.Mock; const useGetSingleIssueMock = useGetSingleIssue as jest.Mock; const useGetIssuesMock = useGetIssues as jest.Mock; +const useKibanaMock = useKibana as jest.Mocked; describe('Jira Fields', () => { const useGetIssueTypesResponse = { @@ -87,6 +89,10 @@ describe('Jira Fields', () => { useGetIssueTypesMock.mockReturnValue(useGetIssueTypesResponse); useGetFieldsByIssueTypeMock.mockReturnValue(useGetFieldsByIssueTypeResponse); useGetSingleIssueMock.mockReturnValue(useGetSingleIssueResponse); + useKibanaMock().services.triggersActionsUi.actionTypeRegistry.get = jest.fn().mockReturnValue({ + actionTypeTitle: '.jira', + iconClass: 'logoSecurity', + }); jest.clearAllMocks(); }); @@ -144,6 +150,7 @@ describe('Jira Fields', () => { priority: 'High', }); }); + test('it searches parent correctly', async () => { useGetFieldsByIssueTypeMock.mockReturnValue({ ...useGetFieldsByIssueTypeResponse, diff --git a/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_itsm_case_fields.test.tsx b/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_itsm_case_fields.test.tsx index 9688ca191d6727..b14842bbf1bbf4 100644 --- a/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_itsm_case_fields.test.tsx +++ b/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_itsm_case_fields.test.tsx @@ -10,6 +10,7 @@ import { waitFor, act } from '@testing-library/react'; import { EuiSelect } from '@elastic/eui'; import { mount } from 'enzyme'; +import { useKibana } from '../../../common/lib/kibana'; import { connector, choices as mockChoices } from '../mock'; import { Choice } from './types'; import Fields from './servicenow_itsm_case_fields'; @@ -24,6 +25,8 @@ jest.mock('./use_get_choices', () => ({ }, })); +const useKibanaMock = useKibana as jest.Mocked; + describe('ServiceNowITSM Fields', () => { const fields = { severity: '1', @@ -36,6 +39,10 @@ describe('ServiceNowITSM Fields', () => { beforeEach(() => { jest.clearAllMocks(); + useKibanaMock().services.triggersActionsUi.actionTypeRegistry.get = jest.fn().mockReturnValue({ + actionTypeTitle: '.servicenow', + iconClass: 'logoSecurity', + }); }); it('all params fields are rendered - isEdit: true', () => { diff --git a/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_sir_case_fields.test.tsx b/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_sir_case_fields.test.tsx index 4a5b34cd3c3cb8..7d42c90a436f7c 100644 --- a/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_sir_case_fields.test.tsx +++ b/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_sir_case_fields.test.tsx @@ -10,6 +10,7 @@ import { mount } from 'enzyme'; import { waitFor, act } from '@testing-library/react'; import { EuiSelect } from '@elastic/eui'; +import { useKibana } from '../../../common/lib/kibana'; import { connector, choices as mockChoices } from '../mock'; import { Choice } from './types'; import Fields from './servicenow_sir_case_fields'; @@ -24,6 +25,8 @@ jest.mock('./use_get_choices', () => ({ }, })); +const useKibanaMock = useKibana as jest.Mocked; + describe('ServiceNowSIR Fields', () => { const fields = { destIp: true, @@ -38,6 +41,10 @@ describe('ServiceNowSIR Fields', () => { beforeEach(() => { jest.clearAllMocks(); + useKibanaMock().services.triggersActionsUi.actionTypeRegistry.get = jest.fn().mockReturnValue({ + actionTypeTitle: '.servicenow-sir', + iconClass: 'logoSecurity', + }); }); it('all params fields are rendered - isEdit: true', () => { diff --git a/x-pack/plugins/cases/public/components/connectors/types.ts b/x-pack/plugins/cases/public/components/connectors/types.ts index 1657153ab645bd..4eb97513b9f58e 100644 --- a/x-pack/plugins/cases/public/components/connectors/types.ts +++ b/x-pack/plugins/cases/public/components/connectors/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { IconType } from '@elastic/eui/src/components/icon/icon'; +import { IconType } from '@elastic/eui'; import React from 'react'; import { diff --git a/x-pack/plugins/cases/public/components/create/connector.test.tsx b/x-pack/plugins/cases/public/components/create/connector.test.tsx index 9eb475f54221d1..b2a8838774b09c 100644 --- a/x-pack/plugins/cases/public/components/create/connector.test.tsx +++ b/x-pack/plugins/cases/public/components/create/connector.test.tsx @@ -25,6 +25,14 @@ jest.mock('../../common/lib/kibana', () => { services: { notifications: {}, http: {}, + triggersActionsUi: { + actionTypeRegistry: { + get: jest.fn().mockReturnValue({ + actionTypeTitle: 'test', + iconClass: 'logoSecurity', + }), + }, + }, }, }), }; diff --git a/x-pack/plugins/cases/public/components/create/form_context.test.tsx b/x-pack/plugins/cases/public/components/create/form_context.test.tsx index cb053b2e784cda..e083f11ced7770 100644 --- a/x-pack/plugins/cases/public/components/create/form_context.test.tsx +++ b/x-pack/plugins/cases/public/components/create/form_context.test.tsx @@ -11,6 +11,7 @@ import { act, waitFor } from '@testing-library/react'; import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; import { ConnectorTypes, SECURITY_SOLUTION_OWNER } from '../../../common'; +import { useKibana } from '../../common/lib/kibana'; import { TestProviders } from '../../common/mock'; import { usePostCase } from '../../containers/use_post_case'; import { usePostComment } from '../../containers/use_post_comment'; @@ -54,6 +55,7 @@ jest.mock('../connectors/jira/use_get_fields_by_issue_type'); jest.mock('../connectors/jira/use_get_single_issue'); jest.mock('../connectors/jira/use_get_issues'); jest.mock('../connectors/servicenow/use_get_choices'); +jest.mock('../../common/lib/kibana'); const useConnectorsMock = useConnectors as jest.Mock; const useCaseConfigureMock = useCaseConfigure as jest.Mock; @@ -67,6 +69,7 @@ const useGetFieldsByIssueTypeMock = useGetFieldsByIssueType as jest.Mock; const useGetChoicesMock = useGetChoices as jest.Mock; const postCase = jest.fn(); const pushCaseToExternalService = jest.fn(); +const useKibanaMock = useKibana as jest.Mocked; const defaultPostCase = { isLoading: false, @@ -130,7 +133,12 @@ describe('Create case', () => { tags: sampleTags, fetchTags, })); + useKibanaMock().services.triggersActionsUi.actionTypeRegistry.get = jest.fn().mockReturnValue({ + actionTypeTitle: '.servicenow', + iconClass: 'logoSecurity', + }); }); + beforeEach(() => { jest.clearAllMocks(); }); diff --git a/x-pack/plugins/cases/public/components/edit_connector/index.test.tsx b/x-pack/plugins/cases/public/components/edit_connector/index.test.tsx index 3b6d4bd3f33f2e..1385e8e8664c37 100644 --- a/x-pack/plugins/cases/public/components/edit_connector/index.test.tsx +++ b/x-pack/plugins/cases/public/components/edit_connector/index.test.tsx @@ -7,15 +7,18 @@ import React from 'react'; import { mount } from 'enzyme'; +import { waitFor } from '@testing-library/react'; import { EditConnector } from './index'; import { getFormMock, useFormMock } from '../__mock__/form'; import { TestProviders } from '../../common/mock'; import { connectorsMock } from '../../containers/configure/mock'; -import { waitFor } from '@testing-library/react'; import { caseUserActions } from '../../containers/mock'; +import { useKibana } from '../../common/lib/kibana'; jest.mock('../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form'); +jest.mock('../../common/lib/kibana'); +const useKibanaMock = useKibana as jest.Mocked; const onSubmit = jest.fn(); const defaultProps = { @@ -33,8 +36,11 @@ describe('EditConnector ', () => { const formHookMock = getFormMock({ connectorId: sampleConnector }); beforeEach(() => { jest.clearAllMocks(); - jest.resetAllMocks(); useFormMock.mockImplementation(() => ({ form: formHookMock })); + useKibanaMock().services.triggersActionsUi.actionTypeRegistry.get = jest.fn().mockReturnValue({ + actionTypeTitle: '.servicenow', + iconClass: 'logoSecurity', + }); }); it('Renders no connector, and then edit', async () => { diff --git a/x-pack/plugins/cases/public/components/edit_connector/index.tsx b/x-pack/plugins/cases/public/components/edit_connector/index.tsx index 56f1a77fc407ed..ad6b5a5e7cddf5 100644 --- a/x-pack/plugins/cases/public/components/edit_connector/index.tsx +++ b/x-pack/plugins/cases/public/components/edit_connector/index.tsx @@ -202,6 +202,7 @@ export const EditConnector = React.memo( payload: true, }); }, [dispatch]); + return ( diff --git a/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx b/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx index 5893d5f8c5af48..3a5cda489947a2 100644 --- a/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx +++ b/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx @@ -13,8 +13,11 @@ import { TestProviders } from '../../common/mock'; import { useGetCases } from '../../containers/use_get_cases'; import { useGetCasesMockState } from '../../containers/mock'; import { SECURITY_SOLUTION_OWNER } from '../../../common'; +import { useCurrentUser } from '../../common/lib/kibana/hooks'; jest.mock('../../containers/use_get_cases'); +jest.mock('../../common/lib/kibana/hooks'); + configure({ testIdAttribute: 'data-test-subj' }); const defaultProps = { allCasesNavigation: { @@ -32,16 +35,25 @@ const defaultProps = { maxCasesToShow: 10, owner: [SECURITY_SOLUTION_OWNER], }; + const setFilters = jest.fn(); const mockData = { ...useGetCasesMockState, setFilters, }; + const useGetCasesMock = useGetCases as jest.Mock; +const useCurrentUserMock = useCurrentUser as jest.Mock; + describe('RecentCases', () => { beforeEach(() => { jest.clearAllMocks(); useGetCasesMock.mockImplementation(() => mockData); + useCurrentUserMock.mockResolvedValue({ + email: 'elastic@elastic.co', + fullName: 'Elastic', + username: 'elastic', + }); }); it('is good at loading', () => { @@ -83,8 +95,9 @@ describe('RecentCases', () => { ); - const yo = getByTestId('myRecentlyReported'); - userEvent.click(yo); + + const element = getByTestId('myRecentlyReported'); + userEvent.click(element); expect(setFilters).toHaveBeenCalled(); }); }); diff --git a/x-pack/plugins/cases/public/components/recent_cases/index.tsx b/x-pack/plugins/cases/public/components/recent_cases/index.tsx index bb34f651d52dfd..8a08a46487c8b0 100644 --- a/x-pack/plugins/cases/public/components/recent_cases/index.tsx +++ b/x-pack/plugins/cases/public/components/recent_cases/index.tsx @@ -50,6 +50,7 @@ const RecentCasesComponent = ({ : {}, [currentUser, recentCasesFilterBy] ); + return ( <> <> diff --git a/x-pack/plugins/cases/public/containers/configure/mock.ts b/x-pack/plugins/cases/public/containers/configure/mock.ts index ef287ea866dcbb..833c2cfb3aa7ca 100644 --- a/x-pack/plugins/cases/public/containers/configure/mock.ts +++ b/x-pack/plugins/cases/public/containers/configure/mock.ts @@ -114,6 +114,14 @@ export const actionTypesMock: ActionTypeConnector[] = [ enabledInConfig: true, enabledInLicense: true, }, + { + id: '.servicenow-sir', + name: 'ServiceNow SIR', + minimumLicenseRequired: 'platinum', + enabled: false, + enabledInConfig: true, + enabledInLicense: true, + }, ]; export const caseConfigurationResposeMock: CasesConfigureResponse = { diff --git a/x-pack/plugins/triggers_actions_ui/public/common/index.ts b/x-pack/plugins/triggers_actions_ui/public/common/index.ts index 01470bdddf4d73..67f4cc603ad926 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/common/index.ts @@ -10,10 +10,3 @@ export * from './constants'; export * from './index_controls'; export * from './lib'; export * from './types'; - -export { - getServiceNowITSMActionType, - getServiceNowSIRActionType, -} from '../application/components/builtin_action_types/servicenow'; -export { getJiraActionType } from '../application/components/builtin_action_types/jira'; -export { getResilientActionType } from '../application/components/builtin_action_types/resilient';