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 { KubeObjectMenuProps } from "../kube-object-menu";
import type { ReplicaSet } from "../../../common/k8s-api/endpoints"; import type { ReplicaSet } from "../../../common/k8s-api/endpoints";
import { MenuItem } from "../menu"; import { MenuItem } from "../menu";
import { ReplicaSetScaleDialog } from "./replicaset-scale-dialog";
import { Icon } from "../icon"; 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>) { export interface ReplicaSetMenuProps extends KubeObjectMenuProps<ReplicaSet> {
const { object, toolbar } = props;
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 "@testing-library/jest-dom/extend-expect";
import { ReplicaSetScaleDialog } from "./replicaset-scale-dialog"; import { ReplicaSetScaleDialog } from "./dialog";
import { render, waitFor, fireEvent } from "@testing-library/react"; import { waitFor, fireEvent } from "@testing-library/react";
import React from "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({ const dummyReplicaSet = new ReplicaSet({
apiVersion: "v1", apiVersion: "v1",
@ -70,15 +77,21 @@ const dummyReplicaSet = new ReplicaSet({
describe("<ReplicaSetScaleDialog />", () => { describe("<ReplicaSetScaleDialog />", () => {
let replicaSetApi: ReplicaSetApi; let replicaSetApi: ReplicaSetApi;
let openReplicaSetScaleDialog: OpenReplicaSetScaleDialog;
let render: DiRender;
beforeEach(() => { beforeEach(() => {
replicaSetApi = new ReplicaSetApi({ const di = getDiForUnitTesting({ doGeneralOverrides: true });
objectConstructor: ReplicaSet,
}); di.override(createStoresAndApisInjectable, () => true);
render = renderFor(di);
replicaSetApi = di.inject(replicaSetApiInjectable);
openReplicaSetScaleDialog = di.inject(openReplicaSetScaleDialogInjectable);
}); });
it("renders w/o errors", () => { it("renders w/o errors", () => {
const { container } = render(<ReplicaSetScaleDialog replicaSetApi={replicaSetApi} />); const { container } = render(<ReplicaSetScaleDialog />);
expect(container).toBeInstanceOf(HTMLElement); expect(container).toBeInstanceOf(HTMLElement);
}); });
@ -89,9 +102,9 @@ describe("<ReplicaSetScaleDialog />", () => {
const initReplicas = 1; const initReplicas = 1;
replicaSetApi.getReplicas = jest.fn().mockImplementationOnce(async () => initReplicas); 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 // we need to wait for the replicaSetScaleDialog to show up
// because there is an <Animate /> in <Dialog /> which renders null at start. // because there is an <Animate /> in <Dialog /> which renders null at start.
await waitFor(async () => { await waitFor(async () => {
@ -109,9 +122,9 @@ describe("<ReplicaSetScaleDialog />", () => {
const initReplicas = 1; const initReplicas = 1;
replicaSetApi.getReplicas = jest.fn().mockImplementationOnce(async () => initReplicas); 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 () => { await waitFor(async () => {
expect(await component.findByTestId("desired-scale")).toHaveTextContent(`${initReplicas}`); expect(await component.findByTestId("desired-scale")).toHaveTextContent(`${initReplicas}`);
expect(await component.findByTestId("current-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. * 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 React, { Component } from "react";
import type { IObservableValue } from "mobx";
import { computed, observable, makeObservable } from "mobx"; import { computed, observable, makeObservable } from "mobx";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import type { DialogProps } from "../dialog"; import type { DialogProps } from "../../dialog";
import { Dialog } from "../dialog"; import { Dialog } from "../../dialog";
import { Wizard, WizardStep } from "../wizard"; import { Wizard, WizardStep } from "../../wizard";
import { Icon } from "../icon"; import { Icon } from "../../icon";
import { Slider } from "../slider"; import { Slider } from "../../slider";
import { Notifications } from "../notifications"; import { Notifications } from "../../notifications";
import { cssNames } from "../../utils"; import { cssNames } from "../../../utils";
import type { ReplicaSet, ReplicaSetApi } from "../../../common/k8s-api/endpoints/replica-set.api"; import type { ReplicaSet, ReplicaSetApi } from "../../../../common/k8s-api/endpoints";
import { replicaSetApi } from "../../../common/k8s-api/endpoints/replica-set.api"; 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> { export interface ReplicaSetScaleDialogProps extends Partial<DialogProps> {
replicaSetApi: ReplicaSetApi;
} }
const dialogState = observable.box<ReplicaSet | undefined>(); interface Dependencies {
replicaSetApi: ReplicaSetApi;
state: IObservableValue<ReplicaSet | undefined>;
}
@observer @observer
export class ReplicaSetScaleDialog extends Component<ReplicaSetScaleDialogProps> { class NonInjectedReplicaSetScaleDialog extends Component<ReplicaSetScaleDialogProps & Dependencies> {
static defaultProps = {
replicaSetApi,
};
@observable ready = false; @observable ready = false;
@observable currentReplicas = 0; @observable currentReplicas = 0;
@observable desiredReplicas = 0; @observable desiredReplicas = 0;
constructor(props: ReplicaSetScaleDialogProps) { constructor(props: ReplicaSetScaleDialogProps & Dependencies) {
super(props); super(props);
makeObservable(this); makeObservable(this);
} }
static open(replicaSet: ReplicaSet) {
dialogState.set(replicaSet);
}
static close() {
dialogState.set(undefined);
}
close = () => { close = () => {
ReplicaSetScaleDialog.close(); this.props.state.set(undefined);
}; };
onOpen = async (replicaSet: ReplicaSet) => { onOpen = async (replicaSet: ReplicaSet) => {
@ -162,8 +155,8 @@ export class ReplicaSetScaleDialog extends Component<ReplicaSetScaleDialogProps>
} }
render() { render() {
const { className, ...dialogProps } = this.props; const { className, state, ...dialogProps } = this.props;
const replicaSet = dialogState.get(); const replicaSet = state.get();
return ( return (
<Dialog <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 { StatefulSetScaleDialog } from "./dialog";
import { waitFor, fireEvent } from "@testing-library/react"; import { waitFor, fireEvent } from "@testing-library/react";
import React from "react"; import React from "react";
import type { OpenStatefulSetDialog } from "./open.injectable"; import type { OpenStatefulSetScaleDialog } from "./open.injectable";
import { getDiForUnitTesting } from "../../../getDiForUnitTesting"; import { getDiForUnitTesting } from "../../../getDiForUnitTesting";
import statefulSetApiInjectable from "../../../../common/k8s-api/endpoints/stateful-set.api.injectable"; import statefulSetApiInjectable from "../../../../common/k8s-api/endpoints/stateful-set.api.injectable";
import createStoresAndApisInjectable from "../../../create-stores-apis.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"; import { type DiRender, renderFor } from "../../test-utils/renderFor";
const dummyStatefulSet = new StatefulSet({ const dummyStatefulSet = new StatefulSet({
@ -88,7 +88,7 @@ const dummyStatefulSet = new StatefulSet({
describe("<StatefulSetScaleDialog />", () => { describe("<StatefulSetScaleDialog />", () => {
let statefulSetApi: StatefulSetApi; let statefulSetApi: StatefulSetApi;
let openStatefulSetDialog: OpenStatefulSetDialog; let openStatefulSetDialog: OpenStatefulSetScaleDialog;
let render: DiRender; let render: DiRender;
beforeEach(() => { beforeEach(() => {
@ -98,7 +98,7 @@ describe("<StatefulSetScaleDialog />", () => {
render = renderFor(di); render = renderFor(di);
statefulSetApi = di.inject(statefulSetApiInjectable); statefulSetApi = di.inject(statefulSetApiInjectable);
openStatefulSetDialog = di.inject(openStatefulSetDialogInjectable); openStatefulSetDialog = di.inject(openStatefulSetScaleDialogInjectable);
}); });
it("renders w/o errors", () => { 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 { getInjectable } from "@ogre-tools/injectable";
import statefulSetDialogStateInjectable from "./state.injectable"; import statefulSetDialogStateInjectable from "./state.injectable";
export type OpenStatefulSetDialog = (obj: StatefulSet) => void; export type OpenStatefulSetScaleDialog = (obj: StatefulSet) => void;
const openStatefulSetDialogInjectable = getInjectable({ const openStatefulSetScaleDialogInjectable = getInjectable({
id: "open-stateful-set-dialog", id: "open-stateful-set-scale-dialog",
instantiate: (di): OpenStatefulSetDialog => { instantiate: (di): OpenStatefulSetScaleDialog => {
const state = di.inject(statefulSetDialogStateInjectable); const state = di.inject(statefulSetDialogStateInjectable);
return (obj) => state.set(obj); 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 type { StatefulSet } from "../../../common/k8s-api/endpoints";
import { MenuItem } from "../menu"; import { MenuItem } from "../menu";
import { Icon } from "../icon"; 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 { withInjectables } from "@ogre-tools/injectable-react";
import openStatefulSetDialogInjectable from "./dialog/open.injectable"; import openStatefulSetScaleDialogInjectable from "./dialog/open.injectable";
export interface StatefulSetMenuProps extends KubeObjectMenuProps<StatefulSet> {} export interface StatefulSetMenuProps extends KubeObjectMenuProps<StatefulSet> {}
interface Dependencies { 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 <Icon
material="open_with" material="open_with"
tooltip="Scale" tooltip="Scale"
@ -33,6 +37,6 @@ const NonInjectedStatefulSetMenu = ({ object, toolbar, openStatefulSetDialog }:
export const StatefulSetMenu = withInjectables<Dependencies, StatefulSetMenuProps>(NonInjectedStatefulSetMenu, { export const StatefulSetMenu = withInjectables<Dependencies, StatefulSetMenuProps>(NonInjectedStatefulSetMenu, {
getProps: (di, props) => ({ getProps: (di, props) => ({
...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 { DeploymentScaleDialog } from "../../components/+workloads-deployments/deployment-scale-dialog";
import { CronJobTriggerDialog } from "../../components/+workloads-cronjobs/cronjob-trigger-dialog"; import { CronJobTriggerDialog } from "../../components/+workloads-cronjobs/cronjob-trigger-dialog";
import { StatefulSetScaleDialog } from "../../components/+workloads-statefulsets/dialog/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 { CommandContainer } from "../../components/command-palette/command-container";
import { ErrorBoundary } from "../../components/error-boundary"; import { ErrorBoundary } from "../../components/error-boundary";
import { MainLayout } from "../../components/layout/main-layout"; import { MainLayout } from "../../components/layout/main-layout";