Skip to content

Commit d85f604

Browse files
committed
test(whatsapp): cover self-chat reload handling
1 parent d1a3d74 commit d85f604

1 file changed

Lines changed: 50 additions & 3 deletions

File tree

src/gateway/server-reload-handlers.test.ts

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,13 @@ import { afterEach, describe, expect, it, vi } from "vitest";
55
import type { ConfigWriteNotification } from "../config/config.js";
66
import type { OpenClawConfig } from "../config/types.openclaw.js";
77
import { consumeGatewaySigusr1RestartIntent } from "../infra/restart.js";
8+
import {
9+
pinActivePluginChannelRegistry,
10+
releasePinnedPluginChannelRegistry,
11+
} from "../plugins/runtime.js";
812
import { createEmptyRuntimeWebToolsMetadata } from "../secrets/runtime-fast-path.js";
913
import { activateSecretsRuntimeSnapshot, clearSecretsRuntimeSnapshot } from "../secrets/runtime.js";
14+
import { createChannelTestPluginBase, createTestRegistry } from "../test-utils/channel-plugins.js";
1015
import { diffConfigPaths } from "./config-diff.js";
1116
import {
1217
buildGatewayReloadPlan,
@@ -141,7 +146,13 @@ vi.mock("../agents/agent-bundle-mcp-tools.js", () => ({
141146
disposeAllSessionMcpRuntimes: hoisted.disposeAllSessionMcpRuntimes,
142147
}));
143148

144-
function createReloadHandlersForTest(logReload = { info: vi.fn(), warn: vi.fn() }) {
149+
function createReloadHandlersForTest(
150+
logReload = { info: vi.fn(), warn: vi.fn() },
151+
channels?: {
152+
start: (channel: ChannelKind) => Promise<void>;
153+
stop: (channel: ChannelKind) => Promise<void>;
154+
},
155+
) {
145156
const cron = { start: vi.fn(async () => {}), stop: vi.fn() };
146157
const heartbeatRunner = {
147158
stop: vi.fn(),
@@ -158,8 +169,8 @@ function createReloadHandlersForTest(logReload = { info: vi.fn(), warn: vi.fn()
158169
channelHealthMonitor: null,
159170
}),
160171
setState: vi.fn(),
161-
startChannel: vi.fn(async () => {}),
162-
stopChannel: vi.fn(async () => {}),
172+
startChannel: channels?.start ?? vi.fn(async () => {}),
173+
stopChannel: channels?.stop ?? vi.fn(async () => {}),
163174
stopPostReadySidecars: vi.fn(),
164175
reloadPlugins: vi.fn(
165176
async (): Promise<GatewayPluginReloadResult> => ({
@@ -889,6 +900,42 @@ describe("gateway channel hot reload handlers", () => {
889900
}
890901
}
891902

903+
it("restarts WhatsApp when the planner receives a selfChatMode change", async () => {
904+
const whatsappPlugin = {
905+
...createChannelTestPluginBase({ id: "whatsapp" }),
906+
reload: {
907+
configPrefixes: ["web", "channels.whatsapp.accounts", "channels.whatsapp.selfChatMode"],
908+
noopPrefixes: ["channels.whatsapp"],
909+
},
910+
};
911+
const registry = createTestRegistry([
912+
{ pluginId: "whatsapp", plugin: whatsappPlugin, source: "test" },
913+
]);
914+
const events: string[] = [];
915+
const channels = {
916+
stop: vi.fn(async (channel: ChannelKind) => {
917+
events.push(`stop:${channel}`);
918+
}),
919+
start: vi.fn(async (channel: ChannelKind) => {
920+
events.push(`start:${channel}`);
921+
}),
922+
};
923+
924+
pinActivePluginChannelRegistry(registry);
925+
try {
926+
const plan = buildGatewayReloadPlan(["channels.whatsapp.selfChatMode"]);
927+
const { applyHotReload } = createReloadHandlersForTest(undefined, channels);
928+
929+
expect(plan.restartGateway).toBe(false);
930+
expect(plan.restartChannels).toEqual(new Set(["whatsapp"]));
931+
await withChannelReloadsEnabled(() => applyHotReload(plan, {}));
932+
933+
expect(events).toEqual(["stop:whatsapp", "start:whatsapp"]);
934+
} finally {
935+
releasePinnedPluginChannelRegistry(registry);
936+
}
937+
});
938+
892939
it("continues restarting later channels after a hot-reload stop failure", async () => {
893940
const events: string[] = [];
894941
const setState = vi.fn();

0 commit comments

Comments
 (0)