import { Client , ApiResponse } from '@elastic/elasticsearch' ; import { TransportRequestPromise } from '@elastic/elasticsearch/lib/Transport' ; import { OpenSearchClient } from './types' ; import { ICustomClusterClient } from './cluster_client' ; const createInternalClientMock = ( ) : DeeplyMockedKeys < Client > => { const client = new Client ( { node : 'http://localhost' , } ) as any ; const omittedProps = [ '_events' , '_eventsCount' , '_maxListeners' , 'constructor' , 'name' , 'serializer' , 'connectionPool' , 'transport' , 'helpers' , ] ; const getAllPropertyDescriptors = ( obj ) => { const descriptors = Object . entries ( Object . getOwnPropertyDescriptors ( obj ) ) ; let prototype = Object . getPrototypeOf ( obj ) ; while ( prototype != null && prototype !== Object . prototype ) { descriptors . push ( ... Object . entries ( Object . getOwnPropertyDescriptors ( prototype ) ) ) ; prototype = Object . getPrototypeOf ( prototype ) ; } return descriptors ; } ; const mockify = ( obj , omitted = [ ] ) => { const descriptors = getAllPropertyDescriptors ( obj ) ; descriptors . filter ( ( [ key ] ) => ! omitted . includes ( key ) ) . forEach ( ( [ key , descriptor ] ) => { if ( typeof descriptor . value === 'function' ) { obj [ key ] = jest . fn ( ( ) => createSuccessTransportRequestPromise ( { } ) ) ; } else if ( typeof obj [ key ] === 'object' && obj [ key ] != null ) { mockify ( obj [ key ] , omitted ) ; } } ) ; } ; mockify ( client , omittedProps ) ; client . close = jest . fn ( ) . mockReturnValue ( Promise . resolve ( ) ) ; client . child = jest . fn ( ) . mockImplementation ( ( ) => createInternalClientMock ( ) ) ; const mockGetter = ( obj , propertyName ) => { Object . defineProperty ( obj , propertyName , { configurable : true , enumerable : false , get : ( ) => jest . fn ( ) , set : undefined , } ) ; } ; mockGetter ( client , 'on' ) ; mockGetter ( client , 'off' ) ; mockGetter ( client , 'once' ) ; client . transport = { request : jest . fn ( ) , } ; return client as DeeplyMockedKeys < Client > ; } ; export type OpenSearchClientMock = DeeplyMockedKeys < OpenSearchClient > ; const createClientMock = ( ) : OpenSearchClientMock => ( createInternalClientMock ( ) as unknown ) as OpenSearchClientMock ; export interface ScopedClusterClientMock { asInternalUser : OpenSearchClientMock ; asCurrentUser : OpenSearchClientMock ; } const createScopedClusterClientMock = ( ) => { const mock = { asInternalUser : createClientMock ( ) , asCurrentUser : createClientMock ( ) , } ; return mock ; } ; export interface ClusterClientMock { asInternalUser : OpenSearchClientMock ; asScoped : jest . MockedFunction < ( ) => ScopedClusterClientMock > ; } const createClusterClientMock = ( ) => { const mock = { asInternalUser : createClientMock ( ) , asScoped : jest . fn ( ) , } ; mock . asScoped . mockReturnValue ( createScopedClusterClientMock ( ) ) ; return mock ; } ; export type CustomClusterClientMock = jest . Mocked < ICustomClusterClient > & ClusterClientMock ; const createCustomClusterClientMock = ( ) => { const mock = { asInternalUser : createClientMock ( ) , asScoped : jest . fn ( ) , close : jest . fn ( ) , } ; mock . asScoped . mockReturnValue ( createScopedClusterClientMock ( ) ) ; mock . close . mockReturnValue ( Promise . resolve ( ) ) ; return mock ; } ; export type MockedTransportRequestPromise < T > = TransportRequestPromise < T > & { abort : jest . MockedFunction < ( ) => undefined > ; } ; const createSuccessTransportRequestPromise = < T > ( body , { statusCode = 200 } = { } ) : MockedTransportRequestPromise < ApiResponse < T > > => { const response = createApiResponse ( { body , statusCode } ) ; const promise = Promise . resolve ( response ) ; ( promise as MockedTransportRequestPromise < ApiResponse < T > > ) . abort = jest . fn ( ) ; return promise as MockedTransportRequestPromise < ApiResponse < T > > ; } ; const createErrorTransportRequestPromise = ( err ) : MockedTransportRequestPromise < never > => { const promise = Promise . reject ( err ) ; ( promise as MockedTransportRequestPromise < never > ) . abort = jest . fn ( ) ; return promise as MockedTransportRequestPromise < never > ; } ; function createApiResponse ( opts = { } ) { return { body : { } , statusCode : 200 , headers : { } , warnings : [ ] , meta : { } as any , ... opts , } ; } export const opensearchClientMock = { createClusterClient : createClusterClientMock , createCustomClusterClient : createCustomClusterClientMock , createScopedClusterClient : createScopedClusterClientMock , createOpenSearchClient : createClientMock , createInternalClient : createInternalClientMock , createSuccessTransportRequestPromise , createErrorTransportRequestPromise , createApiResponse , } ;