返回 DeepSeek-Reasonix
historical-recovery-list.test.tsx
根目录 / desktop / frontend / src / __tests__ / historical-recovery-list.test.tsx
1 import assert from "node:assert/strict";
2 import { managementDom } from "../test-support/managementDom";
3 import { installDesktopHostStub } from "./desktopHostStub";
4 const dom = managementDom();
5 const { default: React, act } = await import("react");
6 const { createRoot } = await import("react-dom/client");
7 const { LocaleProvider } = await import("../lib/i18n");
8 const { HistoricalRecoveryList } = await import("../components/HistoricalRecoveryList");
9 let failRefresh = false;
10 let failRestore = true;
11 const restores: string[] = [];
12 const opened: string[] = [];
13 const host = installDesktopHostStub({
14 ListRecoveryEntries: async (_query: string, cursor: string, limit: number) => {
15 assert.equal(limit, 50);
16 if (failRefresh) throw new Error("list unavailable");
17 return { items: [{ id: cursor ? "second" : "first", title: cursor ? "Second" : "First", canRestore: true, canPreview: true }], nextCursor: cursor ? "" : "next", generation: 4 };
18 },
19 PreviewRecoveryEntry: async () => ({ messages: [{ messageId: "message", content: "Preserved history" }] }),
20 ApplySessionLifecycle: async (request: { operationId: string; targets: { recoveryEntryId: string }[] }) => {
21 const id = request.targets[0].recoveryEntryId;
22 restores.push(request.operationId);
23 if (failRestore) throw new Error("source unavailable");
24 failRefresh = true;
25 return { items: [{ committed: true, ref: { hostId: "local", sessionId: id }, workspaceId: "global" }], generation: 8 };
26 },
27 });
28 const root = createRoot(document.getElementById("root")!);
29 await act(async () => root.render(<LocaleProvider><HistoricalRecoveryList active onOpenSession={async ref => { opened.push(ref.sessionId); }} /></LocaleProvider>));
30 const button = (text: string) => Array.from(document.querySelectorAll<HTMLButtonElement>("button")).find(node => node.textContent?.trim() === text)!;
31 assert.equal(document.querySelectorAll(".archived-sessions__row").length, 1);
32 await act(async () => button("Load more").click());
33 assert.equal(document.querySelectorAll(".archived-sessions__row").length, 2);
34 await act(async () => button("Restore").click());
35 assert.equal(document.querySelectorAll(".archived-sessions__row").length, 2, "failed restore keeps its source entry");
36 failRestore = false;
37 await act(async () => button("Restore").click());
38 assert.equal(restores[0], restores[1], "retry reuses the same operation identity");
39 assert.deepEqual(opened, ["first"]);
40 assert.equal(document.querySelectorAll(".archived-sessions__row").length, 1, "durable success survives a failed list refresh");
41 assert.ok(document.querySelector('[role="alert"]')?.textContent?.toLowerCase().includes("restored"));
42 assert.equal(document.querySelector(".history-clear"), null, "historical entries cannot be bulk purged");
43 await act(async () => root.unmount());
44 host.uninstall(); dom.window.close();
45 console.log("PASS historical pagination, failed restore retention, idempotent retry and committed refresh failure");
46
46 lines Plain Text