import { Client } from 'elasticsearch' ; import sinon from 'sinon' ; import { ToolingLog } from '@osd/dev-utils' ; import { Stats } from '../../stats' ; type StubStats = Stats & { getTestSummary : ( ) => Record < string , number > ; } ; export const createStubStats = ( ) : StubStats => ( { createdIndex : sinon . stub ( ) , createdAliases : sinon . stub ( ) , deletedIndex : sinon . stub ( ) , skippedIndex : sinon . stub ( ) , archivedIndex : sinon . stub ( ) , getTestSummary ( ) { const summary = { } ; Object . keys ( this ) . forEach ( ( key ) => { if ( this [ key ] . callCount ) { summary [ key ] = this [ key ] . callCount ; } } ) ; return summary ; } , } as any ) ; export const createStubLogger = ( ) : ToolingLog => ( { debug : sinon . stub ( ) , info : sinon . stub ( ) , success : sinon . stub ( ) , warning : sinon . stub ( ) , error : sinon . stub ( ) , } as any ) ; export const createStubIndexRecord = ( index , aliases = { } ) => ( { type : 'index' , value : { index , aliases } , } ) ; export const createStubDocRecord = ( index , id ) => ( { type : 'doc' , value : { index , id } , } ) ; const createOpenSearchClientError = ( errorType ) => { const err = new Error ( `OpenSearch Client Error Stub "${ errorType }"` ) ; ( err as any ) . body = { error : { type : errorType , } , } ; return err ; } ; const indexAlias = ( aliases , index ) => Object . keys ( aliases ) . find ( ( k ) => aliases [ k ] === index ) ; type StubClient = Client ; export const createStubClient = ( existingIndices = [ ] , aliases = { } ) : StubClient => ( { indices : { get : sinon . spy ( async ( { index } ) => { if ( ! existingIndices . includes ( index ) ) { throw createOpenSearchClientError ( 'index_not_found_exception' ) ; } return { [ index ] : { mappings : { } , settings : { } , } , } ; } ) , existsAlias : sinon . spy ( ( { name } ) => { return Promise . resolve ( aliases . hasOwnProperty ( name ) ) ; } ) , getAlias : sinon . spy ( async ( { index , name } ) => { if ( index && existingIndices . indexOf ( index ) >= 0 ) { const result = indexAlias ( aliases , index ) ; return { [ index ] : { aliases : result ? { [ result ] : { } } : { } } } ; } if ( name && aliases [ name ] ) { return { [ aliases [ name ] ] : { aliases : { [ name ] : { } } } } ; } return { status : 404 } ; } ) , updateAliases : sinon . spy ( async ( { body } ) => { body . actions . forEach ( ( { add : { index , alias } } ) => { if ( ! existingIndices . includes ( index ) ) { throw createOpenSearchClientError ( 'index_not_found_exception' ) ; } existingIndices . push ( { index , alias } as any ) ; } ) ; return { ok : true } ; } ) , create : sinon . spy ( async ( { index } ) => { if ( existingIndices . includes ( index ) || aliases . hasOwnProperty ( index ) ) { throw createOpenSearchClientError ( 'resource_already_exists_exception' ) ; } else { existingIndices . push ( index ) ; return { ok : true } ; } } ) , delete : sinon . spy ( async ( { index } ) => { const indices = Array . isArray ( index ) ? index : [ index ] ; if ( indices . every ( ( ix ) => existingIndices . includes ( ix ) ) ) { indices . forEach ( ( ix ) => { const alias = Object . keys ( aliases ) . find ( ( k ) => aliases [ k ] === ix ) ; if ( alias ) { delete aliases [ alias ] ; } } ) ; indices . forEach ( ( ix ) => existingIndices . splice ( existingIndices . indexOf ( ix ) , 1 ) ) ; return { ok : true } ; } else { throw createOpenSearchClientError ( 'index_not_found_exception' ) ; } } ) , exists : sinon . spy ( async ( ) => { throw new Error ( 'Do not use indices.exists(). React to errors instead.' ) ; } ) , } , } as any ) ;