返回 DeepSeek-Reasonix
remote-session-cache.test.ts
根目录 / desktop / frontend / src / __tests__ / remote-session-cache.test.ts
1 // Run: tsx src/__tests__/remote-session-cache.test.ts
2
3 import { JSDOM } from "jsdom";
4 import {
5 loadRemoteSessionCache,
6 REMOTE_SESSION_CACHE_TTL_MS,
7 removeRemoteSessionCache,
8 saveRemoteSessionCache,
9 } from "../lib/remoteSessionCache";
10 import type { RemoteSessionView } from "../lib/types";
11
12 let passed = 0;
13 function ok(value: boolean, label: string): void {
14 if (!value) throw new Error(label);
15 passed += 1;
16 process.stdout.write(` PASS ${label}\n`);
17 }
18
19 const dom = new JSDOM("<!doctype html>", { url: "http://localhost/" });
20 globalThis.localStorage = dom.window.localStorage;
21
22 const key = "box\u0000~/app";
23 const rows: RemoteSessionView[] = [{ name: "one", path: "/sessions/one.jsonl", title: "One", turns: 2 }];
24 const now = 10_000;
25
26 saveRemoteSessionCache(key, rows, now);
27 ok(loadRemoteSessionCache(key, now + 1)[0]?.name === "one", "restores a current versioned snapshot");
28
29 saveRemoteSessionCache(key, [
30 { name: "", path: "/sessions/transient-blank.jsonl", title: "", turns: 0, current: true },
31 ...rows,
32 ], now);
33 const withoutBlank = loadRemoteSessionCache(key, now + 1);
34 ok(withoutBlank.length === 1 && withoutBlank[0]?.name === "one",
35 "does not persist a transient blank session with a generated path");
36
37 ok(loadRemoteSessionCache(key, now + REMOTE_SESSION_CACHE_TTL_MS + 1).length === 0, "expires stale snapshots");
38 ok(localStorage.length === 0, "removes an expired snapshot from storage");
39
40 localStorage.setItem("projectTree:remoteSessions:" + key, JSON.stringify(rows));
41 ok(loadRemoteSessionCache(key, now).length === 0, "invalidates the legacy unversioned array schema");
42 ok(localStorage.length === 0, "removes an invalid legacy snapshot");
43
44 localStorage.setItem("projectTree:remoteSessions:" + key, JSON.stringify({
45 version: 1,
46 savedAt: now,
47 rows: [{ name: "bad", title: "Bad", turns: 1, running: "yes" }],
48 }));
49 ok(loadRemoteSessionCache(key, now).length === 0, "rejects malformed optional row fields");
50 ok(localStorage.length === 0, "removes a malformed versioned snapshot");
51
52 localStorage.setItem("projectTree:remoteSessions:" + key, JSON.stringify({
53 version: 1,
54 savedAt: now,
55 rows: [{ name: "empty" }],
56 }));
57 const empty = loadRemoteSessionCache(key, now);
58 ok(empty.length === 1 && empty[0]?.title === "" && empty[0]?.turns === 0,
59 "normalizes Go-omitted zero-value title and turns");
60
61 saveRemoteSessionCache(key, rows, now);
62 removeRemoteSessionCache(key);
63 ok(loadRemoteSessionCache(key, now).length === 0, "explicit removal clears an unpinned project cache");
64
65 console.log(`\n${passed} remote session cache assertions passed.`);
66
66 lines TYPESCRIPT