diff --git a/web/src/components/storage/ProposalDeviceSection.jsx b/web/src/components/storage/ProposalDeviceSection.jsx
index 1b8a42e349..6b9ed801f5 100644
--- a/web/src/components/storage/ProposalDeviceSection.jsx
+++ b/web/src/components/storage/ProposalDeviceSection.jsx
@@ -20,11 +20,19 @@
*/
import React, { useState } from "react";
-import { Button, Form, Skeleton } from "@patternfly/react-core";
+import {
+ Button,
+ Form,
+ Skeleton,
+ Switch,
+ ToggleGroup, ToggleGroupItem,
+ Tooltip
+} from "@patternfly/react-core";
import { _ } from "~/i18n";
+import { Icon } from "~/components/layout";
import { If, Section, Popup } from "~/components/core";
-import { DeviceSelector } from "~/components/storage";
+import { DeviceList, DeviceSelector } from "~/components/storage";
import { deviceLabel } from '~/components/storage/utils';
import { noop } from "~/utils";
@@ -167,6 +175,201 @@ const InstallationDeviceField = ({
);
};
+/**
+ * Form for configuring the system volume group.
+ * @component
+ *
+ * @param {object} props
+ * @param {string} props.id - Form ID.
+ * @param {ProposalSettings} props.settings - Settings used for calculating a proposal.
+ * @param {StorageDevice[]} [props.devices=[]] - Available storage devices.
+ * @param {onSubmitFn} [props.onSubmit=noop] - On submit callback.
+ * @param {onValidateFn} [props.onValidate=noop] - On validate callback.
+ *
+ * @callback onSubmitFn
+ * @param {string[]} devices - Name of the selected devices.
+ *
+ * @callback onValidateFn
+ * @param {boolean} valid
+ */
+const LVMSettingsForm = ({
+ id,
+ settings,
+ devices = [],
+ onSubmit: onSubmitProp = noop,
+ onValidate = noop
+}) => {
+ const [vgDevices, setVgDevices] = useState(settings.systemVGDevices);
+ const [isBootDeviceSelected, setIsBootDeviceSelected] = useState(settings.systemVGDevices.length === 0);
+ const [editedDevices, setEditedDevices] = useState(false);
+
+ const selectBootDevice = () => {
+ setIsBootDeviceSelected(true);
+ onValidate(true);
+ };
+
+ const selectCustomDevices = () => {
+ setIsBootDeviceSelected(false);
+ const { bootDevice } = settings;
+ const customDevices = (vgDevices.length === 0 && !editedDevices) ? [bootDevice] : vgDevices;
+ setVgDevices(customDevices);
+ onValidate(customDevices.length > 0);
+ };
+
+ const onChangeDevices = (selection) => {
+ const selectedDevices = devices.filter(d => selection.includes(d.sid)).map(d => d.name);
+ setVgDevices(selectedDevices);
+ setEditedDevices(true);
+ onValidate(devices.length > 0);
+ };
+
+ const onSubmit = (e) => {
+ e.preventDefault();
+ const customDevices = isBootDeviceSelected ? [] : vgDevices;
+ onSubmitProp(customDevices);
+ };
+
+ const BootDevice = () => {
+ const bootDevice = devices.find(d => d.name === settings.bootDevice);
+
+ // FIXME: In this case, should be a "readOnly" selector.
+ return ;
+ };
+
+ return (
+
+ );
+};
+
+/**
+ * Allows to select LVM and configure the system volume group.
+ * @component
+ *
+ * @param {object} props
+ * @param {ProposalSettings} props.settings - Settings used for calculating a proposal.
+ * @param {StorageDevice[]} [props.devices=[]] - Available storage devices.
+ * @param {boolean} [props.isChecked=false] - Whether LVM is selected.
+ * @param {boolean} [props.isLoading=false] - Whether to show the selector as loading.
+ * @param {onChangeFn} [props.onChange=noop] - On change callback.
+ *
+ * @callback onChangeFn
+ * @param {boolean} lvm
+ */
+const LVMField = ({
+ settings,
+ devices = [],
+ isChecked: isCheckedProp = false,
+ isLoading = false,
+ onChange: onChangeProp = noop
+}) => {
+ const [isChecked, setIsChecked] = useState(isCheckedProp);
+ const [isFormOpen, setIsFormOpen] = useState(false);
+ const [isFormValid, setIsFormValid] = useState(true);
+
+ const onChange = (_, value) => {
+ setIsChecked(value);
+ onChangeProp({ lvm: value, vgDevices: [] });
+ };
+
+ const openForm = () => setIsFormOpen(true);
+
+ const closeForm = () => setIsFormOpen(false);
+
+ const onValidateForm = (valid) => setIsFormValid(valid);
+
+ const onSubmitForm = (vgDevices) => {
+ closeForm();
+ onChangeProp({ vgDevices });
+ };
+
+ const description = _("Configuration of the system volume group. All the file systems will be \
+created in a logical volume of the system volume group.");
+
+ const LVMSettingsButton = () => {
+ return (
+
+
+
+ );
+ };
+
+ if (isLoading) return ;
+
+ return (
+
+
+
} />
+
+
+
+
+ {_("Accept")}
+
+
+
+
+
+ );
+};
+
/**
* Section for editing the selected device
* @component
@@ -195,6 +398,14 @@ export default function ProposalDeviceSection({
}
};
+ const changeLVM = ({ lvm, vgDevices }) => {
+ const settings = {};
+ if (lvm !== undefined) settings.lvm = lvm;
+ if (vgDevices !== undefined) settings.systemVGDevices = vgDevices;
+
+ onChange(settings);
+ };
+
const Description = () => (
+
);
}
diff --git a/web/src/components/storage/ProposalDeviceSection.test.jsx b/web/src/components/storage/ProposalDeviceSection.test.jsx
index e90db6a054..27bb058910 100644
--- a/web/src/components/storage/ProposalDeviceSection.test.jsx
+++ b/web/src/components/storage/ProposalDeviceSection.test.jsx
@@ -66,6 +66,53 @@ const sdb = {
udevPaths: ["pci-0000:00-19"]
};
+const vda = {
+ sid: "59",
+ type: "disk",
+ vendor: "Micron",
+ model: "Micron 1100 SATA",
+ driver: ["ahci", "mmcblk"],
+ bus: "IDE",
+ transport: "usb",
+ dellBOSS: false,
+ sdCard: true,
+ active: true,
+ name: "/dev/vda",
+ size: 1024,
+ systems: ["Windows", "openSUSE Leap 15.2"],
+ udevIds: ["ata-Micron_1100_SATA_512GB_12563", "scsi-0ATA_Micron_1100_SATA_512GB"],
+ udevPaths: ["pci-0000:00-12", "pci-0000:00-12-ata"],
+ partitionTable: { type: "gpt", partitions: [] }
+};
+
+const md0 = {
+ sid: "62",
+ type: "md",
+ level: "raid0",
+ uuid: "12345:abcde",
+ members: ["/dev/vdb"],
+ active: true,
+ name: "/dev/md0",
+ size: 2048,
+ systems: [],
+ udevIds: [],
+ udevPaths: []
+};
+
+const md1 = {
+ sid: "63",
+ type: "md",
+ level: "raid0",
+ uuid: "12345:abcde",
+ members: ["/dev/vdc"],
+ active: true,
+ name: "/dev/md1",
+ size: 4096,
+ systems: [],
+ udevIds: [],
+ udevPaths: []
+};
+
const props = {
settings: {
bootDevice: "/dev/sda",
@@ -76,107 +123,274 @@ const props = {
};
describe("ProposalDeviceSection", () => {
- describe("when set as loading", () => {
- beforeEach(() => {
- props.isLoading = true;
- });
+ describe("Installation device field", () => {
+ describe("when set as loading", () => {
+ beforeEach(() => {
+ props.isLoading = true;
+ });
- describe("and selected device is not defined yet", () => {
+ describe("and selected device is not defined yet", () => {
+ beforeEach(() => {
+ props.settings = { bootDevice: undefined };
+ });
+
+ it("renders a loading hint", () => {
+ plainRender();
+ screen.getByText("Loading selected device");
+ });
+ });
+ });
+ describe("when installation device is not selected yet", () => {
beforeEach(() => {
- props.settings = { bootDevice: undefined };
+ props.settings = { bootDevice: "" };
});
- it("renders a loading hint", () => {
- plainRender();
- screen.getByText("Loading selected device");
+ it("uses a 'No device selected yet' text for the selection button", async () => {
+ const { user } = plainRender();
+ const button = screen.getByRole("button", { name: "No device selected yet" });
+
+ await user.click(button);
+
+ screen.getByRole("dialog", { name: "Installation device" });
});
});
- });
- describe("when installation device is not selected yet", () => {
- beforeEach(() => {
- props.settings = { bootDevice: "" };
+ describe("when installation device is selected", () => {
+ beforeEach(() => {
+ props.settings = { bootDevice: "/dev/sda" };
+ });
+
+ it("uses its name as part of the text for the selection button", async () => {
+ const { user } = plainRender();
+ const button = screen.getByRole("button", { name: /\/dev\/sda/ });
+
+ await user.click(button);
+
+ screen.getByRole("dialog", { name: "Installation device" });
+ });
});
- it("uses a 'No device selected yet' text for the selection button", async () => {
+ it("allows changing the selected device", async () => {
const { user } = plainRender();
- const button = screen.getByRole("button", { name: "No device selected yet" });
+ const button = screen.getByRole("button", { name: "/dev/sda, 1 KiB" });
await user.click(button);
- screen.getByRole("dialog", { name: "Installation device" });
+ const selector = await screen.findByRole("dialog", { name: "Installation device" });
+ const sdbOption = within(selector).getByRole("radio", { name: /sdb/ });
+ const accept = within(selector).getByRole("button", { name: "Accept" });
+
+ await user.click(sdbOption);
+ await user.click(accept);
+
+ expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
+ expect(props.onChange).toHaveBeenCalledWith({ bootDevice: sdb.name });
});
- });
- describe("when installation device is selected", () => {
- beforeEach(() => {
- props.settings = { bootDevice: "/dev/sda" };
+ it("allows canceling a device selection", async () => {
+ const { user } = plainRender();
+ const button = screen.getByRole("button", { name: "/dev/sda, 1 KiB" });
+
+ await user.click(button);
+
+ const selector = await screen.findByRole("dialog", { name: "Installation device" });
+ const sdbOption = within(selector).getByRole("radio", { name: /sdb/ });
+ const cancel = within(selector).getByRole("button", { name: "Cancel" });
+
+ await user.click(sdbOption);
+ await user.click(cancel);
+
+ expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
+ expect(props.onChange).not.toHaveBeenCalled();
});
- it("uses its name as part of the text for the selection button", async () => {
+ it("does not trigger the onChange callback when selection actually did not change", async () => {
const { user } = plainRender();
- const button = screen.getByRole("button", { name: /\/dev\/sda/ });
+ const button = screen.getByRole("button", { name: "/dev/sda, 1 KiB" });
await user.click(button);
- screen.getByRole("dialog", { name: "Installation device" });
+ const selector = await screen.findByRole("dialog", { name: "Installation device" });
+ const sdaOption = within(selector).getByRole("radio", { name: /sda/ });
+ const sdbOption = within(selector).getByRole("radio", { name: /sdb/ });
+ const accept = within(selector).getByRole("button", { name: "Accept" });
+
+ // User selects a different device
+ await user.click(sdbOption);
+ // but then goes back to the selected device
+ await user.click(sdaOption);
+ // and clicks on Accept button
+ await user.click(accept);
+
+ expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
+ // There is no reason for triggering the onChange callback
+ expect(props.onChange).not.toHaveBeenCalled();
});
});
- it("allows changing the selected device", async () => {
- const { user } = plainRender();
- const button = screen.getByRole("button", { name: "/dev/sda, 1 KiB" });
+ describe("LVM field", () => {
+ describe("if LVM setting is not set yet", () => {
+ beforeEach(() => {
+ props.settings = {};
+ });
- await user.click(button);
+ it("does not render the LVM switch", () => {
+ plainRender();
- const selector = await screen.findByRole("dialog", { name: "Installation device" });
- const sdbOption = within(selector).getByRole("radio", { name: /sdb/ });
- const accept = within(selector).getByRole("button", { name: "Accept" });
+ expect(screen.queryByLabelText(/Use logical volume/)).toBeNull();
+ });
+ });
- await user.click(sdbOption);
- await user.click(accept);
+ describe("if LVM setting is set", () => {
+ beforeEach(() => {
+ props.settings = { lvm: false };
+ });
- expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
- expect(props.onChange).toHaveBeenCalledWith({ bootDevice: sdb.name });
- });
+ it("renders the LVM switch", () => {
+ plainRender();
+
+ screen.getByRole("checkbox", { name: /Use logical volume/ });
+ });
+ });
- it("allows canceling a device selection", async () => {
- const { user } = plainRender();
- const button = screen.getByRole("button", { name: "/dev/sda, 1 KiB" });
+ describe("if LVM is set to true", () => {
+ beforeEach(() => {
+ props.availableDevices = [vda, md0, md1];
+ props.settings = { bootDevice: "/dev/vda", lvm: true, systemVGDevices: [] };
+ props.onChange = jest.fn();
+ });
- await user.click(button);
+ it("renders the LVM switch as selected", () => {
+ plainRender();
- const selector = await screen.findByRole("dialog", { name: "Installation device" });
- const sdbOption = within(selector).getByRole("radio", { name: /sdb/ });
- const cancel = within(selector).getByRole("button", { name: "Cancel" });
+ const checkbox = screen.getByRole("checkbox", { name: /Use logical volume/ });
+ expect(checkbox).toBeChecked();
+ });
- await user.click(sdbOption);
- await user.click(cancel);
+ it("renders a button for changing the LVM settings", () => {
+ plainRender();
- expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
- expect(props.onChange).not.toHaveBeenCalled();
- });
+ screen.getByRole("button", { name: /LVM settings/ });
+ });
+
+ it("changes the selection on click", async () => {
+ const { user } = plainRender();
+
+ const checkbox = screen.getByRole("checkbox", { name: /Use logical volume/ });
+ await user.click(checkbox);
+
+ expect(checkbox).not.toBeChecked();
+ expect(props.onChange).toHaveBeenCalled();
+ });
+
+ describe("and user clicks on LVM settings", () => {
+ it("opens the LVM settings dialog", async () => {
+ const { user } = plainRender();
+ const settingsButton = screen.getByRole("button", { name: /LVM settings/ });
+
+ await user.click(settingsButton);
+
+ const popup = await screen.findByRole("dialog");
+ within(popup).getByText("System Volume Group");
+ });
+
+ it("allows selecting either installation device or custom devices", async () => {
+ const { user } = plainRender();
+ const settingsButton = screen.getByRole("button", { name: /LVM settings/ });
+
+ await user.click(settingsButton);
+
+ const popup = await screen.findByRole("dialog");
+ screen.getByText("System Volume Group");
+
+ within(popup).getByRole("button", { name: "Installation device" });
+ within(popup).getByRole("button", { name: "Custom devices" });
+ });
+
+ it("allows to set the installation device as system volume group", async () => {
+ const { user } = plainRender();
+ const settingsButton = screen.getByRole("button", { name: /LVM settings/ });
+
+ await user.click(settingsButton);
- it("does not trigger the onChange callback when selection actually did not change", async () => {
- const { user } = plainRender();
- const button = screen.getByRole("button", { name: "/dev/sda, 1 KiB" });
+ const popup = await screen.findByRole("dialog");
+ screen.getByText("System Volume Group");
- await user.click(button);
+ const bootDeviceButton = within(popup).getByRole("button", { name: "Installation device" });
+ const customDevicesButton = within(popup).getByRole("button", { name: "Custom devices" });
+ const acceptButton = within(popup).getByRole("button", { name: "Accept" });
- const selector = await screen.findByRole("dialog", { name: "Installation device" });
- const sdaOption = within(selector).getByRole("radio", { name: /sda/ });
- const sdbOption = within(selector).getByRole("radio", { name: /sdb/ });
- const accept = within(selector).getByRole("button", { name: "Accept" });
+ await user.click(customDevicesButton);
+ await user.click(bootDeviceButton);
+ await user.click(acceptButton);
- // User selects a different device
- await user.click(sdbOption);
- // but then goes back to the selected device
- await user.click(sdaOption);
- // and clicks on Accept button
- await user.click(accept);
+ expect(props.onChange).toHaveBeenCalledWith(
+ expect.objectContaining({ systemVGDevices: [] })
+ );
+ });
- expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
- // There is no reason for triggering the onChange callback
- expect(props.onChange).not.toHaveBeenCalled();
+ it("allows customize the system volume group", async () => {
+ const { user } = plainRender();
+ const settingsButton = screen.getByRole("button", { name: /LVM settings/ });
+
+ await user.click(settingsButton);
+
+ const popup = await screen.findByRole("dialog");
+ screen.getByText("System Volume Group");
+
+ const customDevicesButton = within(popup).getByRole("button", { name: "Custom devices" });
+ const acceptButton = within(popup).getByRole("button", { name: "Accept" });
+
+ await user.click(customDevicesButton);
+
+ const vdaOption = within(popup).getByRole("row", { name: /vda/ });
+ const md0Option = within(popup).getByRole("row", { name: /md0/ });
+ const md1Option = within(popup).getByRole("row", { name: /md1/ });
+
+ // unselect the boot devices
+ await user.click(vdaOption);
+
+ await user.click(md0Option);
+ await user.click(md1Option);
+
+ await user.click(acceptButton);
+
+ expect(props.onChange).toHaveBeenCalledWith(
+ expect.objectContaining({ systemVGDevices: ["/dev/md0", "/dev/md1"] })
+ );
+ });
+ });
+ });
+
+ describe("if LVM is set to false", () => {
+ beforeEach(() => {
+ props.settings = { lvm: false };
+ props.onChange = jest.fn();
+ });
+
+ it("renders the LVM switch as not selected", () => {
+ plainRender();
+
+ const checkbox = screen.getByRole("checkbox", { name: /Use logical volume/ });
+ expect(checkbox).not.toBeChecked();
+ });
+
+ it("does not render a button for changing the LVM settings", () => {
+ plainRender();
+
+ const button = screen.queryByRole("button", { name: /LVM settings/ });
+ expect(button).toBeNull();
+ });
+
+ it("changes the selection on click", async () => {
+ const { user } = plainRender();
+
+ const checkbox = screen.getByRole("checkbox", { name: /Use logical volume/ });
+ await user.click(checkbox);
+
+ expect(checkbox).toBeChecked();
+ expect(props.onChange).toHaveBeenCalled();
+ });
+ });
});
});
diff --git a/web/src/components/storage/ProposalSettingsSection.jsx b/web/src/components/storage/ProposalSettingsSection.jsx
index 9dedef6fd0..1a8812d949 100644
--- a/web/src/components/storage/ProposalSettingsSection.jsx
+++ b/web/src/components/storage/ProposalSettingsSection.jsx
@@ -20,15 +20,10 @@
*/
import React, { useEffect, useState } from "react";
-import {
- Form, Skeleton, Switch, Checkbox,
- ToggleGroup, ToggleGroupItem,
- Tooltip
-} from "@patternfly/react-core";
+import { Checkbox, Form, Skeleton, Switch, Tooltip } from "@patternfly/react-core";
import { _ } from "~/i18n";
import { If, PasswordAndConfirmationInput, Section, Popup } from "~/components/core";
-import { DeviceList, DeviceSelector } from "~/components/storage";
import { Icon } from "~/components/layout";
import { noop } from "~/utils";
@@ -38,201 +33,6 @@ import { noop } from "~/utils";
* @typedef {import ("~/client/storage").ProposalManager.Volume} Volume
*/
-/**
- * Form for configuring the system volume group.
- * @component
- *
- * @param {object} props
- * @param {string} props.id - Form ID.
- * @param {ProposalSettings} props.settings - Settings used for calculating a proposal.
- * @param {StorageDevice[]} [props.devices=[]] - Available storage devices.
- * @param {onSubmitFn} [props.onSubmit=noop] - On submit callback.
- * @param {onValidateFn} [props.onValidate=noop] - On validate callback.
- *
- * @callback onSubmitFn
- * @param {string[]} devices - Name of the selected devices.
- *
- * @callback onValidateFn
- * @param {boolean} valid
- */
-const LVMSettingsForm = ({
- id,
- settings,
- devices = [],
- onSubmit: onSubmitProp = noop,
- onValidate = noop
-}) => {
- const [vgDevices, setVgDevices] = useState(settings.systemVGDevices);
- const [isBootDeviceSelected, setIsBootDeviceSelected] = useState(settings.systemVGDevices.length === 0);
- const [editedDevices, setEditedDevices] = useState(false);
-
- const selectBootDevice = () => {
- setIsBootDeviceSelected(true);
- onValidate(true);
- };
-
- const selectCustomDevices = () => {
- setIsBootDeviceSelected(false);
- const { bootDevice } = settings;
- const customDevices = (vgDevices.length === 0 && !editedDevices) ? [bootDevice] : vgDevices;
- setVgDevices(customDevices);
- onValidate(customDevices.length > 0);
- };
-
- const onChangeDevices = (selection) => {
- const selectedDevices = devices.filter(d => selection.includes(d.sid)).map(d => d.name);
- setVgDevices(selectedDevices);
- setEditedDevices(true);
- onValidate(devices.length > 0);
- };
-
- const onSubmit = (e) => {
- e.preventDefault();
- const customDevices = isBootDeviceSelected ? [] : vgDevices;
- onSubmitProp(customDevices);
- };
-
- const BootDevice = () => {
- const bootDevice = devices.find(d => d.name === settings.bootDevice);
-
- // FIXME: In this case, should be a "readOnly" selector.
- return ;
- };
-
- return (
-
- );
-};
-
-/**
- * Allows to select LVM and configure the system volume group.
- * @component
- *
- * @param {object} props
- * @param {ProposalSettings} props.settings - Settings used for calculating a proposal.
- * @param {StorageDevice[]} [props.devices=[]] - Available storage devices.
- * @param {boolean} [props.isChecked=false] - Whether LVM is selected.
- * @param {boolean} [props.isLoading=false] - Whether to show the selector as loading.
- * @param {onChangeFn} [props.onChange=noop] - On change callback.
- *
- * @callback onChangeFn
- * @param {boolean} lvm
- */
-const LVMField = ({
- settings,
- devices = [],
- isChecked: isCheckedProp = false,
- isLoading = false,
- onChange: onChangeProp = noop
-}) => {
- const [isChecked, setIsChecked] = useState(isCheckedProp);
- const [isFormOpen, setIsFormOpen] = useState(false);
- const [isFormValid, setIsFormValid] = useState(true);
-
- const onChange = (_, value) => {
- setIsChecked(value);
- onChangeProp({ lvm: value, vgDevices: [] });
- };
-
- const openForm = () => setIsFormOpen(true);
-
- const closeForm = () => setIsFormOpen(false);
-
- const onValidateForm = (valid) => setIsFormValid(valid);
-
- const onSubmitForm = (vgDevices) => {
- closeForm();
- onChangeProp({ vgDevices });
- };
-
- const description = _("Configuration of the system volume group. All the file systems will be \
-created in a logical volume of the system volume group.");
-
- const LVMSettingsButton = () => {
- return (
-
-
-
- );
- };
-
- if (isLoading) return ;
-
- return (
-
-
-
} />
-
-
-
-
- {_("Accept")}
-
-
-
-
-
- );
-};
-
/**
* Form for configuring the encryption password.
* @component
@@ -422,7 +222,6 @@ const EncryptionField = ({
*
* @param {object} props
* @param {ProposalSettings} props.settings
- * @param {StorageDevice[]} [props.availableDevices=[]]
* @param {String[]} [props.encryptionMethods=[]]
* @param {onChangeFn} [props.onChange=noop]
*
@@ -431,18 +230,9 @@ const EncryptionField = ({
*/
export default function ProposalSettingsSection({
settings,
- availableDevices = [],
encryptionMethods = [],
onChange = noop
}) {
- const changeLVM = ({ lvm, vgDevices }) => {
- const settings = {};
- if (lvm !== undefined) settings.lvm = lvm;
- if (vgDevices !== undefined) settings.systemVGDevices = vgDevices;
-
- onChange(settings);
- };
-
const changeEncryption = ({ password, method }) => {
onChange({ encryptionPassword: password, encryptionMethod: method });
};
@@ -452,13 +242,6 @@ export default function ProposalSettingsSection({
return (
<>
-
{
let props;
-const vda = {
- sid: "59",
- type: "disk",
- vendor: "Micron",
- model: "Micron 1100 SATA",
- driver: ["ahci", "mmcblk"],
- bus: "IDE",
- transport: "usb",
- dellBOSS: false,
- sdCard: true,
- active: true,
- name: "/dev/vda",
- size: 1024,
- systems: ["Windows", "openSUSE Leap 15.2"],
- udevIds: ["ata-Micron_1100_SATA_512GB_12563", "scsi-0ATA_Micron_1100_SATA_512GB"],
- udevPaths: ["pci-0000:00-12", "pci-0000:00-12-ata"],
- partitionTable: { type: "gpt", partitions: [] }
-};
-
-const md0 = {
- sid: "62",
- type: "md",
- level: "raid0",
- uuid: "12345:abcde",
- members: ["/dev/vdb"],
- active: true,
- name: "/dev/md0",
- size: 2048,
- systems: [],
- udevIds: [],
- udevPaths: []
-};
-
-const md1 = {
- sid: "63",
- type: "md",
- level: "raid0",
- uuid: "12345:abcde",
- members: ["/dev/vdc"],
- active: true,
- name: "/dev/md1",
- size: 4096,
- systems: [],
- udevIds: [],
- udevPaths: []
-};
-
beforeEach(() => {
props = {};
});
-describe("LVM field", () => {
- describe("if LVM setting is not set yet", () => {
- beforeEach(() => {
- props.settings = {};
- });
-
- it("does not render the LVM switch", () => {
- plainRender();
-
- expect(screen.queryByLabelText(/Use logical volume/)).toBeNull();
- });
- });
-
- describe("if LVM setting is set", () => {
- beforeEach(() => {
- props.settings = { lvm: false };
- });
-
- it("renders the LVM switch", () => {
- plainRender();
-
- screen.getByRole("checkbox", { name: /Use logical volume/ });
- });
- });
-
- describe("if LVM is set to true", () => {
- beforeEach(() => {
- props.availableDevices = [vda, md0, md1];
- props.settings = { bootDevice: "/dev/vda", lvm: true, systemVGDevices: [] };
- props.onChange = jest.fn();
- });
-
- it("renders the LVM switch as selected", () => {
- plainRender();
-
- const checkbox = screen.getByRole("checkbox", { name: /Use logical volume/ });
- expect(checkbox).toBeChecked();
- });
-
- it("renders a button for changing the LVM settings", () => {
- plainRender();
-
- screen.getByRole("button", { name: /LVM settings/ });
- });
-
- it("changes the selection on click", async () => {
- const { user } = plainRender();
-
- const checkbox = screen.getByRole("checkbox", { name: /Use logical volume/ });
- await user.click(checkbox);
-
- expect(checkbox).not.toBeChecked();
- expect(props.onChange).toHaveBeenCalled();
- });
-
- describe("and user clicks on LVM settings", () => {
- it("opens the LVM settings dialog", async () => {
- const { user } = plainRender();
- const settingsButton = screen.getByRole("button", { name: /LVM settings/ });
-
- await user.click(settingsButton);
-
- const popup = await screen.findByRole("dialog");
- within(popup).getByText("System Volume Group");
- });
-
- it("allows selecting either installation device or custom devices", async () => {
- const { user } = plainRender();
- const settingsButton = screen.getByRole("button", { name: /LVM settings/ });
-
- await user.click(settingsButton);
-
- const popup = await screen.findByRole("dialog");
- screen.getByText("System Volume Group");
-
- within(popup).getByRole("button", { name: "Installation device" });
- within(popup).getByRole("button", { name: "Custom devices" });
- });
-
- it("allows to set the installation device as system volume group", async () => {
- const { user } = plainRender();
- const settingsButton = screen.getByRole("button", { name: /LVM settings/ });
-
- await user.click(settingsButton);
-
- const popup = await screen.findByRole("dialog");
- screen.getByText("System Volume Group");
-
- const bootDeviceButton = within(popup).getByRole("button", { name: "Installation device" });
- const customDevicesButton = within(popup).getByRole("button", { name: "Custom devices" });
- const acceptButton = within(popup).getByRole("button", { name: "Accept" });
-
- await user.click(customDevicesButton);
- await user.click(bootDeviceButton);
- await user.click(acceptButton);
-
- expect(props.onChange).toHaveBeenCalledWith(
- expect.objectContaining({ systemVGDevices: [] })
- );
- });
-
- it("allows customize the system volume group", async () => {
- const { user } = plainRender();
- const settingsButton = screen.getByRole("button", { name: /LVM settings/ });
-
- await user.click(settingsButton);
-
- const popup = await screen.findByRole("dialog");
- screen.getByText("System Volume Group");
-
- const customDevicesButton = within(popup).getByRole("button", { name: "Custom devices" });
- const acceptButton = within(popup).getByRole("button", { name: "Accept" });
-
- await user.click(customDevicesButton);
-
- const vdaOption = within(popup).getByRole("row", { name: /vda/ });
- const md0Option = within(popup).getByRole("row", { name: /md0/ });
- const md1Option = within(popup).getByRole("row", { name: /md1/ });
-
- // unselect the boot devices
- await user.click(vdaOption);
-
- await user.click(md0Option);
- await user.click(md1Option);
-
- await user.click(acceptButton);
-
- expect(props.onChange).toHaveBeenCalledWith(
- expect.objectContaining({ systemVGDevices: ["/dev/md0", "/dev/md1"] })
- );
- });
- });
- });
-
- describe("if LVM is set to false", () => {
- beforeEach(() => {
- props.settings = { lvm: false };
- props.onChange = jest.fn();
- });
-
- it("renders the LVM switch as not selected", () => {
- plainRender();
-
- const checkbox = screen.getByRole("checkbox", { name: /Use logical volume/ });
- expect(checkbox).not.toBeChecked();
- });
-
- it("does not render a button for changing the LVM settings", () => {
- plainRender();
-
- const button = screen.queryByRole("button", { name: /LVM settings/ });
- expect(button).toBeNull();
- });
-
- it("changes the selection on click", async () => {
- const { user } = plainRender();
-
- const checkbox = screen.getByRole("checkbox", { name: /Use logical volume/ });
- await user.click(checkbox);
-
- expect(checkbox).toBeChecked();
- expect(props.onChange).toHaveBeenCalled();
- });
- });
-});
-
describe("Encryption field", () => {
describe("if encryption password setting is not set yet", () => {
beforeEach(() => {