import fs from "node:fs"; import os from "node:os"; import path from "node:path"; import { describe, expect, it } from "vitest"; import { ensureDir, existsDir, fileExists, isLegacyWhatsAppAuthFile, readSessionStoreJson5, safeReadDir, } from "./state-migrations.fs.js"; describe("state migration fs helpers", () => { it("reads directories safely and creates missing directories", () => { const base = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-state-migrations-fs-")); const nested = path.join(base, "nested"); expect(safeReadDir(nested)).toEqual([]); ensureDir(nested); fs.writeFileSync(path.join(nested, "file.txt"), "ok", "utf8"); expect(safeReadDir(nested).map((entry) => entry.name)).toEqual(["file.txt"]); expect(existsDir(nested)).toBe(true); expect(existsDir(path.join(nested, "file.txt"))).toBe(false); }); it("distinguishes files from directories", () => { const base = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-state-migrations-fs-")); const filePath = path.join(base, "store.json"); const dirPath = path.join(base, "dir"); fs.writeFileSync(filePath, "{}", "utf8"); fs.mkdirSync(dirPath); expect(fileExists(filePath)).toBe(true); expect(fileExists(dirPath)).toBe(false); expect(fileExists(path.join(base, "missing.json"))).toBe(false); }); it("recognizes legacy whatsapp auth file names", () => { expect(isLegacyWhatsAppAuthFile("creds.json")).toBe(true); expect(isLegacyWhatsAppAuthFile("creds.json.bak")).toBe(true); expect(isLegacyWhatsAppAuthFile("session-123.json")).toBe(true); expect(isLegacyWhatsAppAuthFile("pre-key-1.json")).toBe(true); expect(isLegacyWhatsAppAuthFile("sender-key-1.txt")).toBe(false); expect(isLegacyWhatsAppAuthFile("other.json")).toBe(false); }); it("parses json5 session stores and rejects invalid shapes", () => { const base = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-state-migrations-fs-")); const okPath = path.join(base, "store.json"); const badPath = path.join(base, "bad.json"); const listPath = path.join(base, "list.json"); fs.writeFileSync(okPath, "{session: {sessionId: 'abc', updatedAt: 1}}", "utf8"); fs.writeFileSync(badPath, "{not valid", "utf8"); fs.writeFileSync(listPath, "[]", "utf8"); expect(readSessionStoreJson5(okPath)).toEqual({ ok: true, store: { session: { sessionId: "abc", updatedAt: 1, }, }, }); expect(readSessionStoreJson5(badPath)).toEqual({ ok: false, store: {} }); expect(readSessionStoreJson5(listPath)).toEqual({ ok: false, store: {} }); }); });