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

fix replicasets/scale-dialog/dialog.test.tsx

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2022-04-11 15:14:43 -04:00
parent 1683f482f1
commit 5afa96971e
10 changed files with 140 additions and 71 deletions

View File

@ -6,22 +6,39 @@ import React from "react";
import type { KubeObjectMenuProps } from "../kube-object-menu";
import type { ReplicaSet } from "../../../common/k8s-api/endpoints";
import { MenuItem } from "../menu";
import { ReplicaSetScaleDialog } from "./replicaset-scale-dialog";
import { Icon } from "../icon";
import { withInjectables } from "@ogre-tools/injectable-react";
import type { OpenReplicaSetScaleDialog } from "./scale-dialog/open.injectable";
import openReplicaSetScaleDialogInjectable from "./scale-dialog/open.injectable";
export function ReplicaSetMenu(props: KubeObjectMenuProps<ReplicaSet>) {
const { object, toolbar } = props;
export interface ReplicaSetMenuProps extends KubeObjectMenuProps<ReplicaSet> {
return (
<>
<MenuItem onClick={() => ReplicaSetScaleDialog.open(object)}>
<Icon
material="open_with"
tooltip="Scale"
interactive={toolbar}
/>
<span className="title">Scale</span>
</MenuItem>
</>
);
}
interface Dependencies {
openReplicaSetScaleDialog: OpenReplicaSetScaleDialog;
}
const NonInjectedReplicaSetMenu = ({
object,
toolbar,
openReplicaSetScaleDialog,
}: Dependencies & ReplicaSetMenuProps) => (
<>
<MenuItem onClick={() => openReplicaSetScaleDialog(object)}>
<Icon
material="open_with"
tooltip="Scale"
interactive={toolbar}
/>
<span className="title">Scale</span>
</MenuItem>
</>
);
export const ReplicaSetMenu = withInjectables<Dependencies, ReplicaSetMenuProps>(NonInjectedReplicaSetMenu, {
getProps: (di, props) => ({
...props,
openReplicaSetScaleDialog: di.inject(openReplicaSetScaleDialogInjectable),
}),
});

View File

@ -5,10 +5,17 @@
import "@testing-library/jest-dom/extend-expect";
import { ReplicaSetScaleDialog } from "./replicaset-scale-dialog";
import { render, waitFor, fireEvent } from "@testing-library/react";
import { ReplicaSetScaleDialog } from "./dialog";
import { waitFor, fireEvent } from "@testing-library/react";
import React from "react";
import { ReplicaSet, ReplicaSetApi } from "../../../common/k8s-api/endpoints/replica-set.api";
import type { ReplicaSetApi } from "../../../../common/k8s-api/endpoints/replica-set.api";
import { ReplicaSet } from "../../../../common/k8s-api/endpoints/replica-set.api";
import type { OpenReplicaSetScaleDialog } from "./open.injectable";
import replicaSetApiInjectable from "../../../../common/k8s-api/endpoints/replica-set.api.injectable";
import createStoresAndApisInjectable from "../../../create-stores-apis.injectable";
import { getDiForUnitTesting } from "../../../getDiForUnitTesting";
import { type DiRender, renderFor } from "../../test-utils/renderFor";
import openReplicaSetScaleDialogInjectable from "./open.injectable";
const dummyReplicaSet = new ReplicaSet({
apiVersion: "v1",
@ -70,15 +77,21 @@ const dummyReplicaSet = new ReplicaSet({
describe("<ReplicaSetScaleDialog />", () => {
let replicaSetApi: ReplicaSetApi;
let openReplicaSetScaleDialog: OpenReplicaSetScaleDialog;
let render: DiRender;
beforeEach(() => {
replicaSetApi = new ReplicaSetApi({
objectConstructor: ReplicaSet,
});
const di = getDiForUnitTesting({ doGeneralOverrides: true });
di.override(createStoresAndApisInjectable, () => true);
render = renderFor(di);
replicaSetApi = di.inject(replicaSetApiInjectable);
openReplicaSetScaleDialog = di.inject(openReplicaSetScaleDialogInjectable);
});
it("renders w/o errors", () => {
const { container } = render(<ReplicaSetScaleDialog replicaSetApi={replicaSetApi} />);
const { container } = render(<ReplicaSetScaleDialog />);
expect(container).toBeInstanceOf(HTMLElement);
});
@ -89,9 +102,9 @@ describe("<ReplicaSetScaleDialog />", () => {
const initReplicas = 1;
replicaSetApi.getReplicas = jest.fn().mockImplementationOnce(async () => initReplicas);
const { getByTestId } = render(<ReplicaSetScaleDialog replicaSetApi={replicaSetApi} />);
const { getByTestId } = render(<ReplicaSetScaleDialog />);
ReplicaSetScaleDialog.open(dummyReplicaSet);
openReplicaSetScaleDialog(dummyReplicaSet);
// we need to wait for the replicaSetScaleDialog to show up
// because there is an <Animate /> in <Dialog /> which renders null at start.
await waitFor(async () => {
@ -109,9 +122,9 @@ describe("<ReplicaSetScaleDialog />", () => {
const initReplicas = 1;
replicaSetApi.getReplicas = jest.fn().mockImplementationOnce(async () => initReplicas);
const component = render(<ReplicaSetScaleDialog replicaSetApi={replicaSetApi} />);
const component = render(<ReplicaSetScaleDialog />);
ReplicaSetScaleDialog.open(dummyReplicaSet);
openReplicaSetScaleDialog(dummyReplicaSet);
await waitFor(async () => {
expect(await component.findByTestId("desired-scale")).toHaveTextContent(`${initReplicas}`);
expect(await component.findByTestId("current-scale")).toHaveTextContent(`${initReplicas}`);

View File

@ -3,52 +3,45 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import "./replicaset-scale-dialog.scss";
import "./dialog.scss";
import React, { Component } from "react";
import type { IObservableValue } from "mobx";
import { computed, observable, makeObservable } from "mobx";
import { observer } from "mobx-react";
import type { DialogProps } from "../dialog";
import { Dialog } from "../dialog";
import { Wizard, WizardStep } from "../wizard";
import { Icon } from "../icon";
import { Slider } from "../slider";
import { Notifications } from "../notifications";
import { cssNames } from "../../utils";
import type { ReplicaSet, ReplicaSetApi } from "../../../common/k8s-api/endpoints/replica-set.api";
import { replicaSetApi } from "../../../common/k8s-api/endpoints/replica-set.api";
import type { DialogProps } from "../../dialog";
import { Dialog } from "../../dialog";
import { Wizard, WizardStep } from "../../wizard";
import { Icon } from "../../icon";
import { Slider } from "../../slider";
import { Notifications } from "../../notifications";
import { cssNames } from "../../../utils";
import type { ReplicaSet, ReplicaSetApi } from "../../../../common/k8s-api/endpoints";
import { withInjectables } from "@ogre-tools/injectable-react";
import replicaSetApiInjectable from "../../../../common/k8s-api/endpoints/replica-set.api.injectable";
import replicaSetScaleDialogStateInjectable from "./state.injectable";
export interface ReplicaSetScaleDialogProps extends Partial<DialogProps> {
replicaSetApi: ReplicaSetApi;
}
const dialogState = observable.box<ReplicaSet | undefined>();
interface Dependencies {
replicaSetApi: ReplicaSetApi;
state: IObservableValue<ReplicaSet | undefined>;
}
@observer
export class ReplicaSetScaleDialog extends Component<ReplicaSetScaleDialogProps> {
static defaultProps = {
replicaSetApi,
};
class NonInjectedReplicaSetScaleDialog extends Component<ReplicaSetScaleDialogProps & Dependencies> {
@observable ready = false;
@observable currentReplicas = 0;
@observable desiredReplicas = 0;
constructor(props: ReplicaSetScaleDialogProps) {
constructor(props: ReplicaSetScaleDialogProps & Dependencies) {
super(props);
makeObservable(this);
}
static open(replicaSet: ReplicaSet) {
dialogState.set(replicaSet);
}
static close() {
dialogState.set(undefined);
}
close = () => {
ReplicaSetScaleDialog.close();
this.props.state.set(undefined);
};
onOpen = async (replicaSet: ReplicaSet) => {
@ -162,8 +155,8 @@ export class ReplicaSetScaleDialog extends Component<ReplicaSetScaleDialogProps>
}
render() {
const { className, ...dialogProps } = this.props;
const replicaSet = dialogState.get();
const { className, state, ...dialogProps } = this.props;
const replicaSet = state.get();
return (
<Dialog
@ -179,3 +172,11 @@ export class ReplicaSetScaleDialog extends Component<ReplicaSetScaleDialogProps>
);
}
}
export const ReplicaSetScaleDialog = withInjectables<Dependencies, ReplicaSetScaleDialogProps>(NonInjectedReplicaSetScaleDialog, {
getProps: (di, props) => ({
...props,
replicaSetApi: di.inject(replicaSetApiInjectable),
state: di.inject(replicaSetScaleDialogStateInjectable),
}),
});

View File

@ -0,0 +1,20 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import type { ReplicaSet } from "../../../../common/k8s-api/endpoints";
import replicaSetScaleDialogStateInjectable from "./state.injectable";
export type OpenReplicaSetScaleDialog = (obj: ReplicaSet) => void;
const openReplicaSetScaleDialogInjectable = getInjectable({
id: "open-replica-set-scale-dialog",
instantiate: (di): OpenReplicaSetScaleDialog => {
const state = di.inject(replicaSetScaleDialogStateInjectable);
return (obj) => state.set(obj);
},
});
export default openReplicaSetScaleDialogInjectable;

View File

@ -0,0 +1,14 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { observable } from "mobx";
import type { ReplicaSet } from "../../../../common/k8s-api/endpoints";
const replicaSetScaleDialogStateInjectable = getInjectable({
id: "replica-set-scale-dialog-state",
instantiate: () => observable.box<ReplicaSet | undefined>(),
});
export default replicaSetScaleDialogStateInjectable;

View File

@ -10,11 +10,11 @@ import { StatefulSet } from "../../../../common/k8s-api/endpoints";
import { StatefulSetScaleDialog } from "./dialog";
import { waitFor, fireEvent } from "@testing-library/react";
import React from "react";
import type { OpenStatefulSetDialog } from "./open.injectable";
import type { OpenStatefulSetScaleDialog } from "./open.injectable";
import { getDiForUnitTesting } from "../../../getDiForUnitTesting";
import statefulSetApiInjectable from "../../../../common/k8s-api/endpoints/stateful-set.api.injectable";
import createStoresAndApisInjectable from "../../../create-stores-apis.injectable";
import openStatefulSetDialogInjectable from "./open.injectable";
import openStatefulSetScaleDialogInjectable from "./open.injectable";
import { type DiRender, renderFor } from "../../test-utils/renderFor";
const dummyStatefulSet = new StatefulSet({
@ -88,7 +88,7 @@ const dummyStatefulSet = new StatefulSet({
describe("<StatefulSetScaleDialog />", () => {
let statefulSetApi: StatefulSetApi;
let openStatefulSetDialog: OpenStatefulSetDialog;
let openStatefulSetDialog: OpenStatefulSetScaleDialog;
let render: DiRender;
beforeEach(() => {
@ -98,7 +98,7 @@ describe("<StatefulSetScaleDialog />", () => {
render = renderFor(di);
statefulSetApi = di.inject(statefulSetApiInjectable);
openStatefulSetDialog = di.inject(openStatefulSetDialogInjectable);
openStatefulSetDialog = di.inject(openStatefulSetScaleDialogInjectable);
});
it("renders w/o errors", () => {

View File

@ -7,15 +7,15 @@ import type { StatefulSet } from "../../../../common/k8s-api/endpoints";
import { getInjectable } from "@ogre-tools/injectable";
import statefulSetDialogStateInjectable from "./state.injectable";
export type OpenStatefulSetDialog = (obj: StatefulSet) => void;
export type OpenStatefulSetScaleDialog = (obj: StatefulSet) => void;
const openStatefulSetDialogInjectable = getInjectable({
id: "open-stateful-set-dialog",
instantiate: (di): OpenStatefulSetDialog => {
const openStatefulSetScaleDialogInjectable = getInjectable({
id: "open-stateful-set-scale-dialog",
instantiate: (di): OpenStatefulSetScaleDialog => {
const state = di.inject(statefulSetDialogStateInjectable);
return (obj) => state.set(obj);
},
});
export default openStatefulSetDialogInjectable;
export default openStatefulSetScaleDialogInjectable;

View File

@ -7,19 +7,23 @@ import type { KubeObjectMenuProps } from "../kube-object-menu";
import type { StatefulSet } from "../../../common/k8s-api/endpoints";
import { MenuItem } from "../menu";
import { Icon } from "../icon";
import type { OpenStatefulSetDialog } from "./dialog/open.injectable";
import type { OpenStatefulSetScaleDialog } from "./dialog/open.injectable";
import { withInjectables } from "@ogre-tools/injectable-react";
import openStatefulSetDialogInjectable from "./dialog/open.injectable";
import openStatefulSetScaleDialogInjectable from "./dialog/open.injectable";
export interface StatefulSetMenuProps extends KubeObjectMenuProps<StatefulSet> {}
interface Dependencies {
openStatefulSetDialog: OpenStatefulSetDialog;
openStatefulSetScaleDialog: OpenStatefulSetScaleDialog;
}
const NonInjectedStatefulSetMenu = ({ object, toolbar, openStatefulSetDialog }: Dependencies & StatefulSetMenuProps) => (
const NonInjectedStatefulSetMenu = ({
object,
toolbar,
openStatefulSetScaleDialog,
}: Dependencies & StatefulSetMenuProps) => (
<>
<MenuItem onClick={() => openStatefulSetDialog(object)}>
<MenuItem onClick={() => openStatefulSetScaleDialog(object)}>
<Icon
material="open_with"
tooltip="Scale"
@ -33,6 +37,6 @@ const NonInjectedStatefulSetMenu = ({ object, toolbar, openStatefulSetDialog }:
export const StatefulSetMenu = withInjectables<Dependencies, StatefulSetMenuProps>(NonInjectedStatefulSetMenu, {
getProps: (di, props) => ({
...props,
openStatefulSetDialog: di.inject(openStatefulSetDialogInjectable),
openStatefulSetScaleDialog: di.inject(openStatefulSetScaleDialogInjectable),
}),
});

View File

@ -10,7 +10,7 @@ import { ConfirmDialog } from "../../components/confirm-dialog";
import { DeploymentScaleDialog } from "../../components/+workloads-deployments/deployment-scale-dialog";
import { CronJobTriggerDialog } from "../../components/+workloads-cronjobs/cronjob-trigger-dialog";
import { StatefulSetScaleDialog } from "../../components/+workloads-statefulsets/dialog/dialog";
import { ReplicaSetScaleDialog } from "../../components/+workloads-replicasets/replicaset-scale-dialog";
import { ReplicaSetScaleDialog } from "../../components/+workloads-replicasets/scale-dialog/dialog";
import { CommandContainer } from "../../components/command-palette/command-container";
import { ErrorBoundary } from "../../components/error-boundary";
import { MainLayout } from "../../components/layout/main-layout";