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:
parent
008b990e57
commit
7407c24767
@ -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", () => {});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -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>;
|
||||||
|
|||||||
@ -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),
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
17
packages/core/src/test-utils/mock-interface.ts
Normal file
17
packages/core/src/test-utils/mock-interface.ts
Normal 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]>;
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue
Block a user