test(coverage): bootstrap vitest unit infra and add tests at 90%+ per file (#1245) (#1269)

* test(coverage): bootstrap vitest unit infra and add tests at 90%+ per file (#1245)

Establishes the unit-test runtime AGENTS.md mandates: a vitest "unit"
project alongside the existing storybook project, RTL + jest-dom +
happy-dom, a Mantine-aware render helper, and a 90%-line per-file
coverage gate enforced by CI. Adds 66 test files covering all 62
components under elements/groups/screens/views, plus core/mcp and
clients/web/src/utils. Total: 577 tests, 98.7% line coverage globally.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(coverage): address PR #1269 review feedback

- AGENTS.md: correct coverage gate description (lines ≥ 90, statements ≥ 85,
  functions ≥ 80, branches ≥ 50) with rationale for the relaxed branch
  threshold
- InspectorView.test.tsx: document what the Math.random() mock values
  (0.1 / 0.99) control vs. STUB_SUCCESS_RATE in InspectorView.tsx
- vite.config.ts / tsconfig.test.json: drop unused `globals: true` and the
  `vitest/globals` type now that every test file imports describe/it/expect/vi
  explicitly; manual `afterEach(cleanup)` in setup.ts remains required because
  testing-library auto-cleanup relies on globalThis.afterEach

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Cliff Hall 2026-05-01 15:15:32 -04:00 • committed by GitHub
commit 75f74d64c1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -0,0 +1,328 @@
import { describe, it, expect, vi } from "vitest";
import userEvent from "@testing-library/user-event";
import { renderWithMantine, screen } from "../../../test/renderWithMantine";
import { ExperimentalFeaturesPanel } from "./ExperimentalFeaturesPanel";
import type { RequestHistoryItem } from "./ExperimentalFeaturesPanel";
const baseProps = {
serverExperimental: undefined,
clientExperimental: undefined,
requestDraft:
'{"jsonrpc":"2.0","id":1,"method":"experimental/x","params":{}}',
customHeaders: [],
requestHistory: [],
onToggleClientCapability: vi.fn(),
onRequestChange: vi.fn(),
onSendRequest: vi.fn(),
onAddHeader: vi.fn(),
onRemoveHeader: vi.fn(),
onHeaderChange: vi.fn(),
onCopyResponse: vi.fn(),
onTestCapability: vi.fn(),
};
describe("ExperimentalFeaturesPanel", () => {
it("renders the warning alert and section titles", () => {
renderWithMantine(<ExperimentalFeaturesPanel {...baseProps} />);
expect(
screen.getByText(
"These features are non-standard and may change or be removed.",
),
).toBeInTheDocument();
expect(
screen.getByText("Server Experimental Capabilities:"),
).toBeInTheDocument();
expect(
screen.getByText("Client Experimental Capabilities:"),
).toBeInTheDocument();
expect(screen.getByText("Advanced JSON-RPC Tester")).toBeInTheDocument();
});
it("shows the empty state when no server experimental capabilities are present", () => {
renderWithMantine(<ExperimentalFeaturesPanel {...baseProps} />);
expect(
screen.getByText("No experimental capabilities"),
).toBeInTheDocument();
});
it("renders server capability cards with description and methods", () => {
renderWithMantine(
<ExperimentalFeaturesPanel
{...baseProps}
serverExperimental={{
"experimental/streaming": {
description: "Supports streaming responses",
methods: [
"experimental/stream.start",
"experimental/stream.cancel",
],
},
}}
/>,
);
expect(screen.getByText("experimental/streaming")).toBeInTheDocument();
expect(
screen.getByText("Supports streaming responses"),
).toBeInTheDocument();
expect(
screen.getByText(
"Methods: experimental/stream.start, experimental/stream.cancel",
),
).toBeInTheDocument();
});
it("renders the capability card without description or methods when not provided", () => {
renderWithMantine(
<ExperimentalFeaturesPanel
{...baseProps}
serverExperimental={{
"experimental/bare": {},
}}
/>,
);
expect(screen.getByText("experimental/bare")).toBeInTheDocument();
expect(screen.queryByText(/^Methods:/)).not.toBeInTheDocument();
});
it("invokes onTestCapability when Test is clicked on a capability card", async () => {
const user = userEvent.setup();
const onTestCapability = vi.fn();
renderWithMantine(
<ExperimentalFeaturesPanel
{...baseProps}
onTestCapability={onTestCapability}
serverExperimental={{
"experimental/echo": { description: "Echoes" },
}}
/>,
);
await user.click(screen.getByRole("button", { name: /Test/ }));
expect(onTestCapability).toHaveBeenCalledWith("experimental/echo");
});
it("renders the known client capability toggles with their friendly labels", () => {
renderWithMantine(<ExperimentalFeaturesPanel {...baseProps} />);
expect(
screen.getByRole("checkbox", { name: "Custom sampling" }),
).toBeInTheDocument();
expect(
screen.getByRole("checkbox", { name: "Batch requests" }),
).toBeInTheDocument();
});
it("marks a known client capability checkbox as checked when enabled", () => {
renderWithMantine(
<ExperimentalFeaturesPanel
{...baseProps}
clientExperimental={{ "experimental/batchRequests": {} }}
/>,
);
const sampling = screen.getByRole("checkbox", {
name: "Custom sampling",
}) as HTMLInputElement;
const batch = screen.getByRole("checkbox", {
name: "Batch requests",
}) as HTMLInputElement;
expect(sampling.checked).toBe(false);
expect(batch.checked).toBe(true);
});
it("renders unknown client capabilities by their key", () => {
renderWithMantine(
<ExperimentalFeaturesPanel
{...baseProps}
clientExperimental={{
"experimental/customSampling": {},
"experimental/futureFeatureXyz": {},
}}
/>,
);
expect(
screen.getByRole("checkbox", { name: "experimental/futureFeatureXyz" }),
).toBeInTheDocument();
});
it("invokes onToggleClientCapability when a client checkbox is clicked", async () => {
const user = userEvent.setup();
const onToggleClientCapability = vi.fn();
renderWithMantine(
<ExperimentalFeaturesPanel
{...baseProps}
onToggleClientCapability={onToggleClientCapability}
/>,
);
await user.click(screen.getByRole("checkbox", { name: "Custom sampling" }));
expect(onToggleClientCapability).toHaveBeenCalledWith(
"experimental/customSampling",
true,
);
});
it("invokes onAddHeader when + Add Header is clicked", async () => {
const user = userEvent.setup();
const onAddHeader = vi.fn();
renderWithMantine(
<ExperimentalFeaturesPanel {...baseProps} onAddHeader={onAddHeader} />,
);
await user.click(screen.getByRole("button", { name: "+ Add Header" }));
expect(onAddHeader).toHaveBeenCalledTimes(1);
});
it("renders custom header rows and invokes onHeaderChange when key changes", async () => {
const user = userEvent.setup();
const onHeaderChange = vi.fn();
renderWithMantine(
<ExperimentalFeaturesPanel
{...baseProps}
customHeaders={[{ key: "X-Auth", value: "Bearer 1" }]}
onHeaderChange={onHeaderChange}
/>,
);
const keyInput = screen.getByDisplayValue("X-Auth");
await user.type(keyInput, "Z");
expect(onHeaderChange).toHaveBeenCalled();
const lastCall =
onHeaderChange.mock.calls[onHeaderChange.mock.calls.length - 1];
expect(lastCall[0]).toBe(0);
expect(lastCall[2]).toBe("Bearer 1");
});
it("invokes onHeaderChange when value changes for a header", async () => {
const user = userEvent.setup();
const onHeaderChange = vi.fn();
renderWithMantine(
<ExperimentalFeaturesPanel
{...baseProps}
customHeaders={[{ key: "X-Auth", value: "abc" }]}
onHeaderChange={onHeaderChange}
/>,
);
const valueInput = screen.getByDisplayValue("abc");
await user.type(valueInput, "Z");
expect(onHeaderChange).toHaveBeenCalled();
const lastCall =
onHeaderChange.mock.calls[onHeaderChange.mock.calls.length - 1];
expect(lastCall[0]).toBe(0);
expect(lastCall[1]).toBe("X-Auth");
});
it("invokes onRemoveHeader with the header index when the remove icon is clicked", async () => {
const user = userEvent.setup();
const onRemoveHeader = vi.fn();
renderWithMantine(
<ExperimentalFeaturesPanel
{...baseProps}
customHeaders={[
{ key: "X-Auth", value: "abc" },
{ key: "X-Other", value: "def" },
]}
onRemoveHeader={onRemoveHeader}
/>,
);
const removeButtons = screen.getAllByRole("button", { name: "✕" });
await user.click(removeButtons[1]);
expect(onRemoveHeader).toHaveBeenCalledWith(1);
});
it("invokes onRequestChange when the request textarea changes", async () => {
const user = userEvent.setup();
const onRequestChange = vi.fn();
renderWithMantine(
<ExperimentalFeaturesPanel
{...baseProps}
requestDraft=""
onRequestChange={onRequestChange}
/>,
);
const textarea = screen.getByLabelText("Request");
await user.type(textarea, "x");
expect(onRequestChange).toHaveBeenCalledWith("x");
});
it("invokes onSendRequest when Send Request is clicked", async () => {
const user = userEvent.setup();
const onSendRequest = vi.fn();
renderWithMantine(
<ExperimentalFeaturesPanel
{...baseProps}
onSendRequest={onSendRequest}
/>,
);
await user.click(screen.getByRole("button", { name: "Send Request" }));
expect(onSendRequest).toHaveBeenCalledTimes(1);
});
it("renders a successful response without an Error badge", () => {
renderWithMantine(
<ExperimentalFeaturesPanel
{...baseProps}
response={{
jsonrpc: "2.0",
id: 1,
result: { ok: true },
}}
/>,
);
expect(screen.getByText("Response")).toBeInTheDocument();
expect(screen.queryByText("Error")).not.toBeInTheDocument();
});
it("renders an error response with the Error badge", () => {
renderWithMantine(
<ExperimentalFeaturesPanel
{...baseProps}
response={{
jsonrpc: "2.0",
id: 1,
error: { code: -32601, message: "Method not found" },
}}
/>,
);
expect(screen.getByText("Response")).toBeInTheDocument();
expect(screen.getByText("Error")).toBeInTheDocument();
});
it("invokes onCopyResponse when Copy is clicked", async () => {
const user = userEvent.setup();
const onCopyResponse = vi.fn();
renderWithMantine(
<ExperimentalFeaturesPanel
{...baseProps}
response={{ jsonrpc: "2.0", id: 1, result: { ok: true } }}
onCopyResponse={onCopyResponse}
/>,
);
await user.click(screen.getByRole("button", { name: "Copy" }));
expect(onCopyResponse).toHaveBeenCalledTimes(1);
});
it("renders the request history table when entries are present", () => {
const items: RequestHistoryItem[] = [
{
timestamp: new Date("2026-03-17T10:30:15Z"),
method: "experimental/metrics.get",
status: "success",
durationMs: 42,
},
{
timestamp: new Date("2026-03-17T10:29:50Z"),
method: "experimental/echo",
status: "error",
durationMs: 120,
},
];
renderWithMantine(
<ExperimentalFeaturesPanel {...baseProps} requestHistory={items} />,
);
expect(screen.getByText("Request History:")).toBeInTheDocument();
expect(screen.getByText("experimental/metrics.get")).toBeInTheDocument();
expect(screen.getByText("experimental/echo")).toBeInTheDocument();
expect(screen.getByText("42ms")).toBeInTheDocument();
expect(screen.getByText("120ms")).toBeInTheDocument();
});
it("does not render the history section when requestHistory is empty", () => {
renderWithMantine(<ExperimentalFeaturesPanel {...baseProps} />);
expect(screen.queryByText("Request History:")).not.toBeInTheDocument();
});
});