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

Fix not showing some non-core kinds (#7303)

* Fix not showing some non-core kinds

- Specifically if a Kind is not present within the preferredVersion of
  a group then we don't know that resource exists

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Add technical tests

Signed-off-by: Sebastian Malton <sebastian@malton.name>

---------

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2023-03-07 08:34:29 -08:00 committed by GitHub
parent aee3c38e7e
commit b4c0ca981a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 180 additions and 7 deletions

View File

@ -4,7 +4,6 @@
*/
import { getInjectionToken } from "@ogre-tools/injectable";
import type { Cluster } from "../../common/cluster/cluster";
import type { AsyncResult } from "../../common/utils/async-result";
export interface KubeResourceListGroup {
@ -12,7 +11,11 @@ export interface KubeResourceListGroup {
path: string;
}
export type RequestApiVersions = (cluster: Cluster) => Promise<AsyncResult<KubeResourceListGroup[], Error>>;
export interface ClusterData {
readonly id: string;
}
export type RequestApiVersions = (cluster: ClusterData) => Promise<AsyncResult<KubeResourceListGroup[], Error>>;
export const requestApiVersionsInjectionToken = getInjectionToken<RequestApiVersions>({
id: "request-api-versions-token",

View File

@ -20,10 +20,10 @@ const requestNonCoreApiVersionsInjectable = getInjectable({
return {
callWasSuccessful: true,
response: chain(groups.values())
.filterMap(group => group.preferredVersion?.groupVersion && ({
.flatMap(group => group.versions.map(version => ({
group: group.name,
path: `/apis/${group.preferredVersion.groupVersion}`,
}))
path: `/apis/${version.groupVersion}`,
})))
.collect(v => [...v]),
};
} catch (error) {

View File

@ -0,0 +1,167 @@
/**
* 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";
import asyncFn from "@async-fn/jest";
import type { V1APIGroupList } from "@kubernetes/client-node";
import type { DiContainer } from "@ogre-tools/injectable";
import { getDiForUnitTesting } from "../getDiForUnitTesting";
import type { K8sRequest } from "../k8s-request.injectable";
import k8sRequestInjectable from "../k8s-request.injectable";
import type { RequestApiVersions } from "./request-api-versions";
import requestNonCoreApiVersionsInjectable from "./request-non-core-api-versions.injectable";
describe("requestNonCoreApiVersions", () => {
let di: DiContainer;
let k8sRequestMock: AsyncFnMock<K8sRequest>;
let requestNonCoreApiVersions: RequestApiVersions;
beforeEach(() => {
di = getDiForUnitTesting({ doGeneralOverrides: true });
k8sRequestMock = asyncFn();
di.override(k8sRequestInjectable, () => k8sRequestMock);
requestNonCoreApiVersions = di.inject(requestNonCoreApiVersionsInjectable);
});
describe("when called", () => {
let versionsRequest: ReturnType<RequestApiVersions>;
beforeEach(() => {
versionsRequest = requestNonCoreApiVersions({ id: "some-cluster-id" });
});
it("should request all api groups", () => {
expect(k8sRequestMock).toBeCalledWith({ id: "some-cluster-id" }, "/apis");
});
describe("when api groups request resolves to empty", () => {
beforeEach(async () => {
await k8sRequestMock.resolve({ groups: [] } as V1APIGroupList);
});
it("should return empty list", async () => {
expect(await versionsRequest).toEqual({
callWasSuccessful: true,
response: [],
});
});
});
describe("when api groups request resolves to single group", () => {
beforeEach(async () => {
await k8sRequestMock.resolve({ groups: [{
name: "some-name",
versions: [{
groupVersion: "some-name/v1",
version: "v1",
}],
}] } as V1APIGroupList);
});
it("should return single entry in list", async () => {
expect(await versionsRequest).toEqual({
callWasSuccessful: true,
response: [{
group: "some-name",
path: "/apis/some-name/v1",
}],
});
});
});
describe("when api groups request resolves to single group with multiple versions", () => {
beforeEach(async () => {
await k8sRequestMock.resolve({ groups: [{
name: "some-name",
versions: [
{
groupVersion: "some-name/v1",
version: "v1",
},
{
groupVersion: "some-name/v1beta1",
version: "v1beta1",
},
],
}] } as V1APIGroupList);
});
it("should return multiple entries in list", async () => {
expect(await versionsRequest).toEqual({
callWasSuccessful: true,
response: [
{
group: "some-name",
path: "/apis/some-name/v1",
},
{
group: "some-name",
path: "/apis/some-name/v1beta1",
},
],
});
});
});
describe("when api groups request resolves to multiple groups with multiple versions", () => {
beforeEach(async () => {
await k8sRequestMock.resolve({ groups: [
{
name: "some-name",
versions: [
{
groupVersion: "some-name/v1",
version: "v1",
},
{
groupVersion: "some-name/v1beta1",
version: "v1beta1",
},
],
},
{
name: "some-other-name.foo.com",
versions: [
{
groupVersion: "some-other-name.foo.com/v1",
version: "v1",
},
{
groupVersion: "some-other-name.foo.com/v1beta1",
version: "v1beta1",
},
],
},
] } as V1APIGroupList);
});
it("should return multiple entries in list", async () => {
expect(await versionsRequest).toEqual({
callWasSuccessful: true,
response: [
{
group: "some-name",
path: "/apis/some-name/v1",
},
{
group: "some-name",
path: "/apis/some-name/v1beta1",
},
{
group: "some-other-name.foo.com",
path: "/apis/some-other-name.foo.com/v1",
},
{
group: "some-other-name.foo.com",
path: "/apis/some-other-name.foo.com/v1beta1",
},
],
});
});
});
});
});

View File

@ -2,7 +2,6 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { Cluster } from "../common/cluster/cluster";
import { getInjectable } from "@ogre-tools/injectable";
import type { LensRequestInit } from "../common/fetch/lens-fetch.injectable";
import lensFetchInjectable from "../common/fetch/lens-fetch.injectable";
@ -12,7 +11,11 @@ export interface K8sRequestInit extends LensRequestInit {
timeout?: number;
}
export type K8sRequest = (cluster: Cluster, pathnameAndQuery: string, init?: K8sRequestInit) => Promise<unknown>;
export interface ClusterData {
readonly id: string;
}
export type K8sRequest = (cluster: ClusterData, pathnameAndQuery: string, init?: K8sRequestInit) => Promise<unknown>;
const k8sRequestInjectable = getInjectable({
id: "k8s-request",