Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions x-pack/plugins/actions/server/action_type_registry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ describe('register()', () => {
actionTypeRegistry.register({
id: 'my-action-type',
name: 'My action type',
minimumLicenseRequired: 'basic',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe there's an hook later, but this seems to violate "non-built-in action types can only set a gold+ license"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can set anything here but it will be validated when you register. The registration validation exists here: https://github.com/elastic/kibana/pull/58668/files#diff-adc6606fd00ebc8b46eecefae314f1b5R187 and the built ins don't go through there, they register directly to the actionTypeRegistry.

executor,
});
expect(actionTypeRegistry.has('my-action-type')).toEqual(true);
Expand All @@ -55,12 +56,14 @@ describe('register()', () => {
actionTypeRegistry.register({
id: 'my-action-type',
name: 'My action type',
minimumLicenseRequired: 'basic',
executor,
});
expect(() =>
actionTypeRegistry.register({
id: 'my-action-type',
name: 'My action type',
minimumLicenseRequired: 'basic',
executor,
})
).toThrowErrorMatchingInlineSnapshot(
Expand All @@ -73,6 +76,7 @@ describe('register()', () => {
actionTypeRegistry.register({
id: 'my-action-type',
name: 'My action type',
minimumLicenseRequired: 'basic',
executor,
});
expect(mockTaskManager.registerTaskDefinitions).toHaveBeenCalledTimes(1);
Expand All @@ -94,13 +98,15 @@ describe('get()', () => {
actionTypeRegistry.register({
id: 'my-action-type',
name: 'My action type',
minimumLicenseRequired: 'basic',
executor,
});
const actionType = actionTypeRegistry.get('my-action-type');
expect(actionType).toMatchInlineSnapshot(`
Object {
"executor": [Function],
"id": "my-action-type",
"minimumLicenseRequired": "basic",
"name": "My action type",
}
`);
Expand All @@ -120,6 +126,7 @@ describe('list()', () => {
actionTypeRegistry.register({
id: 'my-action-type',
name: 'My action type',
minimumLicenseRequired: 'basic',
executor,
});
const actionTypes = actionTypeRegistry.list();
Expand All @@ -144,6 +151,7 @@ describe('has()', () => {
actionTypeRegistry.register({
id: 'my-action-type',
name: 'My action type',
minimumLicenseRequired: 'basic',
executor,
});
expect(actionTypeRegistry.has('my-action-type'));
Expand Down
7 changes: 7 additions & 0 deletions x-pack/plugins/actions/server/actions_client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ describe('create()', () => {
actionTypeRegistry.register({
id: 'my-action-type',
name: 'My action type',
minimumLicenseRequired: 'basic',
executor,
});
savedObjectsClient.create.mockResolvedValueOnce(savedObjectCreateResult);
Expand Down Expand Up @@ -100,6 +101,7 @@ describe('create()', () => {
actionTypeRegistry.register({
id: 'my-action-type',
name: 'My action type',
minimumLicenseRequired: 'basic',
validate: {
config: schema.object({
param1: schema.string(),
Expand Down Expand Up @@ -140,6 +142,7 @@ describe('create()', () => {
actionTypeRegistry.register({
id: 'my-action-type',
name: 'My action type',
minimumLicenseRequired: 'basic',
executor,
});
savedObjectsClient.create.mockResolvedValueOnce({
Expand Down Expand Up @@ -233,6 +236,7 @@ describe('create()', () => {
actionTypeRegistry.register({
id: 'my-action-type',
name: 'My action type',
minimumLicenseRequired: 'basic',
executor,
});
savedObjectsClient.create.mockResolvedValueOnce(savedObjectCreateResult);
Expand Down Expand Up @@ -346,6 +350,7 @@ describe('update()', () => {
actionTypeRegistry.register({
id: 'my-action-type',
name: 'My action type',
minimumLicenseRequired: 'basic',
executor,
});
savedObjectsClient.get.mockResolvedValueOnce({
Expand Down Expand Up @@ -407,6 +412,7 @@ describe('update()', () => {
actionTypeRegistry.register({
id: 'my-action-type',
name: 'My action type',
minimumLicenseRequired: 'basic',
validate: {
config: schema.object({
param1: schema.string(),
Expand Down Expand Up @@ -440,6 +446,7 @@ describe('update()', () => {
actionTypeRegistry.register({
id: 'my-action-type',
name: 'My action type',
minimumLicenseRequired: 'basic',
executor,
});
savedObjectsClient.get.mockResolvedValueOnce({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export function getActionType(params: GetActionTypeParams): ActionType {
const { logger, configurationUtilities } = params;
return {
id: '.email',
minimumLicenseRequired: 'gold',
name: i18n.translate('xpack.actions.builtin.emailTitle', {
defaultMessage: 'Email',
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const ParamsSchema = schema.object({
export function getActionType({ logger }: { logger: Logger }): ActionType {
return {
id: '.index',
minimumLicenseRequired: 'basic',
name: i18n.translate('xpack.actions.builtin.esIndexTitle', {
defaultMessage: 'Index',
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export function getActionType({
}): ActionType {
return {
id: '.pagerduty',
minimumLicenseRequired: 'gold',
name: i18n.translate('xpack.actions.builtin.pagerdutyTitle', {
defaultMessage: 'PagerDuty',
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const ParamsSchema = schema.object({
export function getActionType({ logger }: { logger: Logger }): ActionType {
return {
id: '.server-log',
minimumLicenseRequired: 'basic',
name: i18n.translate('xpack.actions.builtin.serverLogTitle', {
defaultMessage: 'Server log',
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export function getActionType({
}): ActionType {
return {
id: '.servicenow',
minimumLicenseRequired: 'gold',

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mikecote @peterschretlen I just spoke with @MikePaquette, can we make this platinum. There is a good chance that's where it will land

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I went ahead and made it platinum here: 9669ebd.

name: i18n.translate('xpack.actions.builtin.servicenowTitle', {
defaultMessage: 'ServiceNow',
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export function getActionType({
}): ActionType {
return {
id: '.slack',
minimumLicenseRequired: 'gold',
name: i18n.translate('xpack.actions.builtin.slackTitle', {
defaultMessage: 'Slack',
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export function getActionType({
}): ActionType {
return {
id: '.webhook',
minimumLicenseRequired: 'gold',
name: i18n.translate('xpack.actions.builtin.webhookTitle', {
defaultMessage: 'Webhook',
}),
Expand Down
16 changes: 11 additions & 5 deletions x-pack/plugins/actions/server/lib/action_executor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { encryptedSavedObjectsMock } from '../../../encrypted_saved_objects/serv
import { savedObjectsClientMock, loggingServiceMock } from '../../../../../src/core/server/mocks';
import { eventLoggerMock } from '../../../event_log/server/mocks';
import { spacesServiceMock } from '../../../spaces/server/spaces_service/spaces_service.mock';
import { ActionType } from '../types';

const actionExecutor = new ActionExecutor({ isESOUsingEphemeralEncryptionKey: false });
const savedObjectsClient = savedObjectsClientMock.create();
Expand Down Expand Up @@ -50,9 +51,10 @@ beforeEach(() => {
});

test('successfully executes', async () => {
const actionType = {
const actionType: jest.Mocked<ActionType> = {
id: 'test',
name: 'Test',
minimumLicenseRequired: 'basic',
executor: jest.fn(),
};
const actionSavedObject = {
Expand Down Expand Up @@ -96,9 +98,10 @@ test('successfully executes', async () => {
});

test('provides empty config when config and / or secrets is empty', async () => {
const actionType = {
const actionType: jest.Mocked<ActionType> = {
id: 'test',
name: 'Test',
minimumLicenseRequired: 'basic',
executor: jest.fn(),
};
const actionSavedObject = {
Expand All @@ -120,9 +123,10 @@ test('provides empty config when config and / or secrets is empty', async () =>
});

test('throws an error when config is invalid', async () => {
const actionType = {
const actionType: jest.Mocked<ActionType> = {
id: 'test',
name: 'Test',
minimumLicenseRequired: 'basic',
validate: {
config: schema.object({
param1: schema.string(),
Expand Down Expand Up @@ -152,9 +156,10 @@ test('throws an error when config is invalid', async () => {
});

test('throws an error when params is invalid', async () => {
const actionType = {
const actionType: jest.Mocked<ActionType> = {
id: 'test',
name: 'Test',
minimumLicenseRequired: 'basic',
validate: {
params: schema.object({
param1: schema.string(),
Expand Down Expand Up @@ -191,9 +196,10 @@ test('throws an error when failing to load action through savedObjectsClient', a
});

test('returns an error if actionType is not enabled', async () => {
const actionType = {
const actionType: jest.Mocked<ActionType> = {
id: 'test',
name: 'Test',
minimumLicenseRequired: 'basic',
executor: jest.fn(),
};
const actionSavedObject = {
Expand Down
19 changes: 17 additions & 2 deletions x-pack/plugins/actions/server/lib/validate_with_schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,26 @@ const executor: ExecutorType = async options => {
};

test('should validate when there are no validators', () => {
const actionType: ActionType = { id: 'foo', name: 'bar', executor };
const actionType: ActionType = {
id: 'foo',
name: 'bar',
minimumLicenseRequired: 'basic',
executor,
};
const testValue = { any: ['old', 'thing'] };

const result = validateConfig(actionType, testValue);
expect(result).toEqual(testValue);
});

test('should validate when there are no individual validators', () => {
const actionType: ActionType = { id: 'foo', name: 'bar', executor, validate: {} };
const actionType: ActionType = {
id: 'foo',
name: 'bar',
minimumLicenseRequired: 'basic',
executor,
validate: {},
};

let result;
const testValue = { any: ['old', 'thing'] };
Expand All @@ -42,6 +53,7 @@ test('should validate when validators return incoming value', () => {
const actionType: ActionType = {
id: 'foo',
name: 'bar',
minimumLicenseRequired: 'basic',
executor,
validate: {
params: selfValidator,
Expand Down Expand Up @@ -69,6 +81,7 @@ test('should validate when validators return different values', () => {
const actionType: ActionType = {
id: 'foo',
name: 'bar',
minimumLicenseRequired: 'basic',
executor,
validate: {
params: selfValidator,
Expand Down Expand Up @@ -99,6 +112,7 @@ test('should throw with expected error when validators fail', () => {
const actionType: ActionType = {
id: 'foo',
name: 'bar',
minimumLicenseRequired: 'basic',
executor,
validate: {
params: erroringValidator,
Expand Down Expand Up @@ -127,6 +141,7 @@ test('should work with @kbn/config-schema', () => {
const actionType: ActionType = {
id: 'foo',
name: 'bar',
minimumLicenseRequired: 'basic',
executor,
validate: {
params: testSchema,
Expand Down
56 changes: 55 additions & 1 deletion x-pack/plugins/actions/server/plugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { ActionsPlugin, ActionsPluginsSetup, ActionsPluginsStart } from './plugin';
import { PluginInitializerContext } from '../../../../src/core/server';
import { coreMock, httpServerMock } from '../../../../src/core/server/mocks';
import { licensingMock } from '../../licensing/server/mocks';
import { encryptedSavedObjectsMock } from '../../encrypted_saved_objects/server/mocks';
import { taskManagerMock } from '../../task_manager/server/mocks';
import { eventLogMock } from '../../event_log/server/mocks';
import { ActionType } from './types';
import {
ActionsPlugin,
ActionsPluginsSetup,
ActionsPluginsStart,
PluginSetupContract,
} from './plugin';

describe('Actions Plugin', () => {
describe('setup()', () => {
Expand Down Expand Up @@ -90,6 +96,54 @@ describe('Actions Plugin', () => {
);
});
});

describe('registerType()', () => {
let setup: PluginSetupContract;
const sampleActionType: ActionType = {
id: 'test',
name: 'test',
minimumLicenseRequired: 'basic',
async executor() {},
};

beforeEach(async () => {
setup = await plugin.setup(coreSetup, pluginsSetup);
});

it('should throw error when license type is invalid', async () => {
expect(() =>
setup.registerType({
...sampleActionType,
minimumLicenseRequired: 'foo' as any,
})
).toThrowErrorMatchingInlineSnapshot(`"\\"foo\\" is not a valid license type"`);
});

it('should throw error when license type is less than gold', async () => {
expect(() =>
setup.registerType({
...sampleActionType,
minimumLicenseRequired: 'basic',
})
).toThrowErrorMatchingInlineSnapshot(
`"Third party action type \\"test\\" can only set minimumLicenseRequired to a gold license or higher"`
);
});

it('should not throw when license type is gold', async () => {
setup.registerType({
...sampleActionType,
minimumLicenseRequired: 'gold',
});
});

it('should not throw when license type is higher than gold', async () => {
setup.registerType({
...sampleActionType,
minimumLicenseRequired: 'platinum',
});
});
});
});
describe('start()', () => {
let plugin: ActionsPlugin;
Expand Down
Loading