1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Update tests to not use private functions

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2022-11-16 12:15:58 -05:00
parent a5873bbf7a
commit 285c9f2b92
3 changed files with 100 additions and 143 deletions

View File

@ -3,68 +3,43 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { UserStore } from "../../common/user-store";
import type { ClusterContextHandler } from "../context-handler/context-handler"; import type { ClusterContextHandler } from "../context-handler/context-handler";
import type { PrometheusService, PrometheusProviderRegistry } from "../prometheus";
import { PrometheusProvider } from "../prometheus";
import mockFs from "mock-fs";
import { getDiForUnitTesting } from "../getDiForUnitTesting"; import { getDiForUnitTesting } from "../getDiForUnitTesting";
import createContextHandlerInjectable from "../context-handler/create-context-handler.injectable"; import createContextHandlerInjectable from "../context-handler/create-context-handler.injectable";
import type { Cluster } from "../../common/cluster/cluster"; import type { Cluster } from "../../common/cluster/cluster";
import createKubeAuthProxyInjectable from "../kube-auth-proxy/create-kube-auth-proxy.injectable"; import createKubeAuthProxyInjectable from "../kube-auth-proxy/create-kube-auth-proxy.injectable";
import prometheusProviderRegistryInjectable from "../prometheus/prometheus-provider-registry.injectable"; import type { DiContainer } from "@ogre-tools/injectable";
import { getInjectable } from "@ogre-tools/injectable";
jest.mock("electron", () => ({ import type { PrometheusProvider } from "../prometheus/provider";
app: { import { prometheusProviderInjectionToken } from "../prometheus/provider";
getVersion: () => "99.99.99", import { runInAction } from "mobx";
getName: () => "lens",
setName: jest.fn(),
setPath: jest.fn(),
getPath: () => "tmp",
getLocale: () => "en",
setLoginItemSettings: jest.fn(),
},
ipcMain: {
on: jest.fn(),
handle: jest.fn(),
},
}));
enum ServiceResult { enum ServiceResult {
Success, Success,
Failure, Failure,
Undefined,
} }
class TestProvider extends PrometheusProvider { const createTestPrometheusProvider = (kind: string, alwaysFail: ServiceResult): PrometheusProvider => ({
name = "TestProvider1"; kind,
rateAccuracy = "1h"; name: "TestProvider1",
isConfigurable = false; isConfigurable: false,
getQuery: () => {
constructor(public id: string, public alwaysFail: ServiceResult) {
super();
}
getQuery(): string {
throw new Error("getQuery is not implemented."); throw new Error("getQuery is not implemented.");
} },
getPrometheusService: async () => {
async getPrometheusService(): Promise<PrometheusService | undefined> { switch (alwaysFail) {
switch (this.alwaysFail) {
case ServiceResult.Success: case ServiceResult.Success:
return { return {
id: this.id, kind,
namespace: "default", namespace: "default",
port: 7000, port: 7000,
service: "", service: "",
}; };
case ServiceResult.Failure: case ServiceResult.Failure:
throw new Error("does fail"); throw new Error("does fail");
case ServiceResult.Undefined:
return undefined;
} }
} },
} });
const clusterStub = { const clusterStub = {
getProxyKubeconfig: () => ({ getProxyKubeconfig: () => ({
@ -74,53 +49,34 @@ const clusterStub = {
} as unknown as Cluster; } as unknown as Cluster;
describe("ContextHandler", () => { describe("ContextHandler", () => {
let createContextHandler: (cluster: Cluster) => ClusterContextHandler | undefined; let createContextHandler: (cluster: Cluster) => ClusterContextHandler;
let prometheusProviderRegistry: PrometheusProviderRegistry; let di: DiContainer;
beforeEach(() => { beforeEach(() => {
const di = getDiForUnitTesting({ doGeneralOverrides: true }); di = getDiForUnitTesting({ doGeneralOverrides: true });
mockFs({
"tmp": {},
});
di.override(createKubeAuthProxyInjectable, () => ({} as any)); di.override(createKubeAuthProxyInjectable, () => ({} as any));
prometheusProviderRegistry = di.inject(prometheusProviderRegistryInjectable);
createContextHandler = di.inject(createContextHandlerInjectable); createContextHandler = di.inject(createContextHandlerInjectable);
}); });
afterEach(() => {
UserStore.resetInstance();
mockFs.restore();
});
describe("getPrometheusService", () => { describe("getPrometheusService", () => {
it.each([ it.each([
[0, 0], [0],
[0, 1], [1],
[0, 2], [2],
[0, 3], [3],
])("should throw from %d success(es) after %d failure(s)", async (successes, failures) => { ])("should throw after %d failure(s)", async (failures) => {
let count = 0; runInAction(() => {
for (let i = 0; i < failures; i += 1) {
di.register(getInjectable({
id: `test-prometheus-provider-failure-${i}`,
injectionToken: prometheusProviderInjectionToken,
instantiate: () => createTestPrometheusProvider(`id_failure_${i}`, ServiceResult.Failure),
}));
}
});
for (let i = 0; i < failures; i += 1) { expect(() => createContextHandler(clusterStub).getPrometheusDetails()).rejects.toThrowError();
const serviceResult = i % 2 === 0 ? ServiceResult.Failure : ServiceResult.Undefined;
prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, serviceResult));
}
for (let i = 0; i < successes; i += 1) {
prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, ServiceResult.Success));
}
expect(() => {
// TODO: Unit test shouldn't access protected or private methods
const contextHandler = createContextHandler(clusterStub) as unknown as { getPrometheusService(): Promise<PrometheusService> };
return contextHandler.getPrometheusService();
}).rejects.toBeDefined();
}); });
it.each([ it.each([
@ -133,24 +89,27 @@ describe("ContextHandler", () => {
[2, 2], [2, 2],
[2, 3], [2, 3],
])("should pick the first provider of %d success(es) after %d failure(s)", async (successes, failures) => { ])("should pick the first provider of %d success(es) after %d failure(s)", async (successes, failures) => {
let count = 0; runInAction(() => {
for (let i = 0; i < failures; i += 1) {
di.register(getInjectable({
id: `test-prometheus-provider-failure-${i}`,
injectionToken: prometheusProviderInjectionToken,
instantiate: () => createTestPrometheusProvider(`id_failure_${i}`, ServiceResult.Failure),
}));
}
for (let i = 0; i < failures; i += 1) { for (let i = 0; i < successes; i += 1) {
const serviceResult = i % 2 === 0 ? ServiceResult.Failure : ServiceResult.Undefined; di.register(getInjectable({
id: `test-prometheus-provider-success-${i}`,
injectionToken: prometheusProviderInjectionToken,
instantiate: () => createTestPrometheusProvider(`id_success_${i}`, ServiceResult.Success),
}));
}
});
prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, serviceResult)); const details = await createContextHandler(clusterStub).getPrometheusDetails();
}
for (let i = 0; i < successes; i += 1) { expect(details.provider.kind === `id_failure_${failures}`);
prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, ServiceResult.Success));
}
// TODO: Unit test shouldn't access protected or private methods
const contextHandler = createContextHandler(clusterStub) as unknown as { getPrometheusService(): Promise<PrometheusService> };
const service = await contextHandler.getPrometheusService();
expect(service.id === `id_${failures}`);
}); });
it.each([ it.each([
@ -163,24 +122,27 @@ describe("ContextHandler", () => {
[2, 2], [2, 2],
[2, 3], [2, 3],
])("should pick the first provider of %d success(es) before %d failure(s)", async (successes, failures) => { ])("should pick the first provider of %d success(es) before %d failure(s)", async (successes, failures) => {
let count = 0; runInAction(() => {
for (let i = 0; i < failures; i += 1) {
di.register(getInjectable({
id: `test-prometheus-provider-failure-${i}`,
injectionToken: prometheusProviderInjectionToken,
instantiate: () => createTestPrometheusProvider(`id_failure_${i}`, ServiceResult.Failure),
}));
}
for (let i = 0; i < successes; i += 1) { for (let i = 0; i < successes; i += 1) {
prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, ServiceResult.Success)); di.register(getInjectable({
} id: `test-prometheus-provider-success-${i}`,
injectionToken: prometheusProviderInjectionToken,
instantiate: () => createTestPrometheusProvider(`id_success_${i}`, ServiceResult.Success),
}));
}
});
for (let i = 0; i < failures; i += 1) { const details = await createContextHandler(clusterStub).getPrometheusDetails();
const serviceResult = i % 2 === 0 ? ServiceResult.Failure : ServiceResult.Undefined;
prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, serviceResult)); expect(details.provider.kind === "id_failure_0");
}
// TODO: Unit test shouldn't access protected or private methods
const contextHandler = createContextHandler(clusterStub) as unknown as { getPrometheusService(): Promise<PrometheusService> };
const service = await contextHandler.getPrometheusService();
expect(service.id === "id_0");
}); });
it.each([ it.each([
@ -193,45 +155,37 @@ describe("ContextHandler", () => {
[2, 2], [2, 2],
[2, 3], [2, 3],
])("should pick the first provider of %d success(es) between %d failure(s)", async (successes, failures) => { ])("should pick the first provider of %d success(es) between %d failure(s)", async (successes, failures) => {
let count = 0;
const beforeSuccesses = Math.floor(successes / 2); const beforeSuccesses = Math.floor(successes / 2);
const afterSuccesses = successes - beforeSuccesses;
for (let i = 0; i < beforeSuccesses; i += 1) { runInAction(() => {
prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, ServiceResult.Success)); for (let i = 0; i < beforeSuccesses; i += 1) {
} di.register(getInjectable({
id: `test-prometheus-provider-success-${i}`,
injectionToken: prometheusProviderInjectionToken,
instantiate: () => createTestPrometheusProvider(`id_success_${i}`, ServiceResult.Success),
}));
}
for (let i = 0; i < failures; i += 1) { for (let i = 0; i < failures; i += 1) {
const serviceResult = i % 2 === 0 ? ServiceResult.Failure : ServiceResult.Undefined; di.register(getInjectable({
id: `test-prometheus-provider-failure-${i}`,
injectionToken: prometheusProviderInjectionToken,
instantiate: () => createTestPrometheusProvider(`id_failure_${i}`, ServiceResult.Failure),
}));
}
prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, serviceResult)); for (let i = beforeSuccesses; i < successes; i += 1) {
} di.register(getInjectable({
id: `test-prometheus-provider-success-${i}`,
injectionToken: prometheusProviderInjectionToken,
instantiate: () => createTestPrometheusProvider(`id_success_${i}`, ServiceResult.Success),
}));
}
});
for (let i = 0; i < afterSuccesses; i += 1) { const details = await createContextHandler(clusterStub).getPrometheusDetails();
prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, ServiceResult.Success));
}
// TODO: Unit test shouldn't access protected or private methods expect(details.provider.kind === "id_success_0");
const contextHandler = createContextHandler(clusterStub) as unknown as { getPrometheusService(): Promise<PrometheusService> };
const service = await contextHandler.getPrometheusService();
expect(service.id === "id_0");
});
it("shouldn't pick the second provider of 2 success(es) after 1 failure(s)", async () => {
let count = 0;
prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, ServiceResult.Failure));
prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, ServiceResult.Success));
prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, ServiceResult.Success));
// TODO: Unit test shouldn't access protected or private methods
const contextHandler = createContextHandler(clusterStub) as unknown as { getPrometheusService(): Promise<PrometheusService> };
const service = await contextHandler.getPrometheusService();
expect(service.id).not.toBe("id_2");
}); });
}); });
}); });

View File

@ -10,11 +10,11 @@ import type httpProxy from "http-proxy";
import type { UrlWithStringQuery } from "url"; import type { UrlWithStringQuery } from "url";
import url from "url"; import url from "url";
import { CoreV1Api } from "@kubernetes/client-node"; import { CoreV1Api } from "@kubernetes/client-node";
import logger from "../logger";
import type { KubeAuthProxy } from "../kube-auth-proxy/kube-auth-proxy"; import type { KubeAuthProxy } from "../kube-auth-proxy/kube-auth-proxy";
import type { CreateKubeAuthProxy } from "../kube-auth-proxy/create-kube-auth-proxy.injectable"; import type { CreateKubeAuthProxy } from "../kube-auth-proxy/create-kube-auth-proxy.injectable";
import type { GetPrometheusProviderByKind } from "../prometheus/get-by-kind.injectable"; import type { GetPrometheusProviderByKind } from "../prometheus/get-by-kind.injectable";
import type { IComputedValue } from "mobx"; import type { IComputedValue } from "mobx";
import type { Logger } from "../../common/logger";
export interface PrometheusDetails { export interface PrometheusDetails {
prometheusPath: string; prometheusPath: string;
@ -33,6 +33,7 @@ export interface ContextHandlerDependencies {
getPrometheusProviderByKind: GetPrometheusProviderByKind; getPrometheusProviderByKind: GetPrometheusProviderByKind;
readonly authProxyCa: string; readonly authProxyCa: string;
readonly prometheusProviders: IComputedValue<PrometheusProvider[]>; readonly prometheusProviders: IComputedValue<PrometheusProvider[]>;
readonly logger: Logger;
} }
export interface ClusterContextHandler { export interface ClusterContextHandler {
@ -78,7 +79,7 @@ export class ContextHandler implements ClusterContextHandler {
protected ensurePrometheusProvider(service: PrometheusService): PrometheusProvider { protected ensurePrometheusProvider(service: PrometheusService): PrometheusProvider {
if (!this.prometheusProvider) { if (!this.prometheusProvider) {
logger.info(`[CONTEXT-HANDLER]: using ${service.kind} as prometheus provider for clusterId=${this.cluster.id}`); this.dependencies.logger.info(`[CONTEXT-HANDLER]: using ${service.kind} as prometheus provider for clusterId=${this.cluster.id}`);
this.prometheusProvider = service.kind; this.prometheusProvider = service.kind;
} }

View File

@ -11,6 +11,7 @@ import kubeAuthProxyCertificateInjectable from "../kube-auth-proxy/kube-auth-pro
import URLParse from "url-parse"; import URLParse from "url-parse";
import getPrometheusProviderByKindInjectable from "../prometheus/get-by-kind.injectable"; import getPrometheusProviderByKindInjectable from "../prometheus/get-by-kind.injectable";
import prometheusProvidersInjectable from "../prometheus/providers.injectable"; import prometheusProvidersInjectable from "../prometheus/providers.injectable";
import loggerInjectable from "../../common/logger.injectable";
const createContextHandlerInjectable = getInjectable({ const createContextHandlerInjectable = getInjectable({
id: "create-context-handler", id: "create-context-handler",
@ -20,6 +21,7 @@ const createContextHandlerInjectable = getInjectable({
createKubeAuthProxy: di.inject(createKubeAuthProxyInjectable), createKubeAuthProxy: di.inject(createKubeAuthProxyInjectable),
getPrometheusProviderByKind: di.inject(getPrometheusProviderByKindInjectable), getPrometheusProviderByKind: di.inject(getPrometheusProviderByKindInjectable),
prometheusProviders: di.inject(prometheusProvidersInjectable), prometheusProviders: di.inject(prometheusProvidersInjectable),
logger: di.inject(loggerInjectable),
}; };
return (cluster: Cluster): ClusterContextHandler => { return (cluster: Cluster): ClusterContextHandler => {