test(infra): dedupe store temp fixtures and cover json5 voicewake sanitization

This commit is contained in:
Peter Steinberger
2026-02-21 19:42:54 +00:00
parent a418c6db06
commit 822688dc13

View File

@@ -20,42 +20,89 @@ import {
setVoiceWakeTriggers,
} from "./voicewake.js";
async function withTempDir(prefix: string, run: (dir: string) => Promise<void>) {
const dir = await fs.mkdtemp(path.join(os.tmpdir(), prefix));
try {
await run(dir);
} finally {
await fs.rm(dir, { recursive: true, force: true });
}
}
describe("infra store", () => {
describe("state migrations fs", () => {
it("treats array session stores as invalid", async () => {
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-session-store-"));
const storePath = path.join(dir, "sessions.json");
await fs.writeFile(storePath, "[]", "utf-8");
await withTempDir("openclaw-session-store-", async (dir) => {
const storePath = path.join(dir, "sessions.json");
await fs.writeFile(storePath, "[]", "utf-8");
const result = readSessionStoreJson5(storePath);
expect(result.ok).toBe(false);
expect(result.store).toEqual({});
const result = readSessionStoreJson5(storePath);
expect(result.ok).toBe(false);
expect(result.store).toEqual({});
});
});
it("parses JSON5 object session stores", async () => {
await withTempDir("openclaw-session-store-", async (dir) => {
const storePath = path.join(dir, "sessions.json");
await fs.writeFile(
storePath,
"{\n // comment allowed in JSON5\n main: { sessionId: 's1', updatedAt: 123 },\n}\n",
"utf-8",
);
const result = readSessionStoreJson5(storePath);
expect(result.ok).toBe(true);
expect(result.store.main?.sessionId).toBe("s1");
expect(result.store.main?.updatedAt).toBe(123);
});
});
});
describe("voicewake store", () => {
it("returns defaults when missing", async () => {
const baseDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-voicewake-"));
const cfg = await loadVoiceWakeConfig(baseDir);
expect(cfg.triggers).toEqual(defaultVoiceWakeTriggers());
expect(cfg.updatedAtMs).toBe(0);
await withTempDir("openclaw-voicewake-", async (baseDir) => {
const cfg = await loadVoiceWakeConfig(baseDir);
expect(cfg.triggers).toEqual(defaultVoiceWakeTriggers());
expect(cfg.updatedAtMs).toBe(0);
});
});
it("sanitizes and persists triggers", async () => {
const baseDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-voicewake-"));
const saved = await setVoiceWakeTriggers([" hi ", "", " there "], baseDir);
expect(saved.triggers).toEqual(["hi", "there"]);
expect(saved.updatedAtMs).toBeGreaterThan(0);
await withTempDir("openclaw-voicewake-", async (baseDir) => {
const saved = await setVoiceWakeTriggers([" hi ", "", " there "], baseDir);
expect(saved.triggers).toEqual(["hi", "there"]);
expect(saved.updatedAtMs).toBeGreaterThan(0);
const loaded = await loadVoiceWakeConfig(baseDir);
expect(loaded.triggers).toEqual(["hi", "there"]);
expect(loaded.updatedAtMs).toBeGreaterThan(0);
const loaded = await loadVoiceWakeConfig(baseDir);
expect(loaded.triggers).toEqual(["hi", "there"]);
expect(loaded.updatedAtMs).toBeGreaterThan(0);
});
});
it("falls back to defaults when triggers empty", async () => {
const baseDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-voicewake-"));
const saved = await setVoiceWakeTriggers(["", " "], baseDir);
expect(saved.triggers).toEqual(defaultVoiceWakeTriggers());
await withTempDir("openclaw-voicewake-", async (baseDir) => {
const saved = await setVoiceWakeTriggers(["", " "], baseDir);
expect(saved.triggers).toEqual(defaultVoiceWakeTriggers());
});
});
it("sanitizes malformed persisted config values", async () => {
await withTempDir("openclaw-voicewake-", async (baseDir) => {
await fs.mkdir(path.join(baseDir, "settings"), { recursive: true });
await fs.writeFile(
path.join(baseDir, "settings", "voicewake.json"),
JSON.stringify({
triggers: [" wake ", "", 42, null],
updatedAtMs: -1,
}),
"utf-8",
);
const loaded = await loadVoiceWakeConfig(baseDir);
expect(loaded.triggers).toEqual(["wake"]);
expect(loaded.updatedAtMs).toBe(0);
});
});
});