refactor: split channel target test helpers

This commit is contained in:
Peter Steinberger
2026-04-28 02:03:06 +01:00
parent 6c859d8c82
commit dc4512ad0c
19 changed files with 110 additions and 68 deletions

View File

@@ -93,7 +93,7 @@ const knownDeprecatedSurfaceMarkers = [
{
code: "plugin-sdk-test-utils-alias",
file: "src/plugin-sdk/test-utils.ts",
marker: "Deprecated compatibility alias",
marker: "focused openclaw/plugin-sdk/* test subpaths",
},
{
code: "plugin-install-config-ledger",

View File

@@ -789,7 +789,7 @@ export const PLUGIN_COMPAT_RECORDS = [
deprecated: "2026-04-26",
warningStarts: "2026-04-26",
removeAfter: "2026-07-26",
replacement: "`openclaw/plugin-sdk/testing`",
replacement: "focused `openclaw/plugin-sdk/*` test subpaths",
docsPath: "/plugins/sdk-migration",
surfaces: ["openclaw/plugin-sdk/test-utils"],
diagnostics: ["plugin SDK compatibility warning"],

View File

@@ -54,6 +54,7 @@ const repoTsFilesCache = new Map<string, string[]>();
const representativeRuntimeSmokeSubpaths = ["channel-runtime", "conversation-runtime"] as const;
const PUBLIC_SDK_TEST_HELPER_SUBPATHS = [
"channel-contract-testing",
"channel-target-testing",
"channel-test-helpers",
"plugin-test-api",
"plugin-test-contracts",
@@ -755,6 +756,10 @@ describe("plugin-sdk subpath exports", () => {
"peekSystemEvents",
"typedCases",
]);
expectSourceMentions("channel-target-testing", [
"installCommonResolveTargetErrorCases",
"ResolveTargetFn",
]);
});
it("keeps public SDK test helper subpaths free of top-level Vitest module mocks", () => {
@@ -1238,7 +1243,7 @@ describe("plugin-sdk subpath exports", () => {
"requestBodyErrorToText",
"withResolvedWebhookRequestPipeline",
]);
expectSourceMentions("testing", ["removeAckReactionAfterReply", "shouldAckReaction"]);
expectSourceMentions("channel-feedback", ["removeAckReactionAfterReply", "shouldAckReaction"]);
});
it("keeps shared plugin-sdk types aligned", () => {

View File

@@ -0,0 +1,78 @@
type ConversationBindingHelpers = {
requestConversationBinding: (...args: unknown[]) => unknown;
detachConversationBinding: (...args: unknown[]) => unknown;
getCurrentConversationBinding: (...args: unknown[]) => unknown;
};
type InteractiveHandlerRegistration<
TChannel extends string,
TContext,
> = ConversationBindingHelpers & {
channel: TChannel;
namespace: string;
handler: (ctx: TContext) => unknown;
};
type BaseInteractiveContext<TChannel extends string> = ConversationBindingHelpers & {
channel: TChannel;
accountId: string;
conversationId: string;
parentConversationId?: string;
senderId: string;
senderUsername?: string;
auth?: unknown;
};
export type TelegramInteractiveHandlerContext = BaseInteractiveContext<"telegram"> & {
callbackId: string;
senderUsername?: string;
threadId?: number;
isGroup?: boolean;
isForum?: boolean;
callback: {
data: string;
namespace: string;
payload: string;
messageId: number;
chatId: string;
messageText?: string;
};
respond: Record<string, (...args: unknown[]) => unknown>;
};
export type DiscordInteractiveHandlerContext = BaseInteractiveContext<"discord"> & {
interactionId: string;
guildId?: string;
interaction: {
data: string;
namespace: string;
payload: string;
[key: string]: unknown;
};
respond: Record<string, (...args: unknown[]) => unknown>;
};
export type SlackInteractiveHandlerContext = BaseInteractiveContext<"slack"> & {
interactionId: string;
threadId?: string;
interaction: {
data: string;
namespace: string;
payload: string;
[key: string]: unknown;
};
respond: Record<string, (...args: unknown[]) => unknown>;
};
export type TelegramInteractiveHandlerRegistration = InteractiveHandlerRegistration<
"telegram",
TelegramInteractiveHandlerContext
>;
export type DiscordInteractiveHandlerRegistration = InteractiveHandlerRegistration<
"discord",
DiscordInteractiveHandlerContext
>;
export type SlackInteractiveHandlerRegistration = InteractiveHandlerRegistration<
"slack",
SlackInteractiveHandlerContext
>;

View File

@@ -1,18 +1,14 @@
import { afterEach, beforeEach, describe, expect, it, vi, type MockInstance } from "vitest";
import * as conversationBinding from "./conversation-binding.js";
import { createInteractiveConversationBindingHelpers } from "./interactive-binding-helpers.js";
import type {
DiscordInteractiveHandlerContext,
DiscordInteractiveHandlerRegistration,
} from "../../test/helpers/channels/interactive-contract.js";
import type {
SlackInteractiveHandlerContext,
SlackInteractiveHandlerRegistration,
} from "../../test/helpers/channels/interactive-contract.js";
import type {
TelegramInteractiveHandlerContext,
TelegramInteractiveHandlerRegistration,
} from "../../test/helpers/channels/interactive-contract.js";
import * as conversationBinding from "./conversation-binding.js";
import { createInteractiveConversationBindingHelpers } from "./interactive-binding-helpers.js";
} from "./interactive-contract.test-helpers.js";
import {
clearPluginInteractiveHandlers,
dispatchPluginInteractiveHandler,