From dc4512ad0c0772c8dba98143f83014faaa760043 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 28 Apr 2026 02:03:06 +0100 Subject: [PATCH] refactor: split channel target test helpers --- CHANGELOG.md | 1 + .../.generated/plugin-sdk-api-baseline.sha256 | 4 +- docs/plugins/compatibility.md | 3 +- docs/plugins/sdk-migration.md | 2 +- docs/plugins/sdk-subpaths.md | 2 + docs/plugins/sdk-testing.md | 102 +++++++++--------- package.json | 4 + scripts/lib/plugin-sdk-doc-metadata.ts | 3 + scripts/lib/plugin-sdk-entrypoints.json | 1 + src/plugin-sdk/channel-target-testing.ts | 6 ++ src/plugin-sdk/test-utils.ts | 2 +- src/plugin-sdk/testing.ts | 4 +- src/plugins/compat/registry.test.ts | 2 +- src/plugins/compat/registry.ts | 2 +- .../contracts/plugin-sdk-subpaths.test.ts | 7 +- .../interactive-contract.test-helpers.ts | 0 src/plugins/interactive.test.ts | 10 +- .../resolve-target-error-cases.ts | 6 +- test/extension-test-boundary.test.ts | 17 +++ 19 files changed, 110 insertions(+), 68 deletions(-) create mode 100644 src/plugin-sdk/channel-target-testing.ts rename test/helpers/channels/interactive-contract.ts => src/plugins/interactive-contract.test-helpers.ts (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index cba5a7d2ffd..bf3e12b0512 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ Docs: https://docs.openclaw.ai - Gateway/startup: pass the plugin metadata snapshot from config validation into plugin bootstrap so startup reuses one manifest product instead of rebuilding plugin metadata. Thanks @shakkernerd. - Plugin SDK/testing: promote bundled plugin/provider/channel contract helpers to focused SDK test subpaths and retire the repo-only `test/helpers/plugins` TypeScript bridge. Thanks @vincentkoc. - Plugin SDK/testing: expose generic channel action, setup, status, and directory contract helpers through `plugin-sdk/channel-test-helpers` so bundled extension tests no longer import repo-only channel helper bridges. Thanks @vincentkoc. +- Plugin SDK/testing: add `plugin-sdk/channel-target-testing` for shared channel target-resolution cases, document channel reaction helpers on `plugin-sdk/channel-feedback`, and keep the old `plugin-sdk/test-utils` alias as compatibility-only. Thanks @vincentkoc. - Plugin SDK/testing: add a focused generic fixture subpath for CLI capture, sandbox, skill, agent-message, system-event, terminal, chunking, auth-token, and typed-case helpers. Thanks @vincentkoc. - Plugin SDK/testing: add focused plugin runtime and environment fixture subpaths so plugin tests can avoid the broad `plugin-sdk/testing` barrel for common setup helpers. Thanks @vincentkoc. - Plugin SDK/testing: add a focused `plugin-sdk/plugin-test-api` helper subpath and move bundled plugin registration tests off the repo-only plugin API bridge. Thanks @vincentkoc. diff --git a/docs/.generated/plugin-sdk-api-baseline.sha256 b/docs/.generated/plugin-sdk-api-baseline.sha256 index 3271a234f7f..7a2759ce79e 100644 --- a/docs/.generated/plugin-sdk-api-baseline.sha256 +++ b/docs/.generated/plugin-sdk-api-baseline.sha256 @@ -1,2 +1,2 @@ -f9c6ac5f5a7f49963a1dde734066293ab847fbb611f941403bed3096e19c4808 plugin-sdk-api-baseline.json -d0c54afbd40ef44a40c27de0f0138178e5389c965a0f5794962c6f84226adaa8 plugin-sdk-api-baseline.jsonl +48cd91661f9fc65e8fb3a091f6deb726d8ccd37f7cec2aa765165f3992e7463f plugin-sdk-api-baseline.json +e8d7069b4d0d7a1a0431d92c845043bb39c3ba106ca0f85cc728a02ece9521bf plugin-sdk-api-baseline.jsonl diff --git a/docs/plugins/compatibility.md b/docs/plugins/compatibility.md index 93949560efe..c7b686e1ecd 100644 --- a/docs/plugins/compatibility.md +++ b/docs/plugins/compatibility.md @@ -98,7 +98,8 @@ Current compatibility records include: `register(api)` - legacy SDK aliases such as `openclaw/extension-api`, `openclaw/plugin-sdk/channel-runtime`, `openclaw/plugin-sdk/command-auth` - status builders, `openclaw/plugin-sdk/test-utils`, and the `ClawdbotConfig` / + status builders, `openclaw/plugin-sdk/test-utils` (replaced by focused + `openclaw/plugin-sdk/*` test subpaths), and the `ClawdbotConfig` / `OpenClawSchemaType` type aliases - bundled plugin allowlist and enablement behavior - legacy provider/channel env-var manifest metadata diff --git a/docs/plugins/sdk-migration.md b/docs/plugins/sdk-migration.md index 2dddf34fea1..7094e865998 100644 --- a/docs/plugins/sdk-migration.md +++ b/docs/plugins/sdk-migration.md @@ -524,7 +524,7 @@ releases. | `plugin-sdk/memory-host-search` | Active memory search facade | Lazy active-memory search-manager runtime facade | | `plugin-sdk/memory-host-status` | Memory host status alias | Vendor-neutral alias for memory host status helpers | | `plugin-sdk/memory-lancedb` | Bundled memory-lancedb helpers | Memory-lancedb helper surface | - | `plugin-sdk/testing` | Test utilities | Test helpers and mocks | + | `plugin-sdk/testing` | Test utilities | Legacy broad compatibility barrel; prefer focused test subpaths such as `plugin-sdk/plugin-test-runtime`, `plugin-sdk/channel-test-helpers`, `plugin-sdk/channel-target-testing`, `plugin-sdk/test-env`, and `plugin-sdk/test-fixtures` | This table is intentionally the common migration subset, not the full SDK diff --git a/docs/plugins/sdk-subpaths.md b/docs/plugins/sdk-subpaths.md index 6aa98498f4e..944cfaa6582 100644 --- a/docs/plugins/sdk-subpaths.md +++ b/docs/plugins/sdk-subpaths.md @@ -25,6 +25,7 @@ For the plugin authoring guide, see [Plugin SDK overview](/plugins/sdk-overview) | `plugin-sdk/testing` | Broad compatibility barrel for legacy plugin tests; prefer focused test subpaths for new extension tests | | `plugin-sdk/plugin-test-api` | Minimal `OpenClawPluginApi` mock builder for direct plugin registration unit tests | | `plugin-sdk/channel-test-helpers` | Channel account lifecycle, directory, send-config, runtime mock, hook, and generic channel contract test helpers | +| `plugin-sdk/channel-target-testing` | Shared channel target-resolution error-case test suite | | `plugin-sdk/plugin-test-contracts` | Plugin registration, package manifest, public artifact, runtime API, import side-effect, and direct import contract helpers | | `plugin-sdk/plugin-test-runtime` | Plugin runtime, registry, provider-registration, setup-wizard, and runtime task-flow fixtures for tests | | `plugin-sdk/provider-test-contracts` | Provider runtime, auth, discovery, onboard, catalog, web-search/fetch, and wizard contract helpers | @@ -270,6 +271,7 @@ For the plugin authoring guide, see [Plugin SDK overview](/plugins/sdk-overview) | `plugin-sdk/testing` | Broad compatibility barrel for legacy plugin tests. New extension tests should import focused SDK subpaths such as `plugin-sdk/plugin-test-runtime`, `plugin-sdk/channel-test-helpers`, `plugin-sdk/test-env`, or `plugin-sdk/test-fixtures` instead | | `plugin-sdk/plugin-test-api` | Minimal `createTestPluginApi` helper for direct plugin registration unit tests without importing repo test helper bridges | | `plugin-sdk/channel-test-helpers` | Channel-oriented test helpers for generic actions/setup/status contracts, directory assertions, account startup lifecycle, send-config threading, runtime mocks, status issues, outbound delivery, and hook registration | + | `plugin-sdk/channel-target-testing` | Shared target-resolution error-case suite for channel tests | | `plugin-sdk/plugin-test-contracts` | Plugin package, registration, public artifact, direct import, runtime API, and import side-effect contract helpers | | `plugin-sdk/provider-test-contracts` | Provider runtime, auth, discovery, onboard, catalog, wizard, web-search/fetch, and stream contract helpers | | `plugin-sdk/test-fixtures` | Generic CLI runtime capture, sandbox context, skill writer, agent-message, system-event, terminal-text, chunking, auth-token, and typed-case fixtures | diff --git a/docs/plugins/sdk-testing.md b/docs/plugins/sdk-testing.md index b38f48e8e1c..84ac207e35d 100644 --- a/docs/plugins/sdk-testing.md +++ b/docs/plugins/sdk-testing.md @@ -27,6 +27,8 @@ plugins. **Channel test helper import:** `openclaw/plugin-sdk/channel-test-helpers` +**Channel target test import:** `openclaw/plugin-sdk/channel-target-testing` + **Plugin contract import:** `openclaw/plugin-sdk/plugin-test-contracts` **Plugin runtime test import:** `openclaw/plugin-sdk/plugin-test-runtime` @@ -42,7 +44,11 @@ Prefer the focused subpaths below for new plugin tests. The broad and helpers that have not moved to a narrower documented surface yet. ```typescript -import { installCommonResolveTargetErrorCases } from "openclaw/plugin-sdk/testing"; +import { + shouldAckReaction, + removeAckReactionAfterReply, +} from "openclaw/plugin-sdk/channel-feedback"; +import { installCommonResolveTargetErrorCases } from "openclaw/plugin-sdk/channel-target-testing"; import { createTestPluginApi } from "openclaw/plugin-sdk/plugin-test-api"; import { expectChannelInboundContextContract } from "openclaw/plugin-sdk/channel-contract-testing"; import { createStartAccountContext } from "openclaw/plugin-sdk/channel-test-helpers"; @@ -55,52 +61,52 @@ import { createCliRuntimeCapture, typedCases } from "openclaw/plugin-sdk/test-fi ### Available exports -| Export | Purpose | -| ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -| `createTestPluginApi` | Build a minimal plugin API mock for direct registration unit tests. Import from `plugin-sdk/plugin-test-api` | -| `expectChannelInboundContextContract` | Assert channel inbound context shape. Import from `plugin-sdk/channel-contract-testing` | -| `installChannelOutboundPayloadContractSuite` | Install channel outbound payload contract cases. Import from `plugin-sdk/channel-contract-testing` | -| `createStartAccountContext` | Build channel account lifecycle contexts. Import from `plugin-sdk/channel-test-helpers` | -| `installChannelActionsContractSuite` | Install generic channel message-action contract cases. Import from `plugin-sdk/channel-test-helpers` | -| `installChannelSetupContractSuite` | Install generic channel setup contract cases. Import from `plugin-sdk/channel-test-helpers` | -| `installChannelStatusContractSuite` | Install generic channel status contract cases. Import from `plugin-sdk/channel-test-helpers` | -| `expectDirectoryIds` | Assert channel directory ids from a directory-list function. Import from `plugin-sdk/channel-test-helpers` | -| `describePluginRegistrationContract` | Install plugin registration contract checks. Import from `plugin-sdk/plugin-test-contracts` | -| `registerSingleProviderPlugin` | Register one provider plugin in loader smoke tests. Import from `plugin-sdk/plugin-test-runtime` | -| `registerProviderPlugin` | Capture all provider kinds from one plugin. Import from `plugin-sdk/plugin-test-runtime` | -| `registerProviderPlugins` | Capture provider registrations across multiple plugins. Import from `plugin-sdk/plugin-test-runtime` | -| `requireRegisteredProvider` | Assert that a provider collection contains an id. Import from `plugin-sdk/plugin-test-runtime` | -| `createRuntimeEnv` | Build a mocked CLI/plugin runtime environment. Import from `plugin-sdk/plugin-test-runtime` | -| `createPluginSetupWizardStatus` | Build setup status helpers for channel plugins. Import from `plugin-sdk/plugin-test-runtime` | -| `describeOpenAIProviderRuntimeContract` | Install provider-family runtime contract checks. Import from `plugin-sdk/provider-test-contracts` | -| `installCommonResolveTargetErrorCases` | Shared test cases for target resolution error handling. Import from `plugin-sdk/testing` until a narrower target-resolution test subpath exists | -| `shouldAckReaction` | Check whether a channel should add an ack reaction. Import from `plugin-sdk/testing` until a narrower reaction test subpath exists | -| `removeAckReactionAfterReply` | Remove ack reaction after reply delivery. Import from `plugin-sdk/testing` until a narrower reaction test subpath exists | -| `createTestRegistry` | Build a channel plugin registry fixture. Import from `plugin-sdk/plugin-test-runtime` or `plugin-sdk/channel-test-helpers` | -| `createEmptyPluginRegistry` | Build an empty plugin registry fixture. Import from `plugin-sdk/plugin-test-runtime` or `plugin-sdk/channel-test-helpers` | -| `setActivePluginRegistry` | Install a registry fixture for plugin runtime tests. Import from `plugin-sdk/plugin-test-runtime` or `plugin-sdk/channel-test-helpers` | -| `createRequestCaptureJsonFetch` | Capture JSON fetch requests in media helper tests. Import from `plugin-sdk/test-env` | -| `withFetchPreconnect` | Run fetch tests with preconnect hooks installed. Import from `plugin-sdk/test-env` | -| `withEnv` / `withEnvAsync` | Temporarily patch environment variables. Import from `plugin-sdk/test-env` | -| `createTempHomeEnv` / `withTempDir` | Create isolated filesystem test fixtures. Import from `plugin-sdk/test-env` | -| `createMockServerResponse` | Create a minimal HTTP server response mock. Import from `plugin-sdk/test-env` | -| `createCliRuntimeCapture` | Capture CLI runtime output in tests. Import from `plugin-sdk/test-fixtures` | -| `createSandboxTestContext` | Build sandbox test contexts. Import from `plugin-sdk/test-fixtures` | -| `writeSkill` | Write skill fixtures. Import from `plugin-sdk/test-fixtures` | -| `makeAgentAssistantMessage` | Build agent transcript message fixtures. Import from `plugin-sdk/test-fixtures` | -| `peekSystemEvents` / `resetSystemEventsForTest` | Inspect and reset system event fixtures. Import from `plugin-sdk/test-fixtures` | -| `sanitizeTerminalText` | Sanitize terminal output for assertions. Import from `plugin-sdk/test-fixtures` | -| `countLines` / `hasBalancedFences` | Assert chunking output shape. Import from `plugin-sdk/test-fixtures` | -| `runProviderCatalog` | Execute a provider catalog hook with test dependencies | -| `resolveProviderWizardOptions` | Resolve provider setup wizard choices in contract tests | -| `resolveProviderModelPickerEntries` | Resolve provider model-picker entries in contract tests | -| `buildProviderPluginMethodChoice` | Build provider wizard choice ids for assertions | -| `setProviderWizardProvidersResolverForTest` | Inject provider wizard providers for isolated tests | -| `createProviderUsageFetch` | Build provider usage fetch fixtures | -| `useFrozenTime` / `useRealTime` | Freeze and restore timers for time-sensitive tests. Import from `plugin-sdk/test-env` | -| `createTestWizardPrompter` | Build a mocked setup wizard prompter | -| `createRuntimeTaskFlow` | Create isolated runtime task-flow state | -| `typedCases` | Preserve literal types for table-driven tests. Import from `plugin-sdk/test-fixtures` | +| Export | Purpose | +| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | +| `createTestPluginApi` | Build a minimal plugin API mock for direct registration unit tests. Import from `plugin-sdk/plugin-test-api` | +| `expectChannelInboundContextContract` | Assert channel inbound context shape. Import from `plugin-sdk/channel-contract-testing` | +| `installChannelOutboundPayloadContractSuite` | Install channel outbound payload contract cases. Import from `plugin-sdk/channel-contract-testing` | +| `createStartAccountContext` | Build channel account lifecycle contexts. Import from `plugin-sdk/channel-test-helpers` | +| `installChannelActionsContractSuite` | Install generic channel message-action contract cases. Import from `plugin-sdk/channel-test-helpers` | +| `installChannelSetupContractSuite` | Install generic channel setup contract cases. Import from `plugin-sdk/channel-test-helpers` | +| `installChannelStatusContractSuite` | Install generic channel status contract cases. Import from `plugin-sdk/channel-test-helpers` | +| `expectDirectoryIds` | Assert channel directory ids from a directory-list function. Import from `plugin-sdk/channel-test-helpers` | +| `describePluginRegistrationContract` | Install plugin registration contract checks. Import from `plugin-sdk/plugin-test-contracts` | +| `registerSingleProviderPlugin` | Register one provider plugin in loader smoke tests. Import from `plugin-sdk/plugin-test-runtime` | +| `registerProviderPlugin` | Capture all provider kinds from one plugin. Import from `plugin-sdk/plugin-test-runtime` | +| `registerProviderPlugins` | Capture provider registrations across multiple plugins. Import from `plugin-sdk/plugin-test-runtime` | +| `requireRegisteredProvider` | Assert that a provider collection contains an id. Import from `plugin-sdk/plugin-test-runtime` | +| `createRuntimeEnv` | Build a mocked CLI/plugin runtime environment. Import from `plugin-sdk/plugin-test-runtime` | +| `createPluginSetupWizardStatus` | Build setup status helpers for channel plugins. Import from `plugin-sdk/plugin-test-runtime` | +| `describeOpenAIProviderRuntimeContract` | Install provider-family runtime contract checks. Import from `plugin-sdk/provider-test-contracts` | +| `installCommonResolveTargetErrorCases` | Shared test cases for target resolution error handling. Import from `plugin-sdk/channel-target-testing` | +| `shouldAckReaction` | Check whether a channel should add an ack reaction. Import from `plugin-sdk/channel-feedback` | +| `removeAckReactionAfterReply` | Remove ack reaction after reply delivery. Import from `plugin-sdk/channel-feedback` | +| `createTestRegistry` | Build a channel plugin registry fixture. Import from `plugin-sdk/plugin-test-runtime` or `plugin-sdk/channel-test-helpers` | +| `createEmptyPluginRegistry` | Build an empty plugin registry fixture. Import from `plugin-sdk/plugin-test-runtime` or `plugin-sdk/channel-test-helpers` | +| `setActivePluginRegistry` | Install a registry fixture for plugin runtime tests. Import from `plugin-sdk/plugin-test-runtime` or `plugin-sdk/channel-test-helpers` | +| `createRequestCaptureJsonFetch` | Capture JSON fetch requests in media helper tests. Import from `plugin-sdk/test-env` | +| `withFetchPreconnect` | Run fetch tests with preconnect hooks installed. Import from `plugin-sdk/test-env` | +| `withEnv` / `withEnvAsync` | Temporarily patch environment variables. Import from `plugin-sdk/test-env` | +| `createTempHomeEnv` / `withTempDir` | Create isolated filesystem test fixtures. Import from `plugin-sdk/test-env` | +| `createMockServerResponse` | Create a minimal HTTP server response mock. Import from `plugin-sdk/test-env` | +| `createCliRuntimeCapture` | Capture CLI runtime output in tests. Import from `plugin-sdk/test-fixtures` | +| `createSandboxTestContext` | Build sandbox test contexts. Import from `plugin-sdk/test-fixtures` | +| `writeSkill` | Write skill fixtures. Import from `plugin-sdk/test-fixtures` | +| `makeAgentAssistantMessage` | Build agent transcript message fixtures. Import from `plugin-sdk/test-fixtures` | +| `peekSystemEvents` / `resetSystemEventsForTest` | Inspect and reset system event fixtures. Import from `plugin-sdk/test-fixtures` | +| `sanitizeTerminalText` | Sanitize terminal output for assertions. Import from `plugin-sdk/test-fixtures` | +| `countLines` / `hasBalancedFences` | Assert chunking output shape. Import from `plugin-sdk/test-fixtures` | +| `runProviderCatalog` | Execute a provider catalog hook with test dependencies | +| `resolveProviderWizardOptions` | Resolve provider setup wizard choices in contract tests | +| `resolveProviderModelPickerEntries` | Resolve provider model-picker entries in contract tests | +| `buildProviderPluginMethodChoice` | Build provider wizard choice ids for assertions | +| `setProviderWizardProvidersResolverForTest` | Inject provider wizard providers for isolated tests | +| `createProviderUsageFetch` | Build provider usage fetch fixtures | +| `useFrozenTime` / `useRealTime` | Freeze and restore timers for time-sensitive tests. Import from `plugin-sdk/test-env` | +| `createTestWizardPrompter` | Build a mocked setup wizard prompter | +| `createRuntimeTaskFlow` | Create isolated runtime task-flow state | +| `typedCases` | Preserve literal types for table-driven tests. Import from `plugin-sdk/test-fixtures` | Bundled-plugin contract suites also use SDK testing subpaths for test-only registry, manifest, public-artifact, and runtime fixture helpers. Core-only @@ -135,7 +141,7 @@ channel target resolution: ```typescript import { describe } from "vitest"; -import { installCommonResolveTargetErrorCases } from "openclaw/plugin-sdk/testing"; +import { installCommonResolveTargetErrorCases } from "openclaw/plugin-sdk/channel-target-testing"; describe("my-channel target resolution", () => { installCommonResolveTargetErrorCases({ diff --git a/package.json b/package.json index 22acdc65286..0e2d62594b2 100644 --- a/package.json +++ b/package.json @@ -502,6 +502,10 @@ "types": "./dist/plugin-sdk/lazy-runtime.d.ts", "default": "./dist/plugin-sdk/lazy-runtime.js" }, + "./plugin-sdk/channel-target-testing": { + "types": "./dist/plugin-sdk/channel-target-testing.d.ts", + "default": "./dist/plugin-sdk/channel-target-testing.js" + }, "./plugin-sdk/channel-test-helpers": { "types": "./dist/plugin-sdk/channel-test-helpers.d.ts", "default": "./dist/plugin-sdk/channel-test-helpers.js" diff --git a/scripts/lib/plugin-sdk-doc-metadata.ts b/scripts/lib/plugin-sdk-doc-metadata.ts index 15982d4394d..f4dfc540f3c 100644 --- a/scripts/lib/plugin-sdk-doc-metadata.ts +++ b/scripts/lib/plugin-sdk-doc-metadata.ts @@ -113,6 +113,9 @@ export const pluginSdkDocMetadata = { "channel-test-helpers": { category: "utilities", }, + "channel-target-testing": { + category: "utilities", + }, "provider-test-contracts": { category: "utilities", }, diff --git a/scripts/lib/plugin-sdk-entrypoints.json b/scripts/lib/plugin-sdk-entrypoints.json index eb6eaf70b20..a1f57d3efdc 100644 --- a/scripts/lib/plugin-sdk-entrypoints.json +++ b/scripts/lib/plugin-sdk-entrypoints.json @@ -109,6 +109,7 @@ "acp-binding-runtime", "acp-binding-resolve-runtime", "lazy-runtime", + "channel-target-testing", "channel-test-helpers", "plugin-test-api", "plugin-test-contracts", diff --git a/src/plugin-sdk/channel-target-testing.ts b/src/plugin-sdk/channel-target-testing.ts new file mode 100644 index 00000000000..35b656062e9 --- /dev/null +++ b/src/plugin-sdk/channel-target-testing.ts @@ -0,0 +1,6 @@ +export { + installCommonResolveTargetErrorCases, + type ResolveTargetFn, + type ResolveTargetMode, + type ResolveTargetResult, +} from "../test-helpers/resolve-target-error-cases.js"; diff --git a/src/plugin-sdk/test-utils.ts b/src/plugin-sdk/test-utils.ts index 26cddc72854..01b154113d2 100644 --- a/src/plugin-sdk/test-utils.ts +++ b/src/plugin-sdk/test-utils.ts @@ -1,4 +1,4 @@ // Deprecated compatibility alias. -// Prefer openclaw/plugin-sdk/testing for public test helpers. +// Prefer focused openclaw/plugin-sdk/* test subpaths for public test helpers. export * from "./testing.js"; diff --git a/src/plugin-sdk/testing.ts b/src/plugin-sdk/testing.ts index 872fb99fa36..ee9aaa62f39 100644 --- a/src/plugin-sdk/testing.ts +++ b/src/plugin-sdk/testing.ts @@ -1,5 +1,5 @@ -// Narrow public testing surface for plugin authors. -// Keep this list additive and limited to helpers we are willing to support. +// Broad legacy compatibility barrel for older plugin tests. +// New tests should import focused plugin-sdk/* test subpaths. export { createAckReactionHandle, diff --git a/src/plugins/compat/registry.test.ts b/src/plugins/compat/registry.test.ts index 51f9ce466be..99390e97ec3 100644 --- a/src/plugins/compat/registry.test.ts +++ b/src/plugins/compat/registry.test.ts @@ -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", diff --git a/src/plugins/compat/registry.ts b/src/plugins/compat/registry.ts index eb53b370a60..4ef516615ac 100644 --- a/src/plugins/compat/registry.ts +++ b/src/plugins/compat/registry.ts @@ -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"], diff --git a/src/plugins/contracts/plugin-sdk-subpaths.test.ts b/src/plugins/contracts/plugin-sdk-subpaths.test.ts index 050207e7ea2..e9a4ec18469 100644 --- a/src/plugins/contracts/plugin-sdk-subpaths.test.ts +++ b/src/plugins/contracts/plugin-sdk-subpaths.test.ts @@ -54,6 +54,7 @@ const repoTsFilesCache = new Map(); 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", () => { diff --git a/test/helpers/channels/interactive-contract.ts b/src/plugins/interactive-contract.test-helpers.ts similarity index 100% rename from test/helpers/channels/interactive-contract.ts rename to src/plugins/interactive-contract.test-helpers.ts diff --git a/src/plugins/interactive.test.ts b/src/plugins/interactive.test.ts index d4ede08ef74..02ea364e55c 100644 --- a/src/plugins/interactive.test.ts +++ b/src/plugins/interactive.test.ts @@ -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, diff --git a/src/test-helpers/resolve-target-error-cases.ts b/src/test-helpers/resolve-target-error-cases.ts index 282c5e82e57..42ce4a9a6c4 100644 --- a/src/test-helpers/resolve-target-error-cases.ts +++ b/src/test-helpers/resolve-target-error-cases.ts @@ -1,14 +1,14 @@ import { expect, it } from "vitest"; -type ResolveTargetMode = "explicit" | "implicit" | "heartbeat"; +export type ResolveTargetMode = "explicit" | "implicit" | "heartbeat"; -type ResolveTargetResult = { +export type ResolveTargetResult = { ok: boolean; to?: string; error?: unknown; }; -type ResolveTargetFn = (params: { +export type ResolveTargetFn = (params: { to?: string; mode: ResolveTargetMode; allowFrom: string[]; diff --git a/test/extension-test-boundary.test.ts b/test/extension-test-boundary.test.ts index dd04cc511ed..5aec30d84c3 100644 --- a/test/extension-test-boundary.test.ts +++ b/test/extension-test-boundary.test.ts @@ -202,4 +202,21 @@ describe("non-extension test boundaries", () => { expect(offenders).toEqual([]); }); + + it("keeps extension tests off legacy broad testing barrels and repo helper bridges", () => { + const bannedPatterns = [ + /["']openclaw\/plugin-sdk\/testing["']/u, + /["']openclaw\/plugin-sdk\/test-utils["']/u, + /["'](?:\.\.\/)+(?:test\/helpers\/channels\/)[^"']+["']/u, + /["'](?:\.\.\/)+(?:test\/helpers\/plugins\/)[^"']+["']/u, + ]; + const files = walkCode(path.join(repoRoot, "extensions")); + + const offenders = files.filter((file) => { + const source = fs.readFileSync(path.join(repoRoot, file), "utf8"); + return bannedPatterns.some((pattern) => pattern.test(source)); + }); + + expect(offenders).toEqual([]); + }); });