chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
// @vitest-environment jsdom
|
||||
import React, { act } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { describe, it, expect, beforeAll, beforeEach, afterEach, vi } from "vitest";
|
||||
import type { CompressionRunModel } from "@/app/(dashboard)/dashboard/compression/studio/compressionFlowModel";
|
||||
|
||||
// ── Polyfill ResizeObserver (required by ReactFlow) ───────────────────────
|
||||
|
||||
beforeAll(() => {
|
||||
globalThis.ResizeObserver = class {
|
||||
observe() {}
|
||||
unobserve() {}
|
||||
disconnect() {}
|
||||
} as unknown as typeof ResizeObserver;
|
||||
});
|
||||
|
||||
// ── Mocks ─────────────────────────────────────────────────────────────────
|
||||
|
||||
// Stub @xyflow/react so ReactFlow renders without canvas/DOM measurement APIs
|
||||
vi.mock("@xyflow/react", async () => {
|
||||
const actual = (await vi.importActual("@xyflow/react")) as Record<string, unknown>;
|
||||
return {
|
||||
...actual,
|
||||
Handle: (_props: Record<string, unknown>) => null,
|
||||
Position: { Left: "left", Right: "right", Top: "top", Bottom: "bottom" },
|
||||
};
|
||||
});
|
||||
|
||||
// ── Import after mocks ─────────────────────────────────────────────────────
|
||||
|
||||
const { CompressionCockpit } =
|
||||
await import("@/app/(dashboard)/dashboard/compression/studio/CompressionCockpit");
|
||||
|
||||
// ── Helpers ───────────────────────────────────────────────────────────────
|
||||
|
||||
const containers: HTMLElement[] = [];
|
||||
|
||||
function mount(ui: React.ReactElement): HTMLElement {
|
||||
const container = document.createElement("div");
|
||||
document.body.appendChild(container);
|
||||
containers.push(container);
|
||||
const root = createRoot(container);
|
||||
act(() => {
|
||||
root.render(ui);
|
||||
});
|
||||
return container;
|
||||
}
|
||||
|
||||
function click(el: Element | null): void {
|
||||
act(() => {
|
||||
el?.dispatchEvent(new MouseEvent("click", { bubbles: true }));
|
||||
});
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
(
|
||||
globalThis as typeof globalThis & { IS_REACT_ACT_ENVIRONMENT?: boolean }
|
||||
).IS_REACT_ACT_ENVIRONMENT = true;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
while (containers.length > 0) {
|
||||
containers.pop()?.remove();
|
||||
}
|
||||
document.body.innerHTML = "";
|
||||
});
|
||||
|
||||
// ── Sample run ────────────────────────────────────────────────────────────
|
||||
|
||||
const SAMPLE_RUN: CompressionRunModel = {
|
||||
requestId: "test-req-001",
|
||||
comboId: "daily-cascade",
|
||||
mode: "stacked",
|
||||
originalTokens: 12480,
|
||||
compressedTokens: 6090,
|
||||
savingsPercent: 51.2,
|
||||
timestamp: 1718000000000,
|
||||
steps: [
|
||||
{
|
||||
engine: "rtk",
|
||||
originalTokens: 12480,
|
||||
compressedTokens: 9734,
|
||||
savingsPercent: 22.0,
|
||||
techniquesUsed: ["strip-comments", "shell-filter"],
|
||||
durationMs: 1.8,
|
||||
},
|
||||
{
|
||||
engine: "headroom",
|
||||
originalTokens: 9734,
|
||||
compressedTokens: 8524,
|
||||
savingsPercent: 12.4,
|
||||
techniquesUsed: ["smartcrusher"],
|
||||
durationMs: 0.9,
|
||||
},
|
||||
{
|
||||
engine: "caveman",
|
||||
originalTokens: 8524,
|
||||
compressedTokens: 6896,
|
||||
savingsPercent: 19.1,
|
||||
techniquesUsed: ["pt-BR", "filler-drop"],
|
||||
durationMs: 0.6,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// ── Tests ─────────────────────────────────────────────────────────────────
|
||||
|
||||
describe("CompressionCockpit", () => {
|
||||
it("renders the cockpit wrapper when a run is provided", () => {
|
||||
const container = mount(<CompressionCockpit run={SAMPLE_RUN} />);
|
||||
expect(container.querySelector("[data-testid='compression-cockpit']")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("renders the ReactFlow canvas", () => {
|
||||
const container = mount(<CompressionCockpit run={SAMPLE_RUN} />);
|
||||
expect(container.querySelector(".react-flow")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("shows the mode in the header", () => {
|
||||
const container = mount(<CompressionCockpit run={SAMPLE_RUN} />);
|
||||
expect(container.textContent).toContain("stacked");
|
||||
});
|
||||
|
||||
it("shows the comboId in the header", () => {
|
||||
const container = mount(<CompressionCockpit run={SAMPLE_RUN} />);
|
||||
expect(container.textContent).toContain("daily-cascade");
|
||||
});
|
||||
|
||||
it("shows the total savings percentage in the header", () => {
|
||||
const container = mount(<CompressionCockpit run={SAMPLE_RUN} />);
|
||||
expect(container.textContent).toContain("51.2");
|
||||
});
|
||||
|
||||
it("shows engine names (from node labels via ReactFlow)", () => {
|
||||
const container = mount(<CompressionCockpit run={SAMPLE_RUN} />);
|
||||
// The engine names appear in the header text even if ReactFlow node internals
|
||||
// don't render in jsdom — we also check the header region.
|
||||
const text = container.textContent ?? "";
|
||||
// At minimum the run metadata renders correctly
|
||||
expect(text).toContain("test-req-001");
|
||||
});
|
||||
|
||||
it("renders the empty state when no run is given", () => {
|
||||
const container = mount(<CompressionCockpit />);
|
||||
expect(container.querySelector("[data-testid='compression-cockpit-empty']")).toBeTruthy();
|
||||
expect(container.textContent).toContain("No compression run available");
|
||||
});
|
||||
|
||||
it("renders replay controls when a run is provided", () => {
|
||||
const container = mount(<CompressionCockpit run={SAMPLE_RUN} />);
|
||||
// Replay button present
|
||||
const text = container.textContent ?? "";
|
||||
expect(text).toContain("Replay");
|
||||
});
|
||||
|
||||
it("offers a Canvas/Waterfall view toggle", () => {
|
||||
const container = mount(<CompressionCockpit run={SAMPLE_RUN} />);
|
||||
expect(container.querySelector("[data-testid='cockpit-view-canvas']")).toBeTruthy();
|
||||
expect(container.querySelector("[data-testid='cockpit-view-waterfall']")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("switches to the waterfall inspector and back to the canvas", () => {
|
||||
const container = mount(<CompressionCockpit run={SAMPLE_RUN} />);
|
||||
// Default view is the ReactFlow canvas, waterfall hidden.
|
||||
expect(container.querySelector(".react-flow")).toBeTruthy();
|
||||
expect(container.querySelector("[data-testid='waterfall-inspector']")).toBeFalsy();
|
||||
|
||||
// Switch to the waterfall (A1) view — the previously-orphan component is now reachable.
|
||||
click(container.querySelector("[data-testid='cockpit-view-waterfall']"));
|
||||
expect(container.querySelector("[data-testid='waterfall-inspector']")).toBeTruthy();
|
||||
expect(container.querySelector(".react-flow")).toBeFalsy();
|
||||
expect(
|
||||
container.querySelector("[data-testid='waterfall-total-savings']")?.textContent
|
||||
).toContain("51.2");
|
||||
|
||||
// Switch back to the canvas.
|
||||
click(container.querySelector("[data-testid='cockpit-view-canvas']"));
|
||||
expect(container.querySelector(".react-flow")).toBeTruthy();
|
||||
expect(container.querySelector("[data-testid='waterfall-inspector']")).toBeFalsy();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user