diff --git a/x-pack/plugins/index_management/__jest__/client_integration/helpers/http_requests.ts b/x-pack/plugins/index_management/__jest__/client_integration/helpers/http_requests.ts index 64b8b79d4b2a1..4726286319e52 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/helpers/http_requests.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/helpers/http_requests.ts @@ -5,10 +5,11 @@ * 2.0. */ -import sinon, { SinonFakeServer } from 'sinon'; +import { httpServiceMock } from '../../../../../../src/core/public/mocks'; import { API_BASE_PATH } from '../../../common/constants'; type HttpResponse = Record | any[]; +type HttpMethod = 'GET' | 'PUT' | 'DELETE' | 'POST'; export interface ResponseError { statusCode: number; @@ -17,139 +18,105 @@ export interface ResponseError { } // Register helpers to mock HTTP Requests -const registerHttpRequestMockHelpers = (server: SinonFakeServer) => { - const setLoadTemplatesResponse = (response: HttpResponse = []) => { - server.respondWith('GET', `${API_BASE_PATH}/index_templates`, [ - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(response), - ]); - }; - - const setLoadIndicesResponse = (response: HttpResponse = []) => { - server.respondWith('GET', `${API_BASE_PATH}/indices`, [ - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(response), - ]); - }; - - const setReloadIndicesResponse = (response: HttpResponse = []) => { - server.respondWith('POST', `${API_BASE_PATH}/indices/reload`, [ - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(response), - ]); - }; - - const setLoadDataStreamsResponse = (response: HttpResponse = []) => { - server.respondWith('GET', `${API_BASE_PATH}/data_streams`, [ - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(response), - ]); - }; - - const setLoadDataStreamResponse = (response: HttpResponse = []) => { - server.respondWith('GET', `${API_BASE_PATH}/data_streams/:id`, [ - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(response), - ]); - }; - - const setDeleteDataStreamResponse = (response: HttpResponse = []) => { - server.respondWith('POST', `${API_BASE_PATH}/delete_data_streams`, [ - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(response), - ]); - }; - - const setDeleteTemplateResponse = (response: HttpResponse = []) => { - server.respondWith('POST', `${API_BASE_PATH}/delete_index_templates`, [ - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(response), - ]); - }; - - const setLoadTemplateResponse = (response?: HttpResponse, error?: any) => { - const status = error ? error.status || 400 : 200; - const body = error ? error.body : response; - - server.respondWith('GET', `${API_BASE_PATH}/index_templates/:id`, [ - status, - { 'Content-Type': 'application/json' }, - JSON.stringify(body), - ]); - }; - - const setCreateTemplateResponse = (response?: HttpResponse, error?: any) => { - const status = error ? error.body.status || 400 : 200; - const body = error ? JSON.stringify(error.body) : JSON.stringify(response); - - server.respondWith('POST', `${API_BASE_PATH}/index_templates`, [ - status, - { 'Content-Type': 'application/json' }, - body, - ]); - }; - - const setUpdateTemplateResponse = (response?: HttpResponse, error?: any) => { - const status = error ? error.status || 400 : 200; - const body = error ? JSON.stringify(error.body) : JSON.stringify(response); - - server.respondWith('PUT', `${API_BASE_PATH}/index_templates/:name`, [ - status, - { 'Content-Type': 'application/json' }, - body, - ]); - }; - - const setUpdateIndexSettingsResponse = (response?: HttpResponse, error?: ResponseError) => { - const status = error ? error.statusCode || 400 : 200; - const body = error ?? response; - - server.respondWith('PUT', `${API_BASE_PATH}/settings/:name`, [ - status, - { 'Content-Type': 'application/json' }, - JSON.stringify(body), - ]); - }; - - const setSimulateTemplateResponse = (response?: HttpResponse, error?: any) => { - const status = error ? error.status || 400 : 200; - const body = error ? JSON.stringify(error.body) : JSON.stringify(response); - - server.respondWith('POST', `${API_BASE_PATH}/index_templates/simulate`, [ - status, - { 'Content-Type': 'application/json' }, - body, - ]); - }; - - const setLoadComponentTemplatesResponse = (response?: HttpResponse, error?: any) => { - const status = error ? error.status || 400 : 200; - const body = error ? error.body : response; - - server.respondWith('GET', `${API_BASE_PATH}/component_templates`, [ - status, - { 'Content-Type': 'application/json' }, - JSON.stringify(body), - ]); - }; - - const setLoadNodesPluginsResponse = (response?: HttpResponse, error?: any) => { - const status = error ? error.status || 400 : 200; - const body = error ? error.body : response; - - server.respondWith('GET', `${API_BASE_PATH}/nodes/plugins`, [ - status, - { 'Content-Type': 'application/json' }, - JSON.stringify(body), - ]); - }; +const registerHttpRequestMockHelpers = ( + httpSetup: ReturnType +) => { + const mockResponses = new Map>>( + ['GET', 'PUT', 'DELETE', 'POST'].map( + (method) => [method, new Map()] as [HttpMethod, Map>] + ) + ); + + const mockMethodImplementation = (method: HttpMethod, path: string) => { + return mockResponses.get(method)?.get(path) ?? Promise.resolve({}); + }; + + httpSetup.get.mockImplementation((path) => + mockMethodImplementation('GET', path as unknown as string) + ); + httpSetup.delete.mockImplementation((path) => + mockMethodImplementation('DELETE', path as unknown as string) + ); + httpSetup.post.mockImplementation((path) => + mockMethodImplementation('POST', path as unknown as string) + ); + httpSetup.put.mockImplementation((path) => + mockMethodImplementation('PUT', path as unknown as string) + ); + + const mockResponse = (method: HttpMethod, path: string, response?: unknown, error?: unknown) => { + const defuse = (promise: Promise) => { + promise.catch(() => {}); + return promise; + }; + + return mockResponses + .get(method)! + .set(path, error ? defuse(Promise.reject({ body: error })) : Promise.resolve(response)); + }; + + const setLoadTemplatesResponse = (response?: HttpResponse, error?: ResponseError) => + mockResponse('GET', `${API_BASE_PATH}/index_templates`, response, error); + + const setLoadIndicesResponse = (response?: HttpResponse, error?: ResponseError) => + mockResponse('GET', `${API_BASE_PATH}/indices`, response, error); + + const setReloadIndicesResponse = (response?: HttpResponse, error?: ResponseError) => + mockResponse('POST', `${API_BASE_PATH}/indices/reload`, response, error); + + const setLoadDataStreamsResponse = (response?: HttpResponse, error?: ResponseError) => + mockResponse('GET', `${API_BASE_PATH}/data_streams`, response, error); + + const setLoadDataStreamResponse = ( + dataStreamId: string, + response?: HttpResponse, + error?: ResponseError + ) => + mockResponse( + 'GET', + `${API_BASE_PATH}/data_streams/${encodeURIComponent(dataStreamId)}`, + response, + error + ); + + const setDeleteDataStreamResponse = (response?: HttpResponse, error?: ResponseError) => + mockResponse('POST', `${API_BASE_PATH}/delete_data_streams`, response, error); + + const setDeleteTemplateResponse = (response?: HttpResponse, error?: ResponseError) => + mockResponse('POST', `${API_BASE_PATH}/delete_index_templates`, response, error); + + const setLoadTemplateResponse = ( + templateId: string, + response?: HttpResponse, + error?: ResponseError + ) => mockResponse('GET', `${API_BASE_PATH}/index_templates/${templateId}`, response, error); + + const setCreateTemplateResponse = (response?: HttpResponse, error?: ResponseError) => + mockResponse('POST', `${API_BASE_PATH}/index_templates`, response, error); + + const setUpdateTemplateResponse = ( + templateId: string, + response?: HttpResponse, + error?: ResponseError + ) => mockResponse('PUT', `${API_BASE_PATH}/index_templates/${templateId}`, response, error); + + const setUpdateIndexSettingsResponse = ( + indexName: string, + response?: HttpResponse, + error?: ResponseError + ) => mockResponse('PUT', `${API_BASE_PATH}/settings/${indexName}`, response, error); + + const setSimulateTemplateResponse = (response?: HttpResponse, error?: ResponseError) => + mockResponse('POST', `${API_BASE_PATH}/index_templates/simulate`, response, error); + + const setLoadComponentTemplatesResponse = (response?: HttpResponse, error?: ResponseError) => + mockResponse('GET', `${API_BASE_PATH}/component_templates`, response, error); + + const setLoadNodesPluginsResponse = (response?: HttpResponse, error?: ResponseError) => + mockResponse('GET', `${API_BASE_PATH}/nodes/plugins`, response, error); + + const setLoadTelemetryResponse = (response?: HttpResponse, error?: ResponseError) => + mockResponse('GET', '/api/ui_counters/_report', response, error); return { setLoadTemplatesResponse, @@ -166,22 +133,16 @@ const registerHttpRequestMockHelpers = (server: SinonFakeServer) => { setSimulateTemplateResponse, setLoadComponentTemplatesResponse, setLoadNodesPluginsResponse, + setLoadTelemetryResponse, }; }; export const init = () => { - const server = sinon.fakeServer.create(); - server.respondImmediately = true; - - // Define default response for unhandled requests. - // We make requests to APIs which don't impact the component under test, e.g. UI metric telemetry, - // and we can mock them all with a 200 instead of mocking each one individually. - server.respondWith([200, {}, 'DefaultSinonMockServerResponse']); - - const httpRequestsMockHelpers = registerHttpRequestMockHelpers(server); + const httpSetup = httpServiceMock.createSetupContract(); + const httpRequestsMockHelpers = registerHttpRequestMockHelpers(httpSetup); return { - server, + httpSetup, httpRequestsMockHelpers, }; }; diff --git a/x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx b/x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx index 1682431900a84..c5b077ef00333 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx @@ -6,11 +6,10 @@ */ import React from 'react'; -import axios from 'axios'; -import axiosXhrAdapter from 'axios/lib/adapters/xhr'; import { merge } from 'lodash'; import SemVer from 'semver/classes/semver'; +import { HttpSetup } from 'src/core/public'; import { notificationServiceMock, docLinksServiceMock, @@ -36,7 +35,6 @@ import { import { componentTemplatesMockDependencies } from '../../../public/application/components/component_templates/__jest__'; import { init as initHttpRequests } from './http_requests'; -const mockHttpClient = axios.create({ adapter: axiosXhrAdapter }); const { GlobalFlyoutProvider } = GlobalFlyout; export const services = { @@ -64,30 +62,24 @@ const { Provider: KibanaReactContextProvider } = createKibanaReactContext({ }); export const setupEnvironment = () => { - // Mock initialization of services - // @ts-ignore - httpService.setup(mockHttpClient); breadcrumbService.setup(() => undefined); documentationService.setup(docLinksServiceMock.createStartContract()); notificationService.setup(notificationServiceMock.createSetupContract()); - const { server, httpRequestsMockHelpers } = initHttpRequests(); - - return { - server, - httpRequestsMockHelpers, - }; + return initHttpRequests(); }; export const WithAppDependencies = - (Comp: any, overridingDependencies: any = {}) => + (Comp: any, httpSetup: HttpSetup, overridingDependencies: any = {}) => (props: any) => { + httpService.setup(httpSetup); const mergedDependencies = merge({}, appDependencies, overridingDependencies); + return ( - + diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts index e3184cadbdc49..2abea510bb944 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts @@ -10,6 +10,7 @@ import { ReactWrapper } from 'enzyme'; import { EuiDescriptionListDescription } from '@elastic/eui'; import { registerTestBed, TestBed, AsyncTestBedConfig, findTestSubject } from '@kbn/test/jest'; +import { HttpSetup } from 'src/core/public'; import { DataStream } from '../../../common'; import { IndexManagementHome } from '../../../public/application/sections/home'; import { indexManagementStore } from '../../../public/application/store'; @@ -41,7 +42,10 @@ export interface DataStreamsTabTestBed extends TestBed { findDetailPanelIndexTemplateLink: () => ReactWrapper; } -export const setup = async (overridingDependencies: any = {}): Promise => { +export const setup = async ( + httpSetup: HttpSetup, + overridingDependencies: any = {} +): Promise => { const testBedConfig: AsyncTestBedConfig = { store: () => indexManagementStore(services as any), memoryRouter: { @@ -52,7 +56,7 @@ export const setup = async (overridingDependencies: any = {}): Promise { - const { server, httpRequestsMockHelpers } = setupEnvironment(); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); let testBed: DataStreamsTabTestBed; - afterAll(() => { - server.restore(); - }); - describe('when there are no data streams', () => { beforeEach(async () => { httpRequestsMockHelpers.setLoadIndicesResponse([]); @@ -53,7 +49,7 @@ describe('Data Streams tab', () => { }); test('displays an empty prompt', async () => { - testBed = await setup({ + testBed = await setup(httpSetup, { url: urlServiceMock, }); @@ -69,7 +65,7 @@ describe('Data Streams tab', () => { }); test('when Ingest Manager is disabled, goes to index templates tab when "Get started" link is clicked', async () => { - testBed = await setup({ + testBed = await setup(httpSetup, { plugins: {}, url: urlServiceMock, }); @@ -89,7 +85,7 @@ describe('Data Streams tab', () => { }); test('when Fleet is enabled, links to Fleet', async () => { - testBed = await setup({ + testBed = await setup(httpSetup, { plugins: { isFleetEnabled: true }, url: urlServiceMock, }); @@ -112,7 +108,7 @@ describe('Data Streams tab', () => { }); httpRequestsMockHelpers.setLoadDataStreamsResponse([hiddenDataStream]); - testBed = await setup({ + testBed = await setup(httpSetup, { plugins: {}, url: urlServiceMock, }); @@ -156,13 +152,13 @@ describe('Data Streams tab', () => { }), ]); - setLoadDataStreamResponse(dataStreamForDetailPanel); + setLoadDataStreamResponse(dataStreamForDetailPanel.name, dataStreamForDetailPanel); const indexTemplate = fixtures.getTemplate({ name: 'indexTemplate' }); setLoadTemplatesResponse({ templates: [indexTemplate], legacyTemplates: [] }); - setLoadTemplateResponse(indexTemplate); + setLoadTemplateResponse(indexTemplate.name, indexTemplate); - testBed = await setup({ history: createMemoryHistory() }); + testBed = await setup(httpSetup, { history: createMemoryHistory() }); await act(async () => { testBed.actions.goToDataStreamsList(); }); @@ -181,7 +177,6 @@ describe('Data Streams tab', () => { test('has a button to reload the data streams', async () => { const { exists, actions } = testBed; - const totalRequests = server.requests.length; expect(exists('reloadButton')).toBe(true); @@ -189,13 +184,14 @@ describe('Data Streams tab', () => { actions.clickReloadButton(); }); - expect(server.requests.length).toBe(totalRequests + 1); - expect(server.requests[server.requests.length - 1].url).toBe(`${API_BASE_PATH}/data_streams`); + expect(httpSetup.get).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/data_streams`, + expect.anything() + ); }); test('has a switch that will reload the data streams with additional stats when clicked', async () => { const { exists, actions, table, component } = testBed; - const totalRequests = server.requests.length; expect(exists('includeStatsSwitch')).toBe(true); @@ -205,9 +201,10 @@ describe('Data Streams tab', () => { }); component.update(); - // A request is sent, but sinon isn't capturing the query parameters for some reason. - expect(server.requests.length).toBe(totalRequests + 1); - expect(server.requests[server.requests.length - 1].url).toBe(`${API_BASE_PATH}/data_streams`); + expect(httpSetup.get).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/data_streams`, + expect.anything() + ); // The table renders with the stats columns though. const { tableCellsValues } = table.getMetaData('dataStreamTable'); @@ -279,19 +276,17 @@ describe('Data Streams tab', () => { await clickConfirmDelete(); - const { method, url, requestBody } = server.requests[server.requests.length - 1]; - - expect(method).toBe('POST'); - expect(url).toBe(`${API_BASE_PATH}/delete_data_streams`); - expect(JSON.parse(JSON.parse(requestBody).body)).toEqual({ - dataStreams: ['dataStream1'], - }); + expect(httpSetup.post).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/delete_data_streams`, + expect.objectContaining({ body: JSON.stringify({ dataStreams: ['dataStream1'] }) }) + ); }); }); describe('detail panel', () => { test('opens when the data stream name in the table is clicked', async () => { const { actions, findDetailPanel, findDetailPanelTitle } = testBed; + httpRequestsMockHelpers.setLoadDataStreamResponse('dataStream1'); await actions.clickNameAt(0); expect(findDetailPanel().length).toBe(1); expect(findDetailPanelTitle()).toBe('dataStream1'); @@ -315,13 +310,10 @@ describe('Data Streams tab', () => { await clickConfirmDelete(); - const { method, url, requestBody } = server.requests[server.requests.length - 1]; - - expect(method).toBe('POST'); - expect(url).toBe(`${API_BASE_PATH}/delete_data_streams`); - expect(JSON.parse(JSON.parse(requestBody).body)).toEqual({ - dataStreams: ['dataStream1'], - }); + expect(httpSetup.post).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/delete_data_streams`, + expect.objectContaining({ body: JSON.stringify({ dataStreams: ['dataStream1'] }) }) + ); }); test('clicking index template name navigates to the index template details', async () => { @@ -358,9 +350,9 @@ describe('Data Streams tab', () => { const dataStreamPercentSign = createDataStreamPayload({ name: '%dataStream' }); setLoadDataStreamsResponse([dataStreamPercentSign]); - setLoadDataStreamResponse(dataStreamPercentSign); + setLoadDataStreamResponse(dataStreamPercentSign.name, dataStreamPercentSign); - testBed = await setup({ + testBed = await setup(httpSetup, { history: createMemoryHistory(), url: urlServiceMock, }); @@ -396,10 +388,11 @@ describe('Data Streams tab', () => { name: 'dataStream1', ilmPolicyName: 'my_ilm_policy', }); + setLoadDataStreamsResponse([dataStreamForDetailPanel]); - setLoadDataStreamResponse(dataStreamForDetailPanel); + setLoadDataStreamResponse(dataStreamForDetailPanel.name, dataStreamForDetailPanel); - testBed = await setup({ + testBed = await setup(httpSetup, { history: createMemoryHistory(), url: urlServiceMock, }); @@ -417,10 +410,11 @@ describe('Data Streams tab', () => { const { setLoadDataStreamsResponse, setLoadDataStreamResponse } = httpRequestsMockHelpers; const dataStreamForDetailPanel = createDataStreamPayload({ name: 'dataStream1' }); + setLoadDataStreamsResponse([dataStreamForDetailPanel]); - setLoadDataStreamResponse(dataStreamForDetailPanel); + setLoadDataStreamResponse(dataStreamForDetailPanel.name, dataStreamForDetailPanel); - testBed = await setup({ + testBed = await setup(httpSetup, { history: createMemoryHistory(), url: urlServiceMock, }); @@ -442,10 +436,11 @@ describe('Data Streams tab', () => { name: 'dataStream1', ilmPolicyName: 'my_ilm_policy', }); + setLoadDataStreamsResponse([dataStreamForDetailPanel]); - setLoadDataStreamResponse(dataStreamForDetailPanel); + setLoadDataStreamResponse(dataStreamForDetailPanel.name, dataStreamForDetailPanel); - testBed = await setup({ + testBed = await setup(httpSetup, { history: createMemoryHistory(), url: { locators: { @@ -476,9 +471,10 @@ describe('Data Streams tab', () => { }, }); const nonManagedDataStream = createDataStreamPayload({ name: 'non-managed-data-stream' }); + httpRequestsMockHelpers.setLoadDataStreamsResponse([managedDataStream, nonManagedDataStream]); - testBed = await setup({ + testBed = await setup(httpSetup, { history: createMemoryHistory(), url: urlServiceMock, }); @@ -520,9 +516,10 @@ describe('Data Streams tab', () => { name: 'hidden-data-stream', hidden: true, }); + httpRequestsMockHelpers.setLoadDataStreamsResponse([hiddenDataStream]); - testBed = await setup({ + testBed = await setup(httpSetup, { history: createMemoryHistory(), url: urlServiceMock, }); @@ -561,7 +558,7 @@ describe('Data Streams tab', () => { beforeEach(async () => { setLoadDataStreamsResponse([dataStreamWithDelete, dataStreamNoDelete]); - testBed = await setup({ history: createMemoryHistory(), url: urlServiceMock }); + testBed = await setup(httpSetup, { history: createMemoryHistory(), url: urlServiceMock }); await act(async () => { testBed.actions.goToDataStreamsList(); }); @@ -599,7 +596,7 @@ describe('Data Streams tab', () => { actions: { clickNameAt }, find, } = testBed; - setLoadDataStreamResponse(dataStreamWithDelete); + setLoadDataStreamResponse(dataStreamWithDelete.name, dataStreamWithDelete); await clickNameAt(1); expect(find('deleteDataStreamButton').exists()).toBeTruthy(); @@ -610,7 +607,7 @@ describe('Data Streams tab', () => { actions: { clickNameAt }, find, } = testBed; - setLoadDataStreamResponse(dataStreamNoDelete); + setLoadDataStreamResponse(dataStreamNoDelete.name, dataStreamNoDelete); await clickNameAt(0); expect(find('deleteDataStreamButton').exists()).toBeFalsy(); diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/home.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/home.helpers.ts index ad8aceb7d56b8..19d4e82bcdb34 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/home.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/home.helpers.ts @@ -6,6 +6,7 @@ */ import { registerTestBed, TestBed, AsyncTestBedConfig } from '@kbn/test/jest'; +import { HttpSetup } from 'src/core/public'; import { IndexManagementHome } from '../../../public/application/sections/home'; import { indexManagementStore } from '../../../public/application/store'; import { WithAppDependencies, services, TestSubjects } from '../helpers'; @@ -19,8 +20,6 @@ const testBedConfig: AsyncTestBedConfig = { doMountAsync: true, }; -const initTestBed = registerTestBed(WithAppDependencies(IndexManagementHome), testBedConfig); - export interface HomeTestBed extends TestBed { actions: { selectHomeTab: (tab: 'indicesTab' | 'templatesTab') => void; @@ -28,7 +27,11 @@ export interface HomeTestBed extends TestBed { }; } -export const setup = async (): Promise => { +export const setup = async (httpSetup: HttpSetup): Promise => { + const initTestBed = registerTestBed( + WithAppDependencies(IndexManagementHome, httpSetup), + testBedConfig + ); const testBed = await initTestBed(); const { find } = testBed; diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/home.test.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/home.test.ts index 426bb11f3c733..5d2e3d0b840a1 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/home.test.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/home.test.ts @@ -20,18 +20,14 @@ import { stubWebWorker } from '@kbn/test/jest'; stubWebWorker(); describe('', () => { - const { server, httpRequestsMockHelpers } = setupEnvironment(); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); let testBed: HomeTestBed; - afterAll(() => { - server.restore(); - }); - describe('on component mount', () => { beforeEach(async () => { httpRequestsMockHelpers.setLoadIndicesResponse([]); - testBed = await setup(); + testBed = await setup(httpSetup); await act(async () => { const { component } = testBed; diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts index 4ddd14562577a..b4c3215cbe535 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts @@ -8,6 +8,7 @@ import { act } from 'react-dom/test-utils'; import { registerTestBed, TestBed, AsyncTestBedConfig, findTestSubject } from '@kbn/test/jest'; +import { HttpSetup } from 'src/core/public'; import { TemplateList } from '../../../public/application/sections/home/template_list'; import { TemplateDeserialized } from '../../../common'; import { WithAppDependencies, TestSubjects } from '../helpers'; @@ -20,8 +21,6 @@ const testBedConfig: AsyncTestBedConfig = { doMountAsync: true, }; -const initTestBed = registerTestBed(WithAppDependencies(TemplateList), testBedConfig); - const createActions = (testBed: TestBed) => { /** * Additional helpers @@ -127,7 +126,11 @@ const createActions = (testBed: TestBed) => { }; }; -export const setup = async (): Promise => { +export const setup = async (httpSetup: HttpSetup): Promise => { + const initTestBed = registerTestBed( + WithAppDependencies(TemplateList, httpSetup), + testBedConfig + ); const testBed = await initTestBed(); return { diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.test.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.test.ts index bf1a78e3cfe90..3d1360d620ff5 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.test.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.test.ts @@ -24,19 +24,15 @@ const removeWhiteSpaceOnArrayValues = (array: any[]) => }); describe('Index Templates tab', () => { - const { server, httpRequestsMockHelpers } = setupEnvironment(); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); let testBed: IndexTemplatesTabTestBed; - afterAll(() => { - server.restore(); - }); - describe('when there are no index templates of either kind', () => { test('should display an empty prompt', async () => { httpRequestsMockHelpers.setLoadTemplatesResponse({ templates: [], legacyTemplates: [] }); await act(async () => { - testBed = await setup(); + testBed = await setup(httpSetup); }); const { exists, component } = testBed; component.update(); @@ -54,7 +50,7 @@ describe('Index Templates tab', () => { }); await act(async () => { - testBed = await setup(); + testBed = await setup(httpSetup); }); const { exists, component } = testBed; component.update(); @@ -68,7 +64,8 @@ describe('Index Templates tab', () => { describe('when there are index templates', () => { // Add a default loadIndexTemplate response - httpRequestsMockHelpers.setLoadTemplateResponse(fixtures.getTemplate()); + const templateMock = fixtures.getTemplate(); + httpRequestsMockHelpers.setLoadTemplateResponse(templateMock.name, templateMock); const template1 = fixtures.getTemplate({ name: `a${getRandomString()}`, @@ -132,7 +129,7 @@ describe('Index Templates tab', () => { httpRequestsMockHelpers.setLoadTemplatesResponse({ templates, legacyTemplates }); await act(async () => { - testBed = await setup(); + testBed = await setup(httpSetup); }); testBed.component.update(); }); @@ -194,7 +191,6 @@ describe('Index Templates tab', () => { test('should have a button to reload the index templates', async () => { const { exists, actions } = testBed; - const totalRequests = server.requests.length; expect(exists('reloadButton')).toBe(true); @@ -202,9 +198,9 @@ describe('Index Templates tab', () => { actions.clickReloadButton(); }); - expect(server.requests.length).toBe(totalRequests + 1); - expect(server.requests[server.requests.length - 1].url).toBe( - `${API_BASE_PATH}/index_templates` + expect(httpSetup.get).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/index_templates`, + expect.anything() ); }); @@ -235,6 +231,7 @@ describe('Index Templates tab', () => { const { find, exists, actions, component } = testBed; // Composable templates + httpRequestsMockHelpers.setLoadTemplateResponse(templates[0].name, templates[0]); await actions.clickTemplateAt(0); expect(exists('templateList')).toBe(true); expect(exists('templateDetails')).toBe(true); @@ -246,6 +243,7 @@ describe('Index Templates tab', () => { }); component.update(); + httpRequestsMockHelpers.setLoadTemplateResponse(legacyTemplates[0].name, legacyTemplates[0]); await actions.clickTemplateAt(0, true); expect(exists('templateList')).toBe(true); @@ -380,13 +378,14 @@ describe('Index Templates tab', () => { confirmButton!.click(); }); - const latestRequest = server.requests[server.requests.length - 1]; - - expect(latestRequest.method).toBe('POST'); - expect(latestRequest.url).toBe(`${API_BASE_PATH}/delete_index_templates`); - expect(JSON.parse(JSON.parse(latestRequest.requestBody).body)).toEqual({ - templates: [{ name: templates[0].name, isLegacy }], - }); + expect(httpSetup.post).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/delete_index_templates`, + expect.objectContaining({ + body: JSON.stringify({ + templates: [{ name: templates[0].name, isLegacy }], + }), + }) + ); }); }); @@ -442,16 +441,14 @@ describe('Index Templates tab', () => { confirmButton!.click(); }); - const latestRequest = server.requests[server.requests.length - 1]; - - expect(latestRequest.method).toBe('POST'); - expect(latestRequest.url).toBe(`${API_BASE_PATH}/delete_index_templates`); - - // Commenting as I don't find a way to make it work. - // It keeps on returning the composable template instead of the legacy one - // expect(JSON.parse(JSON.parse(latestRequest.requestBody).body)).toEqual({ - // templates: [{ name: templateName, isLegacy }], - // }); + expect(httpSetup.post).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/delete_index_templates`, + expect.objectContaining({ + body: JSON.stringify({ + templates: [{ name: templates[0].name, isLegacy: false }], + }), + }) + ); }); }); @@ -463,7 +460,7 @@ describe('Index Templates tab', () => { isLegacy: true, }); - httpRequestsMockHelpers.setLoadTemplateResponse(template); + httpRequestsMockHelpers.setLoadTemplateResponse(template.name, template); }); test('should show details when clicking on a template', async () => { @@ -471,6 +468,7 @@ describe('Index Templates tab', () => { expect(exists('templateDetails')).toBe(false); + httpRequestsMockHelpers.setLoadTemplateResponse(templates[0].name, templates[0]); await actions.clickTemplateAt(0); expect(exists('templateDetails')).toBe(true); @@ -480,6 +478,7 @@ describe('Index Templates tab', () => { beforeEach(async () => { const { actions } = testBed; + httpRequestsMockHelpers.setLoadTemplateResponse(templates[0].name, templates[0]); await actions.clickTemplateAt(0); }); @@ -544,7 +543,7 @@ describe('Index Templates tab', () => { const { find, actions, exists } = testBed; - httpRequestsMockHelpers.setLoadTemplateResponse(template); + httpRequestsMockHelpers.setLoadTemplateResponse(templates[0].name, template); httpRequestsMockHelpers.setSimulateTemplateResponse({ simulateTemplate: 'response' }); await actions.clickTemplateAt(0); @@ -598,8 +597,10 @@ describe('Index Templates tab', () => { const { actions, find, exists } = testBed; - httpRequestsMockHelpers.setLoadTemplateResponse(templateWithNoOptionalFields); - + httpRequestsMockHelpers.setLoadTemplateResponse( + templates[0].name, + templateWithNoOptionalFields + ); await actions.clickTemplateAt(0); expect(find('templateDetails.tab').length).toBe(5); @@ -621,13 +622,12 @@ describe('Index Templates tab', () => { it('should render an error message if error fetching template details', async () => { const { actions, exists } = testBed; const error = { - status: 404, + statusCode: 404, error: 'Not found', message: 'Template not found', }; - httpRequestsMockHelpers.setLoadTemplateResponse(undefined, { body: error }); - + httpRequestsMockHelpers.setLoadTemplateResponse(templates[0].name, undefined, error); await actions.clickTemplateAt(0); expect(exists('sectionError')).toBe(true); diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.helpers.ts index 9b7a12bf95d84..6052ad448f6b5 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.helpers.ts @@ -9,6 +9,7 @@ import { act } from 'react-dom/test-utils'; import { ReactWrapper } from 'enzyme'; import { registerTestBed, TestBed, AsyncTestBedConfig, findTestSubject } from '@kbn/test/jest'; +import { HttpSetup } from 'src/core/public'; import { IndexManagementHome } from '../../../public/application/sections/home'; import { indexManagementStore } from '../../../public/application/store'; import { WithAppDependencies, services, TestSubjects } from '../helpers'; @@ -37,9 +38,12 @@ export interface IndicesTestBed extends TestBed { findDataStreamDetailPanelTitle: () => string; } -export const setup = async (overridingDependencies: any = {}): Promise => { +export const setup = async ( + httpSetup: HttpSetup, + overridingDependencies: any = {} +): Promise => { const initTestBed = registerTestBed( - WithAppDependencies(IndexManagementHome, overridingDependencies), + WithAppDependencies(IndexManagementHome, httpSetup, overridingDependencies), testBedConfig ); const testBed = await initTestBed(); diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.test.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.test.ts index 2be31b0a7907a..af59a4c2f47b5 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.test.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.test.ts @@ -49,22 +49,20 @@ stubWebWorker(); describe('', () => { let testBed: IndicesTestBed; - let server: ReturnType['server']; + let httpSetup: ReturnType['httpSetup']; let httpRequestsMockHelpers: ReturnType['httpRequestsMockHelpers']; beforeEach(() => { - ({ server, httpRequestsMockHelpers } = setupEnvironment()); - }); - - afterAll(() => { - server.restore(); + const mockEnvironment = setupEnvironment(); + httpRequestsMockHelpers = mockEnvironment.httpRequestsMockHelpers; + httpSetup = mockEnvironment.httpSetup; }); describe('on component mount', () => { beforeEach(async () => { httpRequestsMockHelpers.setLoadIndicesResponse([]); - testBed = await setup(); + testBed = await setup(httpSetup); await act(async () => { const { component } = testBed; @@ -118,10 +116,11 @@ describe('', () => { httpRequestsMockHelpers.setLoadDataStreamsResponse([]); httpRequestsMockHelpers.setLoadDataStreamResponse( + 'dataStream1', createDataStreamPayload({ name: 'dataStream1' }) ); - testBed = await setup({ + testBed = await setup(httpSetup, { history: createMemoryHistory(), }); @@ -162,7 +161,7 @@ describe('', () => { beforeEach(async () => { httpRequestsMockHelpers.setLoadIndicesResponse([createNonDataStreamIndex(indexName)]); - testBed = await setup(); + testBed = await setup(httpSetup); const { component, find } = testBed; component.update(); @@ -174,32 +173,36 @@ describe('', () => { const { actions } = testBed; await actions.selectIndexDetailsTab('settings'); - const latestRequest = server.requests[server.requests.length - 1]; - expect(latestRequest.url).toBe(`${API_BASE_PATH}/settings/${encodeURIComponent(indexName)}`); + expect(httpSetup.get).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/settings/${encodeURIComponent(indexName)}` + ); }); test('should encode indexName when loading mappings in detail panel', async () => { const { actions } = testBed; await actions.selectIndexDetailsTab('mappings'); - const latestRequest = server.requests[server.requests.length - 1]; - expect(latestRequest.url).toBe(`${API_BASE_PATH}/mapping/${encodeURIComponent(indexName)}`); + expect(httpSetup.get).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/mapping/${encodeURIComponent(indexName)}` + ); }); test('should encode indexName when loading stats in detail panel', async () => { const { actions } = testBed; await actions.selectIndexDetailsTab('stats'); - const latestRequest = server.requests[server.requests.length - 1]; - expect(latestRequest.url).toBe(`${API_BASE_PATH}/stats/${encodeURIComponent(indexName)}`); + expect(httpSetup.get).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/stats/${encodeURIComponent(indexName)}` + ); }); test('should encode indexName when editing settings in detail panel', async () => { const { actions } = testBed; await actions.selectIndexDetailsTab('edit_settings'); - const latestRequest = server.requests[server.requests.length - 1]; - expect(latestRequest.url).toBe(`${API_BASE_PATH}/settings/${encodeURIComponent(indexName)}`); + expect(httpSetup.get).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/settings/${encodeURIComponent(indexName)}` + ); }); }); @@ -222,7 +225,7 @@ describe('', () => { ]); httpRequestsMockHelpers.setReloadIndicesResponse({ indexNames: [indexNameA, indexNameB] }); - testBed = await setup(); + testBed = await setup(httpSetup); const { component, find } = testBed; component.update(); @@ -230,19 +233,42 @@ describe('', () => { find('indexTableIndexNameLink').at(0).simulate('click'); }); + test('should be able to refresh index', async () => { + const { actions } = testBed; + + await actions.clickManageContextMenuButton(); + await actions.clickContextMenuOption('refreshIndexMenuButton'); + + expect(httpSetup.post).toHaveBeenCalledWith( + `${API_BASE_PATH}/indices/refresh`, + expect.anything() + ); + expect(httpSetup.post).toHaveBeenCalledWith( + `${API_BASE_PATH}/indices/reload`, + expect.anything() + ); + }); + test('should be able to close an open index', async () => { const { actions } = testBed; await actions.clickManageContextMenuButton(); await actions.clickContextMenuOption('closeIndexMenuButton'); - // A refresh call was added after closing an index so we need to check the second to last request. - const latestRequest = server.requests[server.requests.length - 2]; - expect(latestRequest.url).toBe(`${API_BASE_PATH}/indices/close`); + // After the index is closed, we imediately do a reload. So we need to expect to see + // a reload server call also. + expect(httpSetup.post).toHaveBeenCalledWith( + `${API_BASE_PATH}/indices/close`, + expect.anything() + ); + expect(httpSetup.post).toHaveBeenCalledWith( + `${API_BASE_PATH}/indices/reload`, + expect.anything() + ); }); test('should be able to open a closed index', async () => { - testBed = await setup(); + testBed = await setup(httpSetup); const { component, find, actions } = testBed; component.update(); @@ -252,9 +278,16 @@ describe('', () => { await actions.clickManageContextMenuButton(); await actions.clickContextMenuOption('openIndexMenuButton'); - // A refresh call was added after closing an index so we need to check the second to last request. - const latestRequest = server.requests[server.requests.length - 2]; - expect(latestRequest.url).toBe(`${API_BASE_PATH}/indices/open`); + // After the index is opened, we imediately do a reload. So we need to expect to see + // a reload server call also. + expect(httpSetup.post).toHaveBeenCalledWith( + `${API_BASE_PATH}/indices/open`, + expect.anything() + ); + expect(httpSetup.post).toHaveBeenCalledWith( + `${API_BASE_PATH}/indices/reload`, + expect.anything() + ); }); test('should be able to flush index', async () => { @@ -263,11 +296,16 @@ describe('', () => { await actions.clickManageContextMenuButton(); await actions.clickContextMenuOption('flushIndexMenuButton'); - const requestsCount = server.requests.length; - expect(server.requests[requestsCount - 2].url).toBe(`${API_BASE_PATH}/indices/flush`); - // After the indices are flushed, we imediately reload them. So we need to expect to see + // After the index is flushed, we imediately do a reload. So we need to expect to see // a reload server call also. - expect(server.requests[requestsCount - 1].url).toBe(`${API_BASE_PATH}/indices/reload`); + expect(httpSetup.post).toHaveBeenCalledWith( + `${API_BASE_PATH}/indices/flush`, + expect.anything() + ); + expect(httpSetup.post).toHaveBeenCalledWith( + `${API_BASE_PATH}/indices/reload`, + expect.anything() + ); }); test("should be able to clear an index's cache", async () => { @@ -277,8 +315,16 @@ describe('', () => { await actions.clickManageContextMenuButton(); await actions.clickContextMenuOption('clearCacheIndexMenuButton'); - const latestRequest = server.requests[server.requests.length - 2]; - expect(latestRequest.url).toBe(`${API_BASE_PATH}/indices/clear_cache`); + // After the index cache is cleared, we imediately do a reload. So we need to expect to see + // a reload server call also. + expect(httpSetup.post).toHaveBeenCalledWith( + `${API_BASE_PATH}/indices/clear_cache`, + expect.anything() + ); + expect(httpSetup.post).toHaveBeenCalledWith( + `${API_BASE_PATH}/indices/reload`, + expect.anything() + ); }); test('should be able to unfreeze a frozen index', async () => { @@ -295,11 +341,16 @@ describe('', () => { expect(exists('unfreezeIndexMenuButton')).toBe(true); await actions.clickContextMenuOption('unfreezeIndexMenuButton'); - const requestsCount = server.requests.length; - expect(server.requests[requestsCount - 2].url).toBe(`${API_BASE_PATH}/indices/unfreeze`); // After the index is unfrozen, we imediately do a reload. So we need to expect to see // a reload server call also. - expect(server.requests[requestsCount - 1].url).toBe(`${API_BASE_PATH}/indices/reload`); + expect(httpSetup.post).toHaveBeenCalledWith( + `${API_BASE_PATH}/indices/unfreeze`, + expect.anything() + ); + expect(httpSetup.post).toHaveBeenCalledWith( + `${API_BASE_PATH}/indices/reload`, + expect.anything() + ); }); test('should be able to force merge an index', async () => { @@ -315,15 +366,33 @@ describe('', () => { await actions.clickModalConfirm(); - const requestsCount = server.requests.length; - expect(server.requests[requestsCount - 2].url).toBe(`${API_BASE_PATH}/indices/forcemerge`); - // After the index is force merged, we immediately do a reload. So we need to expect to see + // After the index force merged, we imediately do a reload. So we need to expect to see // a reload server call also. - expect(server.requests[requestsCount - 1].url).toBe(`${API_BASE_PATH}/indices/reload`); + expect(httpSetup.post).toHaveBeenCalledWith( + `${API_BASE_PATH}/indices/forcemerge`, + expect.anything() + ); + expect(httpSetup.post).toHaveBeenCalledWith( + `${API_BASE_PATH}/indices/reload`, + expect.anything() + ); }); }); describe('Edit index settings', () => { + const indexName = 'test'; + + beforeEach(async () => { + httpRequestsMockHelpers.setLoadIndicesResponse([createNonDataStreamIndex(indexName)]); + + testBed = await setup(httpSetup); + const { component, find } = testBed; + + component.update(); + + find('indexTableIndexNameLink').at(0).simulate('click'); + }); + test('shows error callout when request fails', async () => { const { actions, find, component, exists } = testBed; @@ -336,7 +405,7 @@ describe('', () => { error: 'Bad Request', message: 'invalid tier names found in ...', }; - httpRequestsMockHelpers.setUpdateIndexSettingsResponse(undefined, error); + httpRequestsMockHelpers.setUpdateIndexSettingsResponse(indexName, undefined, error); await actions.selectIndexDetailsTab('edit_settings'); diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.helpers.ts index dffa6fee19d06..b74a5a67a1b76 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.helpers.ts @@ -6,10 +6,11 @@ */ import { registerTestBed, AsyncTestBedConfig } from '@kbn/test/jest'; +import { HttpSetup } from 'src/core/public'; import { TemplateClone } from '../../../public/application/sections/template_clone'; import { WithAppDependencies } from '../helpers'; -import { formSetup } from './template_form.helpers'; +import { formSetup, TestSubjects } from './template_form.helpers'; import { TEMPLATE_NAME } from './constants'; const testBedConfig: AsyncTestBedConfig = { @@ -20,6 +21,11 @@ const testBedConfig: AsyncTestBedConfig = { doMountAsync: true, }; -const initTestBed = registerTestBed(WithAppDependencies(TemplateClone), testBedConfig); +export const setup = async (httpSetup: HttpSetup) => { + const initTestBed = registerTestBed( + WithAppDependencies(TemplateClone, httpSetup), + testBedConfig + ); -export const setup: any = formSetup.bind(null, initTestBed); + return formSetup(initTestBed); +}; diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.test.tsx b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.test.tsx index 31e65625cfdd0..861b1041a4f14 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.test.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.test.tsx @@ -9,6 +9,7 @@ import React from 'react'; import { act } from 'react-dom/test-utils'; import '../../../test/global_mocks'; +import { API_BASE_PATH } from '../../../common/constants'; import { getComposableTemplate } from '../../../test/fixtures'; import { setupEnvironment } from '../helpers'; @@ -44,23 +45,22 @@ const templateToClone = getComposableTemplate({ describe('', () => { let testBed: TemplateFormTestBed; - - const { server, httpRequestsMockHelpers } = setupEnvironment(); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { jest.useFakeTimers(); + httpRequestsMockHelpers.setLoadTelemetryResponse({}); httpRequestsMockHelpers.setLoadComponentTemplatesResponse([]); - httpRequestsMockHelpers.setLoadTemplateResponse(templateToClone); + httpRequestsMockHelpers.setLoadTemplateResponse(templateToClone.name, templateToClone); }); afterAll(() => { - server.restore(); jest.useRealTimers(); }); beforeEach(async () => { await act(async () => { - testBed = await setup(); + testBed = await setup(httpSetup); }); testBed.component.update(); }); @@ -98,17 +98,19 @@ describe('', () => { actions.clickNextButton(); }); - const latestRequest = server.requests[server.requests.length - 1]; - - const expected = { - ...templateToClone, - name: `${templateToClone.name}-copy`, - indexPatterns: DEFAULT_INDEX_PATTERNS, - }; - - delete expected.template; // As no settings, mappings or aliases have been defined, no "template" param is sent - - expect(JSON.parse(JSON.parse(latestRequest.requestBody).body)).toEqual(expected); + const { priority, version, _kbnMeta } = templateToClone; + expect(httpSetup.post).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/index_templates`, + expect.objectContaining({ + body: JSON.stringify({ + name: `${templateToClone.name}-copy`, + indexPatterns: DEFAULT_INDEX_PATTERNS, + priority, + version, + _kbnMeta, + }), + }) + ); }); }); }); diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.helpers.ts index 450d2c524b445..333441b79d6cc 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.helpers.ts @@ -6,12 +6,13 @@ */ import { registerTestBed, AsyncTestBedConfig } from '@kbn/test/jest'; +import { HttpSetup } from 'src/core/public'; import { TemplateCreate } from '../../../public/application/sections/template_create'; import { WithAppDependencies } from '../helpers'; import { formSetup, TestSubjects } from './template_form.helpers'; -export const setup: any = (isLegacy: boolean = false) => { +export const setup = async (httpSetup: HttpSetup, isLegacy: boolean = false) => { const route = isLegacy ? { pathname: '/create_template', search: '?legacy=true' } : { pathname: '/create_template' }; @@ -25,9 +26,9 @@ export const setup: any = (isLegacy: boolean = false) => { }; const initTestBed = registerTestBed( - WithAppDependencies(TemplateCreate), + WithAppDependencies(TemplateCreate, httpSetup), testBedConfig ); - return formSetup.call(null, initTestBed); + return formSetup(initTestBed); }; diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx index 65d3678735689..078a171ac6a75 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx @@ -9,6 +9,7 @@ import React from 'react'; import { act } from 'react-dom/test-utils'; import '../../../test/global_mocks'; +import { API_BASE_PATH } from '../../../common/constants'; import { setupEnvironment } from '../helpers'; import { @@ -76,7 +77,7 @@ const componentTemplates = [componentTemplate1, componentTemplate2]; describe('', () => { let testBed: TemplateFormTestBed; - const { server, httpRequestsMockHelpers } = setupEnvironment(); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { jest.useFakeTimers(); @@ -89,7 +90,6 @@ describe('', () => { }); afterAll(() => { - server.restore(); jest.useRealTimers(); (window as any)['__react-beautiful-dnd-disable-dev-warnings'] = false; }); @@ -97,7 +97,7 @@ describe('', () => { describe('composable index template', () => { beforeEach(async () => { await act(async () => { - testBed = await setup(); + testBed = await setup(httpSetup); }); }); @@ -130,7 +130,7 @@ describe('', () => { describe('legacy index template', () => { beforeEach(async () => { await act(async () => { - testBed = await setup(true); + testBed = await setup(httpSetup, true); }); }); @@ -150,7 +150,7 @@ describe('', () => { describe('form validation', () => { beforeEach(async () => { await act(async () => { - testBed = await setup(); + testBed = await setup(httpSetup); }); testBed.component.update(); }); @@ -367,7 +367,7 @@ describe('', () => { httpRequestsMockHelpers.setLoadNodesPluginsResponse(['mapper-size']); await act(async () => { - testBed = await setup(); + testBed = await setup(httpSetup); }); testBed.component.update(); await navigateToMappingsStep(); @@ -415,7 +415,7 @@ describe('', () => { describe('review (step 6)', () => { beforeEach(async () => { await act(async () => { - testBed = await setup(); + testBed = await setup(httpSetup); }); testBed.component.update(); @@ -472,7 +472,7 @@ describe('', () => { it('should render a warning message if a wildcard is used as an index pattern', async () => { await act(async () => { - testBed = await setup(); + testBed = await setup(httpSetup); }); testBed.component.update(); @@ -505,7 +505,7 @@ describe('', () => { const MAPPING_FIELDS = [BOOLEAN_MAPPING_FIELD, TEXT_MAPPING_FIELD, KEYWORD_MAPPING_FIELD]; await act(async () => { - testBed = await setup(); + testBed = await setup(httpSetup); }); testBed.component.update(); @@ -534,49 +534,50 @@ describe('', () => { actions.clickNextButton(); }); - const latestRequest = server.requests[server.requests.length - 1]; - - const expected = { - name: TEMPLATE_NAME, - indexPatterns: DEFAULT_INDEX_PATTERNS, - composedOf: ['test_component_template_1'], - template: { - settings: SETTINGS, - mappings: { - properties: { - [BOOLEAN_MAPPING_FIELD.name]: { - type: BOOLEAN_MAPPING_FIELD.type, - }, - [TEXT_MAPPING_FIELD.name]: { - type: TEXT_MAPPING_FIELD.type, - }, - [KEYWORD_MAPPING_FIELD.name]: { - type: KEYWORD_MAPPING_FIELD.type, + expect(httpSetup.post).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/index_templates`, + expect.objectContaining({ + body: JSON.stringify({ + name: TEMPLATE_NAME, + indexPatterns: DEFAULT_INDEX_PATTERNS, + _kbnMeta: { + type: 'default', + hasDatastream: false, + isLegacy: false, + }, + composedOf: ['test_component_template_1'], + template: { + settings: SETTINGS, + mappings: { + properties: { + [BOOLEAN_MAPPING_FIELD.name]: { + type: BOOLEAN_MAPPING_FIELD.type, + }, + [TEXT_MAPPING_FIELD.name]: { + type: TEXT_MAPPING_FIELD.type, + }, + [KEYWORD_MAPPING_FIELD.name]: { + type: KEYWORD_MAPPING_FIELD.type, + }, + }, }, + aliases: ALIASES, }, - }, - aliases: ALIASES, - }, - _kbnMeta: { - type: 'default', - isLegacy: false, - hasDatastream: false, - }, - }; - - expect(JSON.parse(JSON.parse(latestRequest.requestBody).body)).toEqual(expected); + }), + }) + ); }); it('should surface the API errors from the put HTTP request', async () => { const { component, actions, find, exists } = testBed; const error = { - status: 409, + statusCode: 409, error: 'Conflict', message: `There is already a template with name '${TEMPLATE_NAME}'`, }; - httpRequestsMockHelpers.setCreateTemplateResponse(undefined, { body: error }); + httpRequestsMockHelpers.setCreateTemplateResponse(undefined, error); await act(async () => { actions.clickNextButton(); diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_edit.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_edit.helpers.ts index 6c73da3b3379d..3544f19694f49 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_edit.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_edit.helpers.ts @@ -6,6 +6,7 @@ */ import { registerTestBed, AsyncTestBedConfig } from '@kbn/test/jest'; +import { HttpSetup } from 'src/core/public'; import { TemplateEdit } from '../../../public/application/sections/template_edit'; import { WithAppDependencies } from '../helpers'; @@ -20,6 +21,11 @@ const testBedConfig: AsyncTestBedConfig = { doMountAsync: true, }; -const initTestBed = registerTestBed(WithAppDependencies(TemplateEdit), testBedConfig); +export const setup = async (httpSetup: HttpSetup) => { + const initTestBed = registerTestBed( + WithAppDependencies(TemplateEdit, httpSetup), + testBedConfig + ); -export const setup: any = formSetup.bind(null, initTestBed); + return formSetup(initTestBed); +}; diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_edit.test.tsx b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_edit.test.tsx index 9af90e71badfa..5e477bcd3863b 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_edit.test.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_edit.test.tsx @@ -10,6 +10,7 @@ import { act } from 'react-dom/test-utils'; import '../../../test/global_mocks'; import * as fixtures from '../../../test/fixtures'; +import { API_BASE_PATH } from '../../../common/constants'; import { setupEnvironment, kibanaVersion } from '../helpers'; import { TEMPLATE_NAME, SETTINGS, ALIASES, MAPPINGS as DEFAULT_MAPPING } from './constants'; @@ -48,7 +49,7 @@ jest.mock('@elastic/eui', () => { describe('', () => { let testBed: TemplateFormTestBed; - const { server, httpRequestsMockHelpers } = setupEnvironment(); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { jest.useFakeTimers(); @@ -56,7 +57,6 @@ describe('', () => { }); afterAll(() => { - server.restore(); jest.useRealTimers(); }); @@ -71,12 +71,12 @@ describe('', () => { }); beforeAll(() => { - httpRequestsMockHelpers.setLoadTemplateResponse(templateToEdit); + httpRequestsMockHelpers.setLoadTemplateResponse('my_template', templateToEdit); }); beforeEach(async () => { await act(async () => { - testBed = await setup(); + testBed = await setup(httpSetup); }); testBed.component.update(); @@ -114,25 +114,25 @@ describe('', () => { actions.clickNextButton(); }); - const latestRequest = server.requests[server.requests.length - 1]; - const { version } = templateToEdit; - - const expected = { - name: 'index_template_without_mappings', - indexPatterns: ['indexPattern1'], - dataStream: { - hidden: true, - anyUnknownKey: 'should_be_kept', - }, - version, - _kbnMeta: { - type: 'default', - isLegacy: templateToEdit._kbnMeta.isLegacy, - hasDatastream: true, - }, - }; - - expect(JSON.parse(JSON.parse(latestRequest.requestBody).body)).toEqual(expected); + expect(httpSetup.put).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/index_templates/index_template_without_mappings`, + expect.objectContaining({ + body: JSON.stringify({ + name: 'index_template_without_mappings', + indexPatterns: ['indexPattern1'], + version: templateToEdit.version, + dataStream: { + hidden: true, + anyUnknownKey: 'should_be_kept', + }, + _kbnMeta: { + type: 'default', + hasDatastream: true, + isLegacy: templateToEdit._kbnMeta.isLegacy, + }, + }), + }) + ); }); it('allows you to view the "Request" tab of an unmodified template', async () => { @@ -175,24 +175,25 @@ describe('', () => { actions.clickNextButton(); }); - const latestRequest = server.requests[server.requests.length - 1]; - - const expected = { - name: 'test', - indexPatterns: ['myPattern*'], - dataStream: { - hidden: true, - anyUnknownKey: 'should_be_kept', - }, - version: 1, - _kbnMeta: { - type: 'default', - isLegacy: false, - hasDatastream: true, - }, - }; - - expect(JSON.parse(JSON.parse(latestRequest.requestBody).body)).toEqual(expected); + expect(httpSetup.put).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/index_templates/test`, + expect.objectContaining({ + body: JSON.stringify({ + name: 'test', + indexPatterns: ['myPattern*'], + version: 1, + dataStream: { + hidden: true, + anyUnknownKey: 'should_be_kept', + }, + _kbnMeta: { + type: 'default', + hasDatastream: true, + isLegacy: false, + }, + }), + }) + ); }); }); @@ -206,12 +207,12 @@ describe('', () => { }); beforeAll(() => { - httpRequestsMockHelpers.setLoadTemplateResponse(templateToEdit); + httpRequestsMockHelpers.setLoadTemplateResponse('my_template', templateToEdit); }); beforeEach(async () => { await act(async () => { - testBed = await setup(); + testBed = await setup(httpSetup); }); testBed.component.update(); }); @@ -283,40 +284,40 @@ describe('', () => { actions.clickNextButton(); }); - const latestRequest = server.requests[server.requests.length - 1]; - const { version } = templateToEdit; - - const expected = { - name: TEMPLATE_NAME, - version, - priority: 3, - indexPatterns: UPDATED_INDEX_PATTERN, - template: { - mappings: { - properties: { - [UPDATED_MAPPING_TEXT_FIELD_NAME]: { - type: 'text', - store: false, - index: true, - fielddata: false, - eager_global_ordinals: false, - index_phrases: false, - norms: true, - index_options: 'positions', + expect(httpSetup.put).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/index_templates/${TEMPLATE_NAME}`, + expect.objectContaining({ + body: JSON.stringify({ + name: TEMPLATE_NAME, + indexPatterns: UPDATED_INDEX_PATTERN, + priority: 3, + version: templateToEdit.version, + _kbnMeta: { + type: 'default', + hasDatastream: false, + isLegacy: templateToEdit._kbnMeta.isLegacy, + }, + template: { + settings: SETTINGS, + mappings: { + properties: { + [UPDATED_MAPPING_TEXT_FIELD_NAME]: { + type: 'text', + index: true, + eager_global_ordinals: false, + index_phrases: false, + norms: true, + fielddata: false, + store: false, + index_options: 'positions', + }, + }, }, + aliases: ALIASES, }, - }, - settings: SETTINGS, - aliases: ALIASES, - }, - _kbnMeta: { - type: 'default', - isLegacy: templateToEdit._kbnMeta.isLegacy, - hasDatastream: false, - }, - }; - - expect(JSON.parse(JSON.parse(latestRequest.requestBody).body)).toEqual(expected); + }), + }) + ); }); }); }); @@ -335,12 +336,12 @@ describe('', () => { }); beforeAll(() => { - httpRequestsMockHelpers.setLoadTemplateResponse(legacyTemplateToEdit); + httpRequestsMockHelpers.setLoadTemplateResponse('my_template', legacyTemplateToEdit); }); beforeEach(async () => { await act(async () => { - testBed = await setup(); + testBed = await setup(httpSetup); }); testBed.component.update(); @@ -363,24 +364,10 @@ describe('', () => { actions.clickNextButton(); }); - const latestRequest = server.requests[server.requests.length - 1]; - - const { version, template, name, indexPatterns, _kbnMeta, order } = legacyTemplateToEdit; - - const expected = { - name, - indexPatterns, - version, - order, - template: { - aliases: undefined, - mappings: template!.mappings, - settings: undefined, - }, - _kbnMeta, - }; - - expect(JSON.parse(JSON.parse(latestRequest.requestBody).body)).toEqual(expected); + expect(httpSetup.put).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/index_templates/${legacyTemplateToEdit.name}`, + expect.anything() + ); }); }); } diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_form.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_form.helpers.ts index f2fcf7bbab50c..7ac814c330a80 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_form.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_form.helpers.ts @@ -10,7 +10,7 @@ import { act } from 'react-dom/test-utils'; import { TestBed, SetupFunc, UnwrapPromise } from '@kbn/test/jest'; import { TemplateDeserialized } from '../../../common'; -interface MappingField { +export interface MappingField { name: string; type: string; } diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_create.test.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_create.test.tsx index f3957e0cc15c9..81f43a1b46073 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_create.test.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_create.test.tsx @@ -11,6 +11,7 @@ import { act } from 'react-dom/test-utils'; import '../../../../../../../../../src/plugins/es_ui_shared/public/components/code_editor/jest_mock'; import '../../../../../../test/global_mocks'; import { setupEnvironment } from './helpers'; +import { API_BASE_PATH } from './helpers/constants'; import { setup, ComponentTemplateCreateTestBed } from './helpers/component_template_create.helpers'; jest.mock('@elastic/eui', () => { @@ -34,16 +35,12 @@ jest.mock('@elastic/eui', () => { describe('', () => { let testBed: ComponentTemplateCreateTestBed; - const { server, httpRequestsMockHelpers } = setupEnvironment(); - - afterAll(() => { - server.restore(); - }); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); describe('On component mount', () => { beforeEach(async () => { await act(async () => { - testBed = await setup(); + testBed = await setup(httpSetup); }); testBed.component.update(); @@ -108,7 +105,7 @@ describe('', () => { beforeEach(async () => { await act(async () => { - testBed = await setup(); + testBed = await setup(httpSetup); }); const { actions, component } = testBed; @@ -164,37 +161,38 @@ describe('', () => { component.update(); - const latestRequest = server.requests[server.requests.length - 1]; - - const expected = { - name: COMPONENT_TEMPLATE_NAME, - template: { - settings: SETTINGS, - mappings: { - properties: { - [BOOLEAN_MAPPING_FIELD.name]: { - type: BOOLEAN_MAPPING_FIELD.type, + expect(httpSetup.post).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/component_templates`, + expect.objectContaining({ + body: JSON.stringify({ + name: COMPONENT_TEMPLATE_NAME, + template: { + settings: SETTINGS, + mappings: { + properties: { + [BOOLEAN_MAPPING_FIELD.name]: { + type: BOOLEAN_MAPPING_FIELD.type, + }, + }, }, + aliases: ALIASES, }, - }, - aliases: ALIASES, - }, - _kbnMeta: { usedBy: [], isManaged: false }, - }; - - expect(JSON.parse(JSON.parse(latestRequest.requestBody).body)).toEqual(expected); + _kbnMeta: { usedBy: [], isManaged: false }, + }), + }) + ); }); test('should surface API errors if the request is unsuccessful', async () => { const { component, actions, find, exists } = testBed; const error = { - status: 409, + statusCode: 409, error: 'Conflict', message: `There is already a template with name '${COMPONENT_TEMPLATE_NAME}'`, }; - httpRequestsMockHelpers.setCreateComponentTemplateResponse(undefined, { body: error }); + httpRequestsMockHelpers.setCreateComponentTemplateResponse(undefined, error); await act(async () => { actions.clickNextButton(); diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_details.test.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_details.test.ts index 36ea2c27ec4fe..95495af1272c3 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_details.test.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_details.test.ts @@ -32,19 +32,18 @@ const COMPONENT_TEMPLATE_ONLY_REQUIRED_FIELDS: ComponentTemplateDeserialized = { }; describe('', () => { - const { server, httpRequestsMockHelpers } = setupEnvironment(); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); let testBed: ComponentTemplateDetailsTestBed; - afterAll(() => { - server.restore(); - }); - describe('With component template details', () => { beforeEach(async () => { - httpRequestsMockHelpers.setLoadComponentTemplateResponse(COMPONENT_TEMPLATE); + httpRequestsMockHelpers.setLoadComponentTemplateResponse( + COMPONENT_TEMPLATE.name, + COMPONENT_TEMPLATE + ); await act(async () => { - testBed = setup({ + testBed = setup(httpSetup, { componentTemplateName: COMPONENT_TEMPLATE.name, onClose: () => {}, }); @@ -104,11 +103,12 @@ describe('', () => { describe('With only required component template fields', () => { beforeEach(async () => { httpRequestsMockHelpers.setLoadComponentTemplateResponse( + COMPONENT_TEMPLATE_ONLY_REQUIRED_FIELDS.name, COMPONENT_TEMPLATE_ONLY_REQUIRED_FIELDS ); await act(async () => { - testBed = setup({ + testBed = setup(httpSetup, { componentTemplateName: COMPONENT_TEMPLATE_ONLY_REQUIRED_FIELDS.name, onClose: () => {}, }); @@ -156,10 +156,13 @@ describe('', () => { describe('With actions', () => { beforeEach(async () => { - httpRequestsMockHelpers.setLoadComponentTemplateResponse(COMPONENT_TEMPLATE); + httpRequestsMockHelpers.setLoadComponentTemplateResponse( + COMPONENT_TEMPLATE.name, + COMPONENT_TEMPLATE + ); await act(async () => { - testBed = setup({ + testBed = setup(httpSetup, { componentTemplateName: COMPONENT_TEMPLATE.name, onClose: () => {}, actions: [ @@ -197,16 +200,20 @@ describe('', () => { describe('Error handling', () => { const error = { - status: 500, + statusCode: 500, error: 'Internal server error', message: 'Internal server error', }; beforeEach(async () => { - httpRequestsMockHelpers.setLoadComponentTemplateResponse(undefined, { body: error }); + httpRequestsMockHelpers.setLoadComponentTemplateResponse( + COMPONENT_TEMPLATE.name, + undefined, + error + ); await act(async () => { - testBed = setup({ + testBed = setup(httpSetup, { componentTemplateName: COMPONENT_TEMPLATE.name, onClose: () => {}, }); diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_edit.test.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_edit.test.tsx index 1f4abac806276..f3b5b52fe2c41 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_edit.test.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_edit.test.tsx @@ -10,6 +10,7 @@ import { act } from 'react-dom/test-utils'; import '../../../../../../test/global_mocks'; import { setupEnvironment } from './helpers'; +import { API_BASE_PATH } from './helpers/constants'; import { setup, ComponentTemplateEditTestBed } from './helpers/component_template_edit.helpers'; jest.mock('@elastic/eui', () => { @@ -33,11 +34,7 @@ jest.mock('@elastic/eui', () => { describe('', () => { let testBed: ComponentTemplateEditTestBed; - const { server, httpRequestsMockHelpers } = setupEnvironment(); - - afterAll(() => { - server.restore(); - }); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); const COMPONENT_TEMPLATE_NAME = 'comp-1'; const COMPONENT_TEMPLATE_TO_EDIT = { @@ -49,10 +46,13 @@ describe('', () => { }; beforeEach(async () => { - httpRequestsMockHelpers.setLoadComponentTemplateResponse(COMPONENT_TEMPLATE_TO_EDIT); + httpRequestsMockHelpers.setLoadComponentTemplateResponse( + COMPONENT_TEMPLATE_TO_EDIT.name, + COMPONENT_TEMPLATE_TO_EDIT + ); await act(async () => { - testBed = await setup(); + testBed = await setup(httpSetup); }); testBed.component.update(); @@ -98,17 +98,18 @@ describe('', () => { component.update(); - const latestRequest = server.requests[server.requests.length - 1]; - - const expected = { - version: 1, - ...COMPONENT_TEMPLATE_TO_EDIT, - template: { - ...COMPONENT_TEMPLATE_TO_EDIT.template, - }, - }; - - expect(JSON.parse(JSON.parse(latestRequest.requestBody).body)).toEqual(expected); + expect(httpSetup.put).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/component_templates/${COMPONENT_TEMPLATE_TO_EDIT.name}`, + expect.objectContaining({ + body: JSON.stringify({ + ...COMPONENT_TEMPLATE_TO_EDIT, + template: { + ...COMPONENT_TEMPLATE_TO_EDIT.template, + }, + version: 1, + }), + }) + ); }); }); }); diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_list.test.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_list.test.ts index dee15f2ae3a45..a3e9524dcd3ca 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_list.test.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_list.test.ts @@ -16,16 +16,12 @@ import { API_BASE_PATH } from './helpers/constants'; const { setup } = pageHelpers.componentTemplateList; describe('', () => { - const { server, httpRequestsMockHelpers } = setupEnvironment(); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); let testBed: ComponentTemplateListTestBed; - afterAll(() => { - server.restore(); - }); - beforeEach(async () => { await act(async () => { - testBed = await setup(); + testBed = await setup(httpSetup); }); testBed.component.update(); @@ -69,7 +65,6 @@ describe('', () => { test('should reload the component templates data', async () => { const { component, actions } = testBed; - const totalRequests = server.requests.length; await act(async () => { actions.clickReloadButton(); @@ -77,9 +72,9 @@ describe('', () => { component.update(); - expect(server.requests.length).toBe(totalRequests + 1); - expect(server.requests[server.requests.length - 1].url).toBe( - `${API_BASE_PATH}/component_templates` + expect(httpSetup.get).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/component_templates`, + expect.anything() ); }); @@ -103,7 +98,7 @@ describe('', () => { expect(modal).not.toBe(null); expect(modal!.textContent).toContain('Delete component template'); - httpRequestsMockHelpers.setDeleteComponentTemplateResponse({ + httpRequestsMockHelpers.setDeleteComponentTemplateResponse(componentTemplateName, { itemsDeleted: [componentTemplateName], errors: [], }); @@ -114,13 +109,10 @@ describe('', () => { component.update(); - const deleteRequest = server.requests[server.requests.length - 2]; - - expect(deleteRequest.method).toBe('DELETE'); - expect(deleteRequest.url).toBe( - `${API_BASE_PATH}/component_templates/${componentTemplateName}` + expect(httpSetup.delete).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/component_templates/${componentTemplateName}`, + expect.anything() ); - expect(deleteRequest.status).toEqual(200); }); }); @@ -129,7 +121,7 @@ describe('', () => { httpRequestsMockHelpers.setLoadComponentTemplatesResponse([]); await act(async () => { - testBed = await setup(); + testBed = await setup(httpSetup); }); testBed.component.update(); @@ -147,15 +139,15 @@ describe('', () => { describe('Error handling', () => { beforeEach(async () => { const error = { - status: 500, + statusCode: 500, error: 'Internal server error', message: 'Internal server error', }; - httpRequestsMockHelpers.setLoadComponentTemplatesResponse(undefined, { body: error }); + httpRequestsMockHelpers.setLoadComponentTemplatesResponse(undefined, error); await act(async () => { - testBed = await setup(); + testBed = await setup(httpSetup); }); testBed.component.update(); diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_create.helpers.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_create.helpers.ts index 06f0036cc5c77..20190f1079ddd 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_create.helpers.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_create.helpers.ts @@ -6,6 +6,7 @@ */ import { registerTestBed, TestBed, AsyncTestBedConfig } from '@kbn/test/jest'; +import { HttpSetup } from 'src/core/public'; import { BASE_PATH } from '../../../../../../../common'; import { ComponentTemplateCreate } from '../../../component_template_wizard'; @@ -27,9 +28,11 @@ const testBedConfig: AsyncTestBedConfig = { doMountAsync: true, }; -const initTestBed = registerTestBed(WithAppDependencies(ComponentTemplateCreate), testBedConfig); - -export const setup = async (): Promise => { +export const setup = async (httpSetup: HttpSetup): Promise => { + const initTestBed = registerTestBed( + WithAppDependencies(ComponentTemplateCreate, httpSetup), + testBedConfig + ); const testBed = await initTestBed(); return { diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_details.helpers.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_details.helpers.ts index 49bef82ce3d11..a1c6ab4f5f1f9 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_details.helpers.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_details.helpers.ts @@ -6,6 +6,7 @@ */ import { registerTestBed, TestBed } from '@kbn/test/jest'; +import { HttpSetup } from 'src/core/public'; import { WithAppDependencies } from './setup_environment'; import { ComponentTemplateDetailsFlyoutContent } from '../../../component_template_details'; @@ -43,9 +44,9 @@ const createActions = (testBed: TestBed) = }; }; -export const setup = (props: any): ComponentTemplateDetailsTestBed => { +export const setup = (httpSetup: HttpSetup, props: any): ComponentTemplateDetailsTestBed => { const setupTestBed = registerTestBed( - WithAppDependencies(ComponentTemplateDetailsFlyoutContent), + WithAppDependencies(ComponentTemplateDetailsFlyoutContent, httpSetup), { memoryRouter: { wrapComponent: false, diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_edit.helpers.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_edit.helpers.ts index e7b8df245aaa9..e927fdcb28dfd 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_edit.helpers.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_edit.helpers.ts @@ -6,6 +6,7 @@ */ import { registerTestBed, TestBed, AsyncTestBedConfig } from '@kbn/test/jest'; +import { HttpSetup } from 'src/core/public'; import { BASE_PATH } from '../../../../../../../common'; import { ComponentTemplateEdit } from '../../../component_template_wizard'; @@ -27,9 +28,11 @@ const testBedConfig: AsyncTestBedConfig = { doMountAsync: true, }; -const initTestBed = registerTestBed(WithAppDependencies(ComponentTemplateEdit), testBedConfig); - -export const setup = async (): Promise => { +export const setup = async (httpSetup: HttpSetup): Promise => { + const initTestBed = registerTestBed( + WithAppDependencies(ComponentTemplateEdit, httpSetup), + testBedConfig + ); const testBed = await initTestBed(); return { diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_list.helpers.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_list.helpers.ts index 680550d16096b..147ff0c379d0d 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_list.helpers.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_list.helpers.ts @@ -6,6 +6,7 @@ */ import { act } from 'react-dom/test-utils'; +import { HttpSetup } from 'src/core/public'; import { registerTestBed, @@ -26,8 +27,6 @@ const testBedConfig: AsyncTestBedConfig = { doMountAsync: true, }; -const initTestBed = registerTestBed(WithAppDependencies(ComponentTemplateList), testBedConfig); - export type ComponentTemplateListTestBed = TestBed & { actions: ReturnType; }; @@ -74,7 +73,11 @@ const createActions = (testBed: TestBed) => { }; }; -export const setup = async (): Promise => { +export const setup = async (httpSetup: HttpSetup): Promise => { + const initTestBed = registerTestBed( + WithAppDependencies(ComponentTemplateList, httpSetup), + testBedConfig + ); const testBed = await initTestBed(); return { diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/http_requests.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/http_requests.ts index 520da90c58862..025f34066908c 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/http_requests.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/http_requests.ts @@ -5,65 +5,74 @@ * 2.0. */ -import sinon, { SinonFakeServer } from 'sinon'; -import { - ComponentTemplateListItem, - ComponentTemplateDeserialized, - ComponentTemplateSerialized, -} from '../../../shared_imports'; +import { httpServiceMock } from '../../../../../../../../../../src/core/public/mocks'; import { API_BASE_PATH } from './constants'; +type HttpResponse = Record | any[]; +type HttpMethod = 'GET' | 'PUT' | 'DELETE' | 'POST'; + +export interface ResponseError { + statusCode: number; + message: string | Error; + attributes?: Record; +} + // Register helpers to mock HTTP Requests -const registerHttpRequestMockHelpers = (server: SinonFakeServer) => { - const setLoadComponentTemplatesResponse = ( - response?: ComponentTemplateListItem[], - error?: any - ) => { - const status = error ? error.status || 400 : 200; - const body = error ? error.body : response; +const registerHttpRequestMockHelpers = ( + httpSetup: ReturnType +) => { + const mockResponses = new Map>>( + ['GET', 'PUT', 'DELETE', 'POST'].map( + (method) => [method, new Map()] as [HttpMethod, Map>] + ) + ); - server.respondWith('GET', `${API_BASE_PATH}/component_templates`, [ - status, - { 'Content-Type': 'application/json' }, - JSON.stringify(body), - ]); + const mockMethodImplementation = (method: HttpMethod, path: string) => { + return mockResponses.get(method)?.get(path) ?? Promise.resolve({}); }; - const setLoadComponentTemplateResponse = ( - response?: ComponentTemplateDeserialized, - error?: any - ) => { - const status = error ? error.status || 400 : 200; - const body = error ? error.body : response; + httpSetup.get.mockImplementation((path) => + mockMethodImplementation('GET', path as unknown as string) + ); + httpSetup.delete.mockImplementation((path) => + mockMethodImplementation('DELETE', path as unknown as string) + ); + httpSetup.post.mockImplementation((path) => + mockMethodImplementation('POST', path as unknown as string) + ); + httpSetup.put.mockImplementation((path) => + mockMethodImplementation('PUT', path as unknown as string) + ); - server.respondWith('GET', `${API_BASE_PATH}/component_templates/:name`, [ - status, - { 'Content-Type': 'application/json' }, - JSON.stringify(body), - ]); - }; + const mockResponse = (method: HttpMethod, path: string, response?: unknown, error?: unknown) => { + const defuse = (promise: Promise) => { + promise.catch(() => {}); + return promise; + }; - const setDeleteComponentTemplateResponse = (response?: object) => { - server.respondWith('DELETE', `${API_BASE_PATH}/component_templates/:name`, [ - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(response), - ]); + return mockResponses + .get(method)! + .set(path, error ? defuse(Promise.reject({ body: error })) : Promise.resolve(response)); }; - const setCreateComponentTemplateResponse = ( - response?: ComponentTemplateSerialized, - error?: any - ) => { - const status = error ? error.body.status || 400 : 200; - const body = error ? JSON.stringify(error.body) : JSON.stringify(response); + const setLoadComponentTemplatesResponse = (response?: HttpResponse, error?: ResponseError) => + mockResponse('GET', `${API_BASE_PATH}/component_templates`, response, error); - server.respondWith('POST', `${API_BASE_PATH}/component_templates`, [ - status, - { 'Content-Type': 'application/json' }, - body, - ]); - }; + const setLoadComponentTemplateResponse = ( + templateId: string, + response?: HttpResponse, + error?: ResponseError + ) => mockResponse('GET', `${API_BASE_PATH}/component_templates/${templateId}`, response, error); + + const setDeleteComponentTemplateResponse = ( + templateId: string, + response?: HttpResponse, + error?: ResponseError + ) => + mockResponse('DELETE', `${API_BASE_PATH}/component_templates/${templateId}`, response, error); + + const setCreateComponentTemplateResponse = (response?: HttpResponse, error?: ResponseError) => + mockResponse('POST', `${API_BASE_PATH}/component_templates`, response, error); return { setLoadComponentTemplatesResponse, @@ -74,18 +83,11 @@ const registerHttpRequestMockHelpers = (server: SinonFakeServer) => { }; export const init = () => { - const server = sinon.fakeServer.create(); - server.respondImmediately = true; - - // Define default response for unhandled requests. - // We make requests to APIs which don't impact the component under test, e.g. UI metric telemetry, - // and we can mock them all with a 200 instead of mocking each one individually. - server.respondWith([200, {}, 'DefaultMockedResponse']); - - const httpRequestsMockHelpers = registerHttpRequestMockHelpers(server); + const httpSetup = httpServiceMock.createSetupContract(); + const httpRequestsMockHelpers = registerHttpRequestMockHelpers(httpSetup); return { - server, + httpSetup, httpRequestsMockHelpers, }; }; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/setup_environment.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/setup_environment.tsx index d532eaaba8923..9c2017ad651f1 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/setup_environment.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/setup_environment.tsx @@ -6,8 +6,6 @@ */ import React from 'react'; -import axios from 'axios'; -import axiosXhrAdapter from 'axios/lib/adapters/xhr'; import { HttpSetup } from 'kibana/public'; import { @@ -24,7 +22,6 @@ import { ComponentTemplatesProvider } from '../../../component_templates_context import { init as initHttpRequests } from './http_requests'; import { API_BASE_PATH } from './constants'; -const mockHttpClient = axios.create({ adapter: axiosXhrAdapter }); const { GlobalFlyoutProvider } = GlobalFlyout; // We provide the minimum deps required to make the tests pass @@ -32,30 +29,23 @@ const appDependencies = { docLinks: {} as any, } as any; -export const componentTemplatesDependencies = { - httpClient: mockHttpClient as unknown as HttpSetup, +export const componentTemplatesDependencies = (httpSetup: HttpSetup) => ({ + httpClient: httpSetup, apiBasePath: API_BASE_PATH, trackMetric: () => {}, docLinks: docLinksServiceMock.createStartContract(), toasts: notificationServiceMock.createSetupContract().toasts, setBreadcrumbs: () => {}, getUrlForApp: applicationServiceMock.createStartContract().getUrlForApp, -}; +}); -export const setupEnvironment = () => { - const { server, httpRequestsMockHelpers } = initHttpRequests(); +export const setupEnvironment = initHttpRequests; - return { - server, - httpRequestsMockHelpers, - }; -}; - -export const WithAppDependencies = (Comp: any) => (props: any) => +export const WithAppDependencies = (Comp: any, httpSetup: HttpSetup) => (props: any) => ( - +