返回 DeepSeek-Reasonix
mock-remote-catalog.test.ts
根目录 / desktop / frontend / src / __tests__ / mock-remote-catalog.test.ts
1 import assert from "node:assert/strict";
2 import { JSDOM } from "jsdom";
3 import { app } from "../lib/bridge";
4
5 const dom = new JSDOM("", { url: "http://localhost/?mock=bench" });
6 Object.assign(globalThis, { window: dom.window, document: dom.window.document, localStorage: dom.window.localStorage });
7 try {
8 const local = (await app.ListTabs())[0];
9 const remote = await app.OpenRemoteProjectTab("demo", "~/app", { sessionName: "intro" });
10 assert.equal(remote.sessionPath, "~/app/sessions/intro.jsonl");
11 assert.ok((await app.ListTabs()).some(tab => tab.id === remote.id), "remote open and ListTabs share the backend catalog");
12 await app.SetActiveTab(remote.id);
13 assert.deepEqual((await app.ListTabs()).filter(tab => tab.active).map(tab => tab.id), [remote.id]);
14 await app.SetRemoteTabModel(remote.id, "fixture/model");
15 assert.equal((await app.ListTabs()).find(tab => tab.id === remote.id)?.label, "fixture/model");
16 const renewed = await app.OpenRemoteProjectTab("demo", "~/app", { newSession: true });
17 assert.equal(renewed.id, remote.id, "remote new session reuses its workspace surface");
18 assert.ok(renewed.sessionPath && renewed.sessionPath !== remote.sessionPath, "new session replaces the durable session identity");
19 assert.equal((await app.ListTabs()).filter(tab => tab.id === remote.id).length, 1);
20 assert.equal((await app.ListTabs()).find(tab => tab.id === remote.id)?.topicTitle, "New session");
21 const status = await app.RemoteTabStatus(remote.id) as Record<string, unknown>;
22 assert.equal(status.sessionPath, renewed.sessionPath);
23 assert.equal(status.plan, false);
24 assert.equal(status.toolApprovalMode, "workspace-write");
25 assert.equal(status.goal, "");
26 assert.deepEqual((await app.RemoteTabSnapshot(remote.id)).status, status, "snapshot and status share the authoritative composer profile");
27 // A canonical row carries only its immutable session id: opening it must
28 // bind that identity on the tab (the Serve publishes TabMeta.sessionId from
29 // opts.SessionID) instead of falling back to a synthesized basename route.
30 const canonical = await app.OpenRemoteProjectTab("demo", "~/app", { sessionId: "canonical-session-1" });
31 assert.equal(canonical.id, remote.id, "a canonical session reuses its workspace surface");
32 assert.equal(canonical.sessionId, "canonical-session-1", "opening by session id binds the canonical identity");
33 assert.ok(!canonical.sessionPath?.includes("intro"), "a canonical open does not inherit the previous legacy route");
34 const legacy = await app.OpenRemoteProjectTab("demo", "~/app", { sessionName: "intro" });
35 assert.equal(legacy.sessionPath, "~/app/sessions/intro.jsonl", "legacy rows keep their basename route");
36 assert.ok((await app.RemoteProjectSessions("demo", "~/app")).find(row => row.name === "intro")?.current,
37 "the opened legacy session becomes the current row");
38 await app.SetActiveTab(local.id);
39 assert.deepEqual((await app.ListTabs()).filter(tab => tab.active).map(tab => tab.id), [local.id]);
40 await app.CloseRemoteTab(remote.id);
41 assert.ok(!(await app.ListTabs()).some(tab => tab.id === remote.id));
42 await assert.rejects(app.SetActiveTab(remote.id), /not found/);
43 console.log("mock remote catalog: open, refresh, model, new session, selection and close agree");
44 } finally { dom.window.close(); }
45
45 lines TYPESCRIPT