Skip to content

Commit

Permalink
[7.x] [SIEM][CASE] Configuration page tests (#61093) (#62661)
Browse files Browse the repository at this point in the history
* Test ClosureOptionsRadio component

* Test ClosureOptions component

* Test ConnectorsDropdown component

* Test Connectors

* Test FieldMappingRow

* Test FieldMapping

* Create utils functions and refactor to be able to test

* Test Mapping

* Improve tests

* Test ConfigureCases

* Refactor tests

* Fix flacky tests

* Remove snapshots

* Refactor tests

* Test button

* Test reducer

* Move test

* Better structure

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
cnasikas and elasticmachine authored Apr 6, 2020
1 parent 34028fd commit ef156d1
Show file tree
Hide file tree
Showing 22 changed files with 1,807 additions and 39 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import {
Connector,
CasesConfigurationMapping,
} from '../../../../../containers/case/configure/types';
import { State } from '../reducer';
import { ReturnConnectors } from '../../../../../containers/case/configure/use_connectors';
import { ReturnUseCaseConfigure } from '../../../../../containers/case/configure/use_configure';
import { createUseKibanaMock } from '../../../../../mock/kibana_react';

// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { actionTypeRegistryMock } from '../../../../../../../../../plugins/triggers_actions_ui/public/application/action_type_registry.mock';

export const connectors: Connector[] = [
{
id: '123',
actionTypeId: '.servicenow',
name: 'My Connector',
config: {
apiUrl: 'https://instance1.service-now.com',
casesConfiguration: {
mapping: [
{
source: 'title',
target: 'short_description',
actionType: 'overwrite',
},
{
source: 'description',
target: 'description',
actionType: 'append',
},
{
source: 'comments',
target: 'comments',
actionType: 'append',
},
],
},
},
},
{
id: '456',
actionTypeId: '.servicenow',
name: 'My Connector 2',
config: {
apiUrl: 'https://instance2.service-now.com',
casesConfiguration: {
mapping: [
{
source: 'title',
target: 'short_description',
actionType: 'overwrite',
},
{
source: 'description',
target: 'description',
actionType: 'overwrite',
},
{
source: 'comments',
target: 'comments',
actionType: 'append',
},
],
},
},
},
];

export const mapping: CasesConfigurationMapping[] = [
{
source: 'title',
target: 'short_description',
actionType: 'overwrite',
},
{
source: 'description',
target: 'description',
actionType: 'append',
},
{
source: 'comments',
target: 'comments',
actionType: 'append',
},
];

export const searchURL =
'?timerange=(global:(linkTo:!(),timerange:(from:1585487656371,fromStr:now-24h,kind:relative,to:1585574056371,toStr:now)),timeline:(linkTo:!(),timerange:(from:1585227005527,kind:absolute,to:1585313405527)))';

export const initialState: State = {
connectorId: 'none',
closureType: 'close-by-user',
mapping: null,
currentConfiguration: { connectorId: 'none', closureType: 'close-by-user' },
};

export const useCaseConfigureResponse: ReturnUseCaseConfigure = {
loading: false,
persistLoading: false,
refetchCaseConfigure: jest.fn(),
persistCaseConfigure: jest.fn(),
};

export const useConnectorsResponse: ReturnConnectors = {
loading: false,
connectors,
refetchConnectors: jest.fn(),
};

export const kibanaMockImplementationArgs = {
services: {
...createUseKibanaMock()().services,
triggers_actions_ui: { actionTypeRegistry: actionTypeRegistryMock.create() },
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import React from 'react';
import { ReactWrapper, mount } from 'enzyme';
import { EuiText } from '@elastic/eui';

import { ConfigureCaseButton, ConfigureCaseButtonProps } from './button';
import { TestProviders } from '../../../../mock';
import { searchURL } from './__mock__';

describe('Configuration button', () => {
let wrapper: ReactWrapper;
const props: ConfigureCaseButtonProps = {
isDisabled: false,
label: 'My label',
msgTooltip: <></>,
showToolTip: false,
titleTooltip: '',
urlSearch: searchURL,
};

beforeAll(() => {
wrapper = mount(<ConfigureCaseButton {...props} />, { wrappingComponent: TestProviders });
});

test('it renders without the tooltip', () => {
expect(
wrapper
.find('[data-test-subj="configure-case-button"]')
.first()
.exists()
).toBe(true);

expect(
wrapper
.find('[data-test-subj="configure-case-tooltip"]')
.first()
.exists()
).toBe(false);
});

test('it pass the correct props to the button', () => {
expect(
wrapper
.find('[data-test-subj="configure-case-button"]')
.first()
.props()
).toMatchObject({
href: `#/link-to/case/configure${searchURL}`,
iconType: 'controlsHorizontal',
isDisabled: false,
'aria-label': 'My label',
children: 'My label',
});
});

test('it renders the tooltip', () => {
const msgTooltip = <EuiText>{'My message tooltip'}</EuiText>;

const newWrapper = mount(
<ConfigureCaseButton
{...props}
showToolTip={true}
titleTooltip={'My tooltip title'}
msgTooltip={msgTooltip}
/>,
{
wrappingComponent: TestProviders,
}
);

expect(
newWrapper
.find('[data-test-subj="configure-case-tooltip"]')
.first()
.exists()
).toBe(true);

expect(
wrapper
.find('[data-test-subj="configure-case-button"]')
.first()
.exists()
).toBe(true);
});

test('it shows the tooltip when hovering the button', () => {
const msgTooltip = 'My message tooltip';
const titleTooltip = 'My title';

const newWrapper = mount(
<ConfigureCaseButton
{...props}
showToolTip={true}
titleTooltip={titleTooltip}
msgTooltip={<>{msgTooltip}</>}
/>,
{
wrappingComponent: TestProviders,
}
);

newWrapper
.find('[data-test-subj="configure-case-button"]')
.first()
.simulate('mouseOver');

expect(newWrapper.find('.euiToolTipPopover').text()).toBe(`${titleTooltip}${msgTooltip}`);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { EuiButton, EuiToolTip } from '@elastic/eui';
import React, { memo, useMemo } from 'react';
import { getConfigureCasesUrl } from '../../../../components/link_to';

interface ConfigureCaseButtonProps {
export interface ConfigureCaseButtonProps {
label: string;
isDisabled: boolean;
msgTooltip: JSX.Element;
Expand All @@ -32,14 +32,20 @@ const ConfigureCaseButtonComponent: React.FC<ConfigureCaseButtonProps> = ({
iconType="controlsHorizontal"
isDisabled={isDisabled}
aria-label={label}
data-test-subj="configure-case-button"
>
{label}
</EuiButton>
),
[label, isDisabled, urlSearch]
);
return showToolTip ? (
<EuiToolTip position="top" title={titleTooltip} content={<p>{msgTooltip}</p>}>
<EuiToolTip
position="top"
title={titleTooltip}
content={<p>{msgTooltip}</p>}
data-test-subj="configure-case-tooltip"
>
{configureCaseButton}
</EuiToolTip>
) : (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import React from 'react';
import { mount, ReactWrapper } from 'enzyme';

import { ClosureOptions, ClosureOptionsProps } from './closure_options';
import { TestProviders } from '../../../../mock';
import { ClosureOptionsRadio } from './closure_options_radio';

describe('ClosureOptions', () => {
let wrapper: ReactWrapper;
const onChangeClosureType = jest.fn();
const props: ClosureOptionsProps = {
disabled: false,
closureTypeSelected: 'close-by-user',
onChangeClosureType,
};

beforeAll(() => {
wrapper = mount(<ClosureOptions {...props} />, { wrappingComponent: TestProviders });
});

test('it shows the closure options form group', () => {
expect(
wrapper
.find('[data-test-subj="case-closure-options-form-group"]')
.first()
.exists()
).toBe(true);
});

test('it shows the closure options form row', () => {
expect(
wrapper
.find('[data-test-subj="case-closure-options-form-row"]')
.first()
.exists()
).toBe(true);
});

test('it shows closure options', () => {
expect(
wrapper
.find('[data-test-subj="case-closure-options-radio"]')
.first()
.exists()
).toBe(true);
});

test('it pass the correct props to child', () => {
const closureOptionsRadioComponent = wrapper.find(ClosureOptionsRadio);
expect(closureOptionsRadioComponent.props().disabled).toEqual(false);
expect(closureOptionsRadioComponent.props().closureTypeSelected).toEqual('close-by-user');
expect(closureOptionsRadioComponent.props().onChangeClosureType).toEqual(onChangeClosureType);
});

test('the closure type is changed successfully', () => {
wrapper.find('input[id="close-by-pushing"]').simulate('change');

expect(onChangeClosureType).toHaveBeenCalled();
expect(onChangeClosureType).toHaveBeenCalledWith('close-by-pushing');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { ClosureType } from '../../../../containers/case/configure/types';
import { ClosureOptionsRadio } from './closure_options_radio';
import * as i18n from './translations';

interface ClosureOptionsProps {
export interface ClosureOptionsProps {
closureTypeSelected: ClosureType;
disabled: boolean;
onChangeClosureType: (newClosureType: ClosureType) => void;
Expand All @@ -27,12 +27,18 @@ const ClosureOptionsComponent: React.FC<ClosureOptionsProps> = ({
fullWidth
title={<h3>{i18n.CASE_CLOSURE_OPTIONS_TITLE}</h3>}
description={i18n.CASE_CLOSURE_OPTIONS_DESC}
data-test-subj="case-closure-options-form-group"
>
<EuiFormRow fullWidth label={i18n.CASE_CLOSURE_OPTIONS_LABEL}>
<EuiFormRow
fullWidth
label={i18n.CASE_CLOSURE_OPTIONS_LABEL}
data-test-subj="case-closure-options-form-row"
>
<ClosureOptionsRadio
closureTypeSelected={closureTypeSelected}
disabled={disabled}
onChangeClosureType={onChangeClosureType}
data-test-subj="case-closure-options-radio"
/>
</EuiFormRow>
</EuiDescribedFormGroup>
Expand Down
Loading

0 comments on commit ef156d1

Please sign in to comment.