openclaw/src/plugins/channel-plugin-ids.test.ts

215 lines
5.7 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
const listPotentialConfiguredChannelIds = vi.hoisted(() => vi.fn());
const loadPluginManifestRegistry = vi.hoisted(() => vi.fn());
vi.mock("../channels/config-presence.js", () => ({
listPotentialConfiguredChannelIds,
}));
vi.mock("./manifest-registry.js", () => ({
loadPluginManifestRegistry,
}));
import { resolveGatewayStartupPluginIds } from "./channel-plugin-ids.js";
function createManifestRegistryFixture() {
return {
plugins: [
{
id: "demo-channel",
channels: ["demo-channel"],
origin: "bundled",
enabledByDefault: undefined,
providers: [],
cliBackends: [],
},
{
id: "demo-other-channel",
channels: ["demo-other-channel"],
origin: "bundled",
enabledByDefault: undefined,
providers: [],
cliBackends: [],
},
{
id: "browser",
channels: [],
origin: "bundled",
enabledByDefault: true,
providers: [],
cliBackends: [],
},
{
id: "demo-provider-plugin",
channels: [],
origin: "bundled",
enabledByDefault: undefined,
providers: ["demo-provider"],
cliBackends: ["demo-cli"],
},
{
id: "voice-call",
channels: [],
origin: "bundled",
enabledByDefault: undefined,
providers: [],
cliBackends: [],
},
{
id: "demo-global-sidecar",
channels: [],
origin: "global",
enabledByDefault: undefined,
providers: [],
cliBackends: [],
},
],
diagnostics: [],
};
}
function expectStartupPluginIds(config: OpenClawConfig, expected: readonly string[]) {
expect(
resolveGatewayStartupPluginIds({
config,
workspaceDir: "/tmp",
env: process.env,
}),
).toEqual(expected);
expect(loadPluginManifestRegistry).toHaveBeenCalled();
}
function expectStartupPluginIdsCase(params: {
config: OpenClawConfig;
expected: readonly string[];
}) {
expectStartupPluginIds(params.config, params.expected);
}
function createStartupConfig(params: {
enabledPluginIds?: string[];
providerIds?: string[];
modelId?: string;
channelIds?: string[];
allowPluginIds?: string[];
noConfiguredChannels?: boolean;
}) {
return {
...(params.noConfiguredChannels
? {
channels: {},
}
: params.channelIds?.length
? {
channels: Object.fromEntries(
params.channelIds.map((channelId) => [channelId, { enabled: true }]),
),
}
: {}),
...(params.enabledPluginIds?.length
? {
plugins: {
...(params.allowPluginIds?.length ? { allow: params.allowPluginIds } : {}),
entries: Object.fromEntries(
params.enabledPluginIds.map((pluginId) => [pluginId, { enabled: true }]),
),
},
}
: params.allowPluginIds?.length
? {
plugins: {
allow: params.allowPluginIds,
},
}
: {}),
...(params.providerIds?.length
? {
models: {
providers: Object.fromEntries(
params.providerIds.map((providerId) => [
providerId,
{
baseUrl: "https://example.com",
models: [],
},
]),
),
},
}
: {}),
...(params.modelId
? {
agents: {
defaults: {
model: { primary: params.modelId },
models: {
[params.modelId]: {},
},
},
},
}
: {}),
} as OpenClawConfig;
}
describe("resolveGatewayStartupPluginIds", () => {
beforeEach(() => {
listPotentialConfiguredChannelIds.mockReset().mockImplementation((config: OpenClawConfig) => {
if (Object.prototype.hasOwnProperty.call(config, "channels")) {
return Object.keys(config.channels ?? {});
}
return ["demo-channel"];
});
loadPluginManifestRegistry.mockReset().mockReturnValue(createManifestRegistryFixture());
});
it.each([
[
"includes only configured channel plugins at idle startup",
createStartupConfig({
enabledPluginIds: ["voice-call"],
modelId: "demo-cli/demo-model",
}),
["demo-channel", "browser", "voice-call"],
],
[
"keeps bundled startup sidecars with enabledByDefault at idle startup",
{} as OpenClawConfig,
["demo-channel", "browser"],
],
[
"keeps provider plugins out of idle startup when only provider config references them",
createStartupConfig({
providerIds: ["demo-provider"],
}),
["demo-channel", "browser"],
],
[
"includes explicitly enabled non-channel sidecars in startup scope",
createStartupConfig({
enabledPluginIds: ["demo-global-sidecar", "voice-call"],
}),
["demo-channel", "browser", "voice-call", "demo-global-sidecar"],
],
[
"keeps default-enabled startup sidecars when a restrictive allowlist permits them",
createStartupConfig({
allowPluginIds: ["browser"],
noConfiguredChannels: true,
}),
["browser"],
],
[
"includes every configured channel plugin and excludes other channels",
createStartupConfig({
channelIds: ["demo-channel", "demo-other-channel"],
}),
["demo-channel", "demo-other-channel", "browser"],
],
] as const)("%s", (_name, config, expected) => {
expectStartupPluginIdsCase({ config, expected });
});
});