Files
OmniRoute/tests/unit/ui/omniglyphContextPage.test.tsx
Diego Rodrigues de Sa e Souza fd7e4c10e5 feat(compression): omniglyph engine (context-as-image, Fable 5 direct) — stack + single mode (#6556)
* feat(compression): dependência omniglyph (file:) + smoke de import

* feat(compression): engine omniglyph — contexto-como-imagem com gates fail-closed

* fix(compression): omniglyph adapter fail-open no transform (try/catch)

* feat(compression): registra omniglyph no registry e catálogo (single mode, stackPriority 90)

* feat(compression): modo único omniglyph (async), selecionar o modo é o enable

* feat(compression): plumbing supportsVision + providerTransport até os engines

* feat(compression): estimador de tokens image-aware — modo stacked mantém a saída do omniglyph

* docs(compression): corrige comentário do prefixo base64 no decode PNG (64 chars)

* feat(compression): registra omniglyph nas listas de modo/engine (db, combo, deriveDefaultPlan, mcp)

* feat(dashboard): dedicated OmniGlyph engine screen (context-as-image)

Adds a per-engine detail page at /dashboard/context/omniglyph, alongside the
other compression engines in the sidebar. Four sections: the economics (measured
savings), a REAL before→after (dense text vs the rendered PNG page, not a mockup),
the fail-closed gate flow, and the enable control wired to /api/settings/compression
(preview engine, off by default). Sidebar entry + i18n label across all locales.

* chore(compression): consume published omniglyph@^1.0.0 from the npm registry

Replaces the local file: dependency used during the preview phase — npm ci
now resolves omniglyph from the registry with integrity, unblocking CI.

* fix(compression): satisfy v3.8.47 quality gates for the omniglyph engine

- dependency-allowlist: approve omniglyph (own package, published from
  diegosouzapw/OmniGlyph; supply-chain review done by the maintainer)
- ladder maps (#6533 guard): rank omniglyph 80 (stackPriority 90, runs after
  every text engine) with expectedReductionFactor 0.35 (measured 0.23-0.33)
- drop the two explicit any casts in omniglyph tests (no-explicit-any is
  error-level in tests since #6218)

* chore(compression): rebaseline strategySelector for the omniglyph mode dispatch

+18 lines of cohesive dispatch/type wiring at the existing mode chokepoints
(sync no-op + async single-mode branch + providerTransport on the options
types) — not extractable without hiding the dispatch boundary, mirroring the
prior compression rebaselines. Also drops an unused eslint-disable directive
in image-aware-tokens.test.ts (warning-level red under --max-warnings 0).

* chore(quality): register inherited base tests in stryker tap.testFiles

masked-200-exhaustion-fallback-6427 and headroom-codex-quota-snapshot-6379
arrived via the base merge without their stryker registration —
check:mutation-test-coverage --strict requires covering tests to be listed.

* refactor(compression): keep omniglyph wiring under the complexity gate

- extract the async single-mode resolution to engines/omniglyphSingleMode.ts
  (runCompressionAsync was at complexity 17 after the mode branch; back <=15)
- split OmniglyphContextPageClient into section components (was 161 lines in
  one function; every function now under the 80-line cap)
- complexity baseline 2052->2053: the +1 is inherited base drift (the ratchet
  does not run on fast-path merges — same pattern as the v3.8.44/46
  rebaselines); this PR's own code is measured complexity-net-zero

* chore(quality): register 3 more inherited base tests in stryker tap.testFiles

route-guard-middleware-local-only, combo-diagnostics-trace and
idempotency-fusion-collision arrived via the latest base merge without their
stryker registration (fast-path merges skip check:mutation-test-coverage).

* chore(quality): cognitive-complexity baseline 883->884 (inherited base drift)

check:cognitive-complexity measures 884 identically on the pristine
origin/release/v3.8.47 tip and on this HEAD — the PR itself is
cognitive-net-zero (single-mode resolution extracted to its own module,
page client split into section components). Same inherited-drift pattern
as the v3.8.4x release rebaselines.

---------

Co-authored-by: diegosouzapw <diegosouzapw@devbox.local>
2026-07-08 07:56:44 -03:00

142 lines
5.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// @vitest-environment jsdom
import React, { act } from "react";
import { createRoot } from "react-dom/client";
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
import { SAMPLE_METRICS } from "../../../src/app/(dashboard)/dashboard/context/omniglyph/sampleData.ts";
// i18n is not resolved in vitest/jsdom; the page hardcodes its engine copy in English
// anyway (catalog convention), so no next-intl mock is needed. Asserts are on
// i18n-independent content: headings, measured numbers, gate labels, data-testid hooks.
// ── Harness (mirrors tests/unit/ui/compressionPanel.test.tsx) ──────────────────
const containers: HTMLElement[] = [];
const roots: Array<{ unmount: () => void }> = [];
function mount(ui: React.ReactElement): HTMLElement {
const container = document.createElement("div");
document.body.appendChild(container);
containers.push(container);
const root = createRoot(container);
roots.push(root);
act(() => {
root.render(ui);
});
return container;
}
beforeEach(() => {
(
globalThis as typeof globalThis & { IS_REACT_ACT_ENVIRONMENT?: boolean }
).IS_REACT_ACT_ENVIRONMENT = true;
});
afterEach(async () => {
vi.restoreAllMocks();
await act(async () => {
while (roots.length > 0) roots.pop()?.unmount();
});
for (let i = 0; i < 10; i++) await Promise.resolve();
while (containers.length > 0) containers.pop()?.remove();
document.body.innerHTML = "";
});
async function flush() {
await act(async () => {
for (let i = 0; i < 10; i++) await Promise.resolve();
});
}
interface CapturedPut {
url: string;
body: Record<string, unknown>;
}
function setupFetchMock(): { puts: CapturedPut[] } {
const puts: CapturedPut[] = [];
const json = (body: unknown, status = 200) =>
new Response(JSON.stringify(body), { status, headers: { "Content-Type": "application/json" } });
// omniglyph absent from `engines` initially → disabled; rtk/caveman present so we can
// assert they SURVIVE the PUT (the store persists the whole map as one row).
const initialConfig = {
enabled: true,
engines: { rtk: { enabled: true, level: "standard" }, caveman: { enabled: false } },
};
vi.spyOn(globalThis, "fetch").mockImplementation(
async (input: RequestInfo | URL, init?: RequestInit) => {
const url = input.toString();
const method = (init?.method ?? "GET").toUpperCase();
if (url.includes("/api/settings/compression")) {
if (method === "PUT") {
const body = JSON.parse(String(init?.body ?? "{}"));
puts.push({ url, body });
return json({ ...initialConfig, ...body });
}
return json(initialConfig);
}
return json({}, 404);
}
);
return { puts };
}
// ── Tests ──────────────────────────────────────────────────────────────────────
describe("OmniglyphContextPage", () => {
it("renders the four sections with the measured numbers and the real render", async () => {
setupFetchMock();
const { default: Page } = await import(
"../../../src/app/(dashboard)/dashboard/context/omniglyph/OmniglyphContextPageClient"
);
let container!: HTMLElement;
await act(async () => {
container = mount(<Page />);
});
await flush();
const text = container.textContent ?? "";
// Header + preview status
expect(text).toContain("OmniGlyph");
expect(text).toContain("Preview");
// Economics
expect(text).toContain("~10×");
expect(text).toContain("5970%");
// Before → after: measured savings + the real rendered image
expect(text).toContain(`${SAMPLE_METRICS.savingsPct}% tokens on this block`);
const img = container.querySelector("img");
expect(img, "the rendered sample page <img> must be present").toBeTruthy();
expect(img!.getAttribute("src")).toMatch(/^data:image\/png;base64,/);
// Gates
expect(text).toContain("claude-fable-5");
expect(text).toContain("direct Anthropic");
// Config control
expect(container.querySelector('[data-testid="omniglyph-enable-toggle"]')).toBeTruthy();
});
it("enabling the engine PUTs the full engines map with omniglyph on, preserving the others", async () => {
const { puts } = setupFetchMock();
const { default: Page } = await import(
"../../../src/app/(dashboard)/dashboard/context/omniglyph/OmniglyphContextPageClient"
);
let container!: HTMLElement;
await act(async () => {
container = mount(<Page />);
});
await flush();
const toggle = container.querySelector('[data-testid="omniglyph-enable-toggle"] button') as HTMLButtonElement | null;
expect(toggle, "enable toggle button must exist").toBeTruthy();
await act(async () => {
toggle!.click();
});
await flush();
expect(puts.length).toBe(1);
const engines = puts[0]!.body.engines as Record<string, { enabled: boolean }>;
expect(engines.omniglyph).toEqual({ enabled: true });
// The other engines must survive the whole-map PUT.
expect(engines.rtk?.enabled).toBe(true);
expect(engines.caveman?.enabled).toBe(false);
});
});