mirror of
https://github.com/gethomepage/homepage.git
synced 2026-02-08 00:40:52 +08:00
Add widget component tests (netdata..opnsense)
This commit is contained in:
59
src/widgets/netdata/component.test.jsx
Normal file
59
src/widgets/netdata/component.test.jsx
Normal file
@@ -0,0 +1,59 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { screen } from "@testing-library/react";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { renderWithProviders } from "test-utils/render-with-providers";
|
||||
import { findServiceBlockByLabel } from "test-utils/widget-assertions";
|
||||
|
||||
const { useWidgetAPI } = vi.hoisted(() => ({ useWidgetAPI: vi.fn() }));
|
||||
vi.mock("utils/proxy/use-widget-api", () => ({ default: useWidgetAPI }));
|
||||
|
||||
import Component from "./component";
|
||||
|
||||
function expectBlockValue(container, label, value) {
|
||||
const block = findServiceBlockByLabel(container, label);
|
||||
expect(block, `missing block for ${label}`).toBeTruthy();
|
||||
expect(block.textContent).toContain(String(value));
|
||||
}
|
||||
|
||||
describe("widgets/netdata/component", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("renders placeholders while loading", () => {
|
||||
useWidgetAPI.mockReturnValue({ data: undefined, error: undefined });
|
||||
|
||||
const { container } = renderWithProviders(<Component service={{ widget: { type: "netdata" } }} />, {
|
||||
settings: { hideErrors: false },
|
||||
});
|
||||
|
||||
expect(container.querySelectorAll(".service-block")).toHaveLength(2);
|
||||
expect(screen.getByText("netdata.warnings")).toBeInTheDocument();
|
||||
expect(screen.getByText("netdata.criticals")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders error UI when endpoint errors", () => {
|
||||
useWidgetAPI.mockReturnValue({ data: undefined, error: { message: "nope" } });
|
||||
|
||||
renderWithProviders(<Component service={{ widget: { type: "netdata" } }} />, { settings: { hideErrors: false } });
|
||||
|
||||
expect(screen.getAllByText(/widget\.api_error/i).length).toBeGreaterThan(0);
|
||||
expect(screen.getByText("nope")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders warning and critical alarm counts", () => {
|
||||
useWidgetAPI.mockReturnValue({
|
||||
data: { alarms: { warning: 3, critical: 1 } },
|
||||
error: undefined,
|
||||
});
|
||||
|
||||
const { container } = renderWithProviders(<Component service={{ widget: { type: "netdata" } }} />, {
|
||||
settings: { hideErrors: false },
|
||||
});
|
||||
|
||||
expectBlockValue(container, "netdata.warnings", 3);
|
||||
expectBlockValue(container, "netdata.criticals", 1);
|
||||
});
|
||||
});
|
||||
53
src/widgets/nextdns/component.test.jsx
Normal file
53
src/widgets/nextdns/component.test.jsx
Normal file
@@ -0,0 +1,53 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { screen } from "@testing-library/react";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { renderWithProviders } from "test-utils/render-with-providers";
|
||||
|
||||
const { useWidgetAPI } = vi.hoisted(() => ({ useWidgetAPI: vi.fn() }));
|
||||
vi.mock("utils/proxy/use-widget-api", () => ({ default: useWidgetAPI }));
|
||||
|
||||
import Component from "./component";
|
||||
|
||||
describe("widgets/nextdns/component", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("renders waiting status while loading", () => {
|
||||
useWidgetAPI.mockReturnValue({ data: undefined, error: undefined });
|
||||
|
||||
renderWithProviders(<Component service={{ widget: { type: "nextdns" } }} />, { settings: { hideErrors: false } });
|
||||
|
||||
expect(screen.getByText("widget.status")).toBeInTheDocument();
|
||||
expect(screen.getByText("nextdns.wait")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders no-devices status when data array is empty", () => {
|
||||
useWidgetAPI.mockReturnValue({ data: { data: [] }, error: undefined });
|
||||
|
||||
renderWithProviders(<Component service={{ widget: { type: "nextdns" } }} />, { settings: { hideErrors: false } });
|
||||
|
||||
expect(screen.getByText("nextdns.no_devices")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders a block per device status with query counts", () => {
|
||||
useWidgetAPI.mockReturnValue({
|
||||
data: {
|
||||
data: [
|
||||
{ status: "nextdns.active", queries: 10 },
|
||||
{ status: "nextdns.offline", queries: 2 },
|
||||
],
|
||||
},
|
||||
error: undefined,
|
||||
});
|
||||
|
||||
renderWithProviders(<Component service={{ widget: { type: "nextdns" } }} />, { settings: { hideErrors: false } });
|
||||
|
||||
expect(screen.getByText("nextdns.active")).toBeInTheDocument();
|
||||
expect(screen.getByText("nextdns.offline")).toBeInTheDocument();
|
||||
expect(screen.getByText("10")).toBeInTheDocument();
|
||||
expect(screen.getByText("2")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
61
src/widgets/npm/component.test.jsx
Normal file
61
src/widgets/npm/component.test.jsx
Normal file
@@ -0,0 +1,61 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { screen } from "@testing-library/react";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { renderWithProviders } from "test-utils/render-with-providers";
|
||||
import { findServiceBlockByLabel } from "test-utils/widget-assertions";
|
||||
|
||||
const { useWidgetAPI } = vi.hoisted(() => ({ useWidgetAPI: vi.fn() }));
|
||||
vi.mock("utils/proxy/use-widget-api", () => ({ default: useWidgetAPI }));
|
||||
|
||||
import Component from "./component";
|
||||
|
||||
function expectBlockValue(container, label, value) {
|
||||
const block = findServiceBlockByLabel(container, label);
|
||||
expect(block, `missing block for ${label}`).toBeTruthy();
|
||||
expect(block.textContent).toContain(String(value));
|
||||
}
|
||||
|
||||
describe("widgets/npm/component", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("renders placeholders while loading", () => {
|
||||
useWidgetAPI.mockReturnValue({ data: undefined, error: undefined });
|
||||
|
||||
const { container } = renderWithProviders(<Component service={{ widget: { type: "npm" } }} />, {
|
||||
settings: { hideErrors: false },
|
||||
});
|
||||
|
||||
expect(container.querySelectorAll(".service-block")).toHaveLength(3);
|
||||
expect(screen.getByText("npm.enabled")).toBeInTheDocument();
|
||||
expect(screen.getByText("npm.disabled")).toBeInTheDocument();
|
||||
expect(screen.getByText("npm.total")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders error UI when endpoint errors", () => {
|
||||
useWidgetAPI.mockReturnValue({ data: undefined, error: { message: "nope" } });
|
||||
|
||||
renderWithProviders(<Component service={{ widget: { type: "npm" } }} />, { settings: { hideErrors: false } });
|
||||
|
||||
expect(screen.getAllByText(/widget\.api_error/i).length).toBeGreaterThan(0);
|
||||
expect(screen.getByText("nope")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders enabled/disabled/total host counts", () => {
|
||||
useWidgetAPI.mockReturnValue({
|
||||
data: [{ enabled: true }, { enabled: false }, { enabled: 1 }, { enabled: 0 }, { enabled: true }],
|
||||
error: undefined,
|
||||
});
|
||||
|
||||
const { container } = renderWithProviders(<Component service={{ widget: { type: "npm" } }} />, {
|
||||
settings: { hideErrors: false },
|
||||
});
|
||||
|
||||
expectBlockValue(container, "npm.enabled", 3);
|
||||
expectBlockValue(container, "npm.disabled", 2);
|
||||
expectBlockValue(container, "npm.total", 5);
|
||||
});
|
||||
});
|
||||
61
src/widgets/nzbget/component.test.jsx
Normal file
61
src/widgets/nzbget/component.test.jsx
Normal file
@@ -0,0 +1,61 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { screen } from "@testing-library/react";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { renderWithProviders } from "test-utils/render-with-providers";
|
||||
import { findServiceBlockByLabel } from "test-utils/widget-assertions";
|
||||
|
||||
const { useWidgetAPI } = vi.hoisted(() => ({ useWidgetAPI: vi.fn() }));
|
||||
vi.mock("utils/proxy/use-widget-api", () => ({ default: useWidgetAPI }));
|
||||
|
||||
import Component from "./component";
|
||||
|
||||
function expectBlockValue(container, label, value) {
|
||||
const block = findServiceBlockByLabel(container, label);
|
||||
expect(block, `missing block for ${label}`).toBeTruthy();
|
||||
expect(block.textContent).toContain(String(value));
|
||||
}
|
||||
|
||||
describe("widgets/nzbget/component", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("renders placeholders while loading", () => {
|
||||
useWidgetAPI.mockReturnValue({ data: undefined, error: undefined });
|
||||
|
||||
const { container } = renderWithProviders(<Component service={{ widget: { type: "nzbget" } }} />, {
|
||||
settings: { hideErrors: false },
|
||||
});
|
||||
|
||||
expect(container.querySelectorAll(".service-block")).toHaveLength(3);
|
||||
expect(screen.getByText("nzbget.rate")).toBeInTheDocument();
|
||||
expect(screen.getByText("nzbget.remaining")).toBeInTheDocument();
|
||||
expect(screen.getByText("nzbget.downloaded")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders error UI when endpoint errors", () => {
|
||||
useWidgetAPI.mockReturnValue({ data: undefined, error: { message: "nope" } });
|
||||
|
||||
renderWithProviders(<Component service={{ widget: { type: "nzbget" } }} />, { settings: { hideErrors: false } });
|
||||
|
||||
expect(screen.getAllByText(/widget\.api_error/i).length).toBeGreaterThan(0);
|
||||
expect(screen.getByText("nope")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders rate and sizes when loaded", () => {
|
||||
useWidgetAPI.mockReturnValue({
|
||||
data: { DownloadRate: 1234, RemainingSizeMB: 2, DownloadedSizeMB: 3 },
|
||||
error: undefined,
|
||||
});
|
||||
|
||||
const { container } = renderWithProviders(<Component service={{ widget: { type: "nzbget" } }} />, {
|
||||
settings: { hideErrors: false },
|
||||
});
|
||||
|
||||
expectBlockValue(container, "nzbget.rate", 1234);
|
||||
expectBlockValue(container, "nzbget.remaining", 2 * 1024 * 1024);
|
||||
expectBlockValue(container, "nzbget.downloaded", 3 * 1024 * 1024);
|
||||
});
|
||||
});
|
||||
76
src/widgets/octoprint/component.test.jsx
Normal file
76
src/widgets/octoprint/component.test.jsx
Normal file
@@ -0,0 +1,76 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { screen } from "@testing-library/react";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { renderWithProviders } from "test-utils/render-with-providers";
|
||||
import { findServiceBlockByLabel } from "test-utils/widget-assertions";
|
||||
|
||||
const { useWidgetAPI } = vi.hoisted(() => ({ useWidgetAPI: vi.fn() }));
|
||||
vi.mock("utils/proxy/use-widget-api", () => ({ default: useWidgetAPI }));
|
||||
|
||||
import Component from "./component";
|
||||
|
||||
function expectBlockValue(container, label, value) {
|
||||
const block = findServiceBlockByLabel(container, label);
|
||||
expect(block, `missing block for ${label}`).toBeTruthy();
|
||||
expect(block.textContent).toContain(String(value));
|
||||
}
|
||||
|
||||
describe("widgets/octoprint/component", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("renders minimal placeholder while loading", () => {
|
||||
useWidgetAPI.mockReturnValue({ data: undefined, error: undefined });
|
||||
|
||||
const { container } = renderWithProviders(<Component service={{ widget: { type: "octoprint" } }} />, {
|
||||
settings: { hideErrors: false },
|
||||
});
|
||||
|
||||
expect(container.querySelectorAll(".service-block")).toHaveLength(1);
|
||||
expect(screen.getByText("octoprint.printer_state")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders state from job_stats when printer_stats errors but job_stats is available", () => {
|
||||
useWidgetAPI.mockImplementation((_widget, endpoint) => {
|
||||
if (endpoint === "printer_stats") return { data: undefined, error: { message: "printer nope" } };
|
||||
if (endpoint === "job_stats") return { data: { state: "Paused" }, error: undefined };
|
||||
return { data: undefined, error: undefined };
|
||||
});
|
||||
|
||||
const { container } = renderWithProviders(<Component service={{ widget: { type: "octoprint" } }} />, {
|
||||
settings: { hideErrors: false },
|
||||
});
|
||||
|
||||
expectBlockValue(container, "octoprint.printer_state", "Paused");
|
||||
expect(screen.queryByText("printer nope")).toBeNull();
|
||||
});
|
||||
|
||||
it("renders job completion block when printing and completion is present", () => {
|
||||
useWidgetAPI.mockImplementation((_widget, endpoint) => {
|
||||
if (endpoint === "printer_stats") {
|
||||
return {
|
||||
data: {
|
||||
state: { text: "Printing" },
|
||||
temperature: { tool0: { actual: 200 }, bed: { actual: 60 } },
|
||||
},
|
||||
error: undefined,
|
||||
};
|
||||
}
|
||||
if (endpoint === "job_stats") return { data: { progress: { completion: 12.3456 } }, error: undefined };
|
||||
return { data: undefined, error: undefined };
|
||||
});
|
||||
|
||||
const { container } = renderWithProviders(<Component service={{ widget: { type: "octoprint" } }} />, {
|
||||
settings: { hideErrors: false },
|
||||
});
|
||||
|
||||
expect(container.querySelectorAll(".service-block")).toHaveLength(4);
|
||||
expectBlockValue(container, "octoprint.printer_state", "Printing");
|
||||
expectBlockValue(container, "octoprint.temp_tool", "200");
|
||||
expectBlockValue(container, "octoprint.temp_bed", "60");
|
||||
expectBlockValue(container, "octoprint.job_completion", "12.35%");
|
||||
});
|
||||
});
|
||||
58
src/widgets/ombi/component.test.jsx
Normal file
58
src/widgets/ombi/component.test.jsx
Normal file
@@ -0,0 +1,58 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { screen } from "@testing-library/react";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { renderWithProviders } from "test-utils/render-with-providers";
|
||||
import { findServiceBlockByLabel } from "test-utils/widget-assertions";
|
||||
|
||||
const { useWidgetAPI } = vi.hoisted(() => ({ useWidgetAPI: vi.fn() }));
|
||||
vi.mock("utils/proxy/use-widget-api", () => ({ default: useWidgetAPI }));
|
||||
|
||||
import Component from "./component";
|
||||
|
||||
function expectBlockValue(container, label, value) {
|
||||
const block = findServiceBlockByLabel(container, label);
|
||||
expect(block, `missing block for ${label}`).toBeTruthy();
|
||||
expect(block.textContent).toContain(String(value));
|
||||
}
|
||||
|
||||
describe("widgets/ombi/component", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("renders placeholders while loading", () => {
|
||||
useWidgetAPI.mockReturnValue({ data: undefined, error: undefined });
|
||||
|
||||
const { container } = renderWithProviders(<Component service={{ widget: { type: "ombi" } }} />, {
|
||||
settings: { hideErrors: false },
|
||||
});
|
||||
|
||||
expect(container.querySelectorAll(".service-block")).toHaveLength(3);
|
||||
expect(screen.getByText("ombi.pending")).toBeInTheDocument();
|
||||
expect(screen.getByText("ombi.approved")).toBeInTheDocument();
|
||||
expect(screen.getByText("ombi.available")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders error UI when endpoint errors", () => {
|
||||
useWidgetAPI.mockReturnValue({ data: undefined, error: { message: "nope" } });
|
||||
|
||||
renderWithProviders(<Component service={{ widget: { type: "ombi" } }} />, { settings: { hideErrors: false } });
|
||||
|
||||
expect(screen.getAllByText(/widget\.api_error/i).length).toBeGreaterThan(0);
|
||||
expect(screen.getByText("nope")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders request counts when loaded", () => {
|
||||
useWidgetAPI.mockReturnValue({ data: { pending: 1, approved: 2, available: 3 }, error: undefined });
|
||||
|
||||
const { container } = renderWithProviders(<Component service={{ widget: { type: "ombi" } }} />, {
|
||||
settings: { hideErrors: false },
|
||||
});
|
||||
|
||||
expectBlockValue(container, "ombi.pending", 1);
|
||||
expectBlockValue(container, "ombi.approved", 2);
|
||||
expectBlockValue(container, "ombi.available", 3);
|
||||
});
|
||||
});
|
||||
71
src/widgets/opendtu/component.test.jsx
Normal file
71
src/widgets/opendtu/component.test.jsx
Normal file
@@ -0,0 +1,71 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { screen } from "@testing-library/react";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { renderWithProviders } from "test-utils/render-with-providers";
|
||||
import { findServiceBlockByLabel } from "test-utils/widget-assertions";
|
||||
|
||||
const { useWidgetAPI } = vi.hoisted(() => ({ useWidgetAPI: vi.fn() }));
|
||||
vi.mock("utils/proxy/use-widget-api", () => ({ default: useWidgetAPI }));
|
||||
|
||||
import Component from "./component";
|
||||
|
||||
function expectBlockValue(container, label, value) {
|
||||
const block = findServiceBlockByLabel(container, label);
|
||||
expect(block, `missing block for ${label}`).toBeTruthy();
|
||||
expect(block.textContent).toContain(String(value));
|
||||
}
|
||||
|
||||
describe("widgets/opendtu/component", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("renders placeholders while loading", () => {
|
||||
useWidgetAPI.mockReturnValue({ data: undefined, error: undefined });
|
||||
|
||||
const { container } = renderWithProviders(<Component service={{ widget: { type: "opendtu" } }} />, {
|
||||
settings: { hideErrors: false },
|
||||
});
|
||||
|
||||
expect(container.querySelectorAll(".service-block")).toHaveLength(4);
|
||||
expect(screen.getByText("opendtu.yieldDay")).toBeInTheDocument();
|
||||
expect(screen.getByText("opendtu.relativePower")).toBeInTheDocument();
|
||||
expect(screen.getByText("opendtu.absolutePower")).toBeInTheDocument();
|
||||
expect(screen.getByText("opendtu.limit")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders error UI when endpoint errors", () => {
|
||||
useWidgetAPI.mockReturnValue({ data: undefined, error: { message: "nope" } });
|
||||
|
||||
renderWithProviders(<Component service={{ widget: { type: "opendtu" } }} />, { settings: { hideErrors: false } });
|
||||
|
||||
expect(screen.getAllByText(/widget\.api_error/i).length).toBeGreaterThan(0);
|
||||
expect(screen.getByText("nope")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders totals and computed relative power", () => {
|
||||
useWidgetAPI.mockReturnValue({
|
||||
data: {
|
||||
total: {
|
||||
YieldDay: { v: 12.4, u: "kWh" },
|
||||
Power: { v: 250, u: "W" },
|
||||
},
|
||||
inverters: [{ limit_absolute: 200 }, { limit_absolute: 300 }],
|
||||
},
|
||||
error: undefined,
|
||||
});
|
||||
|
||||
const { container } = renderWithProviders(<Component service={{ widget: { type: "opendtu" } }} />, {
|
||||
settings: { hideErrors: false },
|
||||
});
|
||||
|
||||
// yieldDay is rounded and has unit appended.
|
||||
expectBlockValue(container, "opendtu.yieldDay", "12kWh");
|
||||
// relative power is percent of power / totalLimit (250/500*100 = 50)
|
||||
expectBlockValue(container, "opendtu.relativePower", "50");
|
||||
expectBlockValue(container, "opendtu.absolutePower", "250W");
|
||||
expectBlockValue(container, "opendtu.limit", "500W");
|
||||
});
|
||||
});
|
||||
38
src/widgets/openmediavault/component.test.jsx
Normal file
38
src/widgets/openmediavault/component.test.jsx
Normal file
@@ -0,0 +1,38 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
const { ServicesGetStatus, SmartGetList, DownloaderGetDownloadList } = vi.hoisted(() => ({
|
||||
ServicesGetStatus: vi.fn(() => <div data-testid="services.getStatus" />),
|
||||
SmartGetList: vi.fn(() => <div data-testid="smart.getListBg" />),
|
||||
DownloaderGetDownloadList: vi.fn(() => <div data-testid="downloader.getDownloadList" />),
|
||||
}));
|
||||
|
||||
vi.mock("./methods/services_get_status", () => ({ default: ServicesGetStatus }));
|
||||
vi.mock("./methods/smart_get_list", () => ({ default: SmartGetList }));
|
||||
vi.mock("./methods/downloader_get_downloadlist", () => ({ default: DownloaderGetDownloadList }));
|
||||
|
||||
import Component from "./component";
|
||||
|
||||
describe("widgets/openmediavault/component", () => {
|
||||
it("routes services.getStatus method to ServicesGetStatus", () => {
|
||||
render(<Component service={{ widget: { type: "openmediavault", method: "services.getStatus" } }} />);
|
||||
expect(screen.getByTestId("services.getStatus")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("routes smart.getListBg method to SmartGetList", () => {
|
||||
render(<Component service={{ widget: { type: "openmediavault", method: "smart.getListBg" } }} />);
|
||||
expect(screen.getByTestId("smart.getListBg")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("routes downloader.getDownloadList method to DownloaderGetDownloadList", () => {
|
||||
render(<Component service={{ widget: { type: "openmediavault", method: "downloader.getDownloadList" } }} />);
|
||||
expect(screen.getByTestId("downloader.getDownloadList")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("returns null for unknown methods", () => {
|
||||
const { container } = render(<Component service={{ widget: { type: "openmediavault", method: "nope" } }} />);
|
||||
expect(container.firstChild).toBeNull();
|
||||
});
|
||||
});
|
||||
26
src/widgets/openwrt/component.test.jsx
Normal file
26
src/widgets/openwrt/component.test.jsx
Normal file
@@ -0,0 +1,26 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
const { Interface, System } = vi.hoisted(() => ({
|
||||
Interface: vi.fn(() => <div data-testid="openwrt.interface" />),
|
||||
System: vi.fn(() => <div data-testid="openwrt.system" />),
|
||||
}));
|
||||
|
||||
vi.mock("./methods/interface", () => ({ default: Interface }));
|
||||
vi.mock("./methods/system", () => ({ default: System }));
|
||||
|
||||
import Component from "./component";
|
||||
|
||||
describe("widgets/openwrt/component", () => {
|
||||
it("renders System when interfaceName is not set", () => {
|
||||
render(<Component service={{ widget: { type: "openwrt" } }} />);
|
||||
expect(screen.getByTestId("openwrt.system")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders Interface when interfaceName is set", () => {
|
||||
render(<Component service={{ widget: { type: "openwrt", interfaceName: "eth0" } }} />);
|
||||
expect(screen.getByTestId("openwrt.interface")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
86
src/widgets/opnsense/component.test.jsx
Normal file
86
src/widgets/opnsense/component.test.jsx
Normal file
@@ -0,0 +1,86 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { screen } from "@testing-library/react";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { renderWithProviders } from "test-utils/render-with-providers";
|
||||
import { findServiceBlockByLabel } from "test-utils/widget-assertions";
|
||||
|
||||
const { useWidgetAPI } = vi.hoisted(() => ({ useWidgetAPI: vi.fn() }));
|
||||
vi.mock("utils/proxy/use-widget-api", () => ({ default: useWidgetAPI }));
|
||||
|
||||
import Component from "./component";
|
||||
|
||||
function expectBlockValue(container, label, value) {
|
||||
const block = findServiceBlockByLabel(container, label);
|
||||
expect(block, `missing block for ${label}`).toBeTruthy();
|
||||
expect(block.textContent).toContain(String(value));
|
||||
}
|
||||
|
||||
describe("widgets/opnsense/component", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("renders placeholders while loading", () => {
|
||||
useWidgetAPI.mockReturnValue({ data: undefined, error: undefined });
|
||||
|
||||
const { container } = renderWithProviders(<Component service={{ widget: { type: "opnsense" } }} />, {
|
||||
settings: { hideErrors: false },
|
||||
});
|
||||
|
||||
expect(container.querySelectorAll(".service-block")).toHaveLength(4);
|
||||
expect(screen.getByText("opnsense.cpu")).toBeInTheDocument();
|
||||
expect(screen.getByText("opnsense.memory")).toBeInTheDocument();
|
||||
expect(screen.getByText("opnsense.wanUpload")).toBeInTheDocument();
|
||||
expect(screen.getByText("opnsense.wanDownload")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders error UI when either endpoint errors", () => {
|
||||
useWidgetAPI.mockImplementation((_widget, endpoint) => {
|
||||
if (endpoint === "activity") return { data: undefined, error: { message: "nope" } };
|
||||
return { data: undefined, error: undefined };
|
||||
});
|
||||
|
||||
renderWithProviders(<Component service={{ widget: { type: "opnsense" } }} />, { settings: { hideErrors: false } });
|
||||
|
||||
expect(screen.getAllByText(/widget\.api_error/i).length).toBeGreaterThan(0);
|
||||
expect(screen.getByText("nope")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("parses activity headers and renders WAN rx/tx for selected interface", () => {
|
||||
useWidgetAPI.mockImplementation((_widget, endpoint) => {
|
||||
if (endpoint === "activity") {
|
||||
return {
|
||||
data: {
|
||||
headers: ["", "", "CPU: 75.00% idle", "Mem: 123M Active, 456M Inact, 789M Wired"],
|
||||
},
|
||||
error: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
if (endpoint === "interface") {
|
||||
return {
|
||||
data: {
|
||||
interfaces: {
|
||||
wan2: { "bytes transmitted": 1000, "bytes received": 2000 },
|
||||
wan: { "bytes transmitted": 1, "bytes received": 2 },
|
||||
},
|
||||
},
|
||||
error: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
return { data: undefined, error: undefined };
|
||||
});
|
||||
|
||||
const { container } = renderWithProviders(<Component service={{ widget: { type: "opnsense", wan: "wan2" } }} />, {
|
||||
settings: { hideErrors: false },
|
||||
});
|
||||
|
||||
expectBlockValue(container, "opnsense.cpu", "25.00");
|
||||
expectBlockValue(container, "opnsense.memory", "123M");
|
||||
expectBlockValue(container, "opnsense.wanUpload", 1000);
|
||||
expectBlockValue(container, "opnsense.wanDownload", 2000);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user