[Alerting] Ensure a component is specified on the actionParamsFields field in all tests (#86789)

This PR makes the `actionParamsFields` field required, as it is in use by all plugins anyway and only tests were omitting it.
To make this change more streamlined I've added a `createMockActionTypeModel` helper which generates a basic mock `ActionTypeModel`.
This commit is contained in:
Gidi Meir Morris 2021-01-04 16:17:53 +00:00 committed by GitHub
parent 5e5a410204
commit 084bc7be9b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 62 additions and 81 deletions

View file

@ -51,15 +51,12 @@ describe('stepRuleActions utils', () => {
const actionTypeRegistry = actionTypeRegistryMock.create();
beforeAll(() => {
const actionMock = {
const actionMock = actionTypeRegistryMock.createMockActionTypeModel({
id: 'id',
iconClass: 'iconClass',
validateParams: validateParamsMock,
selectMessage: 'message',
validateConnector: jest.fn(),
actionConnectorFields: null,
actionParamsFields: null,
};
});
actionTypeRegistry.get.mockReturnValue(actionMock);
});

View file

@ -1116,7 +1116,7 @@ Each action type should be defined as an `ActionTypeModel` object with the follo
validateConnector: (connector: any) => ValidationResult;
validateParams: (actionParams: any) => ValidationResult;
actionConnectorFields: React.FunctionComponent<any> | null;
actionParamsFields: any;
actionParamsFields: React.LazyExoticComponent<ComponentType<ActionParamsProps<ActionParams>>>;
```
|Property|Description|
|---|---|

View file

@ -4,7 +4,9 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { ActionTypeRegistryContract } from '../types';
import React, { lazy, Fragment } from 'react';
import uuid from 'uuid';
import { ActionTypeModel, ActionTypeRegistryContract } from '../types';
const createActionTypeRegistryMock = () => {
const mocked: jest.Mocked<ActionTypeRegistryContract> = {
@ -16,6 +18,27 @@ const createActionTypeRegistryMock = () => {
return mocked;
};
const mockedActionParamsFields = lazy(async () => ({
default() {
return React.createElement(Fragment);
},
}));
const createMockActionTypeModel = (actionType: Partial<ActionTypeModel> = {}): ActionTypeModel => {
const id = uuid.v4();
return {
id,
iconClass: `iconClass-${id}`,
selectMessage: `selectMessage-${id}`,
validateConnector: jest.fn(),
validateParams: jest.fn(),
actionConnectorFields: null,
actionParamsFields: mockedActionParamsFields,
...actionType,
};
};
export const actionTypeRegistryMock = {
create: createActionTypeRegistryMock,
createMockActionTypeModel,
};

View file

@ -13,7 +13,7 @@ jest.mock('../../../common/lib/kibana');
describe('action_connector_form', () => {
it('renders action_connector_form', () => {
const actionType = {
const actionType = actionTypeRegistryMock.createMockActionTypeModel({
id: 'my-action-type',
iconClass: 'test',
selectMessage: 'test',
@ -24,9 +24,7 @@ describe('action_connector_form', () => {
const validationResult = { errors: {} };
return validationResult;
},
actionConnectorFields: null,
actionParamsFields: null,
};
});
actionTypeRegistry.get.mockReturnValue(actionType);
actionTypeRegistry.has.mockReturnValue(true);

View file

@ -115,20 +115,6 @@ describe('action_form', () => {
actionParamsFields: mockedActionParamsFields,
};
const actionTypeWithoutParams = {
id: 'my-action-type-without-params',
iconClass: 'test',
selectMessage: 'test',
validateConnector: (): ValidationResult => {
return { errors: {} };
},
validateParams: (): ValidationResult => {
const validationResult = { errors: {} };
return validationResult;
},
actionConnectorFields: null,
actionParamsFields: null,
};
const useKibanaMock = useKibana as jest.Mocked<typeof useKibana>;
describe('action_form in alert', () => {
@ -207,7 +193,6 @@ describe('action_form', () => {
disabledByLicenseActionType,
disabledByActionType,
preconfiguredOnly,
actionTypeWithoutParams,
]);
actionTypeRegistry.has.mockReturnValue(true);
actionTypeRegistry.get.mockReturnValue(actionType);
@ -327,14 +312,6 @@ describe('action_form', () => {
enabledInLicense: true,
minimumLicenseRequired: 'basic',
},
{
id: actionTypeWithoutParams.id,
name: 'Action type without params',
enabled: true,
enabledInConfig: true,
enabledInLicense: true,
minimumLicenseRequired: 'basic',
},
]}
/>
);
@ -537,14 +514,6 @@ describe('action_form', () => {
).toBeTruthy();
});
it(`shouldn't render action types without params component`, async () => {
const wrapper = await setup();
const actionOption = wrapper.find(
`[data-test-subj="${actionTypeWithoutParams.id}-ActionTypeSelectOption"]`
);
expect(actionOption.exists()).toBeFalsy();
});
it('recognizes actions with broken connectors', async () => {
await setup([
{

View file

@ -34,7 +34,7 @@ describe('connector_add_flyout', () => {
it('renders action type menu with proper EuiCards for registered action types', () => {
const onActionTypeChange = jest.fn();
const actionType = {
const actionType = actionTypeRegistryMock.createMockActionTypeModel({
id: 'my-action-type',
iconClass: 'test',
selectMessage: 'test',
@ -46,8 +46,7 @@ describe('connector_add_flyout', () => {
return validationResult;
},
actionConnectorFields: null,
actionParamsFields: null,
};
});
actionTypeRegistry.get.mockReturnValueOnce(actionType);
const wrapper = mountWithIntl(
@ -72,7 +71,7 @@ describe('connector_add_flyout', () => {
it(`doesn't renders action types that are disabled via config`, () => {
const onActionTypeChange = jest.fn();
const actionType = {
const actionType = actionTypeRegistryMock.createMockActionTypeModel({
id: 'my-action-type',
iconClass: 'test',
selectMessage: 'test',
@ -84,8 +83,7 @@ describe('connector_add_flyout', () => {
return validationResult;
},
actionConnectorFields: null,
actionParamsFields: null,
};
});
actionTypeRegistry.get.mockReturnValueOnce(actionType);
const wrapper = mountWithIntl(
@ -110,7 +108,7 @@ describe('connector_add_flyout', () => {
it(`renders action types as disabled when disabled by license`, () => {
const onActionTypeChange = jest.fn();
const actionType = {
const actionType = actionTypeRegistryMock.createMockActionTypeModel({
id: 'my-action-type',
iconClass: 'test',
selectMessage: 'test',
@ -122,8 +120,7 @@ describe('connector_add_flyout', () => {
return validationResult;
},
actionConnectorFields: null,
actionParamsFields: null,
};
});
actionTypeRegistry.get.mockReturnValueOnce(actionType);
const wrapper = mountWithIntl(

View file

@ -192,7 +192,7 @@ describe('connector_add_flyout', () => {
let count = 0;
function createActionType() {
return {
return actionTypeRegistryMock.createMockActionTypeModel({
id: `my-action-type-${++count}`,
iconClass: 'test',
selectMessage: 'test',
@ -204,6 +204,5 @@ function createActionType() {
return validationResult;
},
actionConnectorFields: null,
actionParamsFields: null,
};
});
}

View file

@ -33,7 +33,7 @@ describe('connector_add_modal', () => {
};
});
it('renders connector modal form if addModalVisible is true', () => {
const actionTypeModel = {
const actionTypeModel = actionTypeRegistryMock.createMockActionTypeModel({
id: 'my-action-type',
iconClass: 'test',
selectMessage: 'test',
@ -45,8 +45,7 @@ describe('connector_add_modal', () => {
return validationResult;
},
actionConnectorFields: null,
actionParamsFields: null,
};
});
actionTypeRegistry.get.mockReturnValueOnce(actionTypeModel);
actionTypeRegistry.has.mockReturnValue(true);

View file

@ -45,7 +45,7 @@ describe('connector_edit_flyout', () => {
config: {},
};
const actionType = {
const actionType = actionTypeRegistryMock.createMockActionTypeModel({
id: 'test-action-type-id',
iconClass: 'test',
selectMessage: 'test',
@ -57,8 +57,7 @@ describe('connector_edit_flyout', () => {
return validationResult;
},
actionConnectorFields: null,
actionParamsFields: null,
};
});
actionTypeRegistry.get.mockReturnValue(actionType);
actionTypeRegistry.has.mockReturnValue(true);
useKibanaMock().services.actionTypeRegistry = actionTypeRegistry;
@ -90,7 +89,7 @@ describe('connector_edit_flyout', () => {
config: {},
};
const actionType = {
const actionType = actionTypeRegistryMock.createMockActionTypeModel({
id: 'test-action-type-id',
iconClass: 'test',
selectMessage: 'test',
@ -102,8 +101,7 @@ describe('connector_edit_flyout', () => {
return validationResult;
},
actionConnectorFields: null,
actionParamsFields: null,
};
});
actionTypeRegistry.get.mockReturnValue(actionType);
actionTypeRegistry.has.mockReturnValue(true);
useKibanaMock().services.actionTypeRegistry = actionTypeRegistry;

View file

@ -103,7 +103,7 @@ describe('alert_add', () => {
requiresAppContext: false,
};
const actionTypeModel = {
const actionTypeModel = actionTypeRegistryMock.createMockActionTypeModel({
id: 'my-action-type',
iconClass: 'test',
selectMessage: 'test',
@ -115,8 +115,7 @@ describe('alert_add', () => {
return validationResult;
},
actionConnectorFields: null,
actionParamsFields: null,
};
});
actionTypeRegistry.get.mockReturnValueOnce(actionTypeModel);
actionTypeRegistry.has.mockReturnValue(true);
alertTypeRegistry.list.mockReturnValue([alertType]);

View file

@ -61,7 +61,7 @@ describe('alert_edit', () => {
requiresAppContext: false,
};
const actionTypeModel = {
const actionTypeModel = actionTypeRegistryMock.createMockActionTypeModel({
id: 'my-action-type',
iconClass: 'test',
selectMessage: 'test',
@ -73,8 +73,7 @@ describe('alert_edit', () => {
return validationResult;
},
actionConnectorFields: null,
actionParamsFields: null,
};
});
const alert: Alert = {
id: 'ab5661e0-197e-45ee-b477-302d89193b5e',

View file

@ -35,7 +35,7 @@ describe('alert_form', () => {
requiresAppContext: false,
};
const actionType = {
const actionType = actionTypeRegistryMock.createMockActionTypeModel({
id: 'my-action-type',
iconClass: 'test',
selectMessage: 'test',
@ -47,8 +47,7 @@ describe('alert_form', () => {
return validationResult;
},
actionConnectorFields: null,
actionParamsFields: null,
};
});
const alertTypeNonEditable = {
id: 'non-edit-alert-type',

View file

@ -6,6 +6,7 @@
import { TypeRegistry } from './type_registry';
import { ValidationResult, AlertTypeModel, ActionTypeModel } from '../types';
import { actionTypeRegistryMock } from './action_type_registry.mock';
export const ExpressionComponent: React.FunctionComponent = () => {
return null;
@ -30,7 +31,7 @@ const getTestActionType = (
iconClass?: string,
selectedMessage?: string
): ActionTypeModel<any, any> => {
return {
return actionTypeRegistryMock.createMockActionTypeModel({
id: id || 'my-action-type',
iconClass: iconClass || 'test',
selectMessage: selectedMessage || 'test',
@ -42,8 +43,7 @@ const getTestActionType = (
return validationResult;
},
actionConnectorFields: null,
actionParamsFields: null,
};
});
};
beforeEach(() => jest.resetAllMocks());
@ -74,7 +74,12 @@ describe('get()', () => {
expect(actionType).toMatchInlineSnapshot(`
Object {
"actionConnectorFields": null,
"actionParamsFields": null,
"actionParamsFields": Object {
"$$typeof": Symbol(react.lazy),
"_ctor": [Function],
"_result": null,
"_status": -1,
},
"iconClass": "test",
"id": "my-action-type-snapshot",
"selectMessage": "test",
@ -97,7 +102,8 @@ describe('get()', () => {
describe('list()', () => {
test('returns list of action types', () => {
const actionTypeRegistry = new TypeRegistry<ActionTypeModel>();
actionTypeRegistry.register(getTestActionType());
const actionType = getTestActionType();
actionTypeRegistry.register(actionType);
const actionTypes = actionTypeRegistry.list();
expect(actionTypes).toEqual([
{
@ -105,7 +111,7 @@ describe('list()', () => {
iconClass: 'test',
selectMessage: 'test',
actionConnectorFields: null,
actionParamsFields: null,
actionParamsFields: actionType.actionParamsFields,
validateConnector: actionTypes[0].validateConnector,
validateParams: actionTypes[0].validateParams,
},

View file

@ -86,9 +86,7 @@ export interface ActionTypeModel<ActionConfig = any, ActionSecrets = any, Action
ActionConnectorFieldsProps<UserConfiguredActionConnector<ActionConfig, ActionSecrets>>
>
> | null;
actionParamsFields: React.LazyExoticComponent<
ComponentType<ActionParamsProps<ActionParams>>
> | null;
actionParamsFields: React.LazyExoticComponent<ComponentType<ActionParamsProps<ActionParams>>>;
}
export interface ValidationResult {