Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch 2 more operator components to use hooks and remove containers. #6458

Merged
merged 2 commits into from
Jul 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,13 @@ import { act } from "react-dom/test-utils";
import * as ReactRedux from "react-redux";
import { defaultStore, getStore, initialState, mountWrapper } from "shared/specs/mountWrapper";
import { FetchError, IClusterServiceVersion, IStoreState } from "shared/types";
import OperatorInstanceForm, { IOperatorInstanceFormProps } from "./OperatorInstanceForm";
import OperatorInstanceForm from "./OperatorInstanceForm";
import OperatorAdvancedDeploymentForm from "../OperatorInstanceFormBody/OperatorAdvancedDeploymentForm/OperatorAdvancedDeploymentForm";

const defaultProps: IOperatorInstanceFormProps = {
csvName: "foo",
crdName: "foo-cluster",
cluster: initialState.config.kubeappsCluster,
namespace: "kubeapps",
};
import { IClustersState } from "reducers/cluster";
import { MemoryRouter, Route } from "react-router-dom";

const defaultCRD = {
name: defaultProps.crdName,
name: "foo-cluster",
kind: "Foo",
description: "useful description",
} as any;
Expand Down Expand Up @@ -100,7 +95,7 @@ it("renders a fetch error", () => {
errors: { ...initialState.operators.errors, csv: { fetch: new FetchError("Boom!") } },
},
} as Partial<IStoreState>),
<OperatorInstanceForm {...defaultProps} />,
<OperatorInstanceForm />,
);
expect(wrapper.find(Alert)).toIncludeText("Boom!");
expect(wrapper.find(OperatorHeader)).not.toExist();
Expand All @@ -114,26 +109,53 @@ it("renders a create error", () => {
errors: { resource: { create: new Error("Boom!") } },
},
} as Partial<IStoreState>),
<OperatorInstanceForm {...defaultProps} />,
<MemoryRouter
initialEntries={["/c/default/ns/default/operators-instances/new/foo/foo-cluster"]}
>
<Route path={"/c/:cluster/ns/:namespace/operators-instances/new/:csv/:crd"}>
<OperatorInstanceForm />
</Route>
</MemoryRouter>,
);
expect(wrapper.find(Alert)).toIncludeText("Boom!");
});

it("retrieves CSV when mounted", () => {
const getCSV = jest.fn();
actions.operators.getCSV = getCSV;
mountWrapper(defaultStore, <OperatorInstanceForm {...defaultProps} />);
expect(getCSV).toHaveBeenCalledWith(
defaultProps.cluster,
defaultProps.namespace,
defaultProps.csvName,
const store = getStore({
clusters: {
currentCluster: "default-cluster",
clusters: {
"default-cluster": {
currentNamespace: "kubeapps",
},
} as Partial<IClustersState>,
},
} as Partial<IStoreState>);
mountWrapper(
store,
<MemoryRouter
initialEntries={["/c/default/ns/default/operators-instances/new/foo/foo-cluster"]}
>
<Route path={"/c/:cluster/ns/:namespace/operators-instances/new/:csv/:crd"}>
<OperatorInstanceForm />
</Route>
</MemoryRouter>,
);
expect(getCSV).toHaveBeenCalledWith("default-cluster", "kubeapps", "foo");
});

it("retrieves the example values and the target CRD from the given CSV", () => {
const wrapper = mountWrapper(
getStore({ operators: { csv: defaultCSV } } as Partial<IStoreState>),
<OperatorInstanceForm {...defaultProps} />,
<MemoryRouter
initialEntries={["/c/default/ns/default/operators-instances/new/foo/foo-cluster"]}
>
<Route path={"/c/:cluster/ns/:namespace/operators-instances/new/:csv/:crd"}>
<OperatorInstanceForm />
</Route>
</MemoryRouter>,
);
expect(wrapper.find(OperatorInstanceFormBody).props()).toMatchObject({
defaultValues: 'kind: "Foo"\napiVersion: "v1"\n',
Expand All @@ -147,15 +169,21 @@ it("defaults to empty defaultValues if the examples annotation is not found", ()
} as IClusterServiceVersion;
const wrapper = mountWrapper(
getStore({ operators: { csv } } as Partial<IStoreState>),
<OperatorInstanceForm {...defaultProps} />,
<MemoryRouter
initialEntries={["/c/default/ns/default/operators-instances/new/foo/foo-cluster"]}
>
<Route path={"/c/:cluster/ns/:namespace/operators-instances/new/:csv/:crd"}>
<OperatorInstanceForm />
</Route>
</MemoryRouter>,
);
expect(wrapper.find(OperatorInstanceFormBody).props()).toMatchObject({
defaultValues: "",
});
});

it("renders an error if the CRD is not populated", () => {
const wrapper = mountWrapper(defaultStore, <OperatorInstanceForm {...defaultProps} />);
const wrapper = mountWrapper(defaultStore, <OperatorInstanceForm />);
expect(wrapper.find(Alert)).toIncludeText("not found in the definition");
});

Expand All @@ -164,7 +192,13 @@ it("should submit the form", () => {
actions.operators.createResource = createResource;
const wrapper = mountWrapper(
getStore({ operators: { csv: defaultCSV } } as Partial<IStoreState>),
<OperatorInstanceForm {...defaultProps} />,
<MemoryRouter
initialEntries={["/c/default/ns/default/operators-instances/new/foo/foo-cluster"]}
>
<Route path={"/c/:cluster/ns/:namespace/operators-instances/new/:csv/:crd"}>
<OperatorInstanceForm />
</Route>
</MemoryRouter>,
);

act(() => {
Expand All @@ -184,8 +218,8 @@ it("should submit the form", () => {
},
};
expect(createResource).toHaveBeenCalledWith(
defaultProps.cluster,
defaultProps.namespace,
"default-cluster",
"default",
resource.apiVersion,
defaultCRD.name,
resource,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,7 @@ import {
import * as url from "shared/url";
import { parseToString } from "shared/yamlUtils";
import OperatorInstanceFormBody from "../OperatorInstanceFormBody/OperatorInstanceFormBody";

export interface IOperatorInstanceFormProps {
csvName: string;
crdName: string;
cluster: string;
namespace: string;
}

export interface IOperatorInstanceFormBodyState {
defaultValues: string;
crd?: IClusterServiceVersionCRD;
}
import { useParams } from "react-router-dom";

export function parseCSV(
csv: IClusterServiceVersion,
Expand Down Expand Up @@ -71,25 +60,12 @@ export function parseCSV(
});
}

export default function DeploymentFormBody({
csvName,
crdName,
cluster,
namespace,
}: IOperatorInstanceFormProps) {
export default function DeploymentFormBody() {
const dispatch: ThunkDispatch<IStoreState, null, Action> = useDispatch();
const [defaultValues, setDefaultValues] = useState("");
const [crd, setCRD] = useState(undefined as IClusterServiceVersionCRD | undefined);
const [icon, setIcon] = useState(placeholder);

useEffect(() => {
// Clean up component state
setDefaultValues("");
setCRD(undefined);
setIcon(placeholder);
dispatch(actions.operators.getCSV(cluster, namespace, csvName));
}, [cluster, dispatch, namespace, csvName]);

const {
operators: {
csv,
Expand All @@ -99,7 +75,23 @@ export default function DeploymentFormBody({
resource: { create: createError },
},
},
clusters: { currentCluster: cluster, clusters },
} = useSelector((state: IStoreState) => state);
const namespace = clusters[cluster].currentNamespace;

type IDeploymentFormBodyParams = {
csv: string;
crd: string;
};
const { csv: csvName, crd: crdName } = useParams<IDeploymentFormBodyParams>();

useEffect(() => {
// Clean up component state
setDefaultValues("");
setCRD(undefined);
setIcon(placeholder);
dispatch(actions.operators.getCSV(cluster, namespace, csvName));
}, [cluster, dispatch, namespace, csvName]);

useEffect(() => {
if (csv) {
Expand Down
Loading