Skip to content
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
38 changes: 3 additions & 35 deletions web/src/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,59 +24,27 @@ import React from "react";
import { screen } from "@testing-library/react";
import { installerRender, mockRoutes } from "~/test-utils";
import { createClient } from "~/client";
import { useExtendedConfig } from "~/hooks/model/config";
import { useStatus } from "~/hooks/model/status";
import { useSystem } from "~/hooks/model/system";
import { Product } from "~/types/software";
import { PATHS } from "~/router";
import { PRODUCT } from "~/routes/paths";
import App from "./App";
import { System } from "~/model/system/network";
import type { Config } from "~/model/config";
import type { Progress, Stage } from "~/model/status";

jest.mock("~/client");

const tumbleweed: Product = { id: "openSUSE", name: "openSUSE Tumbleweed", registration: false };
const microos: Product = { id: "Leap Micro", name: "openSUSE Micro", registration: false };
const network: System = {
connections: [],
devices: [],
state: {
connectivity: true,
copyNetwork: true,
networkingEnabled: true,
wirelessEnabled: true,
},
accessPoints: [],
};
const mockProgresses: jest.Mock<Progress[]> = jest.fn();
const mockState: jest.Mock<Stage> = jest.fn();
const mockSelectedProduct: jest.Mock<Config["product"]> = jest.fn();

jest.mock("~/hooks/model/system", () => ({
...jest.requireActual("~/hooks/model/system"),
useSystem: (): ReturnType<typeof useSystem> => ({
products: [tumbleweed, microos],
network,
}),

useStatus: (): ReturnType<typeof useStatus> => ({
stage: mockState(),
progresses: mockProgresses(),
}),

useExtendedConfig: (): ReturnType<typeof useExtendedConfig> => ({
product: mockSelectedProduct(),
}),
}));
jest.mock("~/client");

// Mock some components,
// See https://www.chakshunyu.com/blog/how-to-mock-a-react-component-in-jest/#default-export
jest.mock("~/components/layout/Loading", () => () => <div>Loading Mock</div>);
jest.mock("~/components/product/ProductSelectionProgress", () => () => <div>Product progress</div>);

describe("App", () => {
it.todo("adapt to new api/hooks, adding needed mocking");
describe.skip("App", () => {
beforeEach(() => {
// setting the language through a cookie
document.cookie = "agamaLang=en-US; path=/;";
Expand Down
23 changes: 5 additions & 18 deletions web/src/components/core/ChangeProductOption.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) [2024-2025] SUSE LLC
* Copyright (c) [2024-2026] SUSE LLC
*
* All Rights Reserved.
*
Expand All @@ -24,10 +24,9 @@ import React from "react";
import { screen } from "@testing-library/react";
import { installerRender } from "~/test-utils";
import { useSystem } from "~/hooks/model/system";
import { PRODUCT as PATHS } from "~/routes/paths";
import { Product } from "~/types/software";
import { PRODUCT as PATHS } from "~/routes/paths";
import ChangeProductOption from "./ChangeProductOption";
import { System } from "~/model/system/network";

const tumbleweed: Product = {
id: "Tumbleweed",
Expand All @@ -36,6 +35,7 @@ const tumbleweed: Product = {
description: "Tumbleweed description...",
registration: false,
};

const microos: Product = {
id: "MicroOS",
name: "openSUSE MicroOS",
Expand All @@ -44,26 +44,13 @@ const microos: Product = {
registration: false,
};

const network: System = {
connections: [],
devices: [],
state: {
connectivity: true,
copyNetwork: true,
networkingEnabled: true,
wirelessEnabled: true,
},
accessPoints: [],
};

// let registrationInfoMock: RegistrationInfo;
const mockSystemProducts: jest.Mock<Product[]> = jest.fn();

jest.mock("~/hooks/api", () => ({
...jest.requireActual("~/hooks/api"),
jest.mock("~/hooks/model/system", () => ({
...jest.requireActual("~/hooks/model/system"),
useSystem: (): ReturnType<typeof useSystem> => ({
products: mockSystemProducts(),
network,
}),
}));

Expand Down
4 changes: 0 additions & 4 deletions web/src/components/core/Details.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,6 @@ describe("Details", () => {
</Details>,
);

const flexContainer = container.querySelector(
'[class*="pf-v"][class*="-l-flex"][class*=pf-m-column]',
);

screen.getByText("Storage");
screen.getByRole("link", { name: /Use device vdd/i });
const small = container.querySelector("small");
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/core/InstallButton.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
*/

import React from "react";
import { screen, waitFor, within } from "@testing-library/react";
import { screen } from "@testing-library/react";
import { installerRender, mockRoutes } from "~/test-utils";
import { InstallButton } from "~/components/core";
import { PRODUCT, ROOT } from "~/routes/paths";
Expand Down
104 changes: 59 additions & 45 deletions web/src/components/core/InstallationFinished.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) [2022-2024] SUSE LLC
* Copyright (c) [2022-2026] SUSE LLC
*
* All Rights Reserved.
*
Expand All @@ -23,8 +23,10 @@
import React from "react";
import { screen } from "@testing-library/react";
import { plainRender } from "~/test-utils";
import InstallationFinished from "./InstallationFinished";
import type { Storage } from "~/model/config";
import InstallationFinished from "~/components/core/InstallationFinished";

jest.mock("~/components/core/InstallerOptions", () => () => <div>Installer Options</div>);

jest.mock("~/queries/status", () => ({
...jest.requireActual("~/queries/status"),
Expand All @@ -38,8 +40,7 @@ type guidedEncryption = {
pbkdFunction?: string;
};

let mockEncryption: undefined | Storage.Encryption | guidedEncryption;
let mockType: storageConfigType;
const mockUseExtendedConfigFn = jest.fn();

const mockStorageConfig = (
type: storageConfigType,
Expand All @@ -51,56 +52,57 @@ const mockStorageConfig = (
switch (type) {
case "guided":
return {
guided: {
...encryptionHash,
storage: {
guided: {
...encryptionHash,
},
},
};
case "raw":
return {
drives: [
{
partitions: [
{
filesystem: {
path: "/",
storage: {
drives: [
{
partitions: [
{
filesystem: {
path: "/",
},
id: "linux",
...encryptionHash,
},
id: "linux",
...encryptionHash,
},
{
filesystem: {
mountBy: "uuid",
path: "swap",
type: "swap",
{
filesystem: {
mountBy: "uuid",
path: "swap",
type: "swap",
},
id: "swap",
size: "2 GiB",
},
id: "swap",
size: "2 GiB",
},
],
},
],
],
},
],
},
};
}
};

jest.mock("~/queries/storage", () => ({
...jest.requireActual("~/queries/storage"),
useConfig: () => mockStorageConfig(mockType, mockEncryption),
jest.mock("~/hooks/model/config", () => ({
...jest.requireActual("~/hooks/model/config"),
useExtendedConfig: () => mockUseExtendedConfigFn(),
}));

const mockFinishInstallation = jest.fn();

jest.mock("~/api/manager", () => ({
...jest.requireActual("~/api/manager"),
jest.mock("~/model/manager", () => ({
...jest.requireActual("~/model/manager"),
finishInstallation: () => mockFinishInstallation(),
}));

jest.mock("~/components/core/InstallerOptions", () => () => <div>Installer Options</div>);

describe("InstallationFinished", () => {
beforeEach(() => {
mockEncryption = null;
mockType = "guided";
mockUseExtendedConfigFn.mockReturnValue(mockStorageConfig("guided", null));
});

it("shows the finished installation screen", () => {
Expand All @@ -122,16 +124,18 @@ describe("InstallationFinished", () => {

describe("when running storage config in raw mode", () => {
beforeEach(() => {
mockType = "raw";
mockUseExtendedConfigFn.mockReturnValue(mockStorageConfig("raw", null));
});

describe("when TPM is set as encryption method", () => {
beforeEach(() => {
mockEncryption = {
tpmFde: {
password: "n0tS3cr3t",
},
};
mockUseExtendedConfigFn.mockReturnValue(
mockStorageConfig("raw", {
tpmFde: {
password: "n0tS3cr3t",
},
}),
);
});

it("shows the TPM reminder", async () => {
Expand All @@ -141,6 +145,10 @@ describe("InstallationFinished", () => {
});

describe("when TPM is not set as encryption method", () => {
beforeEach(() => {
mockUseExtendedConfigFn.mockReturnValue(mockStorageConfig("raw", null));
});

it("does not show the TPM reminder", async () => {
plainRender(<InstallationFinished />);
expect(screen.queryAllByText(/TPM/)).toHaveLength(0);
Expand All @@ -151,10 +159,12 @@ describe("InstallationFinished", () => {
describe("when running storage config in guided mode", () => {
describe("when TPM is set as encryption method", () => {
beforeEach(() => {
mockEncryption = {
method: "tpm_fde",
password: "n0tS3cr3t",
};
mockUseExtendedConfigFn.mockReturnValue(
mockStorageConfig("guided", {
method: "tpm_fde",
password: "n0tS3cr3t",
}),
);
});

it("shows the TPM reminder", async () => {
Expand All @@ -164,6 +174,10 @@ describe("InstallationFinished", () => {
});

describe("when TPM is not set as encryption method", () => {
beforeEach(() => {
mockUseExtendedConfigFn.mockReturnValue(mockStorageConfig("guided", null));
});

it("does not show the TPM reminder", async () => {
plainRender(<InstallationFinished />);
expect(screen.queryAllByText(/TPM/)).toHaveLength(0);
Expand Down
8 changes: 5 additions & 3 deletions web/src/components/core/InstallationFinished.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) [2022-2025] SUSE LLC
* Copyright (c) [2022-2026] SUSE LLC
*
* All Rights Reserved.
*
Expand Down Expand Up @@ -83,6 +83,8 @@ function usingTpm(config): boolean {
return null;
}

if (config.guided) return config.guided.encryption;

const { drives = [], volumeGroups = [] } = config;

const devices = [
Expand All @@ -97,7 +99,7 @@ function usingTpm(config): boolean {
}

function InstallationFinished() {
const config = useExtendedConfig();
const { storage: storageConfig } = useExtendedConfig();
const { phase, useIguana } = useInstallerStatus({ suspense: true });
const navigate = useNavigate();

Expand Down Expand Up @@ -131,7 +133,7 @@ function InstallationFinished() {
? _("At this point you can power off the machine.")
: _("At this point you can reboot the machine to log in to the new system.")}
</Content>
{usingTpm(config) && <TpmHint />}
{usingTpm(storageConfig) && <TpmHint />}
</EmptyStateBody>
<EmptyStateFooter>
<EmptyStateActions>
Expand Down
14 changes: 11 additions & 3 deletions web/src/components/core/InstallerOptions.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,25 @@ jest.mock("~/api", () => ({
patchConfig: (payload) => mockPatchConfigFn(payload),
}));

jest.mock("~/hooks/api", () => ({
...jest.requireActual("~/hooks/api"),
jest.mock("~/hooks/model/system", () => ({
...jest.requireActual("~/hooks/model/system"),
useSystem: (): ReturnType<typeof useSystem> => ({
l10n: { locales, keymaps, locale: "us_US.UTF-8", keymap: "us" },
network,
}),
}));

jest.mock("~/hooks/model/config/product", () => ({
...jest.requireActual("~/hooks/model/config/product"),
useProductInfo: (): ReturnType<typeof useProductInfo> => mockSelectedProductFn(),
}));

jest.mock("~/hooks/model/status", () => ({
...jest.requireActual("~/hooks/model/status"),
useStatus: (): ReturnType<typeof useStatus> => ({
stage: mockStateFn(),
progresses: mockProgressesFn(),
}),
useProductInfo: (): ReturnType<typeof useProductInfo> => mockSelectedProductFn(),
}));

jest.mock("~/context/installerL10n", () => ({
Expand Down
Loading