mirror of
https://github.com/MeshCore-Beacon/beacon-web.git
synced 2026-10-18 23:00:37 +00:00
Port the qualified web preview at c41e6fa8940fba929704bc2f9a94f119fef4a4ca onto
org dev b4d498e697. Preserve upstream changes and
branch policies; keep the independent private Collector service separate.
Preview-Version: 2.2.1-n30nex.1
Preview-Revision: c41e6fa8940fba929704bc2f9a94f119fef4a4ca
47 lines
3.0 KiB
TypeScript
47 lines
3.0 KiB
TypeScript
import { describe, it, expect, vi } from "vitest";
|
|
import { render, screen, fireEvent } from "@testing-library/react";
|
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
import { CollectedNodeTelemetry } from "../../../src/features/nodes/CollectedNodeTelemetry";
|
|
import { getCollectedNodeTelemetry } from "../../../src/api/client";
|
|
|
|
vi.mock("../../../src/api/client", () => ({ getCollectedNodeTelemetry: vi.fn() }));
|
|
const key = "ab".repeat(32);
|
|
const collector = "cd".repeat(32);
|
|
function mount() { return render(<QueryClientProvider client={new QueryClient({ defaultOptions: { queries: { retry: false } } })}><CollectedNodeTelemetry publicKey={key} active /></QueryClientProvider>); }
|
|
|
|
describe("collector telemetry", () => {
|
|
it("renders status-only and sensor-only reports with absent or null optional collections", async () => {
|
|
vi.mocked(getCollectedNodeTelemetry).mockResolvedValue({ limit: 500, items: [
|
|
{ nodeKey: key, collectorKey: collector, radioKey: "ef".repeat(32), receivedAt: Date.now(), values: { batteryMv: 4120 }, sensors: null },
|
|
{ nodeKey: key, collectorKey: collector, radioKey: "ef".repeat(32), receivedAt: Date.now(), values: null, sensors: [{ channel: 2, kind: "temperature", value: 0, unit: "C" }] },
|
|
] });
|
|
mount();
|
|
await screen.findByText("4.12 V");
|
|
expect(screen.getByText("0 C")).toBeInTheDocument();
|
|
});
|
|
it("shows an initial service failure and lets a retry load actual readings", async () => {
|
|
vi.mocked(getCollectedNodeTelemetry).mockRejectedValueOnce(new Error("unavailable")).mockResolvedValue({ limit: 500, items: [
|
|
{ nodeKey: key, collectorKey: collector, radioKey: "ef".repeat(32), receivedAt: Date.now(), values: { batteryMv: 4120 }, sensors: [] },
|
|
] });
|
|
mount();
|
|
expect(await screen.findByRole("status")).toHaveTextContent("Repeater telemetry could not be loaded.");
|
|
fireEvent.click(screen.getByRole("button", { name: "Retry" }));
|
|
await screen.findByText("4.12 V");
|
|
expect(screen.queryByText("Repeater telemetry could not be loaded.")).not.toBeInTheDocument();
|
|
});
|
|
it("keeps environmental channels and collector attribution without inventing battery percent", async () => {
|
|
vi.mocked(getCollectedNodeTelemetry).mockResolvedValue({ limit: 500, items: [
|
|
{ nodeKey: key, collectorKey: collector, radioKey: "ef".repeat(32), receivedAt: Date.now(), intervalHours: 1,
|
|
values: { batteryMv: 4120 }, sensors: [{ channel: 2, kind: "temperature", value: 21.5, unit: "C" }] },
|
|
{ nodeKey: "12".repeat(32), collectorKey: collector, radioKey: "ef".repeat(32), receivedAt: Date.now(), values: { batteryMv: 9900 }, sensors: [] },
|
|
] });
|
|
mount();
|
|
await screen.findByText("21.5 C");
|
|
expect(screen.getByText("Temperature · Ch 2")).toBeInTheDocument();
|
|
expect(screen.getByText("4.12 V")).toBeInTheDocument();
|
|
expect(screen.queryByText("9.9 V")).not.toBeInTheDocument();
|
|
expect(screen.getAllByTitle(collector)).toHaveLength(2);
|
|
expect(screen.queryByText(/%/)).not.toBeInTheDocument();
|
|
});
|
|
});
|