Skip to content

Commit

Permalink
Merge branch 'main' into reporting-chunk-size
Browse files Browse the repository at this point in the history
  • Loading branch information
kibanamachine authored Apr 23, 2024
2 parents 2b4bb1b + 441d00d commit 8f35d53
Show file tree
Hide file tree
Showing 75 changed files with 1,621 additions and 391 deletions.
15 changes: 7 additions & 8 deletions test/functional/page_objects/settings_page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,7 @@ export class SettingsPageObject extends FtrService {
) {
await this.clickAddField();
await this.setFieldName(name);
await this.setFieldTypeComposite();
await this.setFieldType('Composite');
await this.setCompositeScript(script);
if (subfieldCount > 0) {
await this.testSubjects.find(`typeField_${subfieldCount - 1}`);
Expand Down Expand Up @@ -874,14 +874,13 @@ export class SettingsPageObject extends FtrService {
}

async setFieldType(type: string) {
const typeFieldDataTestSubj = 'typeField';
this.log.debug('set type = ' + type);
await this.comboBox.set('typeField', type);
}

async setFieldTypeComposite() {
this.log.debug('set type = Composite');
await this.testSubjects.setValue('typeField', 'Composite');
await this.browser.pressKeys(this.browser.keys.RETURN);
await this.retry.try(async () => {
await this.comboBox.set(typeFieldDataTestSubj, type);
const comboBox = await this.testSubjects.find(typeFieldDataTestSubj);
expect(await this.comboBox.isOptionSelected(comboBox, type)).to.be(true);
});
}

async setFieldScript(script: string) {
Expand Down
13 changes: 11 additions & 2 deletions x-pack/plugins/actions/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,11 @@ import {
ConnectorWithOptionalDeprecation,
} from './application/connector/lib';
import { createSubActionConnectorFramework } from './sub_action_framework';
import { IServiceAbstract, SubActionConnectorType } from './sub_action_framework/types';
import {
ICaseServiceAbstract,
IServiceAbstract,
SubActionConnectorType,
} from './sub_action_framework/types';
import { SubActionConnector } from './sub_action_framework/sub_action_connector';
import { CaseConnector } from './sub_action_framework/case';
import type { IUnsecuredActionsClient } from './unsecured_actions_client/unsecured_actions_client';
Expand Down Expand Up @@ -128,7 +132,12 @@ export interface PluginSetupContract {
isPreconfiguredConnector(connectorId: string): boolean;

getSubActionConnectorClass: <Config, Secrets>() => IServiceAbstract<Config, Secrets>;
getCaseConnectorClass: <Config, Secrets>() => IServiceAbstract<Config, Secrets>;
getCaseConnectorClass: <Config, Secrets, Incident, GetIncidentResponse>() => ICaseServiceAbstract<
Config,
Secrets,
Incident,
GetIncidentResponse
>;
getActionsHealth: () => { hasPermanentEncryptionKey: boolean };
getActionsConfigurationUtilities: () => ActionsConfigurationUtilities;
setEnabledConnectorTypes: (connectorTypes: EnabledConnectorTypes) => void;
Expand Down
178 changes: 144 additions & 34 deletions x-pack/plugins/actions/server/sub_action_framework/case.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* 2.0.
*/

import { schema } from '@kbn/config-schema';
import { loggingSystemMock } from '@kbn/core/server/mocks';
import { MockedLogger } from '@kbn/logging-mocks';
import { actionsConfigMock } from '../actions_config.mock';
Expand All @@ -13,11 +14,24 @@ import { TestCaseConnector } from './mocks';
import { ActionsConfigurationUtilities } from '../actions_config';

describe('CaseConnector', () => {
const pushToServiceParams = { incident: { externalId: null }, comments: [] };
let logger: MockedLogger;
let services: ReturnType<typeof actionsMock.createServices>;
let mockedActionsConfig: jest.Mocked<ActionsConfigurationUtilities>;
let service: TestCaseConnector;
const pushToServiceIncidentParamsSchema = {
name: schema.string(),
category: schema.nullable(schema.string()),
foo: schema.arrayOf(schema.boolean()),
bar: schema.object({
check: schema.nullable(schema.number()),
}),
};

const incidentSchemaMock = { name: 'Test', category: null, foo: [false], bar: { check: 1 } };
const pushToServiceParams = {
incident: { externalId: null, ...incidentSchemaMock },
comments: [],
};

beforeEach(() => {
jest.resetAllMocks();
Expand All @@ -32,14 +46,17 @@ describe('CaseConnector', () => {
timeout: 360000,
});

service = new TestCaseConnector({
configurationUtilities: mockedActionsConfig,
logger,
connector: { id: 'test-id', type: '.test' },
config: { url: 'https://example.com' },
secrets: { username: 'elastic', password: 'changeme' },
services,
});
service = new TestCaseConnector(
{
configurationUtilities: mockedActionsConfig,
logger,
connector: { id: 'test-id', type: '.test' },
config: { url: 'https://example.com' },
secrets: { username: 'elastic', password: 'changeme' },
services,
},
pushToServiceIncidentParamsSchema
);
});

describe('Sub actions', () => {
Expand All @@ -57,19 +74,24 @@ describe('CaseConnector', () => {
const subAction = subActions.get('pushToService');
expect(
subAction?.schema?.validate({
incident: { externalId: 'test' },
incident: { externalId: 'test', ...incidentSchemaMock },
comments: [{ comment: 'comment', commentId: 'comment-id' }],
})
).toEqual({
incident: { externalId: 'test' },
incident: { externalId: 'test', ...incidentSchemaMock },
comments: [{ comment: 'comment', commentId: 'comment-id' }],
});
});

it('should accept null for externalId', async () => {
const subActions = service.getSubActions();
const subAction = subActions.get('pushToService');
expect(subAction?.schema?.validate({ incident: { externalId: null }, comments: [] }));
expect(
subAction?.schema?.validate({
incident: { externalId: null, ...incidentSchemaMock },
comments: [],
})
);
});

it.each([[undefined], [1], [false], [{ test: 'hello' }], [['test']], [{ test: 'hello' }]])(
Expand All @@ -84,7 +106,12 @@ describe('CaseConnector', () => {
it('should accept null for comments', async () => {
const subActions = service.getSubActions();
const subAction = subActions.get('pushToService');
expect(subAction?.schema?.validate({ incident: { externalId: 'test' }, comments: null }));
expect(
subAction?.schema?.validate({
incident: { externalId: 'test', ...incidentSchemaMock },
comments: null,
})
);
});

it.each([
Expand All @@ -101,33 +128,64 @@ describe('CaseConnector', () => {
expect(() => subAction?.schema?.validate({ incident: { externalId: 'test' }, comments }));
});

it('should allow any field in the params', async () => {
it('should throw if necessary schema params not provided', async () => {
const subActions = service.getSubActions();
const subAction = subActions.get('pushToService');

expect(
expect(() =>
subAction?.schema?.validate({
incident: {
externalId: 'test',
foo: 'foo',
bar: 1,
baz: [{ test: 'hello' }, 1, 'test', false],
isValid: false,
val: null,
},
comments: [{ comment: 'comment', commentId: 'comment-id' }],
})
).toEqual({
incident: {
externalId: 'test',
foo: 'foo',
bar: 1,
baz: [{ test: 'hello' }, 1, 'test', false],
isValid: false,
val: null,
},
comments: [{ comment: 'comment', commentId: 'comment-id' }],
});
).toThrow('[incident.name]: expected value of type [string] but got [undefined]');
});

it('should throw if schema params does not match string type', async () => {
const subActions = service.getSubActions();
const subAction = subActions.get('pushToService');

expect(() =>
subAction?.schema?.validate({
incident: {
externalId: 'test',
name: false,
},
})
).toThrow('[incident.name]: expected value of type [string] but got [boolean]');
});

it('should throw if schema params does not match array type', async () => {
const subActions = service.getSubActions();
const subAction = subActions.get('pushToService');

expect(() =>
subAction?.schema?.validate({
incident: {
externalId: 'test',
name: 'sample',
foo: null,
},
})
).toThrow('[incident.foo]: expected value of type [array] but got [null]');
});

it('should throw if schema params does not match nested object type', async () => {
const subActions = service.getSubActions();
const subAction = subActions.get('pushToService');

expect(() =>
subAction?.schema?.validate({
incident: {
externalId: 'test',
name: 'sample',
foo: [true],
bar: { check: 'hello' },
},
})
).toThrow(
'[incident.bar.check]: types that failed validation:\n- [incident.bar.check.0]: expected value of type [number] but got [string]\n- [incident.bar.check.1]: expected value to equal [null]'
);
});
});

Expand All @@ -144,8 +202,8 @@ describe('CaseConnector', () => {

it('should update an incident if externalId is not null', async () => {
const res = await service.pushToService({
...pushToServiceParams,
incident: { externalId: 'test-id' },
incident: { ...pushToServiceParams.incident, externalId: 'test-id' },
comments: [],
});

expect(res).toEqual({
Expand Down Expand Up @@ -212,4 +270,56 @@ describe('CaseConnector', () => {
});
});
});

describe('PushParamsSchema', () => {
let newService: TestCaseConnector;
beforeEach(() => {
jest.resetAllMocks();
jest.clearAllMocks();

const newPushToServiceSchema = {
name: schema.string(),
externalId: schema.number(),
};

newService = new TestCaseConnector(
{
configurationUtilities: mockedActionsConfig,
logger,
connector: { id: 'test-id', type: '.test' },
config: { url: 'https://example.com' },
secrets: { username: 'elastic', password: 'changeme' },
services,
},
newPushToServiceSchema
);
});

it('should add externalId as null', async () => {
const subActions = newService.getSubActions();
const subAction = subActions.get('pushToService');
expect(
subAction?.schema?.validate({
incident: { name: 'foo' },
comments: [],
})
).toEqual({
incident: { name: 'foo', externalId: null },
comments: [],
});
});

it('should not override externalId schema', async () => {
const subActions = newService.getSubActions();
const subAction = subActions.get('pushToService');
expect(() =>
subAction?.schema?.validate({
incident: { name: 'foo', externalId: 123 },
comments: [],
})
).toThrow(
'[incident.externalId]: types that failed validation:\n- [incident.externalId.0]: expected value of type [string] but got [number]\n- [incident.externalId.1]: expected value to equal [null]'
);
});
});
});
Loading

0 comments on commit 8f35d53

Please sign in to comment.