refactor(test): reuse temp-home helper in voicewake e2e
This commit is contained in:
@@ -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<void>((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<void>((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 () => {
|
||||
|
||||
Reference in New Issue
Block a user