



























1+// Matrix tests cover fake-indexeddb transaction pruning for crypto stores.
2+import "fake-indexeddb/auto";
3+import { afterEach, describe, expect, it } from "vitest";
4+import {
5+installFakeIndexedDbTransactionPruner,
6+pruneFinishedFakeIndexedDbTransactions,
7+} from "./fake-indexeddb-prune.js";
8+9+function openDatabase(name: string): Promise<IDBDatabase> {
10+return new Promise((resolve, reject) => {
11+const request = indexedDB.open(name, 1);
12+request.addEventListener("upgradeneeded", () => {
13+request.result.createObjectStore("sessions", { keyPath: "key" });
14+});
15+request.addEventListener("success", () => resolve(request.result), { once: true });
16+request.addEventListener(
17+"error",
18+() => reject(request.error ?? new Error("database open failed")),
19+{
20+once: true,
21+},
22+);
23+});
24+}
25+26+function deleteDatabase(name: string): Promise<void> {
27+return new Promise((resolve) => {
28+const request = indexedDB.deleteDatabase(name);
29+request.addEventListener("success", () => resolve(), { once: true });
30+request.addEventListener("error", () => resolve(), { once: true });
31+request.addEventListener("blocked", () => resolve(), { once: true });
32+});
33+}
34+35+function putRecord(db: IDBDatabase, key: string): Promise<void> {
36+return new Promise((resolve, reject) => {
37+const transaction = db.transaction("sessions", "readwrite");
38+transaction.objectStore("sessions").put({ key, value: "payload" });
39+transaction.addEventListener("complete", () => resolve(), { once: true });
40+transaction.addEventListener(
41+"error",
42+() => reject(transaction.error ?? new Error("transaction failed")),
43+{
44+once: true,
45+},
46+);
47+transaction.addEventListener(
48+"abort",
49+() => reject(transaction.error ?? new Error("transaction aborted")),
50+{
51+once: true,
52+},
53+);
54+});
55+}
56+57+function rawTransactions(db: IDBDatabase): Array<{ _state?: string }> {
58+return (
59+(db as unknown as { _rawDatabase?: { transactions?: Array<{ _state?: string }> } })[
60+"_rawDatabase"
61+]?.transactions ?? []
62+);
63+}
64+65+describe("Matrix fake-indexeddb transaction pruning", () => {
66+const databaseNames = new Set<string>();
67+68+afterEach(async () => {
69+for (const name of databaseNames) {
70+await deleteDatabase(name);
71+}
72+databaseNames.clear();
73+});
74+75+it("prunes finished transactions for Matrix crypto databases", async () => {
76+installFakeIndexedDbTransactionPruner();
77+const databaseName = `openclaw-matrix-prune-test-${Date.now()}::matrix-sdk-crypto`;
78+databaseNames.add(databaseName);
79+const db = await openDatabase(databaseName);
80+81+for (let i = 0; i < 5; i += 1) {
82+await putRecord(db, `key-${i}`);
83+}
84+85+expect(rawTransactions(db)).toHaveLength(0);
86+db.close();
87+});
88+89+it("prunes finished transactions for Matrix crypto metadata databases", async () => {
90+installFakeIndexedDbTransactionPruner();
91+const databaseName = `openclaw-matrix-meta-prune-test-${Date.now()}::matrix-sdk-crypto-meta`;
92+databaseNames.add(databaseName);
93+const db = await openDatabase(databaseName);
94+95+for (let i = 0; i < 5; i += 1) {
96+await putRecord(db, `key-${i}`);
97+}
98+99+expect(rawTransactions(db)).toHaveLength(0);
100+db.close();
101+});
102+103+it("does not prune unrelated fake-indexeddb databases", async () => {
104+installFakeIndexedDbTransactionPruner();
105+const databaseName = `openclaw-matrix-unrelated-prune-test-${Date.now()}`;
106+databaseNames.add(databaseName);
107+const db = await openDatabase(databaseName);
108+109+await putRecord(db, "key-1");
110+111+expect(
112+rawTransactions(db).filter((transaction) => transaction["_state"] === "finished").length,
113+).toBeGreaterThan(0);
114+db.close();
115+});
116+117+it("keeps active transactions when pruning the raw transaction queue", () => {
118+const rawDatabase = {
119+name: "openclaw-matrix-direct-prune-test::matrix-sdk-crypto",
120+transactions: [{ _state: "finished" }, { _state: "active" }, { _state: "inactive" }],
121+};
122+123+expect(pruneFinishedFakeIndexedDbTransactions(rawDatabase)).toBe(1);
124+expect(rawDatabase.transactions).toEqual([{ _state: "active" }, { _state: "inactive" }]);
125+});
126+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。