Files
diegosouzapw--omniroute/tests/unit/ui/compression-settings-tab-consolidation.test.tsx
2026-07-13 13:39:12 +08:00

145 lines
5.1 KiB
TypeScript

// @vitest-environment jsdom
import React from "react";
import { act } from "react";
import { createRoot } from "react-dom/client";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
// next-intl → echo the key so we can assert on stable identifiers.
vi.mock("next-intl", () => ({
useTranslations: () => (key: string) => key,
}));
vi.mock("next/link", () => ({
default: ({ children, href }: { children: React.ReactNode; href: string }) => (
<a href={href}>{children}</a>
),
}));
vi.mock("@/shared/components", () => ({
Card: ({ children, className }: { children: React.ReactNode; className?: string }) => (
<div data-testid="card" className={className}>
{children}
</div>
),
Button: ({ children, onClick }: { children?: React.ReactNode; onClick?: () => void }) => (
<button onClick={onClick}>{children}</button>
),
}));
const CONFIG = {
enabled: true,
defaultMode: "standard",
autoTriggerTokens: 0,
cacheMinutes: 5,
preserveSystemPrompt: true,
comboOverrides: {},
cavemanConfig: {
enabled: true,
compressRoles: ["user"],
skipRules: [],
minMessageLength: 50,
preservePatterns: [],
intensity: "full",
},
cavemanOutputMode: { enabled: false, intensity: "full", autoClarity: true },
rtkConfig: { enabled: true, intensity: "standard" },
};
let container: HTMLDivElement;
let root: ReturnType<typeof createRoot> | undefined;
beforeEach(() => {
container = document.createElement("div");
document.body.appendChild(container);
vi.stubGlobal(
"fetch",
vi.fn((url: string) => {
const u = String(url);
if (u.includes("/api/settings/compression")) {
return Promise.resolve({ ok: true, json: () => Promise.resolve(CONFIG) });
}
if (u.includes("/api/compression/rules")) {
return Promise.resolve({ ok: true, json: () => Promise.resolve({ rules: [] }) });
}
return Promise.resolve({ ok: false, json: () => Promise.resolve(null) });
})
);
});
afterEach(() => {
act(() => root?.unmount());
root = undefined;
container.remove();
vi.unstubAllGlobals();
vi.restoreAllMocks();
});
async function renderTab() {
const { default: CompressionSettingsTab } =
await import("@/app/(dashboard)/dashboard/settings/components/CompressionSettingsTab");
await act(async () => {
root = createRoot(container);
root.render(<CompressionSettingsTab />);
});
// Drain the on-mount fetch → json → setState microtask chain.
await act(async () => {
await new Promise((resolve) => setTimeout(resolve, 0));
});
}
describe("CompressionSettingsTab — compression controls consolidation (T11)", () => {
it("renders the read-only TokenSaver summary that links to the unified panel", async () => {
await renderTab();
const hrefs = Array.from(container.querySelectorAll("a")).map((a) => a.getAttribute("href"));
expect(hrefs).toContain("/dashboard/context/settings");
expect(container.textContent).toContain("tokenSaverTitle");
});
it("does not render a duplicate caveman engine on/off toggle (panel owns on/off)", async () => {
await renderTab();
const note = container.querySelector('[data-testid="caveman-panel-note"]');
expect(note).not.toBeNull();
// The note points users to the single-source panel...
expect(note?.textContent).toContain("/dashboard/context/settings");
// ...and the caveman header no longer carries its own enable toggle button.
expect(note?.querySelector("button")).toBeNull();
});
it("keeps the advanced caveman tuning the panel does not expose", async () => {
await renderTab();
expect(container.textContent).toContain("compressionRoleUser");
expect(container.textContent).toContain("compressionSkipRules");
expect(container.textContent).toContain("compressionPreservePatterns");
});
it("renders the preserveSystemPrompt 3-way mode select reflecting the shim (T05/C5)", async () => {
await renderTab();
const select = container.querySelector<HTMLSelectElement>(
'[data-testid="preserve-system-mode-select"]'
);
expect(select).not.toBeNull();
const values = Array.from(select!.querySelectorAll("option")).map((o) => o.value);
expect(values).toEqual(["always", "whenNoCache", "never"]);
// CONFIG has preserveSystemPrompt: true and no explicit mode → shim renders "always".
expect(select!.value).toBe("always");
});
it("saves the chosen mode via PUT (T05/C5)", async () => {
await renderTab();
const select = container.querySelector<HTMLSelectElement>(
'[data-testid="preserve-system-mode-select"]'
);
await act(async () => {
select!.value = "never";
select!.dispatchEvent(new Event("change", { bubbles: true }));
await new Promise((resolve) => setTimeout(resolve, 0));
});
const putCall = (globalThis.fetch as ReturnType<typeof vi.fn>).mock.calls.find(
([, init]) => (init as RequestInit | undefined)?.method === "PUT"
);
expect(putCall).toBeTruthy();
const body = JSON.parse(String((putCall![1] as RequestInit).body));
expect(body.preserveSystemPromptMode).toBe("never");
});
});