返回 DeepSeek-Reasonix
recoveryStore.test.ts
根目录 / desktop / electron / src / main / browser / recoveryStore.test.ts
1 import assert from "node:assert/strict";
2 import { test } from "node:test";
3 import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
4 import { tmpdir } from "node:os";
5 import { join } from "node:path";
6 import { BrowserRecoveryStore, type RecoveredTab } from "./recoveryStore.js";
7 import { LazyGuestView } from "./lazyGuestView.js";
8 import { FakeViewFactory } from "./fakeGuestViews.js";
9
10 const tab: RecoveredTab = { id: "tab-2", taskId: "task", sessionId: "session", url: "https://example.test/", title: "Page", viewport: null };
11 test("recovery preserves future fields but never capabilities and rejects expired preview URLs", () => {
12 const directory = mkdtempSync(join(tmpdir(), "browser-recovery-")), path = join(directory, "tabs.json");
13 try {
14 writeFileSync(path, JSON.stringify({ version: 1, future: 42, tabs: [{ ...tab, custom: true, grantId: "old", refs: [1], password: "secret" }, { ...tab, id: "tab-3", url: "http://localhost/__reasonix_workspace_media/expired" }] }));
15 const store = new BrowserRecoveryStore(path, assert.fail);
16 assert.equal(store.tabs.length, 1);
17 store.save(store.tabs);
18 const saved = JSON.parse(readFileSync(path, "utf8"));
19 assert.equal(saved.future, 42); assert.equal(saved.tabs[0].custom, true);
20 for (const key of ["grantId", "refs", "password"]) assert.equal(saved.tabs[0][key], undefined);
21 writeFileSync(path, '{"version":999,"future":"untouched"}');
22 const future = new BrowserRecoveryStore(path, assert.fail); future.save([tab]);
23 assert.equal(readFileSync(path, "utf8"), '{"version":999,"future":"untouched"}');
24 } finally { rmSync(directory, { recursive: true, force: true }); }
25 });
26 test("recovered tabs allocate no page until access and share one initial load", async () => {
27 const factory = new FakeViewFactory();
28 let creates = 0;
29 const lazy = new LazyGuestView({ create: partition => { creates++; return factory.create(partition); } }, "persist:browser", tab);
30 assert.equal(lazy.page.id, -1); assert.equal(lazy.page.getURL(), tab.url);
31 lazy.setBounds({ x: 0, y: 0, width: 800, height: 600 }); lazy.setVisible(false);
32 assert.equal(creates, 0);
33 await Promise.all([lazy.ensureLoaded(), lazy.ensureLoaded()]);
34 assert.equal(creates, 1); assert.equal(lazy.isPlaceholder(), false);
35 lazy.destroy();
36 const unopened = new LazyGuestView(factory, "persist:browser", tab); unopened.destroy();
37 assert.throws(() => unopened.ensureLoaded(), /closed/);
38 });
39
40 test("file preview recovery persists source references without expiring bearer URLs", async () => {
41 const directory = mkdtempSync(join(tmpdir(), "preview-recovery-")), path = join(directory, "tabs.json");
42 try {
43 const reference = { source: "workspace" as const, path: "index.html", toolCallId: "" };
44 const store = new BrowserRecoveryStore(path, assert.fail);
45 store.save([{ ...tab, url: "http://localhost/__reasonix_workspace_media/SECRET", fileReference: reference }]);
46 assert.equal(readFileSync(path, "utf8").includes("SECRET"), false);
47 const loaded = new BrowserRecoveryStore(path, assert.fail);
48 assert.deepEqual(loaded.tabs[0].fileReference, reference);
49 const lazy = new LazyGuestView(new FakeViewFactory(), "persist:browser", loaded.tabs[0]);
50 await assert.rejects(lazy.ensureLoaded(), /fresh file authorization/);
51 assert.equal(lazy.isPlaceholder(), true);
52 } finally { rmSync(directory, { recursive: true, force: true }); }
53 });
54
54 lines TYPESCRIPT