From fc3246d8fd86b21da882899cf15abfdeacc2b7ab Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 27 Mar 2026 04:39:02 +0000 Subject: [PATCH] refactor: add public channel contract test seams --- extensions/discord/runtime-api.ts | 2 ++ extensions/discord/test-api.ts | 1 + extensions/feishu/api.ts | 2 ++ extensions/matrix/api.ts | 2 ++ extensions/slack/test-api.ts | 4 +++ extensions/telegram/runtime-api.ts | 2 ++ extensions/telegram/test-api.ts | 1 + .../contracts/inbound.contract.test.ts | 17 +++++----- .../contracts/registry.contract.test.ts | 32 +++++++------------ 9 files changed, 34 insertions(+), 29 deletions(-) create mode 100644 extensions/discord/test-api.ts create mode 100644 extensions/slack/test-api.ts create mode 100644 extensions/telegram/test-api.ts diff --git a/extensions/discord/runtime-api.ts b/extensions/discord/runtime-api.ts index c1b36754382..3d3f59ed0dc 100644 --- a/extensions/discord/runtime-api.ts +++ b/extensions/discord/runtime-api.ts @@ -17,3 +17,5 @@ export * from "./src/resolve-channels.js"; export * from "./src/resolve-users.js"; export * from "./src/outbound-session-route.js"; export * from "./src/send.js"; + +export const discordSessionBindingAdapterChannels = ["discord"] as const; diff --git a/extensions/discord/test-api.ts b/extensions/discord/test-api.ts new file mode 100644 index 00000000000..84d24f99fef --- /dev/null +++ b/extensions/discord/test-api.ts @@ -0,0 +1 @@ +export { buildFinalizedDiscordDirectInboundContext } from "./src/monitor/inbound-context.test-helpers.js"; diff --git a/extensions/feishu/api.ts b/extensions/feishu/api.ts index 8b602d69239..190b73a5425 100644 --- a/extensions/feishu/api.ts +++ b/extensions/feishu/api.ts @@ -3,3 +3,5 @@ export * from "./src/setup-core.js"; export * from "./src/setup-surface.js"; export * from "./src/thread-bindings.js"; export { __testing as feishuThreadBindingTesting } from "./src/thread-bindings.js"; + +export const feishuSessionBindingAdapterChannels = ["feishu"] as const; diff --git a/extensions/matrix/api.ts b/extensions/matrix/api.ts index 4a3e03f0a31..607926aca99 100644 --- a/extensions/matrix/api.ts +++ b/extensions/matrix/api.ts @@ -6,3 +6,5 @@ export { resetMatrixThreadBindingsForTests, } from "./src/matrix/thread-bindings.js"; export { matrixOnboardingAdapter as matrixSetupWizard } from "./src/onboarding.js"; + +export const matrixSessionBindingAdapterChannels = ["matrix"] as const; diff --git a/extensions/slack/test-api.ts b/extensions/slack/test-api.ts new file mode 100644 index 00000000000..a36b24c73b9 --- /dev/null +++ b/extensions/slack/test-api.ts @@ -0,0 +1,4 @@ +export type { ResolvedSlackAccount } from "./src/accounts.js"; +export type { SlackMessageEvent } from "./src/types.js"; +export { prepareSlackMessage } from "./src/monitor/message-handler/prepare.js"; +export { createInboundSlackTestContext } from "./src/monitor/message-handler/prepare.test-helpers.js"; diff --git a/extensions/telegram/runtime-api.ts b/extensions/telegram/runtime-api.ts index f6aa300acff..6fb4b74f382 100644 --- a/extensions/telegram/runtime-api.ts +++ b/extensions/telegram/runtime-api.ts @@ -83,3 +83,5 @@ export { setTelegramThreadBindingMaxAgeBySessionKey, } from "./src/thread-bindings.js"; export { resolveTelegramToken } from "./src/token.js"; + +export const telegramSessionBindingAdapterChannels = ["telegram"] as const; diff --git a/extensions/telegram/test-api.ts b/extensions/telegram/test-api.ts new file mode 100644 index 00000000000..5eaae08890d --- /dev/null +++ b/extensions/telegram/test-api.ts @@ -0,0 +1 @@ +export { buildTelegramMessageContextForTest } from "./src/bot-message-context.test-harness.js"; diff --git a/src/channels/plugins/contracts/inbound.contract.test.ts b/src/channels/plugins/contracts/inbound.contract.test.ts index 3b54d199d2f..6897e53df3e 100644 --- a/src/channels/plugins/contracts/inbound.contract.test.ts +++ b/src/channels/plugins/contracts/inbound.contract.test.ts @@ -1,7 +1,12 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; -import { buildFinalizedDiscordDirectInboundContext } from "../../../../extensions/discord/src/monitor/inbound-context.test-helpers.js"; -import type { ResolvedSlackAccount } from "../../../../extensions/slack/src/accounts.js"; -import type { SlackMessageEvent } from "../../../../extensions/slack/src/types.js"; +import { buildFinalizedDiscordDirectInboundContext } from "../../../../extensions/discord/test-api.js"; +import { + createInboundSlackTestContext, + prepareSlackMessage, + type ResolvedSlackAccount, + type SlackMessageEvent, +} from "../../../../extensions/slack/test-api.js"; +import { buildTelegramMessageContextForTest } from "../../../../extensions/telegram/test-api.js"; import { withTempHome } from "../../../../test/helpers/temp-home.js"; import type { MsgContext } from "../../../auto-reply/templating.js"; import type { OpenClawConfig } from "../../../config/config.js"; @@ -75,12 +80,6 @@ vi.mock("../../../../extensions/whatsapp/src/auto-reply/deliver-reply.js", () => })); const { finalizeInboundContext } = await import("../../../auto-reply/reply/inbound-context.js"); -const { prepareSlackMessage } = - await import("../../../../extensions/slack/src/monitor/message-handler/prepare.js"); -const { createInboundSlackTestContext } = - await import("../../../../extensions/slack/src/monitor/message-handler/prepare.test-helpers.js"); -const { buildTelegramMessageContextForTest } = - await import("../../../../extensions/telegram/src/bot-message-context.test-harness.js"); function createSlackAccount(config: ResolvedSlackAccount["config"] = {}): ResolvedSlackAccount { return { diff --git a/src/channels/plugins/contracts/registry.contract.test.ts b/src/channels/plugins/contracts/registry.contract.test.ts index 3f731325443..ca67d295ced 100644 --- a/src/channels/plugins/contracts/registry.contract.test.ts +++ b/src/channels/plugins/contracts/registry.contract.test.ts @@ -1,27 +1,19 @@ -import fs from "node:fs"; -import path from "node:path"; import { describe, expect, it } from "vitest"; +import { discordSessionBindingAdapterChannels } from "../../../../extensions/discord/runtime-api.js"; +import { feishuSessionBindingAdapterChannels } from "../../../../extensions/feishu/api.js"; +import { matrixSessionBindingAdapterChannels } from "../../../../extensions/matrix/api.js"; +import { telegramSessionBindingAdapterChannels } from "../../../../extensions/telegram/runtime-api.js"; import { sessionBindingContractChannelIds } from "./manifest.js"; -const sessionBindingAdapterFiles = [ - "../../../../extensions/discord/src/monitor/thread-bindings.manager.ts", - "../../../../extensions/feishu/src/thread-bindings.ts", - "../../../../extensions/matrix/src/matrix/thread-bindings.ts", - "../../../../extensions/telegram/src/thread-bindings.ts", -] as const; - function discoverSessionBindingChannels() { - const channels = new Set(); - for (const relativePath of sessionBindingAdapterFiles) { - const filePath = path.resolve(import.meta.dirname, relativePath); - const source = fs.readFileSync(filePath, "utf8"); - for (const match of source.matchAll( - /registerSessionBindingAdapter\(\{[\s\S]*?channel:\s*"([^"]+)"/g, - )) { - channels.add(match[1]); - } - } - return [...channels].toSorted(); + return [ + ...new Set([ + ...discordSessionBindingAdapterChannels, + ...feishuSessionBindingAdapterChannels, + ...matrixSessionBindingAdapterChannels, + ...telegramSessionBindingAdapterChannels, + ]), + ].toSorted(); } describe("channel contract registry", () => {