mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
fix delete-cluster-dialog.test.tsx
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
977c83502d
commit
203580ad92
@ -58,14 +58,14 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
|
||||
public get contextHandler() {
|
||||
// TODO: remove these once main/renderer are seperate classes
|
||||
assert(this._contextHandler);
|
||||
assert(this._contextHandler, "contextHandler is only defined in the main environment");
|
||||
|
||||
return this._contextHandler;
|
||||
}
|
||||
|
||||
protected get proxyKubeconfigManager() {
|
||||
// TODO: remove these once main/renderer are seperate classes
|
||||
assert(this._proxyKubeconfigManager);
|
||||
assert(this._proxyKubeconfigManager, "proxyKubeconfigManager is only defined in the main environment");
|
||||
|
||||
return this._proxyKubeconfigManager;
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ const createContextHandlerInjectable = getInjectable({
|
||||
instantiate: (di) => {
|
||||
const createKubeAuthProxy = di.inject(createKubeAuthProxyInjectable);
|
||||
|
||||
return (cluster: Cluster): ClusterContextHandler => {
|
||||
return (cluster: Cluster): ClusterContextHandler | undefined => {
|
||||
const clusterUrl = new URLParse(cluster.apiUrl);
|
||||
|
||||
return new ContextHandler(
|
||||
|
||||
@ -13,16 +13,18 @@ export interface KubeConfigManagerInstantiationParameter {
|
||||
cluster: Cluster;
|
||||
}
|
||||
|
||||
export type CreateKubeconfigManager = (cluster: Cluster) => KubeconfigManager | undefined;
|
||||
|
||||
const createKubeconfigManagerInjectable = getInjectable({
|
||||
id: "create-kubeconfig-manager",
|
||||
|
||||
instantiate: (di) => {
|
||||
instantiate: (di): CreateKubeconfigManager => {
|
||||
const dependencies: KubeconfigManagerDependencies = {
|
||||
directoryForTemp: di.inject(directoryForTempInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
};
|
||||
|
||||
return (cluster: Cluster) => new KubeconfigManager(dependencies, cluster);
|
||||
return (cluster) => new KubeconfigManager(dependencies, cluster);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
*/
|
||||
import "@testing-library/jest-dom/extend-expect";
|
||||
import { KubeConfig } from "@kubernetes/client-node";
|
||||
import { fireEvent } from "@testing-library/react";
|
||||
import { fireEvent, screen } from "@testing-library/react";
|
||||
import mockFs from "mock-fs";
|
||||
import React from "react";
|
||||
import * as selectEvent from "react-select-event";
|
||||
@ -16,9 +16,10 @@ import { createClusterInjectionToken } from "../../../../common/cluster/create-c
|
||||
import createContextHandlerInjectable from "../../../../main/context-handler/create-context-handler.injectable";
|
||||
import type { DiRender } from "../../test-utils/renderFor";
|
||||
import { renderFor } from "../../test-utils/renderFor";
|
||||
import hotbarStoreInjectable from "../../../../common/hotbars/store.injectable";
|
||||
import type { OpenDeleteClusterDialog } from "../open.injectable";
|
||||
import openDeleteClusterDialogInjectable from "../open.injectable";
|
||||
import createStoresAndApisInjectable from "../../../create-stores-apis.injectable";
|
||||
import createKubeconfigManagerInjectable from "../../../../main/kubeconfig-manager/create-kubeconfig-manager.injectable";
|
||||
|
||||
jest.mock("electron", () => ({
|
||||
app: {
|
||||
@ -98,12 +99,11 @@ describe("<DeleteClusterDialog />", () => {
|
||||
const { mainDi, rendererDi, runSetups } = getDisForUnitTesting({ doGeneralOverrides: true });
|
||||
|
||||
render = renderFor(rendererDi);
|
||||
|
||||
mainDi.override(createContextHandlerInjectable, () => () => undefined as never);
|
||||
|
||||
mainDi.override(createContextHandlerInjectable, () => () => undefined);
|
||||
mainDi.override(createKubeconfigManagerInjectable, () => () => undefined);
|
||||
mockFs();
|
||||
|
||||
rendererDi.override(hotbarStoreInjectable, () => ({}));
|
||||
rendererDi.override(createStoresAndApisInjectable, () => true);
|
||||
|
||||
await runSetups();
|
||||
|
||||
@ -137,7 +137,7 @@ describe("<DeleteClusterDialog />", () => {
|
||||
expect(container).toBeInstanceOf(HTMLElement);
|
||||
});
|
||||
|
||||
it("shows warning when deleting non-current-context cluster", () => {
|
||||
it("shows warning when deleting non-current-context cluster", async () => {
|
||||
const cluster = createCluster({
|
||||
id: "test",
|
||||
contextName: "test",
|
||||
@ -148,14 +148,14 @@ describe("<DeleteClusterDialog />", () => {
|
||||
});
|
||||
|
||||
openDeleteClusterDialog({ cluster, config });
|
||||
const { getByText } = render(<DeleteClusterDialog />);
|
||||
|
||||
render(<DeleteClusterDialog />);
|
||||
const message = "The contents of kubeconfig file will be changed!";
|
||||
|
||||
expect(getByText(message)).toBeInstanceOf(HTMLElement);
|
||||
expect(await screen.findByText(message)).toBeInstanceOf(HTMLElement);
|
||||
});
|
||||
|
||||
it("shows warning when deleting current-context cluster", () => {
|
||||
it("shows warning when deleting current-context cluster", async () => {
|
||||
const cluster = createCluster({
|
||||
id: "other-cluster",
|
||||
contextName: "other-context",
|
||||
@ -166,10 +166,9 @@ describe("<DeleteClusterDialog />", () => {
|
||||
});
|
||||
|
||||
openDeleteClusterDialog({ cluster, config });
|
||||
render(<DeleteClusterDialog />);
|
||||
|
||||
const { getByTestId } = render(<DeleteClusterDialog />);
|
||||
|
||||
expect(getByTestId("current-context-warning")).toBeInstanceOf(HTMLElement);
|
||||
expect(await screen.findByTestId("current-context-warning")).toBeInstanceOf(HTMLElement);
|
||||
});
|
||||
|
||||
it("shows context switcher when deleting current cluster", async () => {
|
||||
@ -183,14 +182,15 @@ describe("<DeleteClusterDialog />", () => {
|
||||
});
|
||||
|
||||
openDeleteClusterDialog({ cluster, config });
|
||||
render(<DeleteClusterDialog />);
|
||||
|
||||
const { getByText } = render(<DeleteClusterDialog />);
|
||||
const menu = await screen.findByText("Select new context...");
|
||||
|
||||
expect(getByText("Select...")).toBeInTheDocument();
|
||||
selectEvent.openMenu(getByText("Select..."));
|
||||
expect(menu).toBeInTheDocument();
|
||||
selectEvent.openMenu(menu);
|
||||
|
||||
expect(getByText("test")).toBeInTheDocument();
|
||||
expect(getByText("test2")).toBeInTheDocument();
|
||||
expect(await screen.findByText("test")).toBeInTheDocument();
|
||||
expect(await screen.findByText("test2")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows context switcher after checkbox click", async () => {
|
||||
@ -204,21 +204,23 @@ describe("<DeleteClusterDialog />", () => {
|
||||
});
|
||||
|
||||
openDeleteClusterDialog({ cluster, config });
|
||||
render(<DeleteClusterDialog />);
|
||||
|
||||
const { getByText, getByTestId } = render(<DeleteClusterDialog />);
|
||||
const link = getByTestId("context-switch");
|
||||
const link = await screen.findByTestId("context-switch");
|
||||
|
||||
expect(link).toBeInstanceOf(HTMLElement);
|
||||
fireEvent.click(link);
|
||||
|
||||
expect(getByText("Select...")).toBeInTheDocument();
|
||||
selectEvent.openMenu(getByText("Select..."));
|
||||
const menu = await screen.findByText("Select new context...");
|
||||
|
||||
expect(getByText("test")).toBeInTheDocument();
|
||||
expect(getByText("test2")).toBeInTheDocument();
|
||||
expect(menu).toBeInTheDocument();
|
||||
selectEvent.openMenu(menu);
|
||||
|
||||
expect(await screen.findByText("test")).toBeInTheDocument();
|
||||
expect(await screen.findByText("test2")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows warning for internal kubeconfig cluster", () => {
|
||||
it("shows warning for internal kubeconfig cluster", async () => {
|
||||
const cluster = createCluster({
|
||||
id: "some-cluster",
|
||||
contextName: "test",
|
||||
@ -231,10 +233,9 @@ describe("<DeleteClusterDialog />", () => {
|
||||
const spy = jest.spyOn(cluster, "isInLocalKubeconfig").mockImplementation(() => true);
|
||||
|
||||
openDeleteClusterDialog({ cluster, config });
|
||||
render(<DeleteClusterDialog />);
|
||||
|
||||
const { getByTestId } = render(<DeleteClusterDialog />);
|
||||
|
||||
expect(getByTestId("internal-kubeconfig-warning")).toBeInstanceOf(HTMLElement);
|
||||
expect(await screen.findByTestId("internal-kubeconfig-warning")).toBeInstanceOf(HTMLElement);
|
||||
|
||||
spy.mockRestore();
|
||||
});
|
||||
@ -256,7 +257,7 @@ describe("<DeleteClusterDialog />", () => {
|
||||
mockFs.restore();
|
||||
});
|
||||
|
||||
it("shows warning if no other contexts left", () => {
|
||||
it("shows warning if no other contexts left", async () => {
|
||||
const cluster = createCluster({
|
||||
id: "other-cluster",
|
||||
contextName: "other-context",
|
||||
@ -267,10 +268,9 @@ describe("<DeleteClusterDialog />", () => {
|
||||
});
|
||||
|
||||
openDeleteClusterDialog({ cluster, config });
|
||||
render(<DeleteClusterDialog />);
|
||||
|
||||
const { getByTestId } = render(<DeleteClusterDialog />);
|
||||
|
||||
expect(getByTestId("no-more-contexts-warning")).toBeInstanceOf(HTMLElement);
|
||||
expect(await screen.findByTestId("no-more-contexts-warning")).toBeInstanceOf(HTMLElement);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
import styles from "./view.module.scss";
|
||||
|
||||
import type { IObservableValue } from "mobx";
|
||||
import { action, observable } from "mobx";
|
||||
import { action, observable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import React from "react";
|
||||
|
||||
@ -31,7 +31,7 @@ export interface Dependencies {
|
||||
@observer
|
||||
class NonInjectedDeleteClusterDialog extends React.Component<Dependencies> {
|
||||
private readonly showContextSwitch = observable.box(false);
|
||||
private readonly newCurrentContext = observable.box("");
|
||||
private readonly newCurrentContext = observable.box<string | undefined>();
|
||||
|
||||
@action
|
||||
onOpen(state: DeleteClusterDialogState) {
|
||||
@ -99,24 +99,27 @@ class NonInjectedDeleteClusterDialog extends React.Component<Dependencies> {
|
||||
return null;
|
||||
}
|
||||
|
||||
const contextName = this.newCurrentContext.get();
|
||||
const selectOptions = config
|
||||
.contexts
|
||||
.filter(context => context.name !== cluster.contextName);
|
||||
const selectedOption = selectOptions.find(ctx => ctx.name === contextName);
|
||||
|
||||
return (
|
||||
<div className="mt-4">
|
||||
<Select
|
||||
id="delete-cluster-input"
|
||||
options={(
|
||||
config
|
||||
.contexts
|
||||
.filter(context => context.name !== cluster.contextName)
|
||||
.map(ctx => ctx.name)
|
||||
)}
|
||||
value={this.newCurrentContext.get()}
|
||||
onChange={contextName => {
|
||||
if (contextName) {
|
||||
this.newCurrentContext.set(contextName);
|
||||
options={selectOptions}
|
||||
getOptionLabel={opt => opt.name}
|
||||
value={selectedOption}
|
||||
onChange={opt => {
|
||||
if (opt) {
|
||||
this.newCurrentContext.set(opt.name);
|
||||
}
|
||||
}}
|
||||
themeName="light"
|
||||
className="ml-[1px] mr-[1px]"
|
||||
placeholder="Select new context..."
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -25,14 +25,28 @@ export interface SelectOption<T> {
|
||||
label?: React.ReactElement | string;
|
||||
}
|
||||
|
||||
export interface SelectProps<Option, IsMulti extends boolean, Group extends GroupBase<Option> = GroupBase<Option>> extends ReactSelectProps<Option, IsMulti, Group> {
|
||||
export interface SelectProps<
|
||||
/**
|
||||
* This needs to extend `object` because even though `ReactSelectProps` allows for any `T`, the
|
||||
* maintainers of `react-select` says that they don't support it.
|
||||
*
|
||||
* Ref: https://github.com/JedWatson/react-select/issues/5032
|
||||
*/
|
||||
Option extends object,
|
||||
IsMulti extends boolean,
|
||||
Group extends GroupBase<Option> = GroupBase<Option>,
|
||||
> extends ReactSelectProps<Option, IsMulti, Group> {
|
||||
id?: string; // Optional only because of Extension API. Required to make Select deterministic in unit tests
|
||||
themeName?: "dark" | "light" | "outlined" | "lens";
|
||||
menuClass?: string;
|
||||
}
|
||||
|
||||
@observer
|
||||
export class Select<Option, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>> extends React.Component<SelectProps<Option, IsMulti, Group>> {
|
||||
export class Select<
|
||||
Option extends object,
|
||||
IsMulti extends boolean = false,
|
||||
Group extends GroupBase<Option> = GroupBase<Option>,
|
||||
> extends React.Component<SelectProps<Option, IsMulti, Group>> {
|
||||
static defaultProps = {
|
||||
menuPortalTarget: document.body,
|
||||
menuPlacement: "auto",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user