mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-18 04:42:30 +03:00
Resynced onto the release tip. Two fixes applied during boarding: (1) the branch forked before the recent optionalDependencies placement of @huggingface/transformers and onnxruntime-node — its own diff re-added both into "dependencies" as duplicates alongside the real new dependency (react18-json-view); removed the duplicates, ran npm install to sync the lockfile. (2) config/quality/dependency-allowlist.json referenced the wrong package name (react-json-view-lite, an earlier iteration per the PR body) — the code actually imports react18-json-view; fixed the allowlist entry to match. RequestLoggerDetail.tsx crossed its frozen file-size cap (1018->1111); rebaselined with a note — the PR does split out the new logic (RequestLoggerDetail.sections.tsx, JsonTreeExpandControls.tsx, useTimestampTitles.ts, jsonTreeExpandStore.ts, all well under cap), the growth here is irreducible wiring. typecheck:core, check:dashboard-typecheck, check:file-size, check-deps all green after resync; 8/8 vitest + 11/11 native tests pass. Nice, well-structured 6-commit feature with full i18n and good test coverage. Thanks!
82 lines
2.8 KiB
TypeScript
82 lines
2.8 KiB
TypeScript
// @vitest-environment jsdom
|
|
//
|
|
// Regression guard: PayloadSection rendered every payload (request/response
|
|
// bodies, pipeline stages) as a flat <pre> text dump, forcing operators to
|
|
// scroll through the entire raw JSON to find anything in a nested request.
|
|
// It now renders parseable JSON payloads as a collapsible tree
|
|
// (react-json-view-lite) instead, while still falling back to the plain
|
|
// <pre> dump for anything that isn't valid JSON (e.g. a captured error
|
|
// string), since the `json` prop is display text that isn't guaranteed
|
|
// parseable.
|
|
import React, { act } from "react";
|
|
import { createRoot, type Root } from "react-dom/client";
|
|
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
|
|
vi.mock("next-intl", () => ({
|
|
useTranslations: () => (key: string) => key,
|
|
}));
|
|
|
|
vi.mock("@/shared/hooks/useTheme", () => ({
|
|
useTheme: () => ({ isDark: false }),
|
|
}));
|
|
|
|
const { PayloadSection } =
|
|
await import("../../../src/shared/components/RequestLoggerDetail.sections.tsx");
|
|
|
|
let container: HTMLDivElement;
|
|
let root: Root;
|
|
|
|
beforeEach(() => {
|
|
container = document.createElement("div");
|
|
document.body.appendChild(container);
|
|
root = createRoot(container);
|
|
});
|
|
|
|
afterEach(() => {
|
|
act(() => root.unmount());
|
|
container.remove();
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
function renderPayload(json: string) {
|
|
act(() => {
|
|
root.render(
|
|
<PayloadSection title="Test Payload" json={json} onCopy={vi.fn().mockResolvedValue(true)} />
|
|
);
|
|
});
|
|
}
|
|
|
|
describe("PayloadSection collapsible JSON rendering", () => {
|
|
it("renders a valid JSON object payload as a collapsible tree, not a flat <pre> dump", () => {
|
|
renderPayload(JSON.stringify({ model: "gpt-5.6-luna", input: [{ role: "user" }] }, null, 2));
|
|
|
|
expect(container.querySelector("pre")).toBeNull();
|
|
// react-json-view-lite renders expand/collapse controls for object nodes.
|
|
expect(container.querySelectorAll("[aria-label]").length).toBeGreaterThan(0);
|
|
expect(container.textContent).toContain("model");
|
|
expect(container.textContent).toContain("gpt-5.6-luna");
|
|
});
|
|
|
|
it("renders a valid JSON array payload as a collapsible tree", () => {
|
|
renderPayload(JSON.stringify([{ type: "output_text", text: "answer" }], null, 2));
|
|
|
|
expect(container.querySelector("pre")).toBeNull();
|
|
expect(container.textContent).toContain("output_text");
|
|
});
|
|
|
|
it("falls back to the plain <pre> dump for non-JSON payload text", () => {
|
|
renderPayload("Upstream request failed: Model is unavailable.");
|
|
|
|
const pre = container.querySelector("pre");
|
|
expect(pre).not.toBeNull();
|
|
expect(pre?.textContent).toBe("Upstream request failed: Model is unavailable.");
|
|
});
|
|
|
|
it("falls back to the plain <pre> dump for a JSON primitive (not an object/array)", () => {
|
|
renderPayload(JSON.stringify("just a string"));
|
|
|
|
const pre = container.querySelector("pre");
|
|
expect(pre).not.toBeNull();
|
|
});
|
|
});
|