diff --git a/web/src/components/overview/StorageSection.jsx b/web/src/components/overview/StorageSection.jsx
index de10992e41..e5f31648d8 100644
--- a/web/src/components/overview/StorageSection.jsx
+++ b/web/src/components/overview/StorageSection.jsx
@@ -74,7 +74,10 @@ export default function StorageSection ({ showErrors }) {
dispatch({ type: "UPDATE_STATUS", payload: { status } });
};
- cancellablePromise(client.storage.getStatus()).then(updateStatus);
+ cancellablePromise(client.storage.getStatus()).then((result) => {
+ console.log("getStatus", result);
+ updateStatus(result);
+ });
return client.storage.onStatusChange(updateStatus);
}, [client.storage, cancellablePromise]);
@@ -93,6 +96,7 @@ export default function StorageSection ({ showErrors }) {
const errors = showErrors ? state.errors : [];
const SectionContent = () => {
+ console.log("State", state);
if (state.busy || !state.proposal) return ;
return (
@@ -111,7 +115,9 @@ export default function StorageSection ({ showErrors }) {
return (
);
}
diff --git a/web/src/components/overview/StorageSection.test.jsx b/web/src/components/overview/StorageSection.test.jsx
new file mode 100644
index 0000000000..cd28d1d5ae
--- /dev/null
+++ b/web/src/components/overview/StorageSection.test.jsx
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) [2022] SUSE LLC
+ *
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, contact SUSE LLC.
+ *
+ * To contact SUSE LLC about this file by physical or electronic mail, you may
+ * find current contact information at www.suse.com.
+ */
+
+import React from "react";
+import { act, screen, waitFor } from "@testing-library/react";
+import { installerRender, createCallbackMock } from "@/test-utils";
+import { createClient } from "@client";
+import { BUSY, IDLE } from "@client/status";
+import { StorageSection } from "@components/overview";
+
+const mockUseNavigate = jest.fn();
+
+jest.mock("@client");
+jest.mock("@components/core/InstallerSkeleton", () => () => "Loading storage");
+jest.mock("react-router-dom", () => ({
+ ...jest.requireActual("react-router-dom"),
+ useNavigate: () => mockUseNavigate
+}));
+
+let status = IDLE;
+let proposal = {
+ availableDevices: [
+ { id: "/dev/sda", label: "/dev/sda, 500 GiB" },
+ { id: "/dev/sdb", label: "/dev/sdb, 650 GiB" }
+ ],
+ candidateDevices: ["/dev/sda"],
+ lvm: false
+};
+let errors = [];
+
+beforeEach(() => {
+ createClient.mockImplementation(() => {
+ return {
+ storage: {
+ getProposal: jest.fn().mockResolvedValue(proposal),
+ getStatus: jest.fn().mockResolvedValue(status),
+ getValidationErrors: jest.fn().mockResolvedValue(errors),
+ onStatusChange: () => jest.fn()
+ },
+ };
+ });
+});
+
+describe("when there is no proposal yet", () => {
+ beforeEach(() => {
+ proposal = undefined;
+ });
+
+ it("does not render a link a for editing storage settings", async () => {
+ installerRender();
+
+ await waitFor(() => expect(screen.queryByRole("button", { name: "Edit storage settings" })).not.toBeInTheDocument());
+ });
+});
+
+describe("but storage service is busy", () => {
+ beforeEach(() => {
+ status = IDLE;
+ errors = [{ message: "Fake error" }];
+ });
+
+ it("does not render a link a for editing storage settings", async () => {
+ installerRender();
+
+ await waitFor(() => expect(screen.queryByRole("button", { name: "Edit storage settings" })).not.toBeInTheDocument());
+ });
+
+ it("does not render errors", async () => {
+ installerRender();
+
+ await waitFor(() => expect(screen.queryByText("Fake error")).not.toBeInTheDocument());
+ });
+});
+
+// describe("when the user selects another disk", () => {
+// it("changes the selected disk", async () => {
+// calculateStorageProposalFn = jest.fn().mockResolvedValue(0);
+
+// const { user } = installerRender();
+// const button = await screen.findByRole("button", { name: "/dev/sda, 500 GiB" });
+// await user.click(button);
+
+// const targetSelector = await screen.findByLabelText("Device to install into");
+// await user.selectOptions(targetSelector, ["/dev/sdb"]);
+// await user.click(screen.getByRole("button", { name: "Confirm" }));
+
+// await screen.findByRole("button", { name: "/dev/sdb, 650 GiB" });
+// expect(calculateStorageProposalFn).toHaveBeenCalledWith({
+// candidateDevices: ["/dev/sdb"]
+// });
+// });
+// });
+
+// describe("when the storage proposal changes", () => {
+// let callbacks;
+
+// beforeEach(() => {
+// const [mockedFn, callbacksList] = createCallbackMock();
+// callbacks = callbacksList;
+// onStorageProposalChangeFn = mockedFn;
+// });
+
+// it("updates the proposal", async () => {
+// installerRender();
+// await screen.findByRole("button", { name: "/dev/sda, 500 GiB" });
+
+// const [cb] = callbacks;
+// act(() => {
+// cb("/dev/sdb");
+// });
+// await screen.findByRole("button", { name: "/dev/sdb, 650 GiB" });
+// });
+// });
+
+// describe("when the storage actions change", () => {
+// let callbacks;
+
+// beforeEach(() => {
+// const [mockedFn, callbacksList] = createCallbackMock();
+// callbacks = callbacksList;
+// onActionsChangeFn = mockedFn;
+// });
+
+// it("updates the proposal", async () => {
+// installerRender();
+// await screen.findByText("Mount /dev/sda1 as root");
+
+// const [cb] = callbacks;
+// act(() => {
+// cb([{ text: "Mount /dev/sdb1 as root", subvol: false }]);
+// });
+// await screen.findByText("Mount /dev/sdb1 as root");
+// });
+// });
+
+// describe("when showError is set to true", () => {
+// beforeEach(() => {
+// getValidationErrorsFn.mockResolvedValue([{ message: "Could not make a proposal" }]);
+// });
+
+// it("displays the list of errors", async () => {
+// installerRender();
+// await waitFor(() => {
+// expect(screen.queryByText(/Could not make a proposal/)).toBeInTheDocument();
+// });
+// });
+
+// it("refreshes the list of errors when they change", async () => {
+// let callback;
+// onValidationChangeFn.mockImplementation(cb => { callback = cb });
+
+// installerRender();
+// act(() => {
+// callback([{ message: "Could not find a suitable device" }]);
+// });
+// await waitFor(() => {
+// expect(screen.queryByText(/Could not find a suitable device/)).toBeInTheDocument();
+// });
+// });
+// });
diff --git a/web/src/components/storage/Storage.test.jsx b/web/src/components/storage/Storage.test.jsx
deleted file mode 100644
index df8f5bccfb..0000000000
--- a/web/src/components/storage/Storage.test.jsx
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) [2022] SUSE LLC
- *
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as published
- * by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, contact SUSE LLC.
- *
- * To contact SUSE LLC about this file by physical or electronic mail, you may
- * find current contact information at www.suse.com.
- */
-
-import React from "react";
-import { act, screen, waitFor } from "@testing-library/react";
-import { installerRender, createCallbackMock } from "@/test-utils";
-import { createClient } from "@client";
-import { IDLE } from "@client/status";
-import { Storage } from "@components/storage";
-
-jest.mock("@client");
-jest.mock("@components/core/InstallerSkeleton", () => () => "Loading storage");
-
-let proposalSettings;
-let storageActions;
-
-let onActionsChangeFn = jest.fn();
-let onStorageProposalChangeFn = jest.fn();
-let calculateStorageProposalFn;
-const getStatusFn = jest.fn().mockResolvedValue(IDLE);
-const getValidationErrorsFn = jest.fn().mockResolvedValue([]);
-const onValidationChangeFn = jest.fn();
-
-const storageMock = {
- getStorageProposal: () => Promise.resolve(proposalSettings),
- getStorageActions: () => Promise.resolve(storageActions)
-};
-
-beforeEach(() => {
- storageActions = [{ text: "Mount /dev/sda1 as root", subvol: false, delete: false }];
- proposalSettings = {
- availableDevices: [
- { id: "/dev/sda", label: "/dev/sda, 500 GiB" },
- { id: "/dev/sdb", label: "/dev/sdb, 650 GiB" }
- ],
- candidateDevices: ["/dev/sda"],
- lvm: false
- };
- createClient.mockImplementation(() => {
- return {
- storage: {
- ...storageMock,
- calculateStorageProposal: calculateStorageProposalFn,
- onActionsChange: onActionsChangeFn,
- onStorageProposalChange: onStorageProposalChangeFn,
- getStatus: getStatusFn.mockResolvedValue(IDLE),
- onStatusChange: jest.fn(),
- getValidationErrors: getValidationErrorsFn,
- onValidationChange: onValidationChangeFn
- },
- manager: {
- getStatus: jest.fn().mockResolvedValue(IDLE),
- onStatusChange: jest.fn()
- }
- };
- });
-});
-
-describe("when the user selects another disk", () => {
- it("changes the selected disk", async () => {
- calculateStorageProposalFn = jest.fn().mockResolvedValue(0);
-
- const { user } = installerRender();
- const button = await screen.findByRole("button", { name: "/dev/sda, 500 GiB" });
- await user.click(button);
-
- const targetSelector = await screen.findByLabelText("Device to install into");
- await user.selectOptions(targetSelector, ["/dev/sdb"]);
- await user.click(screen.getByRole("button", { name: "Confirm" }));
-
- await screen.findByRole("button", { name: "/dev/sdb, 650 GiB" });
- expect(calculateStorageProposalFn).toHaveBeenCalledWith({
- candidateDevices: ["/dev/sdb"]
- });
- });
-});
-
-describe("when the storage proposal changes", () => {
- let callbacks;
-
- beforeEach(() => {
- const [mockedFn, callbacksList] = createCallbackMock();
- callbacks = callbacksList;
- onStorageProposalChangeFn = mockedFn;
- });
-
- it("updates the proposal", async () => {
- installerRender();
- await screen.findByRole("button", { name: "/dev/sda, 500 GiB" });
-
- const [cb] = callbacks;
- act(() => {
- cb("/dev/sdb");
- });
- await screen.findByRole("button", { name: "/dev/sdb, 650 GiB" });
- });
-});
-
-describe("when the storage actions change", () => {
- let callbacks;
-
- beforeEach(() => {
- const [mockedFn, callbacksList] = createCallbackMock();
- callbacks = callbacksList;
- onActionsChangeFn = mockedFn;
- });
-
- it("updates the proposal", async () => {
- installerRender();
- await screen.findByText("Mount /dev/sda1 as root");
-
- const [cb] = callbacks;
- act(() => {
- cb([{ text: "Mount /dev/sdb1 as root", subvol: false }]);
- });
- await screen.findByText("Mount /dev/sdb1 as root");
- });
-});
-
-describe("when showError is set to true", () => {
- beforeEach(() => {
- getValidationErrorsFn.mockResolvedValue([{ message: "Could not make a proposal" }]);
- });
-
- it("displays the list of errors", async () => {
- installerRender();
- await waitFor(() => {
- expect(screen.queryByText(/Could not make a proposal/)).toBeInTheDocument();
- });
- });
-
- it("refreshes the list of errors when they change", async () => {
- let callback;
- onValidationChangeFn.mockImplementation(cb => { callback = cb });
-
- installerRender();
- act(() => {
- callback([{ message: "Could not find a suitable device" }]);
- });
- await waitFor(() => {
- expect(screen.queryByText(/Could not find a suitable device/)).toBeInTheDocument();
- });
- });
-});