From 152888d611fa25d2a30f34a6185c7f155fad8760 Mon Sep 17 00:00:00 2001
From: shamoon <4887959+shamoon@users.noreply.github.com>
Date: Mon, 16 Feb 2026 08:43:06 -0800
Subject: [PATCH] Enhancement: cover more basic statuses in containers list
(#6334)
---
src/widgets/glances/metrics/containers.jsx | 2 +
.../glances/metrics/containers.test.jsx | 83 +++++++++++++++++++
2 files changed, 85 insertions(+)
diff --git a/src/widgets/glances/metrics/containers.jsx b/src/widgets/glances/metrics/containers.jsx
index 93ecbc28f..8968305a8 100644
--- a/src/widgets/glances/metrics/containers.jsx
+++ b/src/widgets/glances/metrics/containers.jsx
@@ -8,7 +8,9 @@ import useWidgetAPI from "utils/proxy/use-widget-api";
const statusMap = {
running: ,
+ healthy: ,
paused: ,
+ stopped: ,
};
const defaultInterval = 1000;
diff --git a/src/widgets/glances/metrics/containers.test.jsx b/src/widgets/glances/metrics/containers.test.jsx
index b3a8dbeb4..c7c8a71bf 100644
--- a/src/widgets/glances/metrics/containers.test.jsx
+++ b/src/widgets/glances/metrics/containers.test.jsx
@@ -11,6 +11,15 @@ vi.mock("utils/proxy/use-widget-api", () => ({ default: useWidgetAPI }));
// Avoid pulling Next/Image + ThemeContext requirements into these unit tests.
vi.mock("components/resolvedicon", () => ({ default: () => }));
+vi.mock("next-i18next", () => ({
+ useTranslation: () => ({
+ t: (key, opts) => (key === "common.bytes" ? `${key}:${opts?.value}` : key),
+ }),
+}));
+
+// Avoid pulling Next/Image + ThemeContext requirements into these unit tests.
+vi.mock("components/resolvedicon", () => ({ default: () => }));
+
import Component from "./containers";
describe("widgets/glances/metrics/containers", () => {
@@ -21,4 +30,78 @@ describe("widgets/glances/metrics/containers", () => {
});
expect(screen.getByText("-")).toBeInTheDocument();
});
+
+ it("renders a placeholder while loading", () => {
+ useWidgetAPI.mockReturnValue({ data: undefined, error: undefined });
+ renderWithProviders(, {
+ settings: { hideErrors: false },
+ });
+ expect(screen.getByText("-")).toBeInTheDocument();
+ });
+
+ it("renders nothing when there is an error", () => {
+ useWidgetAPI.mockReturnValue({ data: undefined, error: new Error("fail") });
+ renderWithProviders(, {
+ settings: { hideErrors: false },
+ });
+ expect(screen.queryByText("resources.cpu")).not.toBeInTheDocument();
+ expect(screen.queryByText("-")).not.toBeInTheDocument();
+ });
+
+ it("renders container rows using v3 keys and formats values", () => {
+ useWidgetAPI.mockReturnValue({
+ data: [
+ {
+ Id: "one",
+ Status: "running",
+ name: "alpha",
+ cpu_percent: 12.34,
+ memory: { usage: 1000, inactive_file: 400 },
+ },
+ {
+ Id: "two",
+ Status: "paused",
+ name: "beta",
+ cpu_percent: 99.99,
+ memory: { usage: 2000, inactive_file: 1000 },
+ },
+ ],
+ error: undefined,
+ });
+
+ renderWithProviders(, {
+ settings: { hideErrors: false },
+ });
+
+ // data.splice(1) keeps only one item when chart is false
+ expect(screen.getByText("resources.cpu")).toBeInTheDocument();
+ expect(screen.getByText("resources.mem")).toBeInTheDocument();
+
+ expect(screen.getByText("alpha")).toBeInTheDocument();
+ expect(screen.queryByText("beta")).not.toBeInTheDocument();
+
+ expect(screen.getByText("12.3%")).toBeInTheDocument();
+ expect(screen.getByText("common.bytes:600")).toBeInTheDocument();
+ expect(screen.getAllByTestId("resolvedicon")).toHaveLength(1);
+ });
+
+ it("limits rows to 5 when chart is enabled", () => {
+ const data = Array.from({ length: 6 }).map((_, index) => ({
+ Id: `id-${index}`,
+ Status: "healthy",
+ name: `item-${index}`,
+ cpu_percent: index + 0.1,
+ memory: { usage: 100 * (index + 1), inactive_file: 0 },
+ }));
+
+ useWidgetAPI.mockReturnValue({ data, error: undefined });
+
+ renderWithProviders(, {
+ settings: { hideErrors: false },
+ });
+
+ expect(screen.getByText("item-0")).toBeInTheDocument();
+ expect(screen.getByText("item-4")).toBeInTheDocument();
+ expect(screen.queryByText("item-5")).not.toBeInTheDocument();
+ });
});