fixed tests

This commit is contained in:
Gidi Meir Morris 2020-11-05 11:21:30 +00:00
parent 01c7c7d2aa
commit e9f2cd05bd
8 changed files with 93 additions and 49 deletions

View file

@ -5,25 +5,33 @@
*/
import uuid from 'uuid';
import { range } from 'lodash';
import { range, random, pick } from 'lodash';
import { AlertType } from '../../../../plugins/alerts/server';
import { DEFAULT_INSTANCES_TO_GENERATE, ALERTING_EXAMPLE_APP_ID } from '../../common/constants';
const ACTION_GROUPS = [
{ id: 'small', name: 'small', tshirtSize: 1 },
{ id: 'medium', name: 'medium', tshirtSize: 2 },
{ id: 'large', name: 'large', tshirtSize: 3 },
];
export const alertType: AlertType = {
id: 'example.always-firing',
name: 'Always firing',
actionGroups: [{ id: 'default', name: 'default' }],
defaultActionGroupId: 'default',
actionGroups: ACTION_GROUPS.map((actionGroup) => pick(actionGroup, ['id', 'name'])),
defaultActionGroupId: 'small',
async executor({ services, params: { instances = DEFAULT_INSTANCES_TO_GENERATE }, state }) {
const count = (state.count ?? 0) + 1;
range(instances)
.map(() => ({ id: uuid.v4() }))
.forEach((instance: { id: string }) => {
.map(() => ({ id: uuid.v4(), tshirtSize: random(1, 3) }))
.forEach((instance: { id: string; tshirtSize: number }) => {
services
.alertInstanceFactory(instance.id)
.replaceState({ triggerdOnCycle: count })
.scheduleActions('default');
.scheduleActions(
ACTION_GROUPS.find((actionGroup) => actionGroup.tshirtSize === instance.tshirtSize)!.id
);
});
return {

View file

@ -7,6 +7,7 @@
export { NonEmptyString } from './detection_engine/schemas/types/non_empty_string';
export { DefaultArray } from './detection_engine/schemas/types/default_array';
export { DefaultUuid } from './detection_engine/schemas/types/default_uuid';
export { siemRuleActionGroups } from './detection_engine/signals/siem_rule_action_groups';
export { DefaultStringArray } from './detection_engine/schemas/types/default_string_array';
export {
DefaultVersionNumber,

View file

@ -21,10 +21,11 @@ import {
import { AlertAction } from '../../../../../../alerts/common';
import { useKibana } from '../../../../common/lib/kibana';
import { FORM_ERRORS_TITLE } from './translations';
import { siemRuleActionGroups } from '../../../../../common';
type ThrottleSelectField = typeof SelectField;
const DEFAULT_ACTION_GROUP_ID = 'default';
const DEFAULT_ACTION_GROUP = siemRuleActionGroups[0];
const DEFAULT_ACTION_MESSAGE =
'Rule {{context.rule.name}} generated {{state.signals_count}} alerts';
@ -52,12 +53,19 @@ export const RuleActionsField: ThrottleSelectField = ({ field, messageVariables
[field.value]
);
const setActionPropByIndex = (prop: 'id' | 'group', value: string, index: number) => {
const updatedActions = [...(actions as Array<Partial<AlertAction>>)];
updatedActions[index] = deepMerge(updatedActions[index], { [prop]: value });
field.setValue(updatedActions);
};
const setActionIdByIndex = useCallback(
(id: string, index: number) => {
const updatedActions = [...(actions as Array<Partial<AlertAction>>)];
updatedActions[index] = deepMerge(updatedActions[index], { id });
field.setValue(updatedActions);
},
(id: string, index: number) => setActionPropByIndex('id', id, index),
// eslint-disable-next-line react-hooks/exhaustive-deps
[field.setValue, actions]
);
const setActionGroupIdByIndex = useCallback(
(group: string, index: number) => setActionPropByIndex('group', group, index),
// eslint-disable-next-line react-hooks/exhaustive-deps
[field.setValue, actions]
);
@ -118,7 +126,9 @@ export const RuleActionsField: ThrottleSelectField = ({ field, messageVariables
docLinks={docLinks}
capabilities={capabilities}
messageVariables={messageVariables}
defaultActionGroupId={DEFAULT_ACTION_GROUP_ID}
defaultActionGroupId={DEFAULT_ACTION_GROUP.id}
actionGroups={siemRuleActionGroups}
setActionGroupIdByIndex={setActionGroupIdByIndex}
setActionIdByIndex={setActionIdByIndex}
setAlertProperty={setAlertProperty}
setActionParamsProperty={setActionParamsProperty}

View file

@ -7,11 +7,11 @@
import { Logger } from 'src/core/server';
import { schema } from '@kbn/config-schema';
import { NOTIFICATIONS_ID, SERVER_APP_ID } from '../../../../common/constants';
import { siemRuleActionGroups } from '../../../../common';
import { NotificationAlertTypeDefinition } from './types';
import { getSignalsCount } from './get_signals_count';
import { RuleAlertAttributes } from '../signals/types';
import { siemRuleActionGroups } from '../signals/siem_rule_action_groups';
import { scheduleNotificationActions } from './schedule_notification_actions';
import { getNotificationResultsLink } from './utils';
import { parseScheduleDates } from '../../../../common/detection_engine/parse_schedule_dates';

View file

@ -43,7 +43,7 @@ import {
createSearchAfterReturnTypeFromResponse,
} from './utils';
import { signalParamsSchema } from './signal_params_schema';
import { siemRuleActionGroups } from './siem_rule_action_groups';
import { siemRuleActionGroups } from '../../../../common';
import { findMlSignals } from './find_ml_signals';
import { findThresholdSignals } from './find_threshold_signals';
import { bulkCreateMlSignals } from './bulk_create_ml_signals';

View file

@ -112,8 +112,6 @@ describe('action_form', () => {
};
describe('action_form in alert', () => {
let wrapper: ReactWrapper<any>;
async function setup(customActions?: AlertAction[]) {
const { loadAllActions } = jest.requireMock('../../lib/action_connector_api');
loadAllActions.mockResolvedValueOnce([
@ -217,7 +215,7 @@ describe('action_form', () => {
mutedInstanceIds: [],
} as unknown) as Alert;
wrapper = mountWithIntl(
const wrapper = mountWithIntl(
<ActionForm
actions={initialAlert.actions}
messageVariables={[
@ -228,6 +226,10 @@ describe('action_form', () => {
setActionIdByIndex={(id: string, index: number) => {
initialAlert.actions[index].id = id;
}}
actionGroups={[{ id: 'default', name: 'Default' }]}
setActionGroupIdByIndex={(group: string, index: number) => {
initialAlert.actions[index].group = group;
}}
setAlertProperty={(_updatedActions: AlertAction[]) => {}}
setActionParamsProperty={(key: string, value: any, index: number) =>
(initialAlert.actions[index] = { ...initialAlert.actions[index], [key]: value })
@ -297,13 +299,16 @@ describe('action_form', () => {
await nextTick();
wrapper.update();
});
return wrapper;
}
it('renders available action cards', async () => {
await setup();
const wrapper = await setup();
const actionOption = wrapper.find(
`[data-test-subj="${actionType.id}-ActionTypeSelectOption"]`
);
wrapper.debug();
expect(actionOption.exists()).toBeTruthy();
expect(
wrapper
@ -314,7 +319,7 @@ describe('action_form', () => {
});
it('does not render action types disabled by config', async () => {
await setup();
const wrapper = await setup();
const actionOption = wrapper.find(
'[data-test-subj="disabled-by-config-ActionTypeSelectOption"]'
);
@ -322,52 +327,72 @@ describe('action_form', () => {
});
it('render action types which is preconfigured only (disabled by config and with preconfigured connectors)', async () => {
await setup();
const wrapper = await setup();
const actionOption = wrapper.find('[data-test-subj="preconfigured-ActionTypeSelectOption"]');
expect(actionOption.exists()).toBeTruthy();
});
it('renders available action groups for the selected action type', async () => {
const wrapper = await setup();
const actionOption = wrapper.find(
`[data-test-subj="${actionType.id}-ActionTypeSelectOption"]`
);
actionOption.first().simulate('click');
const actionGroupsSelect = wrapper.find(
`[data-test-subj="addNewActionConnectorActionGroup-0"]`
);
expect((actionGroupsSelect.first().props() as any).options).toMatchInlineSnapshot(`
Array [
Object {
"data-test-subj": "addNewActionConnectorActionGroup-0-option-default",
"inputDisplay": "Default",
"value": "default",
},
]
`);
});
it('renders available connectors for the selected action type', async () => {
await setup();
const wrapper = await setup();
const actionOption = wrapper.find(
`[data-test-subj="${actionType.id}-ActionTypeSelectOption"]`
);
actionOption.first().simulate('click');
const combobox = wrapper.find(`[data-test-subj="selectActionConnector-${actionType.id}"]`);
expect((combobox.first().props() as any).options).toMatchInlineSnapshot(`
Array [
Object {
"id": "test",
"key": "test",
"label": "Test connector ",
},
Object {
"id": "test2",
"key": "test2",
"label": "Test connector 2 (preconfigured)",
},
]
`);
Array [
Object {
"id": "test",
"key": "test",
"label": "Test connector ",
},
Object {
"id": "test2",
"key": "test2",
"label": "Test connector 2 (preconfigured)",
},
]
`);
});
it('renders only preconfigured connectors for the selected preconfigured action type', async () => {
await setup();
const wrapper = await setup();
const actionOption = wrapper.find('[data-test-subj="preconfigured-ActionTypeSelectOption"]');
actionOption.first().simulate('click');
const combobox = wrapper.find('[data-test-subj="selectActionConnector-preconfigured"]');
expect((combobox.first().props() as any).options).toMatchInlineSnapshot(`
Array [
Object {
"id": "test3",
"key": "test3",
"label": "Preconfigured Only (preconfigured)",
},
]
`);
Array [
Object {
"id": "test3",
"key": "test3",
"label": "Preconfigured Only (preconfigured)",
},
]
`);
});
it('does not render "Add connector" button for preconfigured only action type', async () => {
await setup();
const wrapper = await setup();
const actionOption = wrapper.find('[data-test-subj="preconfigured-ActionTypeSelectOption"]');
actionOption.first().simulate('click');
const preconfigPannel = wrapper.find('[data-test-subj="alertActionAccordion-default"]');
@ -378,7 +403,7 @@ describe('action_form', () => {
});
it('renders action types disabled by license', async () => {
await setup();
const wrapper = await setup();
const actionOption = wrapper.find(
'[data-test-subj="disabled-by-license-ActionTypeSelectOption"]'
);
@ -391,7 +416,7 @@ describe('action_form', () => {
});
it(`shouldn't render action types without params component`, async () => {
await setup();
const wrapper = await setup();
const actionOption = wrapper.find(
`[data-test-subj="${actionTypeWithoutParams.id}-ActionTypeSelectOption"]`
);

View file

@ -102,7 +102,7 @@ export const ActionForm = ({
const [activeActionItem, setActiveActionItem] = useState<ActiveActionConnectorState | undefined>(
undefined
);
const [isAddActionPanelOpen, setIsAddActionPanelOpen] = useState<boolean>(actions.length === 0);
const [isAddActionPanelOpen, setIsAddActionPanelOpen] = useState<boolean>(true);
const [connectors, setConnectors] = useState<ActionConnector[]>([]);
const [isLoadingConnectors, setIsLoadingConnectors] = useState<boolean>(false);
const [isLoadingActionTypes, setIsLoadingActionTypes] = useState<boolean>(false);
@ -341,7 +341,7 @@ export const ActionForm = ({
singleSelection={{ asPlainText: true }}
options={optionsList}
id={`selectActionConnector-${actionItem.id}`}
data-test-subj={`selectActionConnector-${index}`}
data-test-subj={`selectActionConnector-${actionItem.actionTypeId}`}
selectedOptions={getSelectedOptions(actionItem.id)}
onChange={(selectedOptions) => {
setActionIdByIndex(selectedOptions[0].id ?? '', index);