Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Remote Clusters] Remove axios dependency in tests #128590

Merged
merged 4 commits into from
Mar 30, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,13 @@
* 2.0.
*/

import React from 'react';
import { registerTestBed } from '@kbn/test-jest-helpers';
import { HttpSetup } from 'src/core/public';

import { RemoteClusterAdd } from '../../../public/application/sections';
import { createRemoteClustersStore } from '../../../public/application/store';
import { AppRouter, registerRouter } from '../../../public/application/services';
import { createRemoteClustersActions } from '../helpers';
import { AppContextProvider } from '../../../public/application/app_context';

const ComponentWithContext = ({ isCloudEnabled }: { isCloudEnabled: boolean }) => {
return (
<AppContextProvider context={{ isCloudEnabled, cloudBaseUrl: 'test.com' }}>
<RemoteClusterAdd />
</AppContextProvider>
);
};
import { createRemoteClustersActions, WithAppDependencies } from '../helpers';

const testBedConfig = ({ isCloudEnabled }: { isCloudEnabled: boolean }) => {
return {
Expand All @@ -32,11 +23,12 @@ const testBedConfig = ({ isCloudEnabled }: { isCloudEnabled: boolean }) => {
};
};

const initTestBed = (isCloudEnabled: boolean) =>
registerTestBed(ComponentWithContext, testBedConfig({ isCloudEnabled }))();

export const setup = async (isCloudEnabled = false) => {
const testBed = await initTestBed(isCloudEnabled);
export const setup = async (httpSetup: HttpSetup, overrides?: Record<string, unknown>) => {
const initTestBed = registerTestBed(
WithAppDependencies(RemoteClusterAdd, httpSetup, overrides),
testBedConfig({ isCloudEnabled: !!overrides?.isCloudEnabled })
sabarasaba marked this conversation as resolved.
Show resolved Hide resolved
);
const testBed = await initTestBed();

return {
...testBed,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
* 2.0.
*/

import { SinonFakeServer } from 'sinon';
import { TestBed } from '@kbn/test-jest-helpers';
import { act } from 'react-dom/test-utils';

Expand All @@ -17,20 +16,13 @@ const notInArray = (array: string[]) => (value: string) => array.indexOf(value)

let component: TestBed['component'];
let actions: RemoteClustersActions;
let server: SinonFakeServer;

describe('Create Remote cluster', () => {
beforeAll(() => {
({ server } = setupEnvironment());
});

afterAll(() => {
server.restore();
});
const { httpSetup } = setupEnvironment();

beforeEach(async () => {
await act(async () => {
({ actions, component } = await setup());
({ actions, component } = await setup(httpSetup));
});
component.update();
});
Expand Down Expand Up @@ -95,7 +87,7 @@ describe('Create Remote cluster', () => {
describe('on cloud', () => {
beforeEach(async () => {
await act(async () => {
({ actions, component } = await setup(true));
({ actions, component } = await setup(httpSetup, { isCloudEnabled: true }));
});

component.update();
Expand Down Expand Up @@ -153,7 +145,7 @@ describe('Create Remote cluster', () => {
describe('proxy address', () => {
beforeEach(async () => {
await act(async () => {
({ actions, component } = await setup());
({ actions, component } = await setup(httpSetup));
});

component.update();
Expand Down Expand Up @@ -190,7 +182,7 @@ describe('Create Remote cluster', () => {
describe('on prem', () => {
beforeEach(async () => {
await act(async () => {
({ actions, component } = await setup());
({ actions, component } = await setup(httpSetup));
});

component.update();
Expand Down Expand Up @@ -235,7 +227,7 @@ describe('Create Remote cluster', () => {
describe('on cloud', () => {
beforeEach(async () => {
await act(async () => {
({ actions, component } = await setup(true));
({ actions, component } = await setup(httpSetup, { isCloudEnabled: true }));
});

component.update();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@
*/

import { registerTestBed, TestBedConfig } from '@kbn/test-jest-helpers';
import { HttpSetup } from 'src/core/public';

import React from 'react';
import { RemoteClusterEdit } from '../../../public/application/sections';
import { createRemoteClustersStore } from '../../../public/application/store';
import { AppRouter, registerRouter } from '../../../public/application/services';
import { createRemoteClustersActions } from '../helpers';
import { AppContextProvider } from '../../../public/application/app_context';
import { createRemoteClustersActions, WithAppDependencies } from '../helpers';

export const REMOTE_CLUSTER_EDIT_NAME = 'new-york';

Expand All @@ -22,15 +21,6 @@ export const REMOTE_CLUSTER_EDIT = {
skipUnavailable: true,
};

const ComponentWithContext = (props: { isCloudEnabled: boolean }) => {
const { isCloudEnabled, ...rest } = props;
return (
<AppContextProvider context={{ isCloudEnabled, cloudBaseUrl: 'test.com' }}>
<RemoteClusterEdit {...rest} />
</AppContextProvider>
);
};

const testBedConfig: TestBedConfig = {
store: createRemoteClustersStore,
memoryRouter: {
Expand All @@ -43,11 +33,12 @@ const testBedConfig: TestBedConfig = {
},
};

const initTestBed = (isCloudEnabled: boolean) =>
registerTestBed(ComponentWithContext, testBedConfig)({ isCloudEnabled });

export const setup = async (isCloudEnabled = false) => {
const testBed = await initTestBed(isCloudEnabled);
export const setup = async (httpSetup: HttpSetup, overrides?: Record<string, unknown>) => {
const initTestBed = registerTestBed(
WithAppDependencies(RemoteClusterEdit, httpSetup, overrides),
testBedConfig
);
const testBed = await initTestBed();

return {
...testBed,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,15 @@ import { Cluster } from '../../../common/lib';

let component: TestBed['component'];
let actions: RemoteClustersActions;
const { server, httpRequestsMockHelpers } = setupEnvironment();

describe('Edit Remote cluster', () => {
afterAll(() => {
server.restore();
});
const { httpSetup, httpRequestsMockHelpers } = setupEnvironment();

httpRequestsMockHelpers.setLoadRemoteClustersResponse([REMOTE_CLUSTER_EDIT]);

beforeEach(async () => {
await act(async () => {
({ component, actions } = await setup());
({ component, actions } = await setup(httpSetup));
});
component.update();
});
Expand All @@ -54,7 +51,7 @@ describe('Edit Remote cluster', () => {
let addRemoteClusterTestBed: TestBed;

await act(async () => {
addRemoteClusterTestBed = await setupRemoteClustersAdd();
addRemoteClusterTestBed = await setupRemoteClustersAdd(httpSetup);
});

addRemoteClusterTestBed!.component.update();
Expand Down Expand Up @@ -90,7 +87,7 @@ describe('Edit Remote cluster', () => {
httpRequestsMockHelpers.setLoadRemoteClustersResponse([cluster]);

await act(async () => {
({ component, actions } = await setup(true));
({ component, actions } = await setup(httpSetup, { isCloudEnabled: true }));
});
component.update();

Expand All @@ -108,7 +105,7 @@ describe('Edit Remote cluster', () => {
httpRequestsMockHelpers.setLoadRemoteClustersResponse([cluster]);

await act(async () => {
({ component, actions } = await setup(true));
({ component, actions } = await setup(httpSetup, { isCloudEnabled: true }));
});
component.update();

Expand All @@ -128,7 +125,7 @@ describe('Edit Remote cluster', () => {
httpRequestsMockHelpers.setLoadRemoteClustersResponse([cluster]);

await act(async () => {
({ component, actions } = await setup(true));
({ component, actions } = await setup(httpSetup, { isCloudEnabled: true }));
});
component.update();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,56 @@
* 2.0.
*/

import sinon, { SinonFakeServer } from 'sinon';
import { httpServiceMock } from '../../../../../../src/core/public/mocks';
import { API_BASE_PATH } from '../../../common/constants';
import { Cluster } from '../../../common/lib';

type HttpMethod = 'GET' | 'DELETE';

export interface ResponseError {
statusCode: number;
message: string | Error;
}

// Register helpers to mock HTTP Requests
const registerHttpRequestMockHelpers = (server: SinonFakeServer) => {
const mockResponse = (response: Cluster[] | { itemsDeleted: string[]; errors: string[] }) => [
200,
{ 'Content-Type': 'application/json' },
JSON.stringify(response),
];

const setLoadRemoteClustersResponse = (response: Cluster[] = []) => {
server.respondWith('GET', '/api/remote_clusters', mockResponse(response));
const registerHttpRequestMockHelpers = (
httpSetup: ReturnType<typeof httpServiceMock.createStartContract>
) => {
const mockResponses = new Map<HttpMethod, Map<string, Promise<unknown>>>(
['GET', 'DELETE'].map(
(method) => [method, new Map()] as [HttpMethod, Map<string, Promise<unknown>>]
)
);

const mockMethodImplementation = (method: HttpMethod, path: string) =>
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)
);

const mockResponse = (method: HttpMethod, path: string, response?: unknown, error?: unknown) => {
const defuse = (promise: Promise<unknown>) => {
promise.catch(() => {});
return promise;
};

return mockResponses
.get(method)!
.set(path, error ? defuse(Promise.reject({ body: error })) : Promise.resolve(response));
};

const setLoadRemoteClustersResponse = (response: Cluster[], error?: ResponseError) =>
mockResponse('GET', API_BASE_PATH, response, error);

const setDeleteRemoteClusterResponse = (
response: { itemsDeleted: string[]; errors: string[] } = { itemsDeleted: [], errors: [] }
) => {
server.respondWith('DELETE', /api\/remote_clusters/, mockResponse(response));
};
clusterName: string,
response: { itemsDeleted: string[]; errors: string[] } = { itemsDeleted: [], errors: [] },
error?: ResponseError
) => mockResponse('DELETE', `${API_BASE_PATH}/${clusterName}`, response, error);

return {
setLoadRemoteClustersResponse,
Expand All @@ -33,15 +63,11 @@ const registerHttpRequestMockHelpers = (server: SinonFakeServer) => {
};

export const init = () => {
const server = sinon.fakeServer.create();
server.respondImmediately = true;

// We make requests to APIs which don't impact the UX, e.g. UI metric telemetry,
// and we can mock them all with a 200 instead of mocking each one individually.
server.respondWith([200, {}, '']);
const httpSetup = httpServiceMock.createSetupContract();
const httpRequestsMockHelpers = registerHttpRequestMockHelpers(httpSetup);

return {
server,
httpRequestsMockHelpers: registerHttpRequestMockHelpers(server),
httpSetup,
httpRequestsMockHelpers,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
*/

export { nextTick, getRandomString, findTestSubject } from '@kbn/test-jest-helpers';
export { setupEnvironment } from './setup_environment';
export { setupEnvironment, WithAppDependencies } from './setup_environment';
export type { RemoteClustersActions } from './remote_clusters_actions';
export { createRemoteClustersActions } from './remote_clusters_actions';
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
* 2.0.
*/

import axios from 'axios';
import axiosXhrAdapter from 'axios/lib/adapters/xhr';

import React from 'react';
import { HttpSetup } from 'src/core/public';
import {
notificationServiceMock,
fatalErrorsServiceMock,
docLinksServiceMock,
} from '../../../../../../src/core/public/mocks';

import { AppContextProvider } from '../../../public/application/app_context';
import { usageCollectionPluginMock } from '../../../../../../src/plugins/usage_collection/public/mocks';

import { init as initBreadcrumb } from '../../../public/application/services/breadcrumb';
Expand All @@ -23,27 +23,29 @@ import { init as initUiMetric } from '../../../public/application/services/ui_me
import { init as initDocumentation } from '../../../public/application/services/documentation';
import { init as initHttpRequests } from './http_requests';

export const setupEnvironment = () => {
// axios has a similar interface to HttpSetup, but we
// flatten out the response.
const mockHttpClient = axios.create({ adapter: axiosXhrAdapter });
mockHttpClient.interceptors.response.use(({ data }) => data);
export const WithAppDependencies =
(Comp: any, httpSetup: HttpSetup, overrides: Record<string, unknown> = {}) =>
(props: Record<string, unknown>) => {
const { isCloudEnabled, ...rest } = props;
initHttp(httpSetup);

return (
<AppContextProvider
context={{ isCloudEnabled: !!isCloudEnabled, cloudBaseUrl: 'test.com', ...overrides }}
>
<Comp {...rest} />
</AppContextProvider>
);
};

export const setupEnvironment = () => {
initBreadcrumb(() => {});
initDocumentation(docLinksServiceMock.createStartContract());
initUiMetric(usageCollectionPluginMock.createSetupContract());
initNotification(
notificationServiceMock.createSetupContract().toasts,
fatalErrorsServiceMock.createSetupContract()
);
// This expects HttpSetup but we're giving it AxiosInstance.
// @ts-ignore
initHttp(mockHttpClient);

const { server, httpRequestsMockHelpers } = initHttpRequests();

return {
server,
httpRequestsMockHelpers,
};
return initHttpRequests();
};
Loading