import fs from
"node:fs" ;
import path from
"node:path" ;
import type { OpenClawConfig } from
"openclaw/plugin-sdk/config-runtime" ;
import { describe, expect, it } from
"vitest" ;
import { withTempHome } from
"../../../test/helpers/temp-home.js" ;
import { autoMigrateLegacyMatrixState, detectLegacyMatrixState } from
"./legacy-state.js" ;
function writeFile(filePath: string, value: string) {
fs.mkdirSync(path.dirname(filePath), { recursive:
true });
fs.writeFileSync(filePath, value,
"utf-8" );
}
describe(
"matrix legacy state migration" , () => {
it(
"migrates the flat legacy Matrix store into account-scoped storage" , async () => {
await withTempHome(async (home) => {
const stateDir = path.join(home,
".openclaw" );
writeFile(path.join(stateDir,
"matrix" ,
"bot-storage.json" ),
'{"next_batch":"s1"}' )
;
writeFile(path.join(stateDir, "matrix" , "crypto" , "store.db" ), "crypto" );
const cfg: OpenClawConfig = {
channels: {
matrix: {
homeserver: "https://matrix.example.org ",
userId: "@bot:example.org" ,
accessToken: "tok-123" ,
},
},
};
const detection = detectLegacyMatrixState({ cfg, env: process.env });
expect(detection && "warning" in detection).toBe(false );
if (!detection || "warning" in detection) {
throw new Error("expected a migratable Matrix legacy state plan" );
}
const result = await autoMigrateLegacyMatrixState({ cfg, env: process.env });
expect(result.migrated).toBe(true );
expect(result.warnings).toEqual([]);
expect(fs.existsSync(path.join(stateDir, "matrix" , "bot-storage.json" ))).toBe(false );
expect(fs.existsSync(path.join(stateDir, "matrix" , "crypto" ))).toBe(false );
expect(fs.existsSync(detection.targetStoragePath)).toBe(true );
expect(fs.existsSync(path.join(detection.targetCryptoPath, "store.db" ))).toBe(true );
});
});
it("uses cached Matrix credentials when the config no longer stores an access token" , async () => {
await withTempHome(async (home) => {
const stateDir = path.join(home, ".openclaw" );
writeFile(path.join(stateDir, "matrix" , "bot-storage.json" ), '{"next_batch":"s1"}' );
writeFile(
path.join(stateDir, "credentials" , "matrix" , "credentials.json" ),
JSON.stringify(
{
homeserver: "https://matrix.example.org ",
userId: "@bot:example.org" ,
accessToken: "tok-from-cache" ,
},
null ,
2 ,
),
);
const cfg: OpenClawConfig = {
channels: {
matrix: {
homeserver: "https://matrix.example.org ",
userId: "@bot:example.org" ,
password: "secret" ,
},
},
};
const detection = detectLegacyMatrixState({ cfg, env: process.env });
expect(detection && "warning" in detection).toBe(false );
if (!detection || "warning" in detection) {
throw new Error("expected cached credentials to make Matrix migration resolvable" );
}
expect(detection.targetRootDir).toContain("matrix.example.org__bot_example.org" );
const result = await autoMigrateLegacyMatrixState({ cfg, env: process.env });
expect(result.migrated).toBe(true );
expect(fs.existsSync(detection.targetStoragePath)).toBe(true );
});
});
});
Messung V0.5 in Prozent C=97 H=95 G=95
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-05)
¤
*© Formatika GbR, Deutschland