test: cover glances widget internal modules

This commit is contained in:
shamoon
2026-02-04 10:37:58 -08:00
parent 0b332f95f4
commit 85116bfb02
16 changed files with 402 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
// @vitest-environment jsdom
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
import Block from "./block";
describe("widgets/glances/components/block", () => {
it("renders children with the given absolute position classes", () => {
render(
<Block position="top-1 left-2">
<div>hi</div>
</Block>,
);
const el = screen.getByText("hi").parentElement;
expect(el).toHaveClass("absolute");
expect(el).toHaveClass("top-1");
expect(el).toHaveClass("left-2");
});
});

View File

@@ -0,0 +1,31 @@
// @vitest-environment jsdom
import { render, screen } from "@testing-library/react";
import React from "react";
import { describe, expect, it, vi } from "vitest";
vi.mock("recharts", () => ({
ResponsiveContainer: ({ children }) => <div data-testid="ResponsiveContainer">{children}</div>,
AreaChart: ({ children }) => {
// Filter out raw SVG elements (defs/linearGradient/stop) so jsdom doesn't warn.
const kept = React.Children.toArray(children).filter((child) => typeof child?.type === "function");
return <div data-testid="AreaChart">{kept}</div>;
},
Area: ({ name, dataKey }) => <div data-testid="Area" data-name={name} data-key={dataKey} />,
Tooltip: ({ content }) => <div data-testid="Tooltip">{content}</div>,
}));
import Chart from "./chart";
describe("widgets/glances/components/chart", () => {
it("renders a single-series chart scaffold", () => {
render(<Chart dataPoints={[{ value: 1 }]} formatter={(v) => String(v)} label={["Series"]} />);
expect(screen.getByTestId("ResponsiveContainer")).toBeInTheDocument();
expect(screen.getByTestId("AreaChart")).toBeInTheDocument();
const area = screen.getByTestId("Area");
expect(area).toHaveAttribute("data-name", "Series");
expect(area).toHaveAttribute("data-key", "value");
expect(screen.getByTestId("Tooltip")).toBeInTheDocument();
});
});

View File

@@ -0,0 +1,38 @@
// @vitest-environment jsdom
import { render, screen } from "@testing-library/react";
import React from "react";
import { describe, expect, it, vi } from "vitest";
vi.mock("recharts", () => ({
ResponsiveContainer: ({ children }) => <div data-testid="ResponsiveContainer">{children}</div>,
AreaChart: ({ children, stackOffset }) => (
<div data-testid="AreaChart" data-stackoffset={stackOffset ?? ""}>
{
// Filter out raw SVG elements (defs/linearGradient/stop) so jsdom doesn't warn.
React.Children.toArray(children).filter((child) => typeof child?.type === "function")
}
</div>
),
Area: ({ name, dataKey }) => <div data-testid="Area" data-name={name} data-key={dataKey} />,
Tooltip: ({ content }) => <div data-testid="Tooltip">{content}</div>,
}));
import ChartDual from "./chart_dual";
describe("widgets/glances/components/chart_dual", () => {
it("renders a dual-series chart scaffold", () => {
render(
<ChartDual dataPoints={[{ a: 1, b: 2 }]} formatter={(v) => String(v)} label={["A", "B"]} stackOffset="expand" />,
);
expect(screen.getByTestId("ResponsiveContainer")).toBeInTheDocument();
const chart = screen.getByTestId("AreaChart");
expect(chart).toHaveAttribute("data-stackoffset", "expand");
const areas = screen.getAllByTestId("Area");
expect(areas).toHaveLength(2);
expect(areas[0]).toHaveAttribute("data-key", "a");
expect(areas[1]).toHaveAttribute("data-key", "b");
});
});

View File

@@ -0,0 +1,37 @@
// @vitest-environment jsdom
import { screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
import { renderWithProviders } from "test-utils/render-with-providers";
import Container from "./container";
describe("widgets/glances/components/container", () => {
it("renders children and chart spacing when not in error state", () => {
renderWithProviders(
<Container chart>
<div>child</div>
</Container>,
{ settings: { hideErrors: false } },
);
expect(screen.getByText("child")).toBeInTheDocument();
expect(document.querySelector(".service-container")).toBeTruthy();
expect(document.querySelector(".h-\\[68px\\]")).toBeTruthy();
});
it("renders nothing when error is present and errors are hidden", () => {
const { container } = renderWithProviders(<Container error={{ message: "nope" }} widget={{ hideErrors: true }} />, {
settings: { hideErrors: true },
});
expect(container.firstChild).toBeNull();
});
it("renders the error message when error is present and errors are not hidden", () => {
renderWithProviders(<Container error={{ message: "nope" }} widget={{ hideErrors: false }} />, {
settings: { hideErrors: false },
});
expect(screen.getByText("widget.api_error")).toBeInTheDocument();
});
});

View File

@@ -0,0 +1,29 @@
// @vitest-environment jsdom
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
import CustomTooltip from "./custom_tooltip";
describe("widgets/glances/components/custom_tooltip", () => {
it("returns null when inactive", () => {
const { container } = render(<CustomTooltip active={false} payload={[]} formatter={(v) => String(v)} />);
expect(container.firstChild).toBeNull();
});
it("renders formatted values and series names when active", () => {
render(
<CustomTooltip
active
formatter={(v) => `v=${v}`}
payload={[
{ value: 1, name: "A" },
{ value: 2, name: "B" },
]}
/>,
);
expect(screen.getByText("v=1 A")).toBeInTheDocument();
expect(screen.getByText("v=2 B")).toBeInTheDocument();
});
});

View File

@@ -0,0 +1,13 @@
// @vitest-environment jsdom
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
import Error from "./error";
describe("widgets/glances/components/error", () => {
it("renders the standard widget api error message", () => {
render(<Error />);
expect(screen.getByText("widget.api_error")).toBeInTheDocument();
});
});

View File

@@ -0,0 +1,24 @@
// @vitest-environment jsdom
import { screen } from "@testing-library/react";
import { 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 }));
// Avoid pulling Next/Image + ThemeContext requirements into these unit tests.
vi.mock("components/resolvedicon", () => ({ default: () => <span data-testid="resolvedicon" /> }));
import Component from "./containers";
describe("widgets/glances/metrics/containers", () => {
it("renders a placeholder while loading", () => {
useWidgetAPI.mockReturnValue({ data: undefined, error: undefined });
renderWithProviders(<Component service={{ widget: { chart: false, version: 3 } }} />, {
settings: { hideErrors: false },
});
expect(screen.getByText("-")).toBeInTheDocument();
});
});

View File

@@ -0,0 +1,22 @@
// @vitest-environment jsdom
import { screen } from "@testing-library/react";
import { 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 }));
vi.mock("next/dynamic", () => ({ default: () => () => null }));
import Component from "./cpu";
describe("widgets/glances/metrics/cpu", () => {
it("renders a placeholder while loading", () => {
useWidgetAPI.mockReturnValue({ data: undefined, error: undefined });
renderWithProviders(<Component service={{ widget: { chart: false, version: 3, pointsLimit: 3 } }} />, {
settings: { hideErrors: false },
});
expect(screen.getByText("-")).toBeInTheDocument();
});
});

View File

@@ -0,0 +1,25 @@
// @vitest-environment jsdom
import { screen } from "@testing-library/react";
import { 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 }));
vi.mock("next/dynamic", () => ({ default: () => () => null }));
import Component from "./disk";
describe("widgets/glances/metrics/disk", () => {
it("renders a placeholder while loading", () => {
useWidgetAPI.mockReturnValue({ data: undefined, error: undefined });
renderWithProviders(
<Component service={{ widget: { chart: false, version: 3, pointsLimit: 3, metric: "disk:sda" } }} />,
{
settings: { hideErrors: false },
},
);
expect(screen.getByText("-")).toBeInTheDocument();
});
});

View File

@@ -0,0 +1,25 @@
// @vitest-environment jsdom
import { screen } from "@testing-library/react";
import { 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 }));
vi.mock("next/dynamic", () => ({ default: () => () => null }));
import Component from "./fs";
describe("widgets/glances/metrics/fs", () => {
it("renders a placeholder while loading", () => {
useWidgetAPI.mockReturnValue({ data: undefined, error: undefined });
renderWithProviders(
<Component service={{ widget: { chart: false, version: 3, pointsLimit: 3, metric: "fs:/mnt" } }} />,
{
settings: { hideErrors: false },
},
);
expect(screen.getByText("-")).toBeInTheDocument();
});
});

View File

@@ -0,0 +1,25 @@
// @vitest-environment jsdom
import { screen } from "@testing-library/react";
import { 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 }));
vi.mock("next/dynamic", () => ({ default: () => () => null }));
import Component from "./gpu";
describe("widgets/glances/metrics/gpu", () => {
it("renders a placeholder while loading", () => {
useWidgetAPI.mockReturnValue({ data: undefined, error: undefined });
renderWithProviders(
<Component service={{ widget: { chart: false, version: 3, pointsLimit: 3, metric: "gpu:gpu0" } }} />,
{
settings: { hideErrors: false },
},
);
expect(screen.getByText("-")).toBeInTheDocument();
});
});

View File

@@ -0,0 +1,20 @@
// @vitest-environment jsdom
import { 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 "./info";
describe("widgets/glances/metrics/info", () => {
it("renders a placeholder while loading", () => {
useWidgetAPI.mockReturnValue({ data: undefined, error: undefined });
renderWithProviders(<Component service={{ widget: { chart: false, version: 3 } }} />, {
settings: { hideErrors: false },
});
expect(document.querySelector(".service-container")).toBeTruthy();
});
});

View File

@@ -0,0 +1,22 @@
// @vitest-environment jsdom
import { screen } from "@testing-library/react";
import { 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 }));
vi.mock("next/dynamic", () => ({ default: () => () => null }));
import Component from "./memory";
describe("widgets/glances/metrics/memory", () => {
it("renders a placeholder while loading", () => {
useWidgetAPI.mockReturnValue({ data: undefined, error: undefined });
renderWithProviders(<Component service={{ widget: { chart: false, version: 3, pointsLimit: 3 } }} />, {
settings: { hideErrors: false },
});
expect(screen.getByText("-")).toBeInTheDocument();
});
});

View File

@@ -0,0 +1,23 @@
// @vitest-environment jsdom
import { screen } from "@testing-library/react";
import { 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 }));
vi.mock("next/dynamic", () => ({ default: () => () => null }));
import Component from "./net";
describe("widgets/glances/metrics/net", () => {
it("renders a placeholder while loading", () => {
useWidgetAPI.mockReturnValue({ data: undefined, error: undefined });
renderWithProviders(
<Component service={{ widget: { chart: false, version: 3, pointsLimit: 3, metric: "net:eth0" } }} />,
{ settings: { hideErrors: false } },
);
expect(screen.getByText("-")).toBeInTheDocument();
});
});

View File

@@ -0,0 +1,22 @@
// @vitest-environment jsdom
import { screen } from "@testing-library/react";
import { 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 }));
vi.mock("components/resolvedicon", () => ({ default: () => <span data-testid="resolvedicon" /> }));
import Component from "./process";
describe("widgets/glances/metrics/process", () => {
it("renders a placeholder while loading", () => {
useWidgetAPI.mockReturnValue({ data: undefined, error: undefined });
renderWithProviders(<Component service={{ widget: { chart: false, version: 3 } }} />, {
settings: { hideErrors: false },
});
expect(screen.getByText("-")).toBeInTheDocument();
});
});

View File

@@ -0,0 +1,25 @@
// @vitest-environment jsdom
import { screen } from "@testing-library/react";
import { 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 }));
vi.mock("next/dynamic", () => ({ default: () => () => null }));
import Component from "./sensor";
describe("widgets/glances/metrics/sensor", () => {
it("renders a placeholder while loading", () => {
useWidgetAPI.mockReturnValue({ data: undefined, error: undefined });
renderWithProviders(
<Component service={{ widget: { chart: false, version: 3, pointsLimit: 3, metric: "sensor:CPU" } }} />,
{
settings: { hideErrors: false },
},
);
expect(screen.getByText("-")).toBeInTheDocument();
});
});