Skip to content

Commit

Permalink
[Lists] Add an instance of ExceptionListClient with server extensio…
Browse files Browse the repository at this point in the history
…n points turned off to context object provided to callbacks (#123885)

* Add an instance of ExceptionListClient with server extension points turned off to the `context` provided to callbacks
* Unit test cases to validate context
  • Loading branch information
paul-tavares authored Jan 27, 2022
1 parent 14d6f7c commit 8030693
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
createExtensionPointStorageMock,
} from '../extension_points/extension_point_storage.mock';
import type { ExtensionPointCallbackDataArgument } from '../extension_points';
import { httpServerMock } from '../../../../../../src/core/server/mocks';

import {
getCreateExceptionListItemOptionsMock,
Expand Down Expand Up @@ -49,13 +50,16 @@ describe('exception_list_client', () => {
describe('server extension points execution', () => {
let extensionPointStorageContext: ExtensionPointStorageContextMock;
let exceptionListClient: ExceptionListClient;
let kibanaRequest: ReturnType<typeof httpServerMock.createKibanaRequest>;

beforeEach(() => {
extensionPointStorageContext = createExtensionPointStorageMock();
kibanaRequest = httpServerMock.createKibanaRequest();
});

it('should initialize class instance with `enableServerExtensionPoints` enabled by default', async () => {
exceptionListClient = new ExceptionListClient({
request: kibanaRequest,
savedObjectsClient: getExceptionListSavedObjectClientMock(),
serverExtensionsClient: extensionPointStorageContext.extensionPointStorage.getClient(),
user: 'elastic',
Expand Down Expand Up @@ -98,6 +102,7 @@ describe('exception_list_client', () => {
describe('and server extension points are enabled', () => {
beforeEach(() => {
exceptionListClient = new ExceptionListClient({
request: kibanaRequest,
savedObjectsClient: getExceptionListSavedObjectClientMock(),
serverExtensionsClient:
extensionPointStorageContext.extensionPointStorage.getClient(),
Expand All @@ -111,6 +116,15 @@ describe('exception_list_client', () => {
expect(getExtensionPointCallback()).toHaveBeenCalled();
});

it('should provide `context` object to extension point callbacks', async () => {
await callExceptionListClientMethod();

expect(getExtensionPointCallback().mock.calls[0][0].context).toEqual({
exceptionListClient: expect.any(ExceptionListClient),
request: kibanaRequest,
});
});

it('should error if extension point callback throws an error', async () => {
const error = new Error('foo');
const extensionCallback = getExtensionPointCallback();
Expand Down Expand Up @@ -157,6 +171,7 @@ describe('exception_list_client', () => {
beforeEach(() => {
exceptionListClient = new ExceptionListClient({
enableServerExtensionPoints: false,
request: kibanaRequest,
savedObjectsClient: getExceptionListSavedObjectClientMock(),
serverExtensionsClient:
extensionPointStorageContext.extensionPointStorage.getClient(),
Expand Down Expand Up @@ -305,6 +320,7 @@ describe('exception_list_client', () => {
(methodName, callExceptionListClientMethod, getExtensionPointCallback) => {
beforeEach(() => {
exceptionListClient = new ExceptionListClient({
request: kibanaRequest,
savedObjectsClient: getExceptionListSavedObjectClientMock(),
serverExtensionsClient: extensionPointStorageContext.extensionPointStorage.getClient(),
user: 'elastic',
Expand All @@ -317,6 +333,15 @@ describe('exception_list_client', () => {
expect(getExtensionPointCallback()).toHaveBeenCalled();
});

it('should provide `context` object to extension point callbacks', async () => {
await callExceptionListClientMethod();

expect(getExtensionPointCallback().mock.calls[0][0].context).toEqual({
exceptionListClient: expect.any(ExceptionListClient),
request: kibanaRequest,
});
});

it('should error if extension point callback throws an error', async () => {
const error = new Error('foo');
const extensionCallback = getExtensionPointCallback();
Expand All @@ -332,6 +357,7 @@ describe('exception_list_client', () => {
beforeEach(() => {
exceptionListClient = new ExceptionListClient({
enableServerExtensionPoints: false,
request: kibanaRequest,
savedObjectsClient: getExceptionListSavedObjectClientMock(),
serverExtensionsClient:
extensionPointStorageContext.extensionPointStorage.getClient(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,24 @@ export class ExceptionListClient {
}

private getServerExtensionCallbackContext(): ServerExtensionCallbackContext {
const { user, serverExtensionsClient, savedObjectsClient, request } = this;
let exceptionListClient: undefined | ExceptionListClient;

return {
// Lazy getter so that we only initialize a new instance of the class if needed
get exceptionListClient(): ExceptionListClient {
if (!exceptionListClient) {
exceptionListClient = new ExceptionListClient({
enableServerExtensionPoints: false,
request,
savedObjectsClient,
serverExtensionsClient,
user,
});
}

return exceptionListClient;
},
request: this.request,
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import { MockedLogger, loggerMock } from '@kbn/logging/mocks';

import { httpServerMock } from '../../../../../../src/core/server/mocks';
import { ExceptionListClient } from '../exception_lists/exception_list_client';

import { ExtensionPointStorage } from './extension_point_storage';
import {
Expand Down Expand Up @@ -122,6 +123,7 @@ export const createExtensionPointStorageMock = (

return {
callbackContext: {
exceptionListClient: {} as unknown as ExceptionListClient,
request: httpServerMock.createKibanaRequest(),
},
exceptionPreCreate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,7 @@ describe('When using the ExtensionPointStorageClient', () => {
if (extensionPointsMock.type === 'exceptionsListPreCreateItem') {
expect(extensionPointsMock.callback).toHaveBeenCalledWith(
expect.objectContaining({
context: {
request: expect.any(Object),
},
context: callbackContext,
})
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
UpdateExceptionListItemOptions,
} from '../exception_lists/exception_list_client_types';
import { PromiseFromStreams } from '../exception_lists/import_exception_list_and_items';
import type { ExceptionListClient } from '../exception_lists/exception_list_client';

/**
* The `this` context provided to extension point's callback function
Expand All @@ -30,6 +31,13 @@ export interface ServerExtensionCallbackContext {
* is not triggered via one of the HTTP handlers
*/
request?: KibanaRequest;

/**
* An `ExceptionListClient` instance that **DOES NOT** execute server extension point callbacks.
* This client should be used when needing to access Exception List content from within an Extension
* Point to avoid circular infinite loops
*/
exceptionListClient: ExceptionListClient;
}

export type ServerExtensionCallback<A extends object | void = void, R = A> = (args: {
Expand Down

0 comments on commit 8030693

Please sign in to comment.