[Lists] Add an instance of ExceptionListClient with server extension 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
This commit is contained in:
Paul Tavares 2022-01-27 15:21:42 -05:00 committed by GitHub
parent 14d6f7c871
commit 80306936c1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 54 additions and 3 deletions

View file

@ -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,
@ -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',
@ -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(),
@ -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();
@ -157,6 +171,7 @@ describe('exception_list_client', () => {
beforeEach(() => {
exceptionListClient = new ExceptionListClient({
enableServerExtensionPoints: false,
request: kibanaRequest,
savedObjectsClient: getExceptionListSavedObjectClientMock(),
serverExtensionsClient:
extensionPointStorageContext.extensionPointStorage.getClient(),
@ -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',
@ -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();
@ -332,6 +357,7 @@ describe('exception_list_client', () => {
beforeEach(() => {
exceptionListClient = new ExceptionListClient({
enableServerExtensionPoints: false,
request: kibanaRequest,
savedObjectsClient: getExceptionListSavedObjectClientMock(),
serverExtensionsClient:
extensionPointStorageContext.extensionPointStorage.getClient(),

View file

@ -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,
};
}

View file

@ -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 {
@ -122,6 +123,7 @@ export const createExtensionPointStorageMock = (
return {
callbackContext: {
exceptionListClient: {} as unknown as ExceptionListClient,
request: httpServerMock.createKibanaRequest(),
},
exceptionPreCreate,

View file

@ -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,
})
);
}

View file

@ -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
@ -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: {