Files
openclaw/src/gateway/server-methods/channels.status.test.ts
2026-04-05 08:43:21 +01:00

136 lines
3.7 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from "vitest";
import type { GatewayRequestHandlerOptions } from "./types.js";
const mocks = vi.hoisted(() => ({
loadConfig: vi.fn(() => ({})),
applyPluginAutoEnable: vi.fn(),
listChannelPlugins: vi.fn(),
buildChannelUiCatalog: vi.fn(),
buildChannelAccountSnapshot: vi.fn(),
getChannelActivity: vi.fn(),
}));
vi.mock("../../config/config.js", () => ({
loadConfig: mocks.loadConfig,
readConfigFileSnapshot: vi.fn(async () => ({
config: {},
path: "openclaw.config.json",
raw: "{}",
})),
}));
vi.mock("../../config/plugin-auto-enable.js", () => ({
applyPluginAutoEnable: mocks.applyPluginAutoEnable,
}));
vi.mock("../../channels/plugins/index.js", () => ({
listChannelPlugins: mocks.listChannelPlugins,
getChannelPlugin: vi.fn(),
normalizeChannelId: (value: string) => value,
}));
vi.mock("../../channels/plugins/catalog.js", () => ({
buildChannelUiCatalog: mocks.buildChannelUiCatalog,
}));
vi.mock("../../channels/plugins/status.js", () => ({
buildChannelAccountSnapshot: mocks.buildChannelAccountSnapshot,
}));
vi.mock("../../infra/channel-activity.js", () => ({
getChannelActivity: mocks.getChannelActivity,
}));
import { channelsHandlers } from "./channels.js";
function createOptions(
params: Record<string, unknown>,
overrides?: Partial<GatewayRequestHandlerOptions>,
): GatewayRequestHandlerOptions {
return {
req: { type: "req", id: "req-1", method: "channels.status", params },
params,
client: null,
isWebchatConnect: () => false,
respond: vi.fn(),
context: {
getRuntimeSnapshot: () => ({
channels: {},
channelAccounts: {},
}),
},
...overrides,
} as unknown as GatewayRequestHandlerOptions;
}
describe("channelsHandlers channels.status", () => {
beforeEach(() => {
vi.clearAllMocks();
mocks.loadConfig.mockReturnValue({});
mocks.applyPluginAutoEnable.mockImplementation(({ config }) => ({ config, changes: [] }));
mocks.buildChannelUiCatalog.mockReturnValue({
order: ["whatsapp"],
labels: { whatsapp: "WhatsApp" },
detailLabels: { whatsapp: "WhatsApp" },
systemImages: { whatsapp: undefined },
entries: { whatsapp: { id: "whatsapp" } },
});
mocks.buildChannelAccountSnapshot.mockResolvedValue({
accountId: "default",
configured: true,
});
mocks.getChannelActivity.mockReturnValue({
inboundAt: null,
outboundAt: null,
});
mocks.listChannelPlugins.mockReturnValue([
{
id: "whatsapp",
config: {
listAccountIds: () => ["default"],
resolveAccount: () => ({}),
isEnabled: () => true,
isConfigured: async (_account: unknown, cfg: { autoEnabled?: boolean }) =>
Boolean(cfg.autoEnabled),
},
},
]);
});
it("uses the auto-enabled config snapshot for channel account state", async () => {
const autoEnabledConfig = { autoEnabled: true };
mocks.applyPluginAutoEnable.mockReturnValue({ config: autoEnabledConfig, changes: [] });
const respond = vi.fn();
const opts = createOptions(
{ probe: false, timeoutMs: 2000 },
{
respond,
},
);
await channelsHandlers["channels.status"](opts);
expect(mocks.applyPluginAutoEnable).toHaveBeenCalledWith({
config: {},
env: process.env,
});
expect(mocks.buildChannelAccountSnapshot).toHaveBeenCalledWith(
expect.objectContaining({
cfg: autoEnabledConfig,
accountId: "default",
}),
);
expect(respond).toHaveBeenCalledWith(
true,
expect.objectContaining({
channels: {
whatsapp: expect.objectContaining({
configured: true,
}),
},
}),
undefined,
);
});
});