import { afterEach, describe, expect, mock, test } from "bun:test";
import { useRef } from "react";
import TestRenderer, { act } from "react-test-renderer";
import { MemoryRouter, Route, Routes } from "react-router";
import { toast as sonnerToast } from "sonner";
import { ToastProvider } from "../components/toast";
import { TEST_PRINCIPAL } from "../lib/test-fixtures";
let currentFilesPayload: any = null;
let currentCommitsPayload: any = null;
let currentRunStatus = "succeeded";
const useRunFilesCalls: any[] = [];
const multiFileDiffCalls: any[] = [];
const patchDiffCalls: any[] = [];
let patchDiffMountSeq = 0;
const virtualizerCalls: any[] = [];
const providerCalls: any[] = [];
const mountedRenderers: TestRenderer.ReactTestRenderer[] = [];
mock.module("@pierre/diffs/react", () => ({
MultiFileDiff: (props: any) => {
multiFileDiffCalls.push(props);
return
{props.newFile.name}
;
},
PatchDiff: (props: any) => {
const mountId = useRef(++patchDiffMountSeq);
patchDiffCalls.push({ ...props, mountId: mountId.current });
return (
{props.patch}
);
},
Virtualizer: (props: any) => {
virtualizerCalls.push(props);
return {props.children}
;
},
WorkerPoolContextProvider: (props: any) => {
providerCalls.push(props);
return {props.children}
;
},
}));
mock.module("../lib/queries", () => ({
useRun: () => ({
data: {
id: "run_1",
goal: "Run 1",
title: "Run 1",
workflow: { slug: "default", name: "Default", graph_name: null, node_count: 0, edge_count: 0 },
automation: null,
repository: { name: "fabro", origin_url: null, provider: "unknown" },
created_by: TEST_PRINCIPAL,
origin: { kind: "api" },
labels: {},
lifecycle: {
status: { kind: currentRunStatus },
approval: null,
pending_control: null,
queue_position: null,
error: null,
archived: false,
archived_at: null,
},
sandbox: null,
models: [],
source_directory: null,
timestamps: {
created_at: "2026-05-05T12:00:00Z",
started_at: null,
last_event_at: null,
completed_at: null,
},
billing: null,
size: "XS",
diff: null,
pull_request: null,
current_question: null,
superseded_by: null,
retried_from: null,
links: { web: null },
},
}),
useRunCommits: () => ({
data: currentCommitsPayload,
error: null,
isLoading: false,
isValidating: false,
mutate: mock(() => Promise.resolve(currentCommitsPayload)),
}),
useRunFiles: (id: string | undefined, selection: any) => {
useRunFilesCalls.push({ id, selection });
return {
data: currentFilesPayload,
error: null,
isLoading: false,
isValidating: false,
mutate: mock(() => Promise.resolve(currentFilesPayload)),
};
},
useRunQuestions: () => ({ data: [] }),
}));
const { default: RunFiles } = await import("./run-files");
function makeFiles(count: number) {
return Array.from({ length: count }, (_, index) => {
const name = `src/file-${index}.ts`;
return {
change_kind: "modified",
old_file: { name, contents: `old ${index}\n` },
new_file: { name, contents: `new ${index}\n` },
};
});
}
function makePayload(count: number, source = "sandbox") {
return {
data: makeFiles(count),
meta: {
source,
scope: "committed",
degraded: false,
degraded_reason: null,
total_changed: count,
stats: { additions: count, deletions: count },
truncated: false,
to_sha: "abc1234",
to_sha_committed_at: "2026-05-05T12:00:00Z",
},
};
}
function makePatchPayload(patch: string) {
return {
data: [
{
change_kind: "modified",
old_file: { name: "docs/live.md", contents: null },
new_file: { name: "docs/live.md", contents: null },
unified_patch: patch,
},
],
meta: {
source: "sandbox",
scope: "committed",
degraded: false,
degraded_reason: null,
total_changed: 1,
stats: { additions: 1, deletions: 0 },
truncated: false,
to_sha: "abc1234",
to_sha_committed_at: "2026-05-05T12:00:00Z",
},
};
}
function runFilesTree(initialEntry = "/runs/run_1/files") {
return (
} />
);
}
function renderRunFiles(initialEntry = "/runs/run_1/files") {
(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
let renderer: TestRenderer.ReactTestRenderer | undefined;
act(() => {
renderer = TestRenderer.create(runFilesTree(initialEntry));
});
mountedRenderers.push(renderer!);
return renderer!;
}
function treeText(
node: ReturnType,
): string {
if (!node) return "";
if (typeof node === "string") return node;
if (Array.isArray(node)) return node.map(treeText).join("");
return (node.children ?? []).map(treeText).join("");
}
async function flushAsyncUpdates() {
await act(async () => {
await Promise.resolve();
await new Promise((resolve) => setTimeout(resolve, 0));
});
}
describe("RunFiles rendering", () => {
afterEach(() => {
act(() => {
for (const renderer of mountedRenderers.splice(0)) {
renderer.unmount();
}
});
currentFilesPayload = null;
currentCommitsPayload = null;
currentRunStatus = "succeeded";
multiFileDiffCalls.length = 0;
patchDiffCalls.length = 0;
patchDiffMountSeq = 0;
virtualizerCalls.length = 0;
providerCalls.length = 0;
useRunFilesCalls.length = 0;
sonnerToast.dismiss();
delete (globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT;
});
test("renders a one-file payload through Pierre Virtualizer", () => {
currentFilesPayload = makePayload(1);
const renderer = renderRunFiles();
expect(virtualizerCalls).toHaveLength(1);
expect(renderer.root.findAllByProps({ "data-run-file-row": "true" })).toHaveLength(1);
expect(multiFileDiffCalls[0].options.diffStyle).toBe("split");
});
test("passes the selected URL scope to useRunFiles", () => {
currentFilesPayload = makePayload(1);
renderRunFiles("/runs/run_1/files?scope=all#file=src/file-0.ts");
expect(useRunFilesCalls[0]).toEqual({
id: "run_1",
selection: { kind: "scope", scope: "all" },
});
});
test("passes a selected commit range to useRunFiles", () => {
currentFilesPayload = makePayload(1);
currentCommitsPayload = {
data: [
{
sha: "b".repeat(40),
short_sha: "bbbbbbb",
subject: "fabro(run_1): implement (succeeded)",
parents: [{ sha: "a".repeat(40), short_sha: "aaaaaaa" }],
},
],
};
renderRunFiles(`/runs/run_1/files?commit=${"b".repeat(40)}`);
expect(useRunFilesCalls[0]).toEqual({
id: "run_1",
selection: {
kind: "commit",
fromSha: "a".repeat(40),
toSha: "b".repeat(40),
},
});
});
test("shows the scope picker only for sandbox responses", () => {
currentFilesPayload = makePayload(1, "sandbox");
const sandboxRenderer = renderRunFiles();
expect(
sandboxRenderer.root.findAllByProps({ "aria-label": "Diff selection" }),
).not.toHaveLength(0);
act(() => sandboxRenderer.unmount());
mountedRenderers.pop();
currentFilesPayload = makePayload(1, "final_patch");
const fallbackRenderer = renderRunFiles("/runs/run_1/files?scope=all");
expect(
fallbackRenderer.root.findAllByProps({ "aria-label": "Diff selection" }),
).toHaveLength(0);
});
test("renders a 27-file payload through one Pierre Virtualizer", () => {
currentFilesPayload = makePayload(27);
const renderer = renderRunFiles();
expect(virtualizerCalls).toHaveLength(1);
expect(renderer.root.findAllByProps({ "data-run-file-row": "true" })).toHaveLength(27);
});
test("passes stable Pierre cache keys across unrelated re-renders", () => {
currentFilesPayload = makePayload(1);
const renderer = renderRunFiles();
const firstOldKey = multiFileDiffCalls[0].oldFile.cacheKey;
const firstNewKey = multiFileDiffCalls[0].newFile.cacheKey;
act(() => {
renderer.update(runFilesTree());
});
const lastCall = multiFileDiffCalls[multiFileDiffCalls.length - 1];
expect(firstOldKey).toBe(lastCall.oldFile.cacheKey);
expect(firstNewKey).toBe(lastCall.newFile.cacheKey);
expect(firstOldKey).toContain("fabro-run-file:run_1:abc1234:old:src/file-0.ts:");
expect(firstNewKey).toContain("fabro-run-file:run_1:abc1234:new:src/file-0.ts:");
expect(lastCall.options).not.toHaveProperty("theme");
});
test("remounts patch diffs when the patch changes for the same file", () => {
currentFilesPayload = makePatchPayload(
"diff --git a/docs/live.md b/docs/live.md\n@@ -1 +1 @@\n+committed\n",
);
const renderer = renderRunFiles("/runs/run_1/files?scope=all");
const firstMountId = patchDiffCalls[0].mountId;
currentFilesPayload = makePatchPayload(
"diff --git a/docs/live.md b/docs/live.md\n@@ -1,0 +1,2 @@\n+committed\n+uncommitted\n",
);
act(() => {
renderer.update(runFilesTree("/runs/run_1/files?scope=all"));
});
const lastCall = patchDiffCalls[patchDiffCalls.length - 1];
expect(lastCall.patch).toContain("+uncommitted");
expect(lastCall.mountId).not.toBe(firstMountId);
});
test("refreshing from a populated diff to an empty diff shows a no-changes toast", async () => {
currentFilesPayload = makePayload(1);
const renderer = renderRunFiles("/runs/run_1/files?scope=all");
currentFilesPayload = makePayload(0);
await act(async () => {
renderer.root.findByProps({ "aria-label": "Refresh files" }).props.onClick();
});
await flushAsyncUpdates();
expect(treeText(renderer.toJSON())).toContain("No changes in this run.");
});
});