mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 21:08:25 +00:00
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 fs from "node:fs/promises";
|
||||||
import { createServer } from "node:net";
|
import { createServer } from "node:net";
|
||||||
import os from "node:os";
|
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { afterAll, beforeAll, describe, expect, test } from "vitest";
|
import { afterAll, beforeAll, describe, expect, test } from "vitest";
|
||||||
import { WebSocket } from "ws";
|
import { WebSocket } from "ws";
|
||||||
@@ -11,6 +10,7 @@ import { GatewayLockError } from "../infra/gateway-lock.js";
|
|||||||
import { getActivePluginRegistry, setActivePluginRegistry } from "../plugins/runtime.js";
|
import { getActivePluginRegistry, setActivePluginRegistry } from "../plugins/runtime.js";
|
||||||
import { createOutboundTestPlugin } from "../test-utils/channel-plugins.js";
|
import { createOutboundTestPlugin } from "../test-utils/channel-plugins.js";
|
||||||
import { captureEnv } from "../test-utils/env.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 { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../utils/message-channel.js";
|
||||||
import { createRegistry } from "./server.e2e-registry-helpers.js";
|
import { createRegistry } from "./server.e2e-registry-helpers.js";
|
||||||
import {
|
import {
|
||||||
@@ -81,140 +81,99 @@ const whatsappRegistry = createRegistry([
|
|||||||
const emptyRegistry = createRegistry([]);
|
const emptyRegistry = createRegistry([]);
|
||||||
|
|
||||||
describe("gateway server models + voicewake", () => {
|
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(
|
test(
|
||||||
"voicewake.get returns defaults and voicewake.set broadcasts",
|
"voicewake.get returns defaults and voicewake.set broadcasts",
|
||||||
{ timeout: 60_000 },
|
{ timeout: 60_000 },
|
||||||
async () => {
|
async () => {
|
||||||
const homeDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-home-"));
|
const tempHome = await createTempHomeEnv("openclaw-home-");
|
||||||
const restoreHome = setTempHome(homeDir);
|
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");
|
const changedP = onceMessage(
|
||||||
expect(initial.ok).toBe(true);
|
ws,
|
||||||
expect(initial.payload?.triggers).toEqual(["openclaw", "claude", "computer"]);
|
(o) => o.type === "event" && o.event === "voicewake.changed",
|
||||||
|
);
|
||||||
|
|
||||||
const changedP = onceMessage(
|
const setRes = await rpcReq<{ triggers: string[] }>(ws, "voicewake.set", {
|
||||||
ws,
|
triggers: [" hi ", "", "there"],
|
||||||
(o) => o.type === "event" && o.event === "voicewake.changed",
|
});
|
||||||
);
|
expect(setRes.ok).toBe(true);
|
||||||
|
expect(setRes.payload?.triggers).toEqual(["hi", "there"]);
|
||||||
|
|
||||||
const setRes = await rpcReq<{ triggers: string[] }>(ws, "voicewake.set", {
|
const changed = (await changedP) as { event?: string; payload?: unknown };
|
||||||
triggers: [" hi ", "", "there"],
|
expect(changed.event).toBe("voicewake.changed");
|
||||||
});
|
expect((changed.payload as { triggers?: unknown } | undefined)?.triggers).toEqual([
|
||||||
expect(setRes.ok).toBe(true);
|
"hi",
|
||||||
expect(setRes.payload?.triggers).toEqual(["hi", "there"]);
|
"there",
|
||||||
|
]);
|
||||||
|
|
||||||
const changed = (await changedP) as { event?: string; payload?: unknown };
|
const after = await rpcReq<{ triggers: string[] }>(ws, "voicewake.get");
|
||||||
expect(changed.event).toBe("voicewake.changed");
|
expect(after.ok).toBe(true);
|
||||||
expect((changed.payload as { triggers?: unknown } | undefined)?.triggers).toEqual([
|
expect(after.payload?.triggers).toEqual(["hi", "there"]);
|
||||||
"hi",
|
|
||||||
"there",
|
|
||||||
]);
|
|
||||||
|
|
||||||
const after = await rpcReq<{ triggers: string[] }>(ws, "voicewake.get");
|
const onDisk = JSON.parse(
|
||||||
expect(after.ok).toBe(true);
|
await fs.readFile(
|
||||||
expect(after.payload?.triggers).toEqual(["hi", "there"]);
|
path.join(tempHome.home, ".openclaw", "settings", "voicewake.json"),
|
||||||
|
"utf8",
|
||||||
const onDisk = JSON.parse(
|
),
|
||||||
await fs.readFile(path.join(homeDir, ".openclaw", "settings", "voicewake.json"), "utf8"),
|
) as { triggers?: unknown; updatedAtMs?: unknown };
|
||||||
) as { triggers?: unknown; updatedAtMs?: unknown };
|
expect(onDisk.triggers).toEqual(["hi", "there"]);
|
||||||
expect(onDisk.triggers).toEqual(["hi", "there"]);
|
expect(typeof onDisk.updatedAtMs).toBe("number");
|
||||||
expect(typeof onDisk.updatedAtMs).toBe("number");
|
} finally {
|
||||||
|
await tempHome.restore();
|
||||||
restoreHome();
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
test("pushes voicewake.changed to nodes on connect and on updates", async () => {
|
test("pushes voicewake.changed to nodes on connect and on updates", async () => {
|
||||||
const homeDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-home-"));
|
const tempHome = await createTempHomeEnv("openclaw-home-");
|
||||||
const restoreHome = setTempHome(homeDir);
|
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}`);
|
const first = (await firstEventP) as { event?: string; payload?: unknown };
|
||||||
await new Promise<void>((resolve) => nodeWs.once("open", resolve));
|
expect(first.event).toBe("voicewake.changed");
|
||||||
const firstEventP = onceMessage(
|
expect((first.payload as { triggers?: unknown } | undefined)?.triggers).toEqual([
|
||||||
nodeWs,
|
"openclaw",
|
||||||
(o) => o.type === "event" && o.event === "voicewake.changed",
|
"claude",
|
||||||
);
|
"computer",
|
||||||
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 };
|
const broadcastP = onceMessage(
|
||||||
expect(first.event).toBe("voicewake.changed");
|
nodeWs,
|
||||||
expect((first.payload as { triggers?: unknown } | undefined)?.triggers).toEqual([
|
(o) => o.type === "event" && o.event === "voicewake.changed",
|
||||||
"openclaw",
|
);
|
||||||
"claude",
|
const setRes = await rpcReq<{ triggers: string[] }>(ws, "voicewake.set", {
|
||||||
"computer",
|
triggers: ["openclaw", "computer"],
|
||||||
]);
|
});
|
||||||
|
expect(setRes.ok).toBe(true);
|
||||||
|
|
||||||
const broadcastP = onceMessage(
|
const broadcast = (await broadcastP) as { event?: string; payload?: unknown };
|
||||||
nodeWs,
|
expect(broadcast.event).toBe("voicewake.changed");
|
||||||
(o) => o.type === "event" && o.event === "voicewake.changed",
|
expect((broadcast.payload as { triggers?: unknown } | undefined)?.triggers).toEqual([
|
||||||
);
|
"openclaw",
|
||||||
const setRes = await rpcReq<{ triggers: string[] }>(ws, "voicewake.set", {
|
"computer",
|
||||||
triggers: ["openclaw", "computer"],
|
]);
|
||||||
});
|
|
||||||
expect(setRes.ok).toBe(true);
|
|
||||||
|
|
||||||
const broadcast = (await broadcastP) as { event?: string; payload?: unknown };
|
nodeWs.close();
|
||||||
expect(broadcast.event).toBe("voicewake.changed");
|
} finally {
|
||||||
expect((broadcast.payload as { triggers?: unknown } | undefined)?.triggers).toEqual([
|
await tempHome.restore();
|
||||||
"openclaw",
|
}
|
||||||
"computer",
|
|
||||||
]);
|
|
||||||
|
|
||||||
nodeWs.close();
|
|
||||||
restoreHome();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("models.list returns model catalog", async () => {
|
test("models.list returns model catalog", async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user