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

Fix delete-cluster-dialog tests

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2023-01-04 16:24:07 -05:00
parent 84a9569412
commit f52e79fdaa
5 changed files with 68 additions and 73 deletions

View File

@ -18,6 +18,7 @@ import type { Cluster } from "../../../common/cluster/cluster";
import navigateToCatalogInjectable from "../../../common/front-end-routing/routes/catalog/navigate-to-catalog.injectable"; import navigateToCatalogInjectable from "../../../common/front-end-routing/routes/catalog/navigate-to-catalog.injectable";
import directoryForKubeConfigsInjectable from "../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable"; import directoryForKubeConfigsInjectable from "../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
import joinPathsInjectable from "../../../common/path/join-paths.injectable"; import joinPathsInjectable from "../../../common/path/join-paths.injectable";
import { advanceFakeTime } from "../../../common/test-utils/use-fake-time";
const currentClusterServerUrl = "https://localhost"; const currentClusterServerUrl = "https://localhost";
const nonCurrentClusterServerUrl = "http://localhost"; const nonCurrentClusterServerUrl = "http://localhost";
@ -135,11 +136,8 @@ describe("Deleting a cluster", () => {
describe("when the dialog is opened for the current cluster", () => { describe("when the dialog is opened for the current cluster", () => {
// TODO: replace with actual behaviour instead of technical use // TODO: replace with actual behaviour instead of technical use
beforeEach(async () => { beforeEach(async () => {
openDeleteClusterDialog({ openDeleteClusterDialog(config, currentCluster);
cluster: currentCluster, advanceFakeTime(1000);
config,
});
await rendered.findByTestId("delete-cluster-dialog"); await rendered.findByTestId("delete-cluster-dialog");
}); });
@ -159,11 +157,8 @@ describe("Deleting a cluster", () => {
describe("when the dialog is opened for not the current cluster", () => { describe("when the dialog is opened for not the current cluster", () => {
// TODO: replace with actual behaviour instead of technical use // TODO: replace with actual behaviour instead of technical use
beforeEach(async () => { beforeEach(async () => {
openDeleteClusterDialog({ openDeleteClusterDialog(config, nonCurrentCluster);
cluster: nonCurrentCluster, advanceFakeTime(1000);
config,
});
await rendered.findByTestId("delete-cluster-dialog"); await rendered.findByTestId("delete-cluster-dialog");
}); });
@ -219,11 +214,8 @@ describe("Deleting a cluster", () => {
describe("when the dialog is opened", () => { describe("when the dialog is opened", () => {
// TODO: replace with actual behaviour instead of technical use // TODO: replace with actual behaviour instead of technical use
beforeEach(async () => { beforeEach(async () => {
openDeleteClusterDialog({ openDeleteClusterDialog(config, currentCluster);
cluster: currentCluster, advanceFakeTime(1000);
config,
});
await rendered.findByTestId("delete-cluster-dialog"); await rendered.findByTestId("delete-cluster-dialog");
}); });
@ -258,11 +250,8 @@ describe("Deleting a cluster", () => {
describe("when the dialog is opened", () => { describe("when the dialog is opened", () => {
// TODO: replace with actual behaviour instead of technical use // TODO: replace with actual behaviour instead of technical use
beforeEach(async () => { beforeEach(async () => {
openDeleteClusterDialog({ openDeleteClusterDialog(config, currentCluster);
cluster: currentCluster, advanceFakeTime(1000);
config,
});
await rendered.findByTestId("delete-cluster-dialog"); await rendered.findByTestId("delete-cluster-dialog");
}); });

View File

@ -0,0 +1,10 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { KubeConfig } from "@kubernetes/client-node";
import type { Cluster } from "../../../common/cluster/cluster";
export function isCurrentContext(config: KubeConfig, cluster: Cluster) {
return config.currentContext == cluster.contextName;
}

View File

@ -2,18 +2,25 @@
* Copyright (c) OpenLens Authors. All rights reserved. * Copyright (c) OpenLens Authors. All rights reserved.
* 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 type { KubeConfig } from "@kubernetes/client-node";
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import type { DeleteClusterDialogState } from "./state.injectable"; import type { Cluster } from "../../../common/cluster/cluster";
import { isCurrentContext } from "./is-current-context";
import deleteClusterDialogStateInjectable from "./state.injectable"; import deleteClusterDialogStateInjectable from "./state.injectable";
export type OpenDeleteClusterDialog = (props: DeleteClusterDialogState) => void; export type OpenDeleteClusterDialog = (config: KubeConfig, cluster: Cluster) => void;
const openDeleteClusterDialogInjectable = getInjectable({ const openDeleteClusterDialogInjectable = getInjectable({
id: "open-delete-cluster-dialog", id: "open-delete-cluster-dialog",
instantiate: (di): OpenDeleteClusterDialog => { instantiate: (di): OpenDeleteClusterDialog => {
const state = di.inject(deleteClusterDialogStateInjectable); const state = di.inject(deleteClusterDialogStateInjectable);
return (props) => state.set(props); return (config, cluster) => state.set({
cluster,
config,
newCurrentContext: "",
showContextSwitch: isCurrentContext(config, cluster),
});
}, },
}); });

View File

@ -10,6 +10,8 @@ import type { Cluster } from "../../../common/cluster/cluster";
export interface DeleteClusterDialogState { export interface DeleteClusterDialogState {
config: KubeConfig; config: KubeConfig;
cluster: Cluster; cluster: Cluster;
showContextSwitch: boolean;
newCurrentContext: string;
} }
const deleteClusterDialogStateInjectable = getInjectable({ const deleteClusterDialogStateInjectable = getInjectable({

View File

@ -5,7 +5,7 @@
import styles from "./view.module.scss"; import styles from "./view.module.scss";
import type { IObservableValue } from "mobx"; import type { IObservableValue } from "mobx";
import { action, observable } from "mobx"; import { runInAction } from "mobx";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import React from "react"; import React from "react";
@ -29,6 +29,7 @@ import requestDeleteClusterInjectable from "../../../features/cluster/delete-dia
import type { SaveKubeconfig } from "./save-kubeconfig.injectable"; import type { SaveKubeconfig } from "./save-kubeconfig.injectable";
import saveKubeconfigInjectable from "./save-kubeconfig.injectable"; import saveKubeconfigInjectable from "./save-kubeconfig.injectable";
import showErrorNotificationInjectable from "../notifications/show-error-notification.injectable"; import showErrorNotificationInjectable from "../notifications/show-error-notification.injectable";
import { isCurrentContext } from "./is-current-context";
interface Dependencies { interface Dependencies {
state: IObservableValue<DeleteClusterDialogState | undefined>; state: IObservableValue<DeleteClusterDialogState | undefined>;
@ -42,40 +43,22 @@ interface Dependencies {
@observer @observer
class NonInjectedDeleteClusterDialog extends React.Component<Dependencies> { class NonInjectedDeleteClusterDialog extends React.Component<Dependencies> {
private readonly showContextSwitch = observable.box(false);
private readonly newCurrentContext = observable.box<string | undefined>();
@action
onOpen(state: DeleteClusterDialogState) {
this.newCurrentContext.set("");
this.showContextSwitch.set(this.isCurrentContext(state));
}
onClose = () => {
this.showContextSwitch.set(false);
};
removeContext(state: DeleteClusterDialogState) {
state.config.contexts = state.config.contexts.filter(item =>
item.name !== state.cluster.contextName,
);
}
changeCurrentContext(state: DeleteClusterDialogState) {
const newCurrentContext = this.newCurrentContext.get();
const showContextSwitch = this.showContextSwitch.get();
if (newCurrentContext && showContextSwitch) {
state.config.currentContext = newCurrentContext;
}
}
async onDelete(state: DeleteClusterDialogState) { async onDelete(state: DeleteClusterDialogState) {
const { cluster, config } = state; const { cluster, config, newCurrentContext, showContextSwitch } = state;
await this.props.requestSetClusterAsDeleting(cluster.id); await this.props.requestSetClusterAsDeleting(cluster.id);
this.removeContext(state);
this.changeCurrentContext(state); runInAction(() => {
this.props.state.set({
...state,
config: Object.assign(config, {
contexts: config.contexts.filter(item => item.name !== state.cluster.contextName),
currentContext: newCurrentContext && showContextSwitch
? newCurrentContext
: config.currentContext,
}),
});
});
try { try {
await this.props.saveKubeconfig(config, cluster.kubeConfigPath); await this.props.saveKubeconfig(config, cluster.kubeConfigPath);
@ -85,15 +68,13 @@ class NonInjectedDeleteClusterDialog extends React.Component<Dependencies> {
this.props.showErrorNotification(`Cannot remove cluster, failed to process config file. ${error}`); this.props.showErrorNotification(`Cannot remove cluster, failed to process config file. ${error}`);
} finally { } finally {
await this.props.requestClearClusterAsDeleting(cluster.id); await this.props.requestClearClusterAsDeleting(cluster.id);
this.close();
} }
this.onClose();
} }
shouldDeleteBeDisabled({ cluster, config }: DeleteClusterDialogState): boolean { shouldDeleteBeDisabled({ cluster, config, newCurrentContext, showContextSwitch }: DeleteClusterDialogState): boolean {
const noContextsAvailable = config.contexts.filter(context => context.name !== cluster.contextName).length == 0; const noContextsAvailable = config.contexts.filter(context => context.name !== cluster.contextName).length == 0;
const newContextNotSelected = this.newCurrentContext.get() === ""; const newContextNotSelected = newCurrentContext === "";
const showContextSwitch = this.showContextSwitch.get();
if (noContextsAvailable) { if (noContextsAvailable) {
return false; return false;
@ -102,12 +83,10 @@ class NonInjectedDeleteClusterDialog extends React.Component<Dependencies> {
return showContextSwitch && newContextNotSelected; return showContextSwitch && newContextNotSelected;
} }
isCurrentContext({ cluster, config }: DeleteClusterDialogState) { renderCurrentContextSwitch(state: DeleteClusterDialogState) {
return config.currentContext == cluster.contextName; const { cluster, config, showContextSwitch, newCurrentContext } = state;
}
renderCurrentContextSwitch({ cluster, config }: DeleteClusterDialogState) { if (!showContextSwitch) {
if (!this.showContextSwitch.get()) {
return null; return null;
} }
@ -124,10 +103,13 @@ class NonInjectedDeleteClusterDialog extends React.Component<Dependencies> {
<Select <Select
id="delete-cluster-input" id="delete-cluster-input"
options={selectOptions} options={selectOptions}
value={this.newCurrentContext.get()} value={newCurrentContext}
onChange={opt => { onChange={opt => {
if (opt) { if (opt) {
this.newCurrentContext.set(opt.value); this.props.state.set({
...state,
newCurrentContext: opt.value,
});
} }
}} }}
themeName="light" themeName="light"
@ -185,7 +167,7 @@ class NonInjectedDeleteClusterDialog extends React.Component<Dependencies> {
); );
} }
if (this.isCurrentContext({ cluster, config })) { if (isCurrentContext(config, cluster)) {
return ( return (
<p data-testid="current-context-warning"> <p data-testid="current-context-warning">
This will remove active context in kubeconfig. Use drop down below to&nbsp;select a&nbsp;different one. This will remove active context in kubeconfig. Use drop down below to&nbsp;select a&nbsp;different one.
@ -208,8 +190,10 @@ class NonInjectedDeleteClusterDialog extends React.Component<Dependencies> {
} }
renderContents(state: DeleteClusterDialogState) { renderContents(state: DeleteClusterDialogState) {
const { config, cluster, showContextSwitch } = state;
const contexts = state.config.contexts.filter(context => context.name !== state.cluster.contextName); const contexts = state.config.contexts.filter(context => context.name !== state.cluster.contextName);
const disableDelete = this.shouldDeleteBeDisabled(state); const disableDelete = this.shouldDeleteBeDisabled(state);
const currentContext = isCurrentContext(config, cluster);
return ( return (
<> <>
@ -226,11 +210,16 @@ class NonInjectedDeleteClusterDialog extends React.Component<Dependencies> {
<> <>
<span className="font-semibold">Select current-context</span> <span className="font-semibold">Select current-context</span>
{" "} {" "}
{!this.isCurrentContext(state) && "(optional)"} {!currentContext && "(optional)"}
</> </>
)} )}
value={this.showContextSwitch.get()} value={showContextSwitch}
onChange={value => this.showContextSwitch.set(this.isCurrentContext(state) || value)} onChange={value => {
this.props.state.set({
...state,
showContextSwitch: currentContext || value,
});
}}
/> />
</div> </div>
{this.renderCurrentContextSwitch(state)} {this.renderCurrentContextSwitch(state)}
@ -265,8 +254,6 @@ class NonInjectedDeleteClusterDialog extends React.Component<Dependencies> {
className={styles.dialog} className={styles.dialog}
isOpen={Boolean(state)} isOpen={Boolean(state)}
close={this.close} close={this.close}
onClose={this.onClose}
onOpen={state && (() => this.onOpen(state))}
data-testid={state ? "delete-cluster-dialog" : undefined} data-testid={state ? "delete-cluster-dialog" : undefined}
> >
{state && this.renderContents(state)} {state && this.renderContents(state)}