diff --git a/src/core/server/elasticsearch/elasticsearch_service.mock.ts b/src/core/server/elasticsearch/elasticsearch_service.mock.ts index 672331199ffa0..88bd426b893a7 100644 --- a/src/core/server/elasticsearch/elasticsearch_service.mock.ts +++ b/src/core/server/elasticsearch/elasticsearch_service.mock.ts @@ -19,18 +19,30 @@ import { BehaviorSubject } from 'rxjs'; import { ClusterClient } from './cluster_client'; +import { ScopedClusterClient } from './scoped_cluster_client'; import { ElasticsearchConfig } from './elasticsearch_config'; import { ElasticsearchService, ElasticsearchServiceSetup } from './elasticsearch_service'; +const createScopedClusterClientMock = (): jest.Mocked> => ({ + callAsInternalUser: jest.fn(), + callAsCurrentUser: jest.fn(), +}); + +const createClusterClientMock = (): jest.Mocked> => ({ + callAsInternalUser: jest.fn(), + asScoped: jest.fn().mockImplementation(createScopedClusterClientMock), + close: jest.fn(), +}); + const createSetupContractMock = () => { const setupContract: ElasticsearchServiceSetup = { legacy: { config$: new BehaviorSubject({} as ElasticsearchConfig), }, - createClient: jest.fn(), - adminClient$: new BehaviorSubject({} as ClusterClient), - dataClient$: new BehaviorSubject({} as ClusterClient), + createClient: jest.fn().mockImplementation(createClusterClientMock), + adminClient$: new BehaviorSubject((createClusterClientMock() as unknown) as ClusterClient), + dataClient$: new BehaviorSubject((createClusterClientMock() as unknown) as ClusterClient), }; return setupContract; }; @@ -50,4 +62,6 @@ const createMock = () => { export const elasticsearchServiceMock = { create: createMock, createSetupContract: createSetupContractMock, + createClusterClient: createClusterClientMock, + createScopedClusterClient: createScopedClusterClientMock, }; diff --git a/src/core/server/http/cookie_session_storage.mocks.ts b/src/core/server/http/cookie_session_storage.mocks.ts new file mode 100644 index 0000000000000..3d1ddb08b6053 --- /dev/null +++ b/src/core/server/http/cookie_session_storage.mocks.ts @@ -0,0 +1,46 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { SessionStorageFactory, SessionStorage } from './session_storage'; + +const createSessionStorageMock = (): jest.Mocked> => ({ + get: jest.fn().mockResolvedValue({}), + set: jest.fn(), + clear: jest.fn(), +}); + +type ReturnMocked = { + [K in keyof T]: T[K] extends (...args: any[]) => infer U + ? (...args: any[]) => jest.Mocked + : T[K]; +}; + +type DeepMocked = jest.Mocked>; + +const creatSessionStorageFactoryMock = () => { + const mocked: DeepMocked> = { + asScoped: jest.fn(), + }; + mocked.asScoped.mockImplementation(createSessionStorageMock); + return mocked; +}; + +export const sessionStorageMock = { + create: createSessionStorageMock, + createFactory: creatSessionStorageFactoryMock, +}; diff --git a/src/core/server/http/http_server.mocks.ts b/src/core/server/http/http_server.mocks.ts index df1620b021836..fbf98aa4f9c99 100644 --- a/src/core/server/http/http_server.mocks.ts +++ b/src/core/server/http/http_server.mocks.ts @@ -19,7 +19,55 @@ import { Request, ResponseToolkit } from 'hapi'; import { merge } from 'lodash'; -import { KibanaRequest } from './router'; +import querystring from 'querystring'; + +import { schema } from '@kbn/config-schema'; + +import { KibanaRequest, RouteMethod } from './router'; + +interface RequestFixtureOptions { + headers?: Record; + params?: Record; + body?: Record; + query?: Record; + path?: string; + method?: RouteMethod; +} + +function createKibanaRequestMock({ + path = '/path', + headers = { accept: 'something/html' }, + params = {}, + body = {}, + query = {}, + method = 'get', +}: RequestFixtureOptions = {}) { + const queryString = querystring.stringify(query); + return KibanaRequest.from( + { + headers, + params, + query, + payload: body, + path, + method, + url: { + path, + query: queryString, + search: queryString ? `?${queryString}` : queryString, + }, + route: { settings: {} }, + raw: { + req: {}, + }, + } as any, + { + params: schema.object({}, { allowUnknowns: true }), + body: schema.object({}, { allowUnknowns: true }), + query: schema.object({}, { allowUnknowns: true }), + } + ); +} type DeepPartial = T extends any[] ? DeepPartialArray @@ -54,7 +102,7 @@ function createRawResponseToolkitMock(customization: DeepPartial KibanaRequest.from(createRawRequestMock()), + createKibanaRequest: createKibanaRequestMock, createRawRequest: createRawRequestMock, createRawResponseToolkit: createRawResponseToolkitMock, }; diff --git a/src/core/server/http/http_service.mock.ts b/src/core/server/http/http_service.mock.ts index 0444caab1deb1..b3afc8d84f6b7 100644 --- a/src/core/server/http/http_service.mock.ts +++ b/src/core/server/http/http_service.mock.ts @@ -21,10 +21,22 @@ import { Server } from 'hapi'; import { HttpService } from './http_service'; import { HttpServerSetup } from './http_server'; import { HttpServiceSetup } from './http_service'; +import { OnPreAuthToolkit } from './lifecycle/on_pre_auth'; +import { AuthToolkit } from './lifecycle/auth'; +import { OnPostAuthToolkit } from './lifecycle/on_post_auth'; +import { sessionStorageMock } from './cookie_session_storage.mocks'; type ServiceSetupMockType = jest.Mocked & { basePath: jest.Mocked; }; + +const createBasePathMock = (): jest.Mocked => ({ + get: jest.fn(), + set: jest.fn(), + prepend: jest.fn(), + remove: jest.fn(), +}); + const createSetupContractMock = () => { const setupContract: ServiceSetupMockType = { // we can mock some hapi server method when we need it @@ -33,12 +45,7 @@ const createSetupContractMock = () => { registerAuth: jest.fn(), registerOnPostAuth: jest.fn(), registerRouter: jest.fn(), - basePath: { - get: jest.fn(), - set: jest.fn(), - prepend: jest.fn(), - remove: jest.fn(), - }, + basePath: createBasePathMock(), auth: { get: jest.fn(), isAuthenticated: jest.fn(), @@ -48,17 +55,12 @@ const createSetupContractMock = () => { isTlsEnabled: false, }; setupContract.createNewServer.mockResolvedValue({} as HttpServerSetup); + setupContract.registerAuth.mockResolvedValue({ + sessionStorageFactory: sessionStorageMock.createFactory(), + }); return setupContract; }; -const createStartContractMock = () => { - const startContract = { - isListening: jest.fn(), - }; - startContract.isListening.mockReturnValue(true); - return startContract; -}; - type HttpServiceContract = PublicMethodsOf; const createHttpServiceMock = () => { const mocked: jest.Mocked = { @@ -67,12 +69,32 @@ const createHttpServiceMock = () => { stop: jest.fn(), }; mocked.setup.mockResolvedValue(createSetupContractMock()); - mocked.start.mockResolvedValue(createStartContractMock()); return mocked; }; +const createOnPreAuthToolkitMock = (): jest.Mocked => ({ + next: jest.fn(), + redirected: jest.fn(), + rejected: jest.fn(), +}); + +const createAuthToolkitMock = (): jest.Mocked => ({ + authenticated: jest.fn(), + redirected: jest.fn(), + rejected: jest.fn(), +}); + +const createOnPostAuthToolkitMock = (): jest.Mocked => ({ + next: jest.fn(), + redirected: jest.fn(), + rejected: jest.fn(), +}); + export const httpServiceMock = { create: createHttpServiceMock, + createBasePath: createBasePathMock, createSetupContract: createSetupContractMock, - createStartContract: createStartContractMock, + createOnPreAuthToolkit: createOnPreAuthToolkitMock, + createAuthToolkit: createAuthToolkitMock, + createOnPostAuthToolkit: createOnPostAuthToolkitMock, }; diff --git a/src/core/server/logging/logging_service.mock.ts b/src/core/server/logging/logging_service.mock.ts index 4bef2fe745c7d..d423e6b064e5f 100644 --- a/src/core/server/logging/logging_service.mock.ts +++ b/src/core/server/logging/logging_service.mock.ts @@ -20,6 +20,7 @@ // Test helpers to simplify mocking logs and collecting all their outputs import { Logger } from './logger'; import { LoggingService } from './logging_service'; +import { LoggerFactory } from './logger_factory'; type LoggingServiceContract = PublicMethodsOf; type MockedLogger = jest.Mocked; @@ -50,8 +51,8 @@ const createLoggingServiceMock = () => { return mocked; }; -const collectLoggingServiceMock = (mocked: ReturnType) => { - const mockLog = mocked.get() as MockedLogger; +const collectLoggingServiceMock = (loggerFactory: LoggerFactory) => { + const mockLog = loggerFactory.get() as MockedLogger; return { debug: mockLog.debug.mock.calls, error: mockLog.error.mock.calls, @@ -63,13 +64,14 @@ const collectLoggingServiceMock = (mocked: ReturnType) => { - const mockLog = mocked.get() as MockedLogger; - mocked.get.mockClear(); - mocked.asLoggerFactory.mockClear(); - mocked.upgrade.mockClear(); - mocked.stop.mockClear(); +const clearLoggingServiceMock = (loggerFactory: LoggerFactory) => { + const mockedLoggerFactory = (loggerFactory as unknown) as jest.Mocked; + mockedLoggerFactory.get.mockClear(); + mockedLoggerFactory.asLoggerFactory.mockClear(); + mockedLoggerFactory.upgrade.mockClear(); + mockedLoggerFactory.stop.mockClear(); + const mockLog = loggerFactory.get() as MockedLogger; mockLog.debug.mockClear(); mockLog.info.mockClear(); mockLog.warn.mockClear(); diff --git a/src/core/server/mocks.ts b/src/core/server/mocks.ts index af0eed6ba833d..518221d2b9bd5 100644 --- a/src/core/server/mocks.ts +++ b/src/core/server/mocks.ts @@ -22,6 +22,8 @@ import { loggingServiceMock } from './logging/logging_service.mock'; import { elasticsearchServiceMock } from './elasticsearch/elasticsearch_service.mock'; import { httpServiceMock } from './http/http_service.mock'; +export { httpServerMock } from './http/http_server.mocks'; +export { sessionStorageMock } from './http/cookie_session_storage.mocks'; export { configServiceMock } from './config/config_service.mock'; export { elasticsearchServiceMock } from './elasticsearch/elasticsearch_service.mock'; export { httpServiceMock } from './http/http_service.mock'; @@ -38,7 +40,7 @@ export function pluginInitializerContextConfigMock(config: T) { } function pluginInitializerContextMock(config: T) { - const mock: jest.Mocked> = { + const mock: PluginInitializerContext = { logger: loggingServiceMock.create(), env: { mode: {