From c529bafdc3cf5641608d353630baec1e3cf9dc55 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 21 Feb 2026 12:54:54 +0000 Subject: [PATCH] refactor(test): reuse temp-home helper in voicewake e2e --- .../server.models-voicewake-misc.e2e.test.ts | 195 +++++++----------- 1 file changed, 77 insertions(+), 118 deletions(-) diff --git a/src/gateway/server.models-voicewake-misc.e2e.test.ts b/src/gateway/server.models-voicewake-misc.e2e.test.ts index 33d1b1423..63fe4441f 100644 --- a/src/gateway/server.models-voicewake-misc.e2e.test.ts +++ b/src/gateway/server.models-voicewake-misc.e2e.test.ts @@ -1,6 +1,5 @@ import fs from "node:fs/promises"; import { createServer } from "node:net"; -import os from "node:os"; import path from "node:path"; import { afterAll, beforeAll, describe, expect, test } from "vitest"; import { WebSocket } from "ws"; @@ -11,6 +10,7 @@ import { GatewayLockError } from "../infra/gateway-lock.js"; import { getActivePluginRegistry, setActivePluginRegistry } from "../plugins/runtime.js"; import { createOutboundTestPlugin } from "../test-utils/channel-plugins.js"; import { captureEnv } from "../test-utils/env.js"; +import { createTempHomeEnv } from "../test-utils/temp-home.js"; import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../utils/message-channel.js"; import { createRegistry } from "./server.e2e-registry-helpers.js"; import { @@ -81,140 +81,99 @@ const whatsappRegistry = createRegistry([ const emptyRegistry = createRegistry([]); describe("gateway server models + voicewake", () => { - const setTempHome = (homeDir: string) => { - const prevHome = process.env.HOME; - const prevStateDir = process.env.OPENCLAW_STATE_DIR; - const prevUserProfile = process.env.USERPROFILE; - const prevHomeDrive = process.env.HOMEDRIVE; - const prevHomePath = process.env.HOMEPATH; - process.env.HOME = homeDir; - process.env.OPENCLAW_STATE_DIR = path.join(homeDir, ".openclaw"); - process.env.USERPROFILE = homeDir; - if (process.platform === "win32") { - const parsed = path.parse(homeDir); - process.env.HOMEDRIVE = parsed.root.replace(/\\$/, ""); - process.env.HOMEPATH = homeDir.slice(Math.max(parsed.root.length - 1, 0)); - } - return () => { - if (prevHome === undefined) { - delete process.env.HOME; - } else { - process.env.HOME = prevHome; - } - if (prevStateDir === undefined) { - delete process.env.OPENCLAW_STATE_DIR; - } else { - process.env.OPENCLAW_STATE_DIR = prevStateDir; - } - if (prevUserProfile === undefined) { - delete process.env.USERPROFILE; - } else { - process.env.USERPROFILE = prevUserProfile; - } - if (process.platform === "win32") { - if (prevHomeDrive === undefined) { - delete process.env.HOMEDRIVE; - } else { - process.env.HOMEDRIVE = prevHomeDrive; - } - if (prevHomePath === undefined) { - delete process.env.HOMEPATH; - } else { - process.env.HOMEPATH = prevHomePath; - } - } - }; - }; - test( "voicewake.get returns defaults and voicewake.set broadcasts", { timeout: 60_000 }, async () => { - const homeDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-home-")); - const restoreHome = setTempHome(homeDir); + const tempHome = await createTempHomeEnv("openclaw-home-"); + try { + const initial = await rpcReq<{ triggers: string[] }>(ws, "voicewake.get"); + expect(initial.ok).toBe(true); + expect(initial.payload?.triggers).toEqual(["openclaw", "claude", "computer"]); - const initial = await rpcReq<{ triggers: string[] }>(ws, "voicewake.get"); - expect(initial.ok).toBe(true); - expect(initial.payload?.triggers).toEqual(["openclaw", "claude", "computer"]); + const changedP = onceMessage( + ws, + (o) => o.type === "event" && o.event === "voicewake.changed", + ); - const changedP = onceMessage( - ws, - (o) => o.type === "event" && o.event === "voicewake.changed", - ); + const setRes = await rpcReq<{ triggers: string[] }>(ws, "voicewake.set", { + triggers: [" hi ", "", "there"], + }); + expect(setRes.ok).toBe(true); + expect(setRes.payload?.triggers).toEqual(["hi", "there"]); - const setRes = await rpcReq<{ triggers: string[] }>(ws, "voicewake.set", { - triggers: [" hi ", "", "there"], - }); - expect(setRes.ok).toBe(true); - expect(setRes.payload?.triggers).toEqual(["hi", "there"]); + const changed = (await changedP) as { event?: string; payload?: unknown }; + expect(changed.event).toBe("voicewake.changed"); + expect((changed.payload as { triggers?: unknown } | undefined)?.triggers).toEqual([ + "hi", + "there", + ]); - const changed = (await changedP) as { event?: string; payload?: unknown }; - expect(changed.event).toBe("voicewake.changed"); - expect((changed.payload as { triggers?: unknown } | undefined)?.triggers).toEqual([ - "hi", - "there", - ]); + const after = await rpcReq<{ triggers: string[] }>(ws, "voicewake.get"); + expect(after.ok).toBe(true); + expect(after.payload?.triggers).toEqual(["hi", "there"]); - const after = await rpcReq<{ triggers: string[] }>(ws, "voicewake.get"); - expect(after.ok).toBe(true); - expect(after.payload?.triggers).toEqual(["hi", "there"]); - - const onDisk = JSON.parse( - await fs.readFile(path.join(homeDir, ".openclaw", "settings", "voicewake.json"), "utf8"), - ) as { triggers?: unknown; updatedAtMs?: unknown }; - expect(onDisk.triggers).toEqual(["hi", "there"]); - expect(typeof onDisk.updatedAtMs).toBe("number"); - - restoreHome(); + const onDisk = JSON.parse( + await fs.readFile( + path.join(tempHome.home, ".openclaw", "settings", "voicewake.json"), + "utf8", + ), + ) as { triggers?: unknown; updatedAtMs?: unknown }; + expect(onDisk.triggers).toEqual(["hi", "there"]); + expect(typeof onDisk.updatedAtMs).toBe("number"); + } finally { + await tempHome.restore(); + } }, ); test("pushes voicewake.changed to nodes on connect and on updates", async () => { - const homeDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-home-")); - const restoreHome = setTempHome(homeDir); + const tempHome = await createTempHomeEnv("openclaw-home-"); + try { + const nodeWs = new WebSocket(`ws://127.0.0.1:${port}`); + await new Promise((resolve) => nodeWs.once("open", resolve)); + const firstEventP = onceMessage( + nodeWs, + (o) => o.type === "event" && o.event === "voicewake.changed", + ); + await connectOk(nodeWs, { + role: "node", + client: { + id: GATEWAY_CLIENT_NAMES.NODE_HOST, + version: "1.0.0", + platform: "ios", + mode: GATEWAY_CLIENT_MODES.NODE, + }, + }); - const nodeWs = new WebSocket(`ws://127.0.0.1:${port}`); - await new Promise((resolve) => nodeWs.once("open", resolve)); - const firstEventP = onceMessage( - nodeWs, - (o) => o.type === "event" && o.event === "voicewake.changed", - ); - await connectOk(nodeWs, { - role: "node", - client: { - id: GATEWAY_CLIENT_NAMES.NODE_HOST, - version: "1.0.0", - platform: "ios", - mode: GATEWAY_CLIENT_MODES.NODE, - }, - }); + const first = (await firstEventP) as { event?: string; payload?: unknown }; + expect(first.event).toBe("voicewake.changed"); + expect((first.payload as { triggers?: unknown } | undefined)?.triggers).toEqual([ + "openclaw", + "claude", + "computer", + ]); - const first = (await firstEventP) as { event?: string; payload?: unknown }; - expect(first.event).toBe("voicewake.changed"); - expect((first.payload as { triggers?: unknown } | undefined)?.triggers).toEqual([ - "openclaw", - "claude", - "computer", - ]); + const broadcastP = onceMessage( + nodeWs, + (o) => o.type === "event" && o.event === "voicewake.changed", + ); + const setRes = await rpcReq<{ triggers: string[] }>(ws, "voicewake.set", { + triggers: ["openclaw", "computer"], + }); + expect(setRes.ok).toBe(true); - const broadcastP = onceMessage( - nodeWs, - (o) => o.type === "event" && o.event === "voicewake.changed", - ); - const setRes = await rpcReq<{ triggers: string[] }>(ws, "voicewake.set", { - triggers: ["openclaw", "computer"], - }); - expect(setRes.ok).toBe(true); + const broadcast = (await broadcastP) as { event?: string; payload?: unknown }; + expect(broadcast.event).toBe("voicewake.changed"); + expect((broadcast.payload as { triggers?: unknown } | undefined)?.triggers).toEqual([ + "openclaw", + "computer", + ]); - const broadcast = (await broadcastP) as { event?: string; payload?: unknown }; - expect(broadcast.event).toBe("voicewake.changed"); - expect((broadcast.payload as { triggers?: unknown } | undefined)?.triggers).toEqual([ - "openclaw", - "computer", - ]); - - nodeWs.close(); - restoreHome(); + nodeWs.close(); + } finally { + await tempHome.restore(); + } }); test("models.list returns model catalog", async () => {