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

Fixup tests

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2023-03-10 11:22:04 -05:00
parent 008b990e57
commit 7407c24767
5 changed files with 242 additions and 199 deletions

View File

@ -22,8 +22,10 @@ import type { DetectClusterMetadata } from "../../main/cluster-detectors/detect-
import detectClusterMetadataInjectable from "../../main/cluster-detectors/detect-cluster-metadata.injectable"; import detectClusterMetadataInjectable from "../../main/cluster-detectors/detect-cluster-metadata.injectable";
import type { ClusterConnection } from "../../main/cluster/cluster-connection.injectable"; import type { ClusterConnection } from "../../main/cluster/cluster-connection.injectable";
import clusterConnectionInjectable from "../../main/cluster/cluster-connection.injectable"; import clusterConnectionInjectable from "../../main/cluster/cluster-connection.injectable";
import type { KubeAuthProxy } from "../../main/kube-auth-proxy/create-kube-auth-proxy.injectable";
import createKubeAuthProxyInjectable from "../../main/kube-auth-proxy/create-kube-auth-proxy.injectable";
import type { Mocked } from "../../test-utils/mock-interface";
import { flushPromises } from "@k8slens/test-utils"; import { flushPromises } from "@k8slens/test-utils";
import { setTimeout } from "timers/promises";
describe("Refresh Cluster Accessibility Technical Tests", () => { describe("Refresh Cluster Accessibility Technical Tests", () => {
let builder: ApplicationBuilder; let builder: ApplicationBuilder;
@ -32,6 +34,7 @@ describe("Refresh Cluster Accessibility Technical Tests", () => {
let listNamespaceMock: AsyncFnMock<CoreV1Api["listNamespace"]>; let listNamespaceMock: AsyncFnMock<CoreV1Api["listNamespace"]>;
let k8sRequestMock: AsyncFnMock<K8sRequest>; let k8sRequestMock: AsyncFnMock<K8sRequest>;
let detectClusterMetadataMock: AsyncFnMock<DetectClusterMetadata>; let detectClusterMetadataMock: AsyncFnMock<DetectClusterMetadata>;
let kubeAuthProxyMock: Mocked<KubeAuthProxy>;
beforeEach(async () => { beforeEach(async () => {
builder = getApplicationBuilder(); builder = getApplicationBuilder();
@ -40,6 +43,14 @@ describe("Refresh Cluster Accessibility Technical Tests", () => {
mainDi.override(broadcastMessageInjectable, () => async () => {}); mainDi.override(broadcastMessageInjectable, () => async () => {});
kubeAuthProxyMock = {
apiPrefix: "/some-api-prefix",
port: 0,
exit: jest.fn(),
run: asyncFn(),
};
mainDi.override(createKubeAuthProxyInjectable, () => () => kubeAuthProxyMock);
detectClusterMetadataMock = asyncFn(); detectClusterMetadataMock = asyncFn();
mainDi.override(detectClusterMetadataInjectable, () => detectClusterMetadataMock); mainDi.override(detectClusterMetadataInjectable, () => detectClusterMetadataMock);
@ -101,326 +112,333 @@ describe("Refresh Cluster Accessibility Technical Tests", () => {
cluster = clusterStore.getById("some-cluster-id") ?? (() => { throw new Error("missing cluster"); })(); cluster = clusterStore.getById("some-cluster-id") ?? (() => { throw new Error("missing cluster"); })();
clusterConnection = mainDi.inject(clusterConnectionInjectable, cluster); clusterConnection = mainDi.inject(clusterConnectionInjectable, cluster);
refreshPromise = clusterConnection.refreshAccessibilityAndMetadata(); refreshPromise = clusterConnection.refreshAccessibilityAndMetadata();
// NOTE: I don't know why these are all are required to get the tests to pass
await flushPromises();
await setTimeout(50);
await flushPromises();
}); });
it("requests if cluster has admin permissions", async () => { it("starts kubeAuthProxy", () => {
expect(createSelfSubjectAccessReviewMock).toBeCalledWith(anyObject({ expect(kubeAuthProxyMock.run).toBeCalled();
spec: {
namespace: "kube-system",
resource: "*",
verb: "create",
},
}));
}); });
describe.each([ true, false ])("when cluster admin request resolves to %p", (isAdmin) => { describe("when kubeAuthProxy has started running and its port is found", () => {
beforeEach(async () => { beforeEach(async () => {
await createSelfSubjectAccessReviewMock.resolve({ kubeAuthProxyMock.port = 1235;
body: { await kubeAuthProxyMock.run.resolve();
status: { await flushPromises();
allowed: isAdmin,
},
} as PartialDeep<V1SelfSubjectAccessReview>,
} as any);
}); });
it("requests if cluster has global watch permissions", () => { it("requests if cluster has admin permissions", async () => {
expect(createSelfSubjectAccessReviewMock).toBeCalledWith(anyObject({ expect(createSelfSubjectAccessReviewMock).toBeCalledWith(anyObject({
spec: { spec: {
verb: "watch", namespace: "kube-system",
resource: "*", resource: "*",
verb: "create",
}, },
})); }));
}); });
describe.each([ true, false ])("when cluster global watch request resolves with %p", (globalWatch) => { describe.each([ true, false ])("when cluster admin request resolves to %p", (isAdmin) => {
beforeEach(async () => { beforeEach(async () => {
await createSelfSubjectAccessReviewMock.resolve({ await createSelfSubjectAccessReviewMock.resolve({
body: { body: {
status: { status: {
allowed: globalWatch, allowed: isAdmin,
}, },
} as PartialDeep<V1SelfSubjectAccessReview>, } as PartialDeep<V1SelfSubjectAccessReview>,
} as any); } as any);
}); });
it("requests namespaces", () => { it("requests if cluster has global watch permissions", () => {
expect(listNamespaceMock).toBeCalled(); expect(createSelfSubjectAccessReviewMock).toBeCalledWith(anyObject({
spec: {
verb: "watch",
resource: "*",
},
}));
}); });
describe("when list namespaces resolves", () => { describe.each([ true, false ])("when cluster global watch request resolves with %p", (globalWatch) => {
beforeEach(async () => { beforeEach(async () => {
await listNamespaceMock.resolve(listNamespaceResponse); await createSelfSubjectAccessReviewMock.resolve({
body: {
status: {
allowed: globalWatch,
},
} as PartialDeep<V1SelfSubjectAccessReview>,
} as any);
}); });
it("requests core api versions", () => { it("requests namespaces", () => {
expect(k8sRequestMock).toBeCalledWith( expect(listNamespaceMock).toBeCalled();
anyObject({ id: "some-cluster-id" }),
"/api",
);
}); });
describe("when core api versions request resolves", () => { describe("when list namespaces resolves", () => {
beforeEach(async () => { beforeEach(async () => {
await k8sRequestMock.resolve({ await listNamespaceMock.resolve(listNamespaceResponse);
serverAddressByClientCIDRs: [],
versions: [
"v1",
],
} as V1APIVersions);
}); });
it("requests non-core api resource kinds", () => { it("requests core api versions", () => {
expect(k8sRequestMock).toBeCalledWith( expect(k8sRequestMock).toBeCalledWith(
anyObject({ id: "some-cluster-id" }), anyObject({ id: "some-cluster-id" }),
"/apis", "/api",
); );
}); });
describe("when non-core api resource kinds request resolves", () => { describe("when core api versions request resolves", () => {
beforeEach(async () => { beforeEach(async () => {
await k8sRequestMock.resolve(nonCoreApiResponse); await k8sRequestMock.resolve({
serverAddressByClientCIDRs: [],
versions: [
"v1",
],
} as V1APIVersions);
}); });
it("requests specific resource kinds in core", () => { it("requests non-core api resource kinds", () => {
expect(k8sRequestMock).toBeCalledWith( expect(k8sRequestMock).toBeCalledWith(
anyObject({ id: "some-cluster-id" }), anyObject({ id: "some-cluster-id" }),
"/api/v1", "/apis",
); );
}); });
describe("when core specific resource kinds request resolves", () => { describe("when non-core api resource kinds request resolves", () => {
beforeEach(async () => { beforeEach(async () => {
await k8sRequestMock.resolve(coreApiKindsResponse); await k8sRequestMock.resolve(nonCoreApiResponse);
}); });
it("requests specific resources kinds from the first non-core response", () => { it("requests specific resource kinds in core", () => {
expect(k8sRequestMock).toBeCalledWith( expect(k8sRequestMock).toBeCalledWith(
anyObject({ id: "some-cluster-id" }), anyObject({ id: "some-cluster-id" }),
"/apis/node.k8s.io/v1", "/api/v1",
); );
}); });
describe("when first specific resource kinds request resolves", () => { describe("when core specific resource kinds request resolves", () => {
beforeEach(async () => { beforeEach(async () => {
await k8sRequestMock.resolve(nodeK8sIoKindsResponse); await k8sRequestMock.resolve(coreApiKindsResponse);
}); });
it("requests specific resources kinds from the second non-core response", () => { it("requests specific resources kinds from the first non-core response", () => {
expect(k8sRequestMock).toBeCalledWith( expect(k8sRequestMock).toBeCalledWith(
anyObject({ id: "some-cluster-id" }), anyObject({ id: "some-cluster-id" }),
"/apis/discovery.k8s.io/v1", "/apis/node.k8s.io/v1",
); );
}); });
describe("when second specific resource kinds request resolves", () => { describe("when first specific resource kinds request resolves", () => {
beforeEach(async () => { beforeEach(async () => {
await k8sRequestMock.resolve(discoveryK8sIoKindsResponse); await k8sRequestMock.resolve(nodeK8sIoKindsResponse);
}); });
it("requests namespace list permissions for 'default' namespace", () => { it("requests specific resources kinds from the second non-core response", () => {
expect(createSelfSubjectRulesReviewMock).toBeCalledWith(anyObject({ expect(k8sRequestMock).toBeCalledWith(
spec: { anyObject({ id: "some-cluster-id" }),
namespace: "default", "/apis/discovery.k8s.io/v1",
}, );
}));
}); });
describe("when the permissions are incomplete", () => { describe("when second specific resource kinds request resolves", () => {
beforeEach(async () => { beforeEach(async () => {
await createSelfSubjectRulesReviewMock.resolve(defaultIncompletePermissions); await k8sRequestMock.resolve(discoveryK8sIoKindsResponse);
}); });
it("requests namespace list permissions for 'my-namespace' namespace", () => { it("requests namespace list permissions for 'default' namespace", () => {
expect(createSelfSubjectRulesReviewMock).toBeCalledWith(anyObject({ expect(createSelfSubjectRulesReviewMock).toBeCalledWith(anyObject({
spec: { spec: {
namespace: "my-namespace", namespace: "default",
}, },
})); }));
}); });
describe("when the permissions request for 'my-namespace' resolves as empty", () => { describe("when the permissions are incomplete", () => {
beforeEach(async () => {
await createSelfSubjectRulesReviewMock.resolve(defaultIncompletePermissions);
});
it("requests namespace list permissions for 'my-namespace' namespace", () => {
expect(createSelfSubjectRulesReviewMock).toBeCalledWith(anyObject({
spec: {
namespace: "my-namespace",
},
}));
});
describe("when the permissions request for 'my-namespace' resolves as empty", () => {
beforeEach(async () => {
await createSelfSubjectRulesReviewMock.resolve(emptyPermissions);
});
it("requests cluster metadata", () => {
expect(detectClusterMetadataMock).toBeCalledWith(anyObject({ id: "some-cluster-id" }));
});
describe("when cluster metadata request resolves", () => {
beforeEach(async () => {
await detectClusterMetadataMock.resolve({});
});
it("allows the call to refreshAccessibilityAndMetadata to resolve", async () => {
await refreshPromise;
});
it("should have the cluster displaying 'pods'", () => {
expect(cluster.resourcesToShow.has("pods")).toBe(true);
});
it("should have the cluster displaying 'namespaces'", () => {
expect(cluster.resourcesToShow.has("namespaces")).toBe(true);
});
});
});
describe.skip("when the permissions are incomplete", () => {});
describe.skip("when the permissions resolve to a single entry with 'list' verb", () => {});
describe.skip("when the permissions resolve to multiple entries with the 'list' verb not on the first entry", () => {});
});
describe("when the permissions resolve to an empty list", () => {
beforeEach(async () => { beforeEach(async () => {
await createSelfSubjectRulesReviewMock.resolve(emptyPermissions); await createSelfSubjectRulesReviewMock.resolve(emptyPermissions);
}); });
it("requests cluster metadata", () => { it("requests namespace list permissions for 'my-namespace' namespace", () => {
expect(detectClusterMetadataMock).toBeCalledWith(anyObject({ id: "some-cluster-id" })); expect(createSelfSubjectRulesReviewMock).toBeCalledWith(anyObject({
spec: {
namespace: "my-namespace",
},
}));
}); });
describe("when cluster metadata request resolves", () => { describe("when the permissions request for 'my-namespace' resolves as empty", () => {
beforeEach(async () => { beforeEach(async () => {
await detectClusterMetadataMock.resolve({}); await createSelfSubjectRulesReviewMock.resolve(emptyPermissions);
}); });
it("allows the call to refreshAccessibilityAndMetadata to resolve", async () => { it("requests cluster metadata", () => {
await refreshPromise; expect(detectClusterMetadataMock).toBeCalledWith(anyObject({ id: "some-cluster-id" }));
}); });
it("should have the cluster displaying 'pods'", () => { describe("when cluster metadata request resolves", () => {
expect(cluster.resourcesToShow.has("pods")).toBe(true); beforeEach(async () => {
}); await detectClusterMetadataMock.resolve({});
});
it("should have the cluster displaying 'namespaces'", () => { it("allows the call to refreshAccessibilityAndMetadata to resolve", async () => {
expect(cluster.resourcesToShow.has("namespaces")).toBe(true); await refreshPromise;
});
it("should have the cluster displaying 'pods'", () => {
expect(cluster.resourcesToShow.has("pods")).toBe(false);
});
it("should have the cluster not displaying 'namespaces'", () => {
expect(cluster.resourcesToShow.has("namespaces")).toBe(false);
});
}); });
}); });
describe.skip("when the permissions are incomplete", () => {});
describe.skip("when the permissions resolve to a single entry with 'list' verb", () => {});
describe.skip("when the permissions resolve to multiple entries with the 'list' verb not on the first entry", () => {});
}); });
describe.skip("when the permissions are incomplete", () => {}); describe("when the permissions resolve to a single entry with 'list' verb", () => {
describe.skip("when the permissions resolve to a single entry with 'list' verb", () => {});
describe.skip("when the permissions resolve to multiple entries with the 'list' verb not on the first entry", () => {});
});
describe("when the permissions resolve to an empty list", () => {
beforeEach(async () => {
await createSelfSubjectRulesReviewMock.resolve(emptyPermissions);
});
it("requests namespace list permissions for 'my-namespace' namespace", () => {
expect(createSelfSubjectRulesReviewMock).toBeCalledWith(anyObject({
spec: {
namespace: "my-namespace",
},
}));
});
describe("when the permissions request for 'my-namespace' resolves as empty", () => {
beforeEach(async () => { beforeEach(async () => {
await createSelfSubjectRulesReviewMock.resolve(emptyPermissions); await createSelfSubjectRulesReviewMock.resolve(defaultSingleListPermissions);
}); });
it("requests cluster metadata", () => { it("requests namespace list permissions for 'my-namespace' namespace", () => {
expect(detectClusterMetadataMock).toBeCalledWith(anyObject({ id: "some-cluster-id" })); expect(createSelfSubjectRulesReviewMock).toBeCalledWith(anyObject({
spec: {
namespace: "my-namespace",
},
}));
}); });
describe("when cluster metadata request resolves", () => { describe("when the permissions request for 'my-namespace' resolves as empty", () => {
beforeEach(async () => { beforeEach(async () => {
await detectClusterMetadataMock.resolve({}); await createSelfSubjectRulesReviewMock.resolve(emptyPermissions);
}); });
it("allows the call to refreshAccessibilityAndMetadata to resolve", async () => { it("requests cluster metadata", () => {
await refreshPromise; expect(detectClusterMetadataMock).toBeCalledWith(anyObject({ id: "some-cluster-id" }));
}); });
it("should have the cluster displaying 'pods'", () => { describe("when cluster metadata request resolves", () => {
expect(cluster.resourcesToShow.has("pods")).toBe(false); beforeEach(async () => {
}); await detectClusterMetadataMock.resolve({});
});
it("should have the cluster not displaying 'namespaces'", () => { it("allows the call to refreshAccessibilityAndMetadata to resolve", async () => {
expect(cluster.resourcesToShow.has("namespaces")).toBe(false); await refreshPromise;
});
it("should have the cluster displaying 'pods'", () => {
expect(cluster.resourcesToShow.has("pods")).toBe(true);
});
it("should have the cluster not displaying 'namespaces'", () => {
expect(cluster.resourcesToShow.has("namespaces")).toBe(false);
});
}); });
}); });
describe.skip("when the permissions are incomplete", () => {});
describe.skip("when the permissions resolve to a single entry with 'list' verb", () => {});
describe.skip("when the permissions resolve to multiple entries with the 'list' verb not on the first entry", () => {});
}); });
describe.skip("when the permissions are incomplete", () => {}); describe("when the permissions resolve to multiple entries with the 'list' verb not on the first entry", () => {
describe.skip("when the permissions resolve to a single entry with 'list' verb", () => {});
describe.skip("when the permissions resolve to multiple entries with the 'list' verb not on the first entry", () => {});
});
describe("when the permissions resolve to a single entry with 'list' verb", () => {
beforeEach(async () => {
await createSelfSubjectRulesReviewMock.resolve(defaultSingleListPermissions);
});
it("requests namespace list permissions for 'my-namespace' namespace", () => {
expect(createSelfSubjectRulesReviewMock).toBeCalledWith(anyObject({
spec: {
namespace: "my-namespace",
},
}));
});
describe("when the permissions request for 'my-namespace' resolves as empty", () => {
beforeEach(async () => { beforeEach(async () => {
await createSelfSubjectRulesReviewMock.resolve(emptyPermissions); await createSelfSubjectRulesReviewMock.resolve(defaultMultipleListPermissions);
}); });
it("requests cluster metadata", () => { it("requests namespace list permissions for 'my-namespace' namespace", () => {
expect(detectClusterMetadataMock).toBeCalledWith(anyObject({ id: "some-cluster-id" })); expect(createSelfSubjectRulesReviewMock).toBeCalledWith(anyObject({
spec: {
namespace: "my-namespace",
},
}));
}); });
describe("when cluster metadata request resolves", () => { describe("when the permissions request for 'my-namespace' resolves as empty", () => {
beforeEach(async () => { beforeEach(async () => {
await detectClusterMetadataMock.resolve({}); await createSelfSubjectRulesReviewMock.resolve(emptyPermissions);
}); });
it("allows the call to refreshAccessibilityAndMetadata to resolve", async () => { it("requests cluster metadata", () => {
await refreshPromise; expect(detectClusterMetadataMock).toBeCalledWith(anyObject({ id: "some-cluster-id" }));
}); });
it("should have the cluster displaying 'pods'", () => { describe("when cluster metadata request resolves", () => {
expect(cluster.resourcesToShow.has("pods")).toBe(true); beforeEach(async () => {
}); await detectClusterMetadataMock.resolve({});
});
it("should have the cluster not displaying 'namespaces'", () => { it("allows the call to refreshAccessibilityAndMetadata to resolve", async () => {
expect(cluster.resourcesToShow.has("namespaces")).toBe(false); await refreshPromise;
});
it("should have the cluster displaying 'pods'", () => {
expect(cluster.resourcesToShow.has("pods")).toBe(true);
});
it("should have the cluster not displaying 'namespaces'", () => {
expect(cluster.resourcesToShow.has("namespaces")).toBe(false);
});
}); });
}); });
});
describe.skip("when the permissions are incomplete", () => {}); describe.skip("when the permissions are incomplete", () => {});
describe.skip("when the permissions resolve to a single entry with 'list' verb", () => {}); describe.skip("when the permissions resolve to a single entry with 'list' verb", () => {});
describe.skip("when the permissions resolve to multiple entries with the 'list' verb not on the first entry", () => {}); describe.skip("when the permissions resolve to multiple entries with the 'list' verb not on the first entry", () => {});
});
}); });
describe("when the permissions resolve to multiple entries with the 'list' verb not on the first entry", () => { describe.skip("when second specific resource kinds rejects", () => {});
beforeEach(async () => {
await createSelfSubjectRulesReviewMock.resolve(defaultMultipleListPermissions);
});
it("requests namespace list permissions for 'my-namespace' namespace", () => {
expect(createSelfSubjectRulesReviewMock).toBeCalledWith(anyObject({
spec: {
namespace: "my-namespace",
},
}));
});
describe("when the permissions request for 'my-namespace' resolves as empty", () => {
beforeEach(async () => {
await createSelfSubjectRulesReviewMock.resolve(emptyPermissions);
});
it("requests cluster metadata", () => {
expect(detectClusterMetadataMock).toBeCalledWith(anyObject({ id: "some-cluster-id" }));
});
describe("when cluster metadata request resolves", () => {
beforeEach(async () => {
await detectClusterMetadataMock.resolve({});
});
it("allows the call to refreshAccessibilityAndMetadata to resolve", async () => {
await refreshPromise;
});
it("should have the cluster displaying 'pods'", () => {
expect(cluster.resourcesToShow.has("pods")).toBe(true);
});
it("should have the cluster not displaying 'namespaces'", () => {
expect(cluster.resourcesToShow.has("namespaces")).toBe(false);
});
});
});
describe.skip("when the permissions are incomplete", () => {});
describe.skip("when the permissions resolve to a single entry with 'list' verb", () => {});
describe.skip("when the permissions resolve to multiple entries with the 'list' verb not on the first entry", () => {});
});
}); });
describe.skip("when second specific resource kinds rejects", () => {});
}); });
});
describe.skip("when first specific resource kinds rejects", () => {}); describe.skip("when first specific resource kinds rejects", () => {});
});
}); });
}); });
}); });

View File

@ -8,7 +8,7 @@ import { getInjectable, lifecycleEnum } from "@ogre-tools/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 kubeAuthProxyCertificateInjectable from "../kube-auth-proxy/kube-auth-proxy-certificate.injectable"; import kubeAuthProxyCertificateInjectable from "../kube-auth-proxy/kube-auth-proxy-certificate.injectable";
import type { KubeAuthProxy } from "../kube-auth-proxy/kube-auth-proxy"; import type { KubeAuthProxy } from "../kube-auth-proxy/create-kube-auth-proxy.injectable";
export interface KubeAuthProxyServer { export interface KubeAuthProxyServer {
getApiTarget(isLongRunningRequest?: boolean): Promise<ServerOptions>; getApiTarget(isLongRunningRequest?: boolean): Promise<ServerOptions>;

View File

@ -4,7 +4,7 @@
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import type { KubeAuthProxyDependencies } from "./kube-auth-proxy"; import type { KubeAuthProxyDependencies } from "./kube-auth-proxy";
import { KubeAuthProxy } from "./kube-auth-proxy"; import { KubeAuthProxyImpl } from "./kube-auth-proxy";
import type { Cluster } from "../../common/cluster/cluster"; import type { Cluster } from "../../common/cluster/cluster";
import spawnInjectable from "../child-process/spawn.injectable"; import spawnInjectable from "../child-process/spawn.injectable";
import kubeAuthProxyCertificateInjectable from "./kube-auth-proxy-certificate.injectable"; import kubeAuthProxyCertificateInjectable from "./kube-auth-proxy-certificate.injectable";
@ -15,6 +15,13 @@ import getPortFromStreamInjectable from "../utils/get-port-from-stream.injectabl
import getDirnameOfPathInjectable from "../../common/path/get-dirname.injectable"; import getDirnameOfPathInjectable from "../../common/path/get-dirname.injectable";
import broadcastConnectionUpdateInjectable from "../cluster/broadcast-connection-update.injectable"; import broadcastConnectionUpdateInjectable from "../cluster/broadcast-connection-update.injectable";
export interface KubeAuthProxy {
readonly apiPrefix: string;
readonly port: number;
run: () => Promise<void>;
exit: () => void;
}
export type CreateKubeAuthProxy = (cluster: Cluster, env: NodeJS.ProcessEnv) => KubeAuthProxy; export type CreateKubeAuthProxy = (cluster: Cluster, env: NodeJS.ProcessEnv) => KubeAuthProxy;
const createKubeAuthProxyInjectable = getInjectable({ const createKubeAuthProxyInjectable = getInjectable({
@ -33,7 +40,7 @@ const createKubeAuthProxyInjectable = getInjectable({
return (cluster, env) => { return (cluster, env) => {
const clusterUrl = new URL(cluster.apiUrl.get()); const clusterUrl = new URL(cluster.apiUrl.get());
return new KubeAuthProxy({ return new KubeAuthProxyImpl({
...dependencies, ...dependencies,
proxyCert: di.inject(kubeAuthProxyCertificateInjectable, clusterUrl.hostname), proxyCert: di.inject(kubeAuthProxyCertificateInjectable, clusterUrl.hostname),
broadcastConnectionUpdate: di.inject(broadcastConnectionUpdateInjectable, cluster), broadcastConnectionUpdate: di.inject(broadcastConnectionUpdateInjectable, cluster),

View File

@ -16,6 +16,7 @@ import type { Logger } from "../../common/logger";
import type { WaitUntilPortIsUsed } from "./wait-until-port-is-used/wait-until-port-is-used.injectable"; import type { WaitUntilPortIsUsed } from "./wait-until-port-is-used/wait-until-port-is-used.injectable";
import type { GetDirnameOfPath } from "../../common/path/get-dirname.injectable"; import type { GetDirnameOfPath } from "../../common/path/get-dirname.injectable";
import type { BroadcastConnectionUpdate } from "../cluster/broadcast-connection-update.injectable"; import type { BroadcastConnectionUpdate } from "../cluster/broadcast-connection-update.injectable";
import type { KubeAuthProxy } from "./create-kube-auth-proxy.injectable";
const startingServeMatcher = "starting to serve on (?<address>.+)"; const startingServeMatcher = "starting to serve on (?<address>.+)";
const startingServeRegex = Object.assign(TypedRegEx(startingServeMatcher, "i"), { const startingServeRegex = Object.assign(TypedRegEx(startingServeMatcher, "i"), {
@ -33,7 +34,7 @@ export interface KubeAuthProxyDependencies {
broadcastConnectionUpdate: BroadcastConnectionUpdate; broadcastConnectionUpdate: BroadcastConnectionUpdate;
} }
export class KubeAuthProxy { export class KubeAuthProxyImpl implements KubeAuthProxy {
public readonly apiPrefix = `/${randomBytes(8).toString("hex")}`; public readonly apiPrefix = `/${randomBytes(8).toString("hex")}`;
public get port(): number { public get port(): number {

View File

@ -0,0 +1,17 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { AsyncFnMock } from "@async-fn/jest";
type GetMockedType<T> =
T extends (...args: any[]) => Promise<any>
? AsyncFnMock<T>
: T extends (...args: any[]) => any
? jest.MockedFunction<T>
: T;
export type Mocked<T extends object> = {
-readonly [P in keyof T]: GetMockedType<T[P]>;
};