mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
fix statefulsets/dialog/dialog.test.tsx
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
474b509199
commit
1683f482f1
@ -11,6 +11,7 @@ import podApiInjectable from "./pod.api.injectable";
|
||||
import replicaSetApiInjectable from "./replica-set.api.injectable";
|
||||
import roleApiInjectable from "./role.api.injectable";
|
||||
import serviceAccountApiInjectable from "./service-account.api.injectable";
|
||||
import statefulSetApiInjectable from "./stateful-set.api.injectable";
|
||||
|
||||
/**
|
||||
* @deprecated use `di.inject(clusterRoleBindingApiInjectable)` instead
|
||||
@ -46,3 +47,8 @@ export const daemonSetApi = asLegacyGlobalForExtensionApi(daemonSetApiInjectable
|
||||
* @deprecated use `di.inject(replicaSetApiInjectable)` instead
|
||||
*/
|
||||
export const replicaSetApi = asLegacyGlobalForExtensionApi(replicaSetApiInjectable);
|
||||
|
||||
/**
|
||||
* @deprecated use `di.inject(statefulSetApiInjectable)` instead
|
||||
*/
|
||||
export const statefulSetApi = asLegacyGlobalForExtensionApi(statefulSetApiInjectable);
|
||||
|
||||
19
src/common/k8s-api/endpoints/stateful-set.api.injectable.ts
Normal file
19
src/common/k8s-api/endpoints/stateful-set.api.injectable.ts
Normal file
@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 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 assert from "assert";
|
||||
import { createStoresAndApisInjectionToken } from "../create-stores-apis.token";
|
||||
import { StatefulSetApi } from "./stateful-set.api";
|
||||
|
||||
const statefulSetApiInjectable = getInjectable({
|
||||
id: "stateful-set-api",
|
||||
instantiate: (di) => {
|
||||
assert(di.inject(createStoresAndApisInjectionToken), "statefulSetApi is only available in certain environments");
|
||||
|
||||
return new StatefulSetApi();
|
||||
},
|
||||
});
|
||||
|
||||
export default statefulSetApiInjectable;
|
||||
@ -7,7 +7,6 @@ import type { DerivedKubeApiOptions, IgnoredKubeApiOptions } from "../kube-api";
|
||||
import { KubeApi } from "../kube-api";
|
||||
import { metricsApi } from "./metrics.api";
|
||||
import type { PodMetricData } from "./pod.api";
|
||||
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
|
||||
import type { KubeObjectScope, LabelSelector } from "../kube-object";
|
||||
import { KubeObject } from "../kube-object";
|
||||
import type { PodTemplateSpec } from "./types/pod-template-spec";
|
||||
@ -121,7 +120,3 @@ export class StatefulSet extends KubeObject<StatefulSetStatus, StatefulSetSpec,
|
||||
return containers.map(container => container.image);
|
||||
}
|
||||
}
|
||||
|
||||
export const statefulSetApi = isClusterPageContext()
|
||||
? new StatefulSetApi()
|
||||
: undefined as never;
|
||||
|
||||
@ -10,6 +10,7 @@ import podApiInjectable from "../../common/k8s-api/endpoints/pod.api.injectable"
|
||||
import replicaSetApiInjectable from "../../common/k8s-api/endpoints/replica-set.api.injectable";
|
||||
import roleApiInjectable from "../../common/k8s-api/endpoints/role.api.injectable";
|
||||
import serviceAccountApiInjectable from "../../common/k8s-api/endpoints/service-account.api.injectable";
|
||||
import statefulSetApiInjectable from "../../common/k8s-api/endpoints/stateful-set.api.injectable";
|
||||
import { asLegacyGlobalForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api";
|
||||
|
||||
/**
|
||||
@ -27,6 +28,7 @@ export const roleApi = asLegacyGlobalForExtensionApi(roleApiInjectable);
|
||||
export const podsApi = asLegacyGlobalForExtensionApi(podApiInjectable);
|
||||
export const daemonSetApi = asLegacyGlobalForExtensionApi(daemonSetApiInjectable);
|
||||
export const replicaSetApi = asLegacyGlobalForExtensionApi(replicaSetApiInjectable);
|
||||
export const statefulSetApi = asLegacyGlobalForExtensionApi(statefulSetApiInjectable);
|
||||
|
||||
export { ResourceStack } from "../../common/k8s/resource-stack";
|
||||
export { apiManager } from "../../common/k8s-api/api-manager";
|
||||
@ -37,7 +39,7 @@ export { Pod, PodApi as PodsApi } from "../../common/k8s-api/endpoints/pod.api";
|
||||
export { Node, nodeApi as nodesApi, NodeApi as NodesApi } from "../../common/k8s-api/endpoints/nodes.api";
|
||||
export { Deployment, deploymentApi, DeploymentApi } from "../../common/k8s-api/endpoints/deployment.api";
|
||||
export { DaemonSet } from "../../common/k8s-api/endpoints/daemon-set.api";
|
||||
export { StatefulSet, statefulSetApi } from "../../common/k8s-api/endpoints/stateful-set.api";
|
||||
export { StatefulSet } from "../../common/k8s-api/endpoints/stateful-set.api";
|
||||
export { Job, jobApi } from "../../common/k8s-api/endpoints/job.api";
|
||||
export { CronJob, cronJobApi } from "../../common/k8s-api/endpoints/cron-job.api";
|
||||
export { ConfigMap, configMapApi } from "../../common/k8s-api/endpoints/configmap.api";
|
||||
|
||||
@ -15,6 +15,7 @@ import roleApiInjectable from "../../common/k8s-api/endpoints/role.api.injectabl
|
||||
import podApiInjectable from "../../common/k8s-api/endpoints/pod.api.injectable";
|
||||
import daemonSetApiInjectable from "../../common/k8s-api/endpoints/daemon-set.api.injectable";
|
||||
import replicaSetApiInjectable from "../../common/k8s-api/endpoints/replica-set.api.injectable";
|
||||
import statefulSetApiInjectable from "../../common/k8s-api/endpoints/stateful-set.api.injectable";
|
||||
|
||||
export function isAllowedResource(resource: KubeResource | KubeResource[]) {
|
||||
const resources = castArray(resource);
|
||||
@ -36,6 +37,7 @@ export const roleApi = asLegacyGlobalForExtensionApi(roleApiInjectable);
|
||||
export const podsApi = asLegacyGlobalForExtensionApi(podApiInjectable);
|
||||
export const daemonSetApi = asLegacyGlobalForExtensionApi(daemonSetApiInjectable);
|
||||
export const replicaSetApi = asLegacyGlobalForExtensionApi(replicaSetApiInjectable);
|
||||
export const statefulSetApi = asLegacyGlobalForExtensionApi(statefulSetApiInjectable);
|
||||
|
||||
export {
|
||||
BaseKubeJsonApiObjectMetadata,
|
||||
@ -49,7 +51,7 @@ export { Pod, PodApi as PodsApi } from "../../common/k8s-api/endpoints/pod.api";
|
||||
export { Node, nodeApi as nodesApi, NodeApi as NodesApi } from "../../common/k8s-api/endpoints/nodes.api";
|
||||
export { Deployment, deploymentApi, DeploymentApi } from "../../common/k8s-api/endpoints/deployment.api";
|
||||
export { DaemonSet } from "../../common/k8s-api/endpoints/daemon-set.api";
|
||||
export { StatefulSet, statefulSetApi } from "../../common/k8s-api/endpoints/stateful-set.api";
|
||||
export { StatefulSet } from "../../common/k8s-api/endpoints/stateful-set.api";
|
||||
export { Job, jobApi } from "../../common/k8s-api/endpoints/job.api";
|
||||
export { CronJob, cronJobApi } from "../../common/k8s-api/endpoints/cron-job.api";
|
||||
export { ConfigMap, configMapApi } from "../../common/k8s-api/endpoints/configmap.api";
|
||||
|
||||
@ -5,10 +5,17 @@
|
||||
|
||||
import "@testing-library/jest-dom/extend-expect";
|
||||
|
||||
import { StatefulSet, StatefulSetApi } from "../../../common/k8s-api/endpoints";
|
||||
import { StatefulSetScaleDialog } from "./statefulset-scale-dialog";
|
||||
import { render, waitFor, fireEvent } from "@testing-library/react";
|
||||
import type { StatefulSetApi } from "../../../../common/k8s-api/endpoints";
|
||||
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 { 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 { type DiRender, renderFor } from "../../test-utils/renderFor";
|
||||
|
||||
const dummyStatefulSet = new StatefulSet({
|
||||
apiVersion: "v1",
|
||||
@ -81,15 +88,21 @@ const dummyStatefulSet = new StatefulSet({
|
||||
|
||||
describe("<StatefulSetScaleDialog />", () => {
|
||||
let statefulSetApi: StatefulSetApi;
|
||||
let openStatefulSetDialog: OpenStatefulSetDialog;
|
||||
let render: DiRender;
|
||||
|
||||
beforeEach(() => {
|
||||
statefulSetApi = new StatefulSetApi({
|
||||
objectConstructor: StatefulSet,
|
||||
});
|
||||
const di = getDiForUnitTesting({ doGeneralOverrides: true });
|
||||
|
||||
di.override(createStoresAndApisInjectable, () => true);
|
||||
|
||||
render = renderFor(di);
|
||||
statefulSetApi = di.inject(statefulSetApiInjectable);
|
||||
openStatefulSetDialog = di.inject(openStatefulSetDialogInjectable);
|
||||
});
|
||||
|
||||
it("renders w/o errors", () => {
|
||||
const { container } = render(<StatefulSetScaleDialog statefulSetApi={statefulSetApi} />);
|
||||
const { container } = render(<StatefulSetScaleDialog />);
|
||||
|
||||
expect(container).toBeInstanceOf(HTMLElement);
|
||||
});
|
||||
@ -100,9 +113,9 @@ describe("<StatefulSetScaleDialog />", () => {
|
||||
const initReplicas = 1;
|
||||
|
||||
statefulSetApi.getReplicas = jest.fn().mockImplementationOnce(async () => initReplicas);
|
||||
const { getByTestId } = render(<StatefulSetScaleDialog statefulSetApi={statefulSetApi} />);
|
||||
const { getByTestId } = render(<StatefulSetScaleDialog />);
|
||||
|
||||
StatefulSetScaleDialog.open(dummyStatefulSet);
|
||||
openStatefulSetDialog(dummyStatefulSet);
|
||||
// we need to wait for the StatefulSetScaleDialog to show up
|
||||
// because there is an <Animate /> in <Dialog /> which renders null at start.
|
||||
await waitFor(async () => {
|
||||
@ -120,9 +133,9 @@ describe("<StatefulSetScaleDialog />", () => {
|
||||
const initReplicas = 1;
|
||||
|
||||
statefulSetApi.getReplicas = jest.fn().mockImplementationOnce(async () => initReplicas);
|
||||
const component = render(<StatefulSetScaleDialog statefulSetApi={statefulSetApi} />);
|
||||
const component = render(<StatefulSetScaleDialog />);
|
||||
|
||||
StatefulSetScaleDialog.open(dummyStatefulSet);
|
||||
openStatefulSetDialog(dummyStatefulSet);
|
||||
await waitFor(async () => {
|
||||
expect(await component.findByTestId("desired-scale")).toHaveTextContent(`${initReplicas}`);
|
||||
expect(await component.findByTestId("current-scale")).toHaveTextContent(`${initReplicas}`);
|
||||
@ -3,51 +3,45 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import "./statefulset-scale-dialog.scss";
|
||||
import "./dialog.scss";
|
||||
|
||||
import type { StatefulSet, StatefulSetApi } from "../../../common/k8s-api/endpoints";
|
||||
import { statefulSetApi } from "../../../common/k8s-api/endpoints";
|
||||
import type { StatefulSet, StatefulSetApi } from "../../../../common/k8s-api/endpoints";
|
||||
import React, { Component } from "react";
|
||||
import type { IObservableValue } from "mobx";
|
||||
import { computed, makeObservable, observable } 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 { 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 { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import statefulSetApiInjectable from "../../../../common/k8s-api/endpoints/stateful-set.api.injectable";
|
||||
import statefulSetDialogStateInjectable from "./state.injectable";
|
||||
|
||||
export interface StatefulSetScaleDialogProps extends Partial<DialogProps> {
|
||||
statefulSetApi: StatefulSetApi;
|
||||
}
|
||||
|
||||
const dialogState = observable.box<StatefulSet | undefined>();
|
||||
interface Dependencies {
|
||||
statefulSetApi: StatefulSetApi;
|
||||
state: IObservableValue<StatefulSet | undefined>;
|
||||
}
|
||||
|
||||
@observer
|
||||
export class StatefulSetScaleDialog extends Component<StatefulSetScaleDialogProps> {
|
||||
static defaultProps = {
|
||||
statefulSetApi,
|
||||
};
|
||||
class NonInjectedStatefulSetScaleDialog extends Component<StatefulSetScaleDialogProps & Dependencies> {
|
||||
@observable ready = false;
|
||||
@observable currentReplicas = 0;
|
||||
@observable desiredReplicas = 0;
|
||||
|
||||
constructor(props: StatefulSetScaleDialogProps) {
|
||||
constructor(props: StatefulSetScaleDialogProps & Dependencies) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
static open(statefulSet: StatefulSet) {
|
||||
dialogState.set(statefulSet);
|
||||
}
|
||||
|
||||
static close() {
|
||||
dialogState.set(undefined);
|
||||
}
|
||||
|
||||
close = () => {
|
||||
StatefulSetScaleDialog.close();
|
||||
this.props.state.set(undefined);
|
||||
};
|
||||
|
||||
onOpen = async (statefulSet: StatefulSet) => {
|
||||
@ -161,8 +155,8 @@ export class StatefulSetScaleDialog extends Component<StatefulSetScaleDialogProp
|
||||
}
|
||||
|
||||
render() {
|
||||
const { className, ...dialogProps } = this.props;
|
||||
const statefulSet = dialogState.get();
|
||||
const { className, state, ...dialogProps } = this.props;
|
||||
const statefulSet = state.get();
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
@ -178,3 +172,11 @@ export class StatefulSetScaleDialog extends Component<StatefulSetScaleDialogProp
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const StatefulSetScaleDialog = withInjectables<Dependencies, StatefulSetScaleDialogProps>(NonInjectedStatefulSetScaleDialog, {
|
||||
getProps: (di, props) => ({
|
||||
...props,
|
||||
statefulSetApi: di.inject(statefulSetApiInjectable),
|
||||
state: di.inject(statefulSetDialogStateInjectable),
|
||||
}),
|
||||
});
|
||||
@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
const openStatefulSetDialogInjectable = getInjectable({
|
||||
id: "open-stateful-set-dialog",
|
||||
instantiate: (di): OpenStatefulSetDialog => {
|
||||
const state = di.inject(statefulSetDialogStateInjectable);
|
||||
|
||||
return (obj) => state.set(obj);
|
||||
},
|
||||
});
|
||||
|
||||
export default openStatefulSetDialogInjectable;
|
||||
@ -0,0 +1,15 @@
|
||||
/**
|
||||
* 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 { StatefulSet } from "../../../../common/k8s-api/endpoints";
|
||||
|
||||
const statefulSetDialogStateInjectable = getInjectable({
|
||||
id: "stateful-set-dialog-state",
|
||||
instantiate: () => observable.box<StatefulSet | undefined>(),
|
||||
});
|
||||
|
||||
export default statefulSetDialogStateInjectable;
|
||||
@ -6,22 +6,33 @@ import React from "react";
|
||||
import type { KubeObjectMenuProps } from "../kube-object-menu";
|
||||
import type { StatefulSet } from "../../../common/k8s-api/endpoints";
|
||||
import { MenuItem } from "../menu";
|
||||
import { StatefulSetScaleDialog } from "./statefulset-scale-dialog";
|
||||
import { Icon } from "../icon";
|
||||
import type { OpenStatefulSetDialog } from "./dialog/open.injectable";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import openStatefulSetDialogInjectable from "./dialog/open.injectable";
|
||||
|
||||
export function StatefulSetMenu(props: KubeObjectMenuProps<StatefulSet>) {
|
||||
const { object, toolbar } = props;
|
||||
export interface StatefulSetMenuProps extends KubeObjectMenuProps<StatefulSet> {}
|
||||
|
||||
return (
|
||||
<>
|
||||
<MenuItem onClick={() => StatefulSetScaleDialog.open(object)}>
|
||||
<Icon
|
||||
material="open_with"
|
||||
tooltip="Scale"
|
||||
interactive={toolbar}
|
||||
/>
|
||||
<span className="title">Scale</span>
|
||||
</MenuItem>
|
||||
</>
|
||||
);
|
||||
interface Dependencies {
|
||||
openStatefulSetDialog: OpenStatefulSetDialog;
|
||||
}
|
||||
|
||||
const NonInjectedStatefulSetMenu = ({ object, toolbar, openStatefulSetDialog }: Dependencies & StatefulSetMenuProps) => (
|
||||
<>
|
||||
<MenuItem onClick={() => openStatefulSetDialog(object)}>
|
||||
<Icon
|
||||
material="open_with"
|
||||
tooltip="Scale"
|
||||
interactive={toolbar}
|
||||
/>
|
||||
<span className="title">Scale</span>
|
||||
</MenuItem>
|
||||
</>
|
||||
);
|
||||
|
||||
export const StatefulSetMenu = withInjectables<Dependencies, StatefulSetMenuProps>(NonInjectedStatefulSetMenu, {
|
||||
getProps: (di, props) => ({
|
||||
...props,
|
||||
openStatefulSetDialog: di.inject(openStatefulSetDialogInjectable),
|
||||
}),
|
||||
});
|
||||
|
||||
@ -19,6 +19,7 @@ export interface MainLayoutProps {
|
||||
sidebar: React.ReactNode;
|
||||
className?: string;
|
||||
footer?: React.ReactNode;
|
||||
children?: React.ReactNode | React.ReactNode[];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -18,7 +18,6 @@ export interface WizardCommonProps<D> {
|
||||
reset?: () => void;
|
||||
done?: () => void;
|
||||
hideSteps?: boolean;
|
||||
children?: React.ReactElement<WizardStepProps<D>>[] | React.ReactElement<WizardStepProps<D>>;
|
||||
}
|
||||
|
||||
export interface WizardProps<D> extends WizardCommonProps<D> {
|
||||
@ -27,6 +26,7 @@ export interface WizardProps<D> extends WizardCommonProps<D> {
|
||||
title?: string;
|
||||
header?: React.ReactNode;
|
||||
onChange?: (step: number) => void;
|
||||
children?: React.ReactElement<WizardStepProps<D>>[] | React.ReactElement<WizardStepProps<D>>;
|
||||
}
|
||||
|
||||
interface State {
|
||||
@ -128,6 +128,7 @@ export interface WizardStepProps<D> extends WizardCommonProps<D> {
|
||||
noValidate?: boolean; // no validate form attribute
|
||||
skip?: boolean; // don't render the step
|
||||
scrollable?: boolean;
|
||||
children?: React.ReactNode | React.ReactNode[];
|
||||
}
|
||||
|
||||
interface WizardStepState {
|
||||
|
||||
@ -9,7 +9,7 @@ import { Redirect } from "react-router";
|
||||
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/statefulset-scale-dialog";
|
||||
import { StatefulSetScaleDialog } from "../../components/+workloads-statefulsets/dialog/dialog";
|
||||
import { ReplicaSetScaleDialog } from "../../components/+workloads-replicasets/replicaset-scale-dialog";
|
||||
import { CommandContainer } from "../../components/command-palette/command-container";
|
||||
import { ErrorBoundary } from "../../components/error-boundary";
|
||||
|
||||
Loading…
Reference in New Issue
Block a user