fix(tests): narrow bundled plugin test seams

This commit is contained in:
Peter Steinberger
2026-04-06 23:34:09 +01:00
parent 096e6462c7
commit ab0c102ed7
20 changed files with 120 additions and 29 deletions

View File

@@ -5,6 +5,7 @@ import type {
ChannelThreadingAdapter,
} from "../../channels/plugins/types.js";
import type { OpenClawConfig } from "../../config/config.js";
import { compileSlackInteractiveReplies } from "../../plugin-sdk/slack.js";
import { setActivePluginRegistry } from "../../plugins/runtime.js";
import {
createChannelTestPluginBase,

View File

@@ -0,0 +1,16 @@
// Manual facade. Keep loader boundary explicit.
type SecuritySurface = typeof import("@openclaw/feishu/security-contract-api.js");
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-runtime.js";
function loadSecuritySurface(): SecuritySurface {
return loadBundledPluginPublicSurfaceModuleSync<SecuritySurface>({
dirName: "feishu",
artifactBasename: "security-contract-api.js",
});
}
export const collectFeishuSecurityAuditFindings: SecuritySurface["collectFeishuSecurityAuditFindings"] =
((...args) =>
loadSecuritySurface().collectFeishuSecurityAuditFindings(
...args,
)) as SecuritySurface["collectFeishuSecurityAuditFindings"];

30
src/plugin-sdk/slack.ts Normal file
View File

@@ -0,0 +1,30 @@
// Manual facade. Keep loader boundary explicit.
type InteractiveRepliesSurface = typeof import("@openclaw/slack/interactive-replies-api.js");
type SecuritySurface = typeof import("@openclaw/slack/security-contract-api.js");
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-runtime.js";
function loadInteractiveRepliesSurface(): InteractiveRepliesSurface {
return loadBundledPluginPublicSurfaceModuleSync<InteractiveRepliesSurface>({
dirName: "slack",
artifactBasename: "interactive-replies-api.js",
});
}
function loadSecuritySurface(): SecuritySurface {
return loadBundledPluginPublicSurfaceModuleSync<SecuritySurface>({
dirName: "slack",
artifactBasename: "security-contract-api.js",
});
}
export const compileSlackInteractiveReplies: InteractiveRepliesSurface["compileSlackInteractiveReplies"] =
((...args) =>
loadInteractiveRepliesSurface().compileSlackInteractiveReplies(
...args,
)) as InteractiveRepliesSurface["compileSlackInteractiveReplies"];
export const collectSlackSecurityAuditFindings: SecuritySurface["collectSlackSecurityAuditFindings"] =
((...args) =>
loadSecuritySurface().collectSlackSecurityAuditFindings(
...args,
)) as SecuritySurface["collectSlackSecurityAuditFindings"];

View File

@@ -1,11 +1,20 @@
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
import * as googleChatSecrets from "../../extensions/googlechat/src/secret-contract.ts";
import * as ircSecrets from "../../extensions/irc/src/secret-contract.ts";
import * as slackSecrets from "../../extensions/slack/src/secret-contract.ts";
import type { AuthProfileStore } from "../agents/auth-profiles.js";
import type { OpenClawConfig } from "../config/config.js";
import { createEmptyPluginRegistry } from "../plugins/registry.js";
import { setActivePluginRegistry } from "../plugins/runtime.js";
import { loadBundledChannelSecretContractApi } from "./channel-contract-api.js";
const googleChatSecrets = loadBundledChannelSecretContractApi("googlechat");
const ircSecrets = loadBundledChannelSecretContractApi("irc");
const slackSecrets = loadBundledChannelSecretContractApi("slack");
if (
!googleChatSecrets?.collectRuntimeConfigAssignments ||
!ircSecrets?.collectRuntimeConfigAssignments ||
!slackSecrets?.collectRuntimeConfigAssignments
) {
throw new Error("Missing channel secret contract api");
}
vi.mock("../channels/plugins/bootstrap-registry.js", () => {
return {

View File

@@ -1,9 +1,14 @@
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
import * as discordSecrets from "../../extensions/discord/src/secret-config-contract.ts";
import type { AuthProfileStore } from "../agents/auth-profiles.js";
import type { OpenClawConfig } from "../config/config.js";
import { createEmptyPluginRegistry } from "../plugins/registry.js";
import { setActivePluginRegistry } from "../plugins/runtime.js";
import { loadBundledChannelSecretContractApi } from "./channel-contract-api.js";
const discordSecrets = loadBundledChannelSecretContractApi("discord");
if (!discordSecrets?.collectRuntimeConfigAssignments) {
throw new Error("Missing Discord secret contract api");
}
vi.mock("../channels/plugins/bootstrap-registry.js", () => {
return {

View File

@@ -1,8 +1,13 @@
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
import * as telegramSecrets from "../../extensions/telegram/src/secret-contract.ts";
import type { OpenClawConfig } from "../config/config.js";
import { createEmptyPluginRegistry } from "../plugins/registry.js";
import { setActivePluginRegistry } from "../plugins/runtime.js";
import { loadBundledChannelSecretContractApi } from "./channel-contract-api.js";
const telegramSecrets = loadBundledChannelSecretContractApi("telegram");
if (!telegramSecrets?.collectRuntimeConfigAssignments) {
throw new Error("Missing Telegram secret contract api");
}
vi.mock("../channels/plugins/bootstrap-registry.js", () => {
return {

View File

@@ -1,9 +1,14 @@
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import * as telegramSecrets from "../../extensions/telegram/src/secret-contract.ts";
import type { OpenClawConfig } from "../config/config.js";
import { createEmptyPluginRegistry } from "../plugins/registry.js";
import { setActivePluginRegistry } from "../plugins/runtime.js";
import type { PluginWebSearchProviderEntry } from "../plugins/types.js";
import { loadBundledChannelSecretContractApi } from "./channel-contract-api.js";
const telegramSecrets = loadBundledChannelSecretContractApi("telegram");
if (!telegramSecrets?.collectRuntimeConfigAssignments) {
throw new Error("Missing Telegram secret contract api");
}
type WebProviderUnderTest = "brave" | "gemini" | "grok" | "kimi" | "perplexity" | "firecrawl";

View File

@@ -1,10 +1,15 @@
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import * as matrixSecrets from "../../extensions/matrix/src/secret-contract.ts";
import type { AuthProfileStore } from "../agents/auth-profiles.js";
import type { OpenClawConfig } from "../config/config.js";
import { createEmptyPluginRegistry } from "../plugins/registry.js";
import { setActivePluginRegistry } from "../plugins/runtime.js";
import type { PluginWebSearchProviderEntry } from "../plugins/types.js";
import { loadBundledChannelSecretContractApi } from "./channel-contract-api.js";
const matrixSecrets = loadBundledChannelSecretContractApi("matrix");
if (!matrixSecrets?.collectRuntimeConfigAssignments) {
throw new Error("Missing Matrix secret contract api");
}
type WebProviderUnderTest = "brave" | "gemini" | "grok" | "kimi" | "perplexity" | "firecrawl";

View File

@@ -1,9 +1,14 @@
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import * as matrixSecrets from "../../extensions/matrix/src/secret-contract.ts";
import type { OpenClawConfig } from "../config/config.js";
import { createEmptyPluginRegistry } from "../plugins/registry.js";
import { setActivePluginRegistry } from "../plugins/runtime.js";
import type { PluginWebSearchProviderEntry } from "../plugins/types.js";
import { loadBundledChannelSecretContractApi } from "./channel-contract-api.js";
const matrixSecrets = loadBundledChannelSecretContractApi("matrix");
if (!matrixSecrets?.collectRuntimeConfigAssignments) {
throw new Error("Missing Matrix secret contract api");
}
type WebProviderUnderTest = "brave" | "gemini" | "grok" | "kimi" | "perplexity" | "firecrawl";

View File

@@ -1,9 +1,14 @@
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
import * as nextcloudTalkSecrets from "../../extensions/nextcloud-talk/src/secret-contract.ts";
import type { AuthProfileStore } from "../agents/auth-profiles.js";
import type { OpenClawConfig } from "../config/config.js";
import { createEmptyPluginRegistry } from "../plugins/registry.js";
import { setActivePluginRegistry } from "../plugins/runtime.js";
import { loadBundledChannelSecretContractApi } from "./channel-contract-api.js";
const nextcloudTalkSecrets = loadBundledChannelSecretContractApi("nextcloud-talk");
if (!nextcloudTalkSecrets?.collectRuntimeConfigAssignments) {
throw new Error("Missing Nextcloud Talk secret contract api");
}
vi.mock("../channels/plugins/bootstrap-registry.js", () => {
return {

View File

@@ -1,9 +1,14 @@
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
import * as telegramSecrets from "../../extensions/telegram/src/secret-contract.ts";
import type { AuthProfileStore } from "../agents/auth-profiles.js";
import type { OpenClawConfig } from "../config/config.js";
import { createEmptyPluginRegistry } from "../plugins/registry.js";
import { setActivePluginRegistry } from "../plugins/runtime.js";
import { loadBundledChannelSecretContractApi } from "./channel-contract-api.js";
const telegramSecrets = loadBundledChannelSecretContractApi("telegram");
if (!telegramSecrets?.collectRuntimeConfigAssignments) {
throw new Error("Missing Telegram secret contract api");
}
vi.mock("../channels/plugins/bootstrap-registry.js", () => {
return {

View File

@@ -1,9 +1,14 @@
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
import * as zaloSecrets from "../../extensions/zalo/src/secret-contract.ts";
import type { AuthProfileStore } from "../agents/auth-profiles.js";
import type { OpenClawConfig } from "../config/config.js";
import { createEmptyPluginRegistry } from "../plugins/registry.js";
import { setActivePluginRegistry } from "../plugins/runtime.js";
import { loadBundledChannelSecretContractApi } from "./channel-contract-api.js";
const zaloSecrets = loadBundledChannelSecretContractApi("zalo");
if (!zaloSecrets?.collectRuntimeConfigAssignments) {
throw new Error("Missing Zalo secret contract api");
}
vi.mock("../channels/plugins/bootstrap-registry.js", () => {
return {

View File

@@ -1,7 +1,6 @@
import { describe, expect, it, vi } from "vitest";
import type { ResolvedSlackAccount } from "../../extensions/slack/src/accounts.js";
import { collectSlackSecurityAuditFindings } from "../../extensions/slack/src/security-audit.js";
import type { OpenClawConfig } from "../config/config.js";
import { collectSlackSecurityAuditFindings } from "../plugin-sdk/slack.js";
import { withChannelSecurityStateDir } from "./audit-channel-security.test-helpers.js";
const { readChannelAllowFromStoreMock } = vi.hoisted(() => ({
@@ -14,7 +13,7 @@ vi.mock("openclaw/plugin-sdk/conversation-runtime", () => ({
function createSlackAccount(
config: NonNullable<OpenClawConfig["channels"]>["slack"],
): ResolvedSlackAccount {
): Parameters<typeof collectSlackSecurityAuditFindings>[0]["account"] {
return {
accountId: "default",
enabled: true,
@@ -22,7 +21,7 @@ function createSlackAccount(
botTokenSource: "config",
appTokenSource: "config",
config,
} as ResolvedSlackAccount;
} as Parameters<typeof collectSlackSecurityAuditFindings>[0]["account"];
}
describe("security audit slack command findings", () => {

View File

@@ -1,6 +1,6 @@
import { describe, expect, it } from "vitest";
import { collectFeishuSecurityAuditFindings } from "../../extensions/feishu/src/security-audit.js";
import type { OpenClawConfig } from "../config/config.js";
import { collectFeishuSecurityAuditFindings } from "../plugin-sdk/feishu-security.js";
describe("security audit Feishu doc risk findings", () => {
it.each([