perf(test): avoid bundled setup in auto-enable tests

This commit is contained in:
Peter Steinberger
2026-04-22 17:13:42 +01:00
parent dd46783c34
commit fd93b7f2ab
5 changed files with 194 additions and 20 deletions

View File

@@ -1,4 +1,7 @@
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { createTestPluginApi } from "../../test/helpers/plugins/plugin-api.js";
import setupPlugin from "./setup-api.js";
const { createAcpxRuntimeServiceMock, tryDispatchAcpReplyHookMock } = vi.hoisted(() => ({
createAcpxRuntimeServiceMock: vi.fn(),
@@ -15,6 +18,24 @@ vi.mock("./runtime-api.js", () => ({
import plugin from "./index.js";
type AcpxAutoEnableProbe = Parameters<OpenClawPluginApi["registerAutoEnableProbe"]>[0];
function registerAcpxAutoEnableProbe(): AcpxAutoEnableProbe {
const probes: AcpxAutoEnableProbe[] = [];
setupPlugin.register(
createTestPluginApi({
registerAutoEnableProbe(probe) {
probes.push(probe);
},
}),
);
const probe = probes[0];
if (!probe) {
throw new Error("expected ACPX setup plugin to register an auto-enable probe");
}
return probe;
}
describe("acpx plugin", () => {
beforeEach(() => {
vi.clearAllMocks();
@@ -38,4 +59,14 @@ describe("acpx plugin", () => {
expect(api.registerService).toHaveBeenCalledWith(service);
expect(api.on).toHaveBeenCalledWith("reply_dispatch", tryDispatchAcpReplyHookMock);
});
it("declares setup auto-enable reasons for ACPX-owned ACP config", () => {
const probe = registerAcpxAutoEnableProbe();
expect(probe({ config: { acp: { enabled: true } }, env: {} })).toBe("ACP runtime configured");
expect(probe({ config: { acp: { backend: "acpx" } }, env: {} })).toBe("ACP runtime configured");
expect(probe({ config: { acp: { enabled: true, backend: "custom-runtime" } }, env: {} })).toBe(
null,
);
});
});

View File

@@ -7,6 +7,9 @@ import {
registerBrowserPlugin,
} from "./plugin-registration.js";
import type { OpenClawPluginApi } from "./runtime-api.js";
import setupPlugin from "./setup-api.js";
type BrowserAutoEnableProbe = Parameters<OpenClawPluginApi["registerAutoEnableProbe"]>[0];
const runtimeApiMocks = vi.hoisted(() => ({
createBrowserPluginService: vi.fn(() => ({ id: "browser-control", start: vi.fn() })),
@@ -51,6 +54,22 @@ function createApi() {
return { api, registerCli, registerGatewayMethod, registerService, registerTool };
}
function registerBrowserAutoEnableProbe(): BrowserAutoEnableProbe {
const probes: BrowserAutoEnableProbe[] = [];
setupPlugin.register(
createTestPluginApi({
registerAutoEnableProbe(probe) {
probes.push(probe);
},
}),
);
const probe = probes[0];
if (!probe) {
throw new Error("expected browser setup plugin to register an auto-enable probe");
}
return probe;
}
describe("browser plugin", () => {
it("exposes static browser metadata on the plugin definition", () => {
expect(browserPluginReload).toEqual({ restartPrefixes: ["browser"] });
@@ -86,4 +105,18 @@ describe("browser plugin", () => {
agentSessionKey: "agent:main:webchat:direct:123",
});
});
it("declares setup auto-enable reasons for browser config surfaces", () => {
const probe = registerBrowserAutoEnableProbe();
expect(probe({ config: { browser: { defaultProfile: "openclaw" } }, env: {} })).toBe(
"browser configured",
);
expect(probe({ config: { tools: { alsoAllow: ["browser"] } }, env: {} })).toBe(
"browser tool referenced",
);
expect(
probe({ config: { browser: { defaultProfile: "openclaw", enabled: false } }, env: {} }),
).toBeNull();
});
});

View File

@@ -1,6 +1,9 @@
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
import { describe, expect, it } from "vitest";
import { createTestPluginApi } from "../../test/helpers/plugins/plugin-api.js";
import { registerSingleProviderPlugin } from "../../test/helpers/plugins/plugin-registration.js";
import plugin from "./index.js";
import setupPlugin from "./setup-api.js";
import {
createXaiPayloadCaptureStream,
expectXaiFastToolStreamShaping,
@@ -27,7 +30,45 @@ function createProviderModel(overrides: {
};
}
type XaiAutoEnableProbe = Parameters<OpenClawPluginApi["registerAutoEnableProbe"]>[0];
function registerXaiAutoEnableProbe(): XaiAutoEnableProbe {
const probes: XaiAutoEnableProbe[] = [];
setupPlugin.register(
createTestPluginApi({
registerAutoEnableProbe(probe) {
probes.push(probe);
},
}),
);
const probe = probes[0];
if (!probe) {
throw new Error("expected xAI setup plugin to register an auto-enable probe");
}
return probe;
}
describe("xai provider plugin", () => {
it("declares setup auto-enable reasons for plugin-owned tool config", () => {
const probe = registerXaiAutoEnableProbe();
expect(
probe({
config: { plugins: { entries: { xai: { config: { xSearch: { enabled: true } } } } } },
env: {},
}),
).toBe("xai tool configured");
expect(
probe({
config: {
plugins: { entries: { xai: { config: { codeExecution: { enabled: true } } } } },
},
env: {},
}),
).toBe("xai tool configured");
expect(probe({ config: {}, env: {} })).toBeNull();
});
it("owns replay policy for xAI OpenAI-compatible transports", async () => {
const provider = await registerSingleProviderPlugin(plugin);

View File

@@ -2,6 +2,7 @@ import { afterAll, describe, expect, it } from "vitest";
import {
applyPluginAutoEnable,
detectPluginAutoEnableCandidates,
materializePluginAutoEnableCandidates,
resolvePluginAutoEnableCandidateReason,
} from "./plugin-auto-enable.js";
import {
@@ -97,16 +98,20 @@ describe("applyPluginAutoEnable core", () => {
expect(Object.getPrototypeOf(result.autoEnabledReasons)).toBeNull();
});
it("auto-enables browser when browser config exists under a restrictive plugins.allow", () => {
const result = applyPluginAutoEnable({
it("materializes setup auto-enable candidates under a restrictive plugins.allow", () => {
const result = materializePluginAutoEnableCandidates({
config: {
browser: {
defaultProfile: "openclaw",
},
plugins: {
allow: ["telegram"],
},
},
candidates: [
{
pluginId: "browser",
kind: "setup-auto-enable",
reason: "browser configured",
},
],
env,
});
@@ -115,16 +120,20 @@ describe("applyPluginAutoEnable core", () => {
expect(result.changes).toContain("browser configured, enabled automatically.");
});
it("auto-enables browser when tools.alsoAllow references browser", () => {
const result = applyPluginAutoEnable({
it("materializes setup auto-enable tool-reference reasons", () => {
const result = materializePluginAutoEnableCandidates({
config: {
tools: {
alsoAllow: ["browser"],
},
plugins: {
allow: ["telegram"],
},
},
candidates: [
{
pluginId: "browser",
kind: "setup-auto-enable",
reason: "browser tool referenced",
},
],
env,
});

View File

@@ -1,5 +1,8 @@
import { afterAll, describe, expect, it } from "vitest";
import { applyPluginAutoEnable } from "./plugin-auto-enable.js";
import {
applyPluginAutoEnable,
materializePluginAutoEnableCandidates,
} from "./plugin-auto-enable.js";
import {
makeIsolatedEnv,
makeRegistry,
@@ -26,12 +29,19 @@ describe("applyPluginAutoEnable providers", () => {
},
},
env,
manifestRegistry: makeRegistry([
{
id: "google",
channels: [],
autoEnableWhenConfiguredProviders: ["google-gemini-cli"],
},
]),
});
expect(result.config.plugins?.entries?.google?.enabled).toBe(true);
});
it("auto-enables bundled provider plugins when plugin-owned web search config exists", () => {
it("auto-enables provider plugins when plugin-owned web search config exists", () => {
const result = applyPluginAutoEnable({
config: {
plugins: {
@@ -47,14 +57,24 @@ describe("applyPluginAutoEnable providers", () => {
},
},
env,
manifestRegistry: makeRegistry([
{
id: "xai",
channels: [],
providers: ["xai"],
contracts: {
webSearchProviders: ["grok"],
},
},
]),
});
expect(result.config.plugins?.entries?.xai?.enabled).toBe(true);
expect(result.changes).toContain("xai web search configured, enabled automatically.");
});
it("auto-enables xai when the plugin-owned x_search tool is configured", () => {
const result = applyPluginAutoEnable({
it("materializes xai setup auto-enable when the plugin-owned x_search tool is configured", () => {
const result = materializePluginAutoEnableCandidates({
config: {
plugins: {
entries: {
@@ -68,15 +88,23 @@ describe("applyPluginAutoEnable providers", () => {
},
},
},
candidates: [
{
pluginId: "xai",
kind: "setup-auto-enable",
reason: "xai tool configured",
},
],
env,
manifestRegistry: makeRegistry([{ id: "xai", channels: [] }]),
});
expect(result.config.plugins?.entries?.xai?.enabled).toBe(true);
expect(result.changes).toContain("xai tool configured, enabled automatically.");
});
it("auto-enables xai when the plugin-owned codeExecution config is configured", () => {
const result = applyPluginAutoEnable({
it("materializes xai setup auto-enable when the plugin-owned codeExecution config is configured", () => {
const result = materializePluginAutoEnableCandidates({
config: {
plugins: {
entries: {
@@ -91,7 +119,15 @@ describe("applyPluginAutoEnable providers", () => {
},
},
},
candidates: [
{
pluginId: "xai",
kind: "setup-auto-enable",
reason: "xai tool configured",
},
],
env,
manifestRegistry: makeRegistry([{ id: "xai", channels: [] }]),
});
expect(result.config.plugins?.entries?.xai?.enabled).toBe(true);
@@ -111,6 +147,13 @@ describe("applyPluginAutoEnable providers", () => {
},
},
env,
manifestRegistry: makeRegistry([
{
id: "minimax",
channels: [],
autoEnableWhenConfiguredProviders: ["minimax-portal"],
},
]),
});
expect(result.config.plugins?.entries?.minimax?.enabled).toBe(true);
@@ -130,6 +173,13 @@ describe("applyPluginAutoEnable providers", () => {
},
},
env,
manifestRegistry: makeRegistry([
{
id: "minimax",
channels: [],
autoEnableWhenConfiguredProviders: ["minimax"],
},
]),
});
expect(result.config.plugins?.entries?.minimax?.enabled).toBe(true);
@@ -148,6 +198,7 @@ describe("applyPluginAutoEnable providers", () => {
},
},
env,
manifestRegistry: makeRegistry([]),
});
expect(result.config.plugins?.entries?.openai).toBeUndefined();
@@ -249,13 +300,20 @@ describe("applyPluginAutoEnable providers", () => {
expect(result.changes).toContain("acme tool configured, enabled automatically.");
});
it("auto-enables acpx plugin when ACP is configured", () => {
const result = applyPluginAutoEnable({
it("materializes acpx setup auto-enable when ACP is configured", () => {
const result = materializePluginAutoEnableCandidates({
config: {
acp: {
enabled: true,
},
},
candidates: [
{
pluginId: "acpx",
kind: "setup-auto-enable",
reason: "ACP runtime configured",
},
],
env,
});
@@ -263,17 +321,19 @@ describe("applyPluginAutoEnable providers", () => {
expect(result.changes.join("\n")).toContain("ACP runtime configured, enabled automatically.");
});
it("does not auto-enable acpx when a different ACP backend is configured", () => {
const result = applyPluginAutoEnable({
it("does not materialize acpx when no setup auto-enable candidate is present", () => {
const result = materializePluginAutoEnableCandidates({
config: {
acp: {
enabled: true,
backend: "custom-runtime",
},
},
candidates: [],
env,
});
expect(result.config.plugins?.entries?.acpx?.enabled).toBeUndefined();
expect(result.changes).toEqual([]);
});
});