返回 DeepSeek-Reasonix
runtime-notification-retention.test.ts
根目录 / desktop / frontend / src / __tests__ / runtime-notification-retention.test.ts
1 import assert from "node:assert/strict";
2 import { createRuntimeNotifications } from "../lib/runtimeNotifications";
3 import { runtimeStateStore, type RuntimeSession } from "../lib/runtimeStateStore";
4 import { t } from "../lib/i18n";
5
6 let alerts = 0;
7 let revision = 0;
8 const owner = createRuntimeNotifications(() => ({ activeTabId: "B", t, showToast() { alerts++; } }));
9 function session(index: number): RuntimeSession {
10 return { tabId: `detached:${index}`, scope: "global", workspaceRoot: "", topicId: "", sessionPath: "",
11 sessionGeneration: 1, open: false, remote: false, freshness: "synced",
12 state: { schemaVersion: 1, runtimeEpoch: `runtime:${index}`, activityRevision: 1, revision: 1,
13 phase: "executing", running: true, turnId: `turn:${index}`, turnStatus: "in_progress", turnEventSeq: 1,
14 pendingPrompt: true, pendingInteractions: [{ requestId: "1", kind: "ask", turnId: `turn:${index}`,
15 runtimeEpoch: `runtime:${index}`, headId: "head" }],
16 cancelRequested: false, cancellable: true, backgroundJobs: 0, activity: "" } };
17 }
18 function publish(sessions: RuntimeSession[]) {
19 runtimeStateStore.commit({ epoch: "fixture", revision: ++revision, topics: [], sessions });
20 }
21 publish([]);
22 owner.start();
23 try {
24 publish([session(0)]);
25 assert.equal(alerts, 1);
26 for (let index = 1; index <= 600; index++) {
27 owner.accept({ event: { kind: "approval_request", tabId: "C", turnId: `other:${index}`, approval: { id: "1" } } });
28 }
29 assert.equal(alerts, 601);
30 publish([session(0)]);
31 assert.equal(alerts, 601, "history eviction must not re-alert a still-pending background question");
32 const manyPending = Array.from({ length: 600 }, (_, index) => session(index + 1000));
33 publish(manyPending);
34 assert.equal(alerts, 1201);
35 publish(manyPending);
36 assert.equal(alerts, 1201, "more pending requests than the history cap cannot create an alert storm");
37 publish(manyPending.map(item => ({ ...item, freshness: "unknown" })));
38 publish(manyPending);
39 assert.equal(alerts, 1201, "disconnect and reconnect retain known pending identities beyond the history cap");
40 owner.accept({ event: { kind: "ask_request", tabId: "reattached", turnId: "turn:1000", ask: { id: "1" } } });
41 assert.equal(alerts, 1201, "wire replay also respects retained pending identities");
42 publish([]);
43 publish([session(9000)]);
44 assert.equal(alerts, 1202, "a new pending request still alerts after the old requests resolve");
45 console.log("runtime notifications: pending identities survive bounded history eviction and repeated large snapshots");
46 } finally { owner.dispose(); }
47
47 lines TYPESCRIPT