mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Technical requirements for behavioural unit tests (#5084)
* Implement a lot of technical requirements for behavioural unit tests Note: the crux of this was to make routing env-agnostic, and not based on URLs as magic strings, but instead something type-enforced. Note: extension-based routes comply to same exact interface by "late-registering" their routes when installed. Routes are just injectables. Note: another chunk of global shared state is no more. Note: a lot of explicit side effects have been cornered to injectables. Note: a lot of stuff has become reactive as part if this. Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Make a directory commonly available Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Require id for <Select /> to prevent non-deterministic renders This was caused by global state in a 3rd party lib: "react-select". Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Specify id for all <Select /> to satisfy previous commit Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Prevent explicit side effect in component by using existing dependency instead Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Extract instantiation of "conf" as injectables for causing side effects Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Introduce a legacy-helper to make gradual refactoring of inheritors of Singleton easier Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Make legacy unit tests for hotbar green and more simple by using the new legacy helper Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Temporarily kludge all unit tests green with a disclaimer about allowing side-effects Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Remove kludge in previous commit by explicitly permitting specific side effects where old unit tests require it Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Prevent old unit test with side effects from accessing file system Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Migrate to actual typing for di.permitSideEffects Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Prevent unit tests from failing because of non-standard method of HTML-element not present in js-dom Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Adapt integration tests to recent changes Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Fix code style Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Fix artifact from bad rebase Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Add a deprecation from a review comment Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Remove change that is not required Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove redundant comment Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Fix code style Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove redundant file Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Fix bad merge Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Improve variable name Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Tweak logger interface to be more descriptive Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Make injecting legacy singleton always provide new instance Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove conditional typing when not needed Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Improve naming of variable Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove unnecessary code style changes Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove flag for causing side effects from too broad scope Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Override side-effects in unit test using injectable instead of monkey patching Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Flag some side-effects and add general overrides Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Fix unit tests in CI by removing explicit side-effect Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Remove explicit side-effect from getting default shell Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce abstraction for getting absolute paths Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Switch to using abstraction for getting absolute path to control explicit side effect Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce abstraction for joining paths Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Switch to using abstraction for joining paths to control explicit side effect Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Fix fake implementation for join paths Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Fix test after removing explicit side effect Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove explicit side effects from kubeconfig-syncs Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Fix arguments after removing explicit side effect Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Make registrators not async for not being needed anymore Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Make generalCatalogEntities non-observable, as there is no requirement Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Remove redundant code Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Simplify logic for registering general catalog entity sources Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Add TODO Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Replace function for getting application menu items with reactive solution Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Fix typo in interface name Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove global shared state usages of hot bar store Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove redundant enum Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
1 parent
ab2cd27a27
commit
a277cfcf02
583 files changed
+13073
-6556
No files matched your search
@@ -9,52 +9,35 @@ import { observer } from "mobx-react";
|
||||
import React from "react";
|
||||
|
||||
import { Button } from "../button";
|
||||
import type { KubeConfig } from "@kubernetes/client-node";
|
||||
import type { Cluster } from "../../../common/cluster/cluster";
|
||||
import { saveKubeconfig } from "./save-config";
|
||||
import { Notifications } from "../notifications";
|
||||
import { HotbarStore } from "../../../common/hotbar-store";
|
||||
import { boundMethod } from "autobind-decorator";
|
||||
import { Dialog } from "../dialog";
|
||||
import { Icon } from "../icon";
|
||||
import { Select } from "../select";
|
||||
import { Checkbox } from "../checkbox";
|
||||
import { requestClearClusterAsDeleting, requestDeleteCluster, requestSetClusterAsDeleting } from "../../ipc";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import hotbarStoreInjectable from "../../../common/hotbar-store.injectable";
|
||||
import type { DeleteClusterDialogModel } from "./delete-cluster-dialog-model/delete-cluster-dialog-model";
|
||||
import deleteClusterDialogModelInjectable from "./delete-cluster-dialog-model/delete-cluster-dialog-model.injectable";
|
||||
import type { HotbarStore } from "../../../common/hotbar-store";
|
||||
|
||||
interface DialogState {
|
||||
isOpen: boolean;
|
||||
config?: KubeConfig;
|
||||
cluster?: Cluster;
|
||||
interface Dependencies {
|
||||
hotbarStore: HotbarStore;
|
||||
model: DeleteClusterDialogModel;
|
||||
}
|
||||
|
||||
const dialogState: DialogState = observable({
|
||||
isOpen: false,
|
||||
});
|
||||
|
||||
export interface DeleteClusterDialogProps {}
|
||||
|
||||
@observer
|
||||
export class DeleteClusterDialog extends React.Component<DeleteClusterDialogProps> {
|
||||
class NonInjectedDeleteClusterDialog extends React.Component<Dependencies> {
|
||||
@observable showContextSwitch = false;
|
||||
@observable newCurrentContext = "";
|
||||
|
||||
constructor(props: DeleteClusterDialogProps) {
|
||||
constructor(props: Dependencies) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
static open({ config, cluster }: Partial<DialogState>) {
|
||||
dialogState.isOpen = true;
|
||||
dialogState.config = config;
|
||||
dialogState.cluster = cluster;
|
||||
}
|
||||
|
||||
static close() {
|
||||
dialogState.isOpen = false;
|
||||
dialogState.cluster = null;
|
||||
dialogState.config = null;
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
onOpen() {
|
||||
this.newCurrentContext = "";
|
||||
@@ -66,25 +49,25 @@ export class DeleteClusterDialog extends React.Component<DeleteClusterDialogProp
|
||||
|
||||
@boundMethod
|
||||
onClose() {
|
||||
DeleteClusterDialog.close();
|
||||
this.props.model.close();
|
||||
this.showContextSwitch = false;
|
||||
}
|
||||
|
||||
removeContext() {
|
||||
dialogState.config.contexts = dialogState.config.contexts.filter(item =>
|
||||
item.name !== dialogState.cluster.contextName,
|
||||
this.props.model.config.contexts = this.props.model.config.contexts.filter(item =>
|
||||
item.name !== this.props.model.cluster.contextName,
|
||||
);
|
||||
}
|
||||
|
||||
changeCurrentContext() {
|
||||
if (this.newCurrentContext && this.showContextSwitch) {
|
||||
dialogState.config.currentContext = this.newCurrentContext;
|
||||
this.props.model.config.currentContext = this.newCurrentContext;
|
||||
}
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
async onDelete() {
|
||||
const { cluster, config } = dialogState;
|
||||
const { cluster, config } = this.props.model;
|
||||
|
||||
await requestSetClusterAsDeleting(cluster.id);
|
||||
this.removeContext();
|
||||
@@ -92,7 +75,7 @@ export class DeleteClusterDialog extends React.Component<DeleteClusterDialogProp
|
||||
|
||||
try {
|
||||
await saveKubeconfig(config, cluster.kubeConfigPath);
|
||||
HotbarStore.getInstance().removeAllHotbarItems(cluster.id);
|
||||
this.props.hotbarStore.removeAllHotbarItems(cluster.id);
|
||||
await requestDeleteCluster(cluster.id);
|
||||
} catch(error) {
|
||||
Notifications.error(`Cannot remove cluster, failed to process config file. ${error}`);
|
||||
@@ -104,7 +87,7 @@ export class DeleteClusterDialog extends React.Component<DeleteClusterDialogProp
|
||||
}
|
||||
|
||||
@computed get disableDelete() {
|
||||
const { cluster, config } = dialogState;
|
||||
const { cluster, config } = this.props.model;
|
||||
const noContextsAvailable = config.contexts.filter(context => context.name !== cluster.contextName).length == 0;
|
||||
const newContextNotSelected = this.newCurrentContext === "";
|
||||
|
||||
@@ -116,12 +99,12 @@ export class DeleteClusterDialog extends React.Component<DeleteClusterDialogProp
|
||||
}
|
||||
|
||||
isCurrentContext() {
|
||||
return dialogState.config.currentContext == dialogState.cluster.contextName;
|
||||
return this.props.model.config.currentContext == this.props.model.cluster.contextName;
|
||||
}
|
||||
|
||||
renderCurrentContextSwitch() {
|
||||
if (!this.showContextSwitch) return null;
|
||||
const { cluster, config } = dialogState;
|
||||
const { cluster, config } = this.props.model;
|
||||
const contexts = config.contexts.filter(context => context.name !== cluster.contextName);
|
||||
|
||||
const options = [
|
||||
@@ -134,6 +117,7 @@ export class DeleteClusterDialog extends React.Component<DeleteClusterDialogProp
|
||||
return (
|
||||
<div className="mt-4">
|
||||
<Select
|
||||
id="delete-cluster-input"
|
||||
options={options}
|
||||
value={this.newCurrentContext}
|
||||
onChange={({ value }) => this.newCurrentContext = value}
|
||||
@@ -145,7 +129,7 @@ export class DeleteClusterDialog extends React.Component<DeleteClusterDialogProp
|
||||
}
|
||||
|
||||
renderDeleteMessage() {
|
||||
const { cluster } = dialogState;
|
||||
const { cluster } = this.props.model;
|
||||
|
||||
if (cluster.isInLocalKubeconfig()) {
|
||||
return (
|
||||
@@ -163,7 +147,7 @@ export class DeleteClusterDialog extends React.Component<DeleteClusterDialogProp
|
||||
}
|
||||
|
||||
getWarningMessage() {
|
||||
const { cluster, config } = dialogState;
|
||||
const { cluster, config } = this.props.model;
|
||||
const contexts = config.contexts.filter(context => context.name !== cluster.contextName);
|
||||
|
||||
if (!contexts.length) {
|
||||
@@ -205,7 +189,7 @@ export class DeleteClusterDialog extends React.Component<DeleteClusterDialogProp
|
||||
}
|
||||
|
||||
render() {
|
||||
const { cluster, config, isOpen } = dialogState;
|
||||
const { cluster, config, isOpen } = this.props.model;
|
||||
|
||||
if (!cluster || !config) return null;
|
||||
|
||||
@@ -257,3 +241,14 @@ export class DeleteClusterDialog extends React.Component<DeleteClusterDialogProp
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const DeleteClusterDialog = withInjectables<Dependencies>(
|
||||
NonInjectedDeleteClusterDialog,
|
||||
|
||||
{
|
||||
getProps: (di) => ({
|
||||
hotbarStore: di.inject(hotbarStoreInjectable),
|
||||
model: di.inject(deleteClusterDialogModelInjectable),
|
||||
}),
|
||||
},
|
||||
);
|
||||
Reference in new issue
Block a user