mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:20:43 +00:00
test: expose provider media test helpers
This commit is contained in:
@@ -19,6 +19,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: move core-only channel contract fixtures under the channel contract test tree and retire the old `test/helpers/channels` bridge directory so plugin tests stay on focused SDK surfaces. Thanks @vincentkoc.
|
||||
- Plugin SDK: move maintained bundled channels off the deprecated `channel-config-schema-legacy` subpath, add an explicit bundled-channel schema SDK surface, and track both remaining legacy test/config compatibility barrels with dated removal windows. Thanks @vincentkoc.
|
||||
- Plugin SDK/testing: expose media provider capability assertions and provider HTTP mocks through focused SDK test subpaths, and retire the repo-only media-generation test helper bridge. Thanks @vincentkoc.
|
||||
- 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.
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
8f23f155251c05cab51ee8926e7a359bd64a0ba34e82a80d93d0ed96d07c8a04 plugin-sdk-api-baseline.json
|
||||
181fea7f35c49032e6894605a06ca1419e5b6ccc1a3d8987d952a1d24a8154bc plugin-sdk-api-baseline.jsonl
|
||||
31fd2178f08a4fcb28d6319eaa464b572b1e36a0fab700056f643feaccf95aa8 plugin-sdk-api-baseline.json
|
||||
65b239e91e4d5f4cac71527058aa53179a8dcf65f8c50f4eabab346def966e74 plugin-sdk-api-baseline.jsonl
|
||||
|
||||
@@ -67,6 +67,26 @@ Use `--json` for stable machine-readable output in CI annotations. OpenClaw
|
||||
core should expose contracts and fixtures the inspector can consume, but should
|
||||
not publish the inspector binary from the main `openclaw` package.
|
||||
|
||||
### Maintainer acceptance lane
|
||||
|
||||
Use Blacksmith Testbox for the installable-package acceptance lane when validating
|
||||
the external inspector against OpenClaw plugin packages. Run it from a clean
|
||||
OpenClaw checkout after the package is built:
|
||||
|
||||
```sh
|
||||
blacksmith testbox warmup ci-check-testbox.yml --ref main --idle-timeout 90
|
||||
blacksmith testbox run --id <tbx_id> "pnpm install && pnpm build && npm exec --yes @openclaw/plugin-inspector@0.1.0 -- ./extensions/telegram --json"
|
||||
blacksmith testbox run --id <tbx_id> "npm exec --yes @openclaw/plugin-inspector@0.1.0 -- ./extensions/discord --json"
|
||||
blacksmith testbox run --id <tbx_id> "npm exec --yes @openclaw/plugin-inspector@0.1.0 -- <clawhub-plugin-dir> --json"
|
||||
blacksmith testbox stop <tbx_id>
|
||||
```
|
||||
|
||||
Keep this lane opt-in for maintainers because it installs an external npm
|
||||
package and may inspect plugin packages cloned outside the repo. The local repo
|
||||
guards cover the SDK export map, compatibility registry metadata, deprecated
|
||||
SDK-import burn-down, and bundled extension import boundaries; Testbox inspector
|
||||
proof covers the package as external plugin authors consume it.
|
||||
|
||||
## Deprecation policy
|
||||
|
||||
OpenClaw should not remove a documented plugin contract in the same release
|
||||
|
||||
@@ -16,23 +16,24 @@ For the plugin authoring guide, see [Plugin SDK overview](/plugins/sdk-overview)
|
||||
|
||||
## Plugin entry
|
||||
|
||||
| Subpath | Key exports |
|
||||
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `plugin-sdk/plugin-entry` | `definePluginEntry` |
|
||||
| `plugin-sdk/core` | `defineChannelPluginEntry`, `createChatChannelPlugin`, `createChannelPluginBase`, `defineSetupPluginEntry`, `buildChannelConfigSchema` |
|
||||
| `plugin-sdk/config-schema` | `OpenClawSchema` |
|
||||
| `plugin-sdk/provider-entry` | `defineSingleProviderPluginEntry` |
|
||||
| `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 |
|
||||
| `plugin-sdk/test-env` | Test environment, fetch/network, live-test, temporary filesystem, and time-control fixtures |
|
||||
| `plugin-sdk/test-fixtures` | Generic CLI, sandbox, skill, agent-message, system-event, terminal, chunking, auth-token, and typed-case test fixtures |
|
||||
| `plugin-sdk/migration` | Migration provider item helpers such as `createMigrationItem`, reason constants, item status markers, redaction helpers, and `summarizeMigrationItems` |
|
||||
| `plugin-sdk/migration-runtime` | Runtime migration helpers such as `copyMigrationFileItem` and `writeMigrationReport` |
|
||||
| Subpath | Key exports |
|
||||
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `plugin-sdk/plugin-entry` | `definePluginEntry` |
|
||||
| `plugin-sdk/core` | `defineChannelPluginEntry`, `createChatChannelPlugin`, `createChannelPluginBase`, `defineSetupPluginEntry`, `buildChannelConfigSchema` |
|
||||
| `plugin-sdk/config-schema` | `OpenClawSchema` |
|
||||
| `plugin-sdk/provider-entry` | `defineSingleProviderPluginEntry` |
|
||||
| `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, media capability, web-search/fetch, and wizard contract helpers |
|
||||
| `plugin-sdk/provider-http-test-mocks` | Opt-in Vitest HTTP/auth mocks for provider tests that exercise `plugin-sdk/provider-http` |
|
||||
| `plugin-sdk/test-env` | Test environment, fetch/network, live-test, temporary filesystem, and time-control fixtures |
|
||||
| `plugin-sdk/test-fixtures` | Generic CLI, sandbox, skill, agent-message, system-event, terminal, chunking, auth-token, and typed-case test fixtures |
|
||||
| `plugin-sdk/migration` | Migration provider item helpers such as `createMigrationItem`, reason constants, item status markers, redaction helpers, and `summarizeMigrationItems` |
|
||||
| `plugin-sdk/migration-runtime` | Runtime migration helpers such as `copyMigrationFileItem` and `writeMigrationReport` |
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Channel subpaths">
|
||||
@@ -274,7 +275,8 @@ For the plugin authoring guide, see [Plugin SDK overview](/plugins/sdk-overview)
|
||||
| `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/provider-test-contracts` | Provider runtime, auth, discovery, onboard, catalog, wizard, media capability, web-search/fetch, and stream contract helpers |
|
||||
| `plugin-sdk/provider-http-test-mocks` | Opt-in Vitest HTTP/auth mocks for provider tests that exercise `plugin-sdk/provider-http` |
|
||||
| `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 |
|
||||
</Accordion>
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@ plugins.
|
||||
|
||||
**Provider contract import:** `openclaw/plugin-sdk/provider-test-contracts`
|
||||
|
||||
**Provider HTTP mock import:** `openclaw/plugin-sdk/provider-http-test-mocks`
|
||||
|
||||
**Environment/network test import:** `openclaw/plugin-sdk/test-env`
|
||||
|
||||
**Generic fixture import:** `openclaw/plugin-sdk/test-fixtures`
|
||||
@@ -52,6 +54,7 @@ import { createStartAccountContext } from "openclaw/plugin-sdk/channel-test-help
|
||||
import { describePluginRegistrationContract } from "openclaw/plugin-sdk/plugin-test-contracts";
|
||||
import { registerSingleProviderPlugin } from "openclaw/plugin-sdk/plugin-test-runtime";
|
||||
import { describeOpenAIProviderRuntimeContract } from "openclaw/plugin-sdk/provider-test-contracts";
|
||||
import { getProviderHttpMocks } from "openclaw/plugin-sdk/provider-http-test-mocks";
|
||||
import { withEnv, withFetchPreconnect } from "openclaw/plugin-sdk/test-env";
|
||||
import { createCliRuntimeCapture, typedCases } from "openclaw/plugin-sdk/test-fixtures";
|
||||
```
|
||||
@@ -76,6 +79,11 @@ import { createCliRuntimeCapture, typedCases } from "openclaw/plugin-sdk/test-fi
|
||||
| `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` |
|
||||
| `expectExplicitVideoGenerationCapabilities` | Assert video providers declare explicit generation mode capabilities. Import from `plugin-sdk/provider-test-contracts` |
|
||||
| `expectExplicitMusicGenerationCapabilities` | Assert music providers declare explicit generation/edit capabilities. Import from `plugin-sdk/provider-test-contracts` |
|
||||
| `mockSuccessfulDashscopeVideoTask` | Install a successful DashScope-compatible video task response. Import from `plugin-sdk/provider-test-contracts` |
|
||||
| `getProviderHttpMocks` | Access opt-in provider HTTP/auth Vitest mocks. Import from `plugin-sdk/provider-http-test-mocks` |
|
||||
| `installProviderHttpMockCleanup` | Reset provider HTTP/auth mocks after each test. Import from `plugin-sdk/provider-http-test-mocks` |
|
||||
| `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` |
|
||||
@@ -112,9 +120,10 @@ Keep new extension tests on a documented focused SDK subpath such as
|
||||
`plugin-sdk/plugin-test-api`, `plugin-sdk/channel-contract-testing`,
|
||||
`plugin-sdk/channel-test-helpers`, `plugin-sdk/plugin-test-contracts`,
|
||||
`plugin-sdk/plugin-test-runtime`, `plugin-sdk/provider-test-contracts`,
|
||||
`plugin-sdk/test-env`, or `plugin-sdk/test-fixtures` rather than importing the
|
||||
broad `plugin-sdk/testing` compatibility barrel, repo `src/**` files, or repo
|
||||
`test/helpers/plugins/*` bridges directly.
|
||||
`plugin-sdk/provider-http-test-mocks`, `plugin-sdk/test-env`, or
|
||||
`plugin-sdk/test-fixtures` rather than importing the broad `plugin-sdk/testing`
|
||||
compatibility barrel, repo `src/**` files, or repo `test/helpers/plugins/*`
|
||||
bridges directly.
|
||||
|
||||
### Types
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { beforeAll, describe, expect, it } from "vitest";
|
||||
import {
|
||||
expectDashscopeVideoTaskPoll,
|
||||
expectSuccessfulDashscopeVideoResult,
|
||||
mockSuccessfulDashscopeVideoTask,
|
||||
} from "../../test/helpers/media-generation/dashscope-video-provider.js";
|
||||
import { expectExplicitVideoGenerationCapabilities } from "../../test/helpers/media-generation/provider-capability-assertions.js";
|
||||
import {
|
||||
getProviderHttpMocks,
|
||||
installProviderHttpMockCleanup,
|
||||
} from "../../test/helpers/media-generation/provider-http-mocks.js";
|
||||
} from "openclaw/plugin-sdk/provider-http-test-mocks";
|
||||
import {
|
||||
expectDashscopeVideoTaskPoll,
|
||||
expectExplicitVideoGenerationCapabilities,
|
||||
expectSuccessfulDashscopeVideoResult,
|
||||
mockSuccessfulDashscopeVideoTask,
|
||||
} from "openclaw/plugin-sdk/provider-test-contracts";
|
||||
import { beforeAll, describe, expect, it } from "vitest";
|
||||
|
||||
const { postJsonRequestMock, fetchWithTimeoutMock } = getProviderHttpMocks();
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { beforeAll, describe, expect, it, vi } from "vitest";
|
||||
import { expectExplicitVideoGenerationCapabilities } from "../../test/helpers/media-generation/provider-capability-assertions.js";
|
||||
import {
|
||||
getProviderHttpMocks,
|
||||
installProviderHttpMockCleanup,
|
||||
} from "../../test/helpers/media-generation/provider-http-mocks.js";
|
||||
} from "openclaw/plugin-sdk/provider-http-test-mocks";
|
||||
import { expectExplicitVideoGenerationCapabilities } from "openclaw/plugin-sdk/provider-test-contracts";
|
||||
import { beforeAll, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const { postJsonRequestMock, fetchWithTimeoutMock } = getProviderHttpMocks();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { expectExplicitMusicGenerationCapabilities } from "openclaw/plugin-sdk/provider-test-contracts";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { expectExplicitMusicGenerationCapabilities } from "../../test/helpers/media-generation/provider-capability-assertions.js";
|
||||
import { buildComfyMusicGenerationProvider } from "./music-generation-provider.js";
|
||||
import { _setComfyFetchGuardForTesting } from "./workflow-runtime.js";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { expectExplicitVideoGenerationCapabilities } from "openclaw/plugin-sdk/provider-test-contracts";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { expectExplicitVideoGenerationCapabilities } from "../../test/helpers/media-generation/provider-capability-assertions.js";
|
||||
import {
|
||||
buildComfyConfig,
|
||||
mockComfyCloudJobResponses,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { beforeAll, describe, expect, it, vi } from "vitest";
|
||||
import { expectExplicitVideoGenerationCapabilities } from "../../test/helpers/media-generation/provider-capability-assertions.js";
|
||||
import {
|
||||
getProviderHttpMocks,
|
||||
installProviderHttpMockCleanup,
|
||||
} from "../../test/helpers/media-generation/provider-http-mocks.js";
|
||||
} from "openclaw/plugin-sdk/provider-http-test-mocks";
|
||||
import { expectExplicitVideoGenerationCapabilities } from "openclaw/plugin-sdk/provider-test-contracts";
|
||||
import { beforeAll, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const { postJsonRequestMock, resolveProviderHttpRequestConfigMock } = getProviderHttpMocks();
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as providerAuth from "openclaw/plugin-sdk/provider-auth-runtime";
|
||||
import * as providerHttp from "openclaw/plugin-sdk/provider-http";
|
||||
import { expectExplicitVideoGenerationCapabilities } from "openclaw/plugin-sdk/provider-test-contracts";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { expectExplicitVideoGenerationCapabilities } from "../../test/helpers/media-generation/provider-capability-assertions.js";
|
||||
import {
|
||||
_setFalVideoFetchGuardForTesting,
|
||||
buildFalVideoGenerationProvider,
|
||||
|
||||
@@ -17,7 +17,7 @@ vi.mock("./google-genai-runtime.js", () => ({
|
||||
}));
|
||||
|
||||
import * as providerAuthRuntime from "openclaw/plugin-sdk/provider-auth-runtime";
|
||||
import { expectExplicitMusicGenerationCapabilities } from "../../test/helpers/media-generation/provider-capability-assertions.js";
|
||||
import { expectExplicitMusicGenerationCapabilities } from "openclaw/plugin-sdk/provider-test-contracts";
|
||||
import { buildGoogleMusicGenerationProvider } from "./music-generation-provider.js";
|
||||
|
||||
describe("google music generation provider", () => {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
getProviderHttpMocks,
|
||||
installProviderHttpMockCleanup,
|
||||
} from "../../test/helpers/media-generation/provider-http-mocks.js";
|
||||
} from "openclaw/plugin-sdk/provider-http-test-mocks";
|
||||
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const transcodeAudioBufferToOpusMock = vi.hoisted(() => vi.fn());
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ vi.mock("./google-genai-runtime.js", () => ({
|
||||
}));
|
||||
|
||||
import * as providerAuthRuntime from "openclaw/plugin-sdk/provider-auth-runtime";
|
||||
import { expectExplicitVideoGenerationCapabilities } from "../../test/helpers/media-generation/provider-capability-assertions.js";
|
||||
import { expectExplicitVideoGenerationCapabilities } from "openclaw/plugin-sdk/provider-test-contracts";
|
||||
import { buildGoogleVideoGenerationProvider } from "./video-generation-provider.js";
|
||||
|
||||
describe("google video generation provider", () => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { expectExplicitMusicGenerationCapabilities } from "openclaw/plugin-sdk/provider-test-contracts";
|
||||
import { beforeAll, describe, expect, it, vi } from "vitest";
|
||||
import { expectExplicitMusicGenerationCapabilities } from "../../test/helpers/media-generation/provider-capability-assertions.js";
|
||||
import {
|
||||
getMinimaxProviderHttpMocks,
|
||||
installMinimaxProviderHttpMockCleanup,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { expectExplicitVideoGenerationCapabilities } from "openclaw/plugin-sdk/provider-test-contracts";
|
||||
import { beforeAll, describe, expect, it, vi } from "vitest";
|
||||
import { expectExplicitVideoGenerationCapabilities } from "../../test/helpers/media-generation/provider-capability-assertions.js";
|
||||
import {
|
||||
getMinimaxProviderHttpMocks,
|
||||
installMinimaxProviderHttpMockCleanup,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { beforeAll, describe, expect, it, vi } from "vitest";
|
||||
import { expectExplicitVideoGenerationCapabilities } from "../../test/helpers/media-generation/provider-capability-assertions.js";
|
||||
import {
|
||||
getProviderHttpMocks,
|
||||
installProviderHttpMockCleanup,
|
||||
} from "../../test/helpers/media-generation/provider-http-mocks.js";
|
||||
} from "openclaw/plugin-sdk/provider-http-test-mocks";
|
||||
import { expectExplicitVideoGenerationCapabilities } from "openclaw/plugin-sdk/provider-test-contracts";
|
||||
import { beforeAll, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const { postJsonRequestMock, fetchWithTimeoutMock, resolveProviderHttpRequestConfigMock } =
|
||||
getProviderHttpMocks();
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { beforeAll, describe, expect, it } from "vitest";
|
||||
import {
|
||||
expectDashscopeVideoTaskPoll,
|
||||
expectSuccessfulDashscopeVideoResult,
|
||||
mockSuccessfulDashscopeVideoTask,
|
||||
} from "../../test/helpers/media-generation/dashscope-video-provider.js";
|
||||
import { expectExplicitVideoGenerationCapabilities } from "../../test/helpers/media-generation/provider-capability-assertions.js";
|
||||
import {
|
||||
getProviderHttpMocks,
|
||||
installProviderHttpMockCleanup,
|
||||
} from "../../test/helpers/media-generation/provider-http-mocks.js";
|
||||
} from "openclaw/plugin-sdk/provider-http-test-mocks";
|
||||
import {
|
||||
expectDashscopeVideoTaskPoll,
|
||||
expectExplicitVideoGenerationCapabilities,
|
||||
expectSuccessfulDashscopeVideoResult,
|
||||
mockSuccessfulDashscopeVideoTask,
|
||||
} from "openclaw/plugin-sdk/provider-test-contracts";
|
||||
import { beforeAll, describe, expect, it } from "vitest";
|
||||
|
||||
const { postJsonRequestMock, fetchWithTimeoutMock } = getProviderHttpMocks();
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { beforeAll, describe, expect, it, vi } from "vitest";
|
||||
import { expectExplicitVideoGenerationCapabilities } from "../../test/helpers/media-generation/provider-capability-assertions.js";
|
||||
import {
|
||||
getProviderHttpMocks,
|
||||
installProviderHttpMockCleanup,
|
||||
} from "../../test/helpers/media-generation/provider-http-mocks.js";
|
||||
} from "openclaw/plugin-sdk/provider-http-test-mocks";
|
||||
import { expectExplicitVideoGenerationCapabilities } from "openclaw/plugin-sdk/provider-test-contracts";
|
||||
import { beforeAll, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const { postJsonRequestMock, fetchWithTimeoutMock } = getProviderHttpMocks();
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { beforeAll, describe, expect, it, vi } from "vitest";
|
||||
import { expectExplicitVideoGenerationCapabilities } from "../../test/helpers/media-generation/provider-capability-assertions.js";
|
||||
import {
|
||||
getProviderHttpMocks,
|
||||
installProviderHttpMockCleanup,
|
||||
} from "../../test/helpers/media-generation/provider-http-mocks.js";
|
||||
} from "openclaw/plugin-sdk/provider-http-test-mocks";
|
||||
import { expectExplicitVideoGenerationCapabilities } from "openclaw/plugin-sdk/provider-test-contracts";
|
||||
import { beforeAll, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const { postJsonRequestMock, fetchWithTimeoutMock } = getProviderHttpMocks();
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { expectExplicitVideoGenerationCapabilities } from "openclaw/plugin-sdk/provider-test-contracts";
|
||||
import { installPinnedHostnameTestHooks } from "openclaw/plugin-sdk/test-env";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { expectExplicitVideoGenerationCapabilities } from "../../test/helpers/media-generation/provider-capability-assertions.js";
|
||||
import {
|
||||
binaryResponse,
|
||||
jsonResponse,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { beforeAll, describe, expect, it, vi } from "vitest";
|
||||
import { expectExplicitVideoGenerationCapabilities } from "../../test/helpers/media-generation/provider-capability-assertions.js";
|
||||
import {
|
||||
getProviderHttpMocks,
|
||||
installProviderHttpMockCleanup,
|
||||
} from "../../test/helpers/media-generation/provider-http-mocks.js";
|
||||
} from "openclaw/plugin-sdk/provider-http-test-mocks";
|
||||
import { expectExplicitVideoGenerationCapabilities } from "openclaw/plugin-sdk/provider-test-contracts";
|
||||
import { beforeAll, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const { postJsonRequestMock, fetchWithTimeoutMock } = getProviderHttpMocks();
|
||||
|
||||
|
||||
@@ -522,6 +522,10 @@
|
||||
"types": "./dist/plugin-sdk/plugin-test-runtime.d.ts",
|
||||
"default": "./dist/plugin-sdk/plugin-test-runtime.js"
|
||||
},
|
||||
"./plugin-sdk/provider-http-test-mocks": {
|
||||
"types": "./dist/plugin-sdk/provider-http-test-mocks.d.ts",
|
||||
"default": "./dist/plugin-sdk/provider-http-test-mocks.js"
|
||||
},
|
||||
"./plugin-sdk/provider-test-contracts": {
|
||||
"types": "./dist/plugin-sdk/provider-test-contracts.d.ts",
|
||||
"default": "./dist/plugin-sdk/provider-test-contracts.js"
|
||||
|
||||
@@ -33,6 +33,10 @@ const FORBIDDEN_PATTERNS: Array<{ pattern: RegExp; hint: string }> = [
|
||||
pattern: /["'](?:\.\.\/)+(?:test\/helpers\/channels\/)[^"']+["']/,
|
||||
hint: "Use openclaw/plugin-sdk/channel-test-helpers or another focused SDK test subpath instead of repo-only channel helper bridges.",
|
||||
},
|
||||
{
|
||||
pattern: /["'](?:\.\.\/)+(?:test\/helpers\/media-generation\/)[^"']+["']/,
|
||||
hint: "Use openclaw/plugin-sdk/provider-test-contracts or openclaw/plugin-sdk/provider-http-test-mocks instead of repo-only media provider helper bridges.",
|
||||
},
|
||||
{
|
||||
pattern: /["'](?:\.\.\/)+(?:src\/channels\/plugins\/contracts\/test-helpers\/)[^"']+["']/,
|
||||
hint: "Use openclaw/plugin-sdk/channel-test-helpers or another focused SDK test subpath instead of core-only channel contract helpers.",
|
||||
@@ -107,6 +111,9 @@ const RETIRED_EXTENSION_TEST_HELPER_BRIDGE_FILES = [
|
||||
"test/helpers/plugins/typed-cases.ts",
|
||||
"test/helpers/plugins/web-fetch-provider-contract.ts",
|
||||
"test/helpers/plugins/web-search-provider-contract.ts",
|
||||
"test/helpers/media-generation/dashscope-video-provider.ts",
|
||||
"test/helpers/media-generation/provider-capability-assertions.ts",
|
||||
"test/helpers/media-generation/provider-http-mocks.ts",
|
||||
];
|
||||
|
||||
function isExtensionTestFile(filePath: string): boolean {
|
||||
|
||||
@@ -119,6 +119,9 @@ export const pluginSdkDocMetadata = {
|
||||
"provider-test-contracts": {
|
||||
category: "utilities",
|
||||
},
|
||||
"provider-http-test-mocks": {
|
||||
category: "utilities",
|
||||
},
|
||||
"test-env": {
|
||||
category: "utilities",
|
||||
},
|
||||
|
||||
@@ -114,6 +114,7 @@
|
||||
"plugin-test-api",
|
||||
"plugin-test-contracts",
|
||||
"plugin-test-runtime",
|
||||
"provider-http-test-mocks",
|
||||
"provider-test-contracts",
|
||||
"test-env",
|
||||
"test-fixtures",
|
||||
|
||||
4
src/plugin-sdk/provider-http-test-mocks.ts
Normal file
4
src/plugin-sdk/provider-http-test-mocks.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export {
|
||||
getProviderHttpMocks,
|
||||
installProviderHttpMockCleanup,
|
||||
} from "./test-helpers/provider-http-mocks.js";
|
||||
@@ -32,6 +32,17 @@ export {
|
||||
createConfigWithFallbacks,
|
||||
createLegacyProviderConfig,
|
||||
} from "./test-helpers/onboard-config.js";
|
||||
export {
|
||||
expectDashscopeVideoTaskPoll,
|
||||
expectSuccessfulDashscopeVideoResult,
|
||||
mockSuccessfulDashscopeVideoTask,
|
||||
resetDashscopeVideoProviderMocks,
|
||||
type DashscopeVideoProviderMocks,
|
||||
} from "./test-helpers/dashscope-video-provider.js";
|
||||
export {
|
||||
expectExplicitMusicGenerationCapabilities,
|
||||
expectExplicitVideoGenerationCapabilities,
|
||||
} from "./test-helpers/provider-media-capability-assertions.js";
|
||||
export {
|
||||
expectProviderOnboardAllowlistAlias,
|
||||
expectProviderOnboardMergedLegacyConfig,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { VideoGenerationResult } from "openclaw/plugin-sdk/video-generation";
|
||||
import { expect, vi } from "vitest";
|
||||
import type { VideoGenerationResult } from "../video-generation.js";
|
||||
|
||||
type ClearableMock = {
|
||||
mockClear(): unknown;
|
||||
@@ -1,9 +1,9 @@
|
||||
import { afterEach, vi } from "vitest";
|
||||
import type {
|
||||
pollProviderOperationJson,
|
||||
resolveProviderHttpRequestConfig,
|
||||
sanitizeConfiguredModelProviderRequest,
|
||||
} from "openclaw/plugin-sdk/provider-http";
|
||||
import { afterEach, vi } from "vitest";
|
||||
} from "../provider-http.js";
|
||||
|
||||
type ResolveProviderHttpRequestConfigParams = Parameters<
|
||||
typeof resolveProviderHttpRequestConfig
|
||||
@@ -1,10 +1,8 @@
|
||||
import { expect } from "vitest";
|
||||
import { listSupportedMusicGenerationModes } from "../../../src/music-generation/capabilities.js";
|
||||
import type {
|
||||
MusicGenerationProviderPlugin,
|
||||
VideoGenerationProviderPlugin,
|
||||
} from "../../../src/plugins/types.js";
|
||||
import { listSupportedVideoGenerationModes } from "../../../src/video-generation/capabilities.js";
|
||||
import { listSupportedMusicGenerationModes } from "../../music-generation/capabilities.js";
|
||||
import type { MusicGenerationProviderPlugin } from "../../plugins/types.js";
|
||||
import type { VideoGenerationProviderPlugin } from "../../plugins/types.js";
|
||||
import { listSupportedVideoGenerationModes } from "../../video-generation/capabilities.js";
|
||||
|
||||
function hasPositiveModeLimit(
|
||||
value: number | undefined,
|
||||
@@ -24,6 +24,13 @@ const PRIVATE_BUNDLED_SDK_SURFACE_PATTERN =
|
||||
const GENERIC_CORE_HELPER_FILES = ["src/polls.ts", "src/poll-params.ts"] as const;
|
||||
const GENERIC_CORE_PLUGIN_OWNER_NAME_PATTERN =
|
||||
/\b(?:bluebubbles|discord|feishu|googlechat|matrix|mattermost|msteams|slack|telegram|whatsapp|zalo|zalouser)\b/gi;
|
||||
const DEPRECATED_EXTENSION_SDK_SPECIFIERS = new Set([
|
||||
"openclaw/plugin-sdk",
|
||||
"openclaw/plugin-sdk/channel-config-schema-legacy",
|
||||
"openclaw/plugin-sdk/compat",
|
||||
"openclaw/plugin-sdk/testing",
|
||||
"openclaw/plugin-sdk/test-utils",
|
||||
]);
|
||||
|
||||
function collectPluginSdkPackageExports(): string[] {
|
||||
const packageJson = JSON.parse(readFileSync(resolve(REPO_ROOT, "package.json"), "utf8")) as {
|
||||
@@ -267,6 +274,32 @@ function collectExtensionTestHelperImportLeaks(): Array<{ file: string; specifie
|
||||
return leaks;
|
||||
}
|
||||
|
||||
function collectDeprecatedExtensionSdkImports(): Array<{ file: string; specifier: string }> {
|
||||
const leaks: Array<{ file: string; specifier: string }> = [];
|
||||
const importPatterns = [
|
||||
/\b(?:import|export)\b[\s\S]*?\bfrom\s*["'](openclaw\/plugin-sdk(?:\/[a-z0-9][a-z0-9-]*)?)["']/g,
|
||||
/\bimport\s*\(\s*["'](openclaw\/plugin-sdk(?:\/[a-z0-9][a-z0-9-]*)?)["']\s*\)/g,
|
||||
/\bvi\.(?:mock|doMock)\s*\(\s*["'](openclaw\/plugin-sdk(?:\/[a-z0-9][a-z0-9-]*)?)["']/g,
|
||||
];
|
||||
for (const file of collectExtensionFiles(resolve(REPO_ROOT, "extensions"))) {
|
||||
const repoRelativePath = relative(REPO_ROOT, file).replaceAll("\\", "/");
|
||||
const source = readFileSync(file, "utf8");
|
||||
for (const importPattern of importPatterns) {
|
||||
for (const match of source.matchAll(importPattern)) {
|
||||
const specifier = match[1];
|
||||
if (!specifier || !DEPRECATED_EXTENSION_SDK_SPECIFIERS.has(specifier)) {
|
||||
continue;
|
||||
}
|
||||
leaks.push({
|
||||
file: repoRelativePath,
|
||||
specifier,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return leaks;
|
||||
}
|
||||
|
||||
function collectCrossOwnerReservedSdkImports(): Array<{
|
||||
file: string;
|
||||
specifier: string;
|
||||
@@ -430,6 +463,10 @@ describe("plugin-sdk package contract guardrails", () => {
|
||||
expect(collectExtensionTestHelperImportLeaks()).toEqual([]);
|
||||
});
|
||||
|
||||
it("keeps extension sources off deprecated plugin-sdk compatibility imports", () => {
|
||||
expect(collectDeprecatedExtensionSdkImports()).toEqual([]);
|
||||
});
|
||||
|
||||
it("keeps reserved SDK compatibility subpaths inside their owning bundled plugins", () => {
|
||||
expect(collectCrossOwnerReservedSdkImports()).toEqual([]);
|
||||
});
|
||||
|
||||
@@ -59,10 +59,12 @@ const PUBLIC_SDK_TEST_HELPER_SUBPATHS = [
|
||||
"plugin-test-api",
|
||||
"plugin-test-contracts",
|
||||
"plugin-test-runtime",
|
||||
"provider-http-test-mocks",
|
||||
"provider-test-contracts",
|
||||
"test-env",
|
||||
"test-fixtures",
|
||||
] as const;
|
||||
const PUBLIC_SDK_TEST_HELPER_SUBPATHS_WITH_TOP_LEVEL_MOCKS = ["provider-http-test-mocks"] as const;
|
||||
|
||||
const importResolvedPluginSdkSubpath = async (specifier: string) => import(specifier);
|
||||
|
||||
@@ -760,16 +762,25 @@ describe("plugin-sdk subpath exports", () => {
|
||||
"installCommonResolveTargetErrorCases",
|
||||
"ResolveTargetFn",
|
||||
]);
|
||||
expectSourceMentions("provider-http-test-mocks", [
|
||||
"getProviderHttpMocks",
|
||||
"installProviderHttpMockCleanup",
|
||||
]);
|
||||
});
|
||||
|
||||
it("keeps public SDK test helper subpaths free of top-level Vitest module mocks", () => {
|
||||
const violations = PUBLIC_SDK_TEST_HELPER_SUBPATHS.flatMap((subpath) =>
|
||||
collectReexportedSourceFiles(resolve(PLUGIN_SDK_DIR, `${subpath}.ts`)).flatMap((file) =>
|
||||
topLevelVitestModuleMockLines(file).map(
|
||||
(line) => `${file.slice(REPO_ROOT.length + 1)}:${line}`,
|
||||
it("keeps public SDK test helper subpaths free of top-level Vitest module mocks outside opt-in mock helpers", () => {
|
||||
const optInMockSubpaths = new Set<string>(PUBLIC_SDK_TEST_HELPER_SUBPATHS_WITH_TOP_LEVEL_MOCKS);
|
||||
const violations = PUBLIC_SDK_TEST_HELPER_SUBPATHS.filter(
|
||||
(subpath) => !optInMockSubpaths.has(subpath),
|
||||
)
|
||||
.flatMap((subpath) =>
|
||||
collectReexportedSourceFiles(resolve(PLUGIN_SDK_DIR, `${subpath}.ts`)).flatMap((file) =>
|
||||
topLevelVitestModuleMockLines(file).map(
|
||||
(line) => `${file.slice(REPO_ROOT.length + 1)}:${line}`,
|
||||
),
|
||||
),
|
||||
),
|
||||
).toSorted();
|
||||
)
|
||||
.toSorted();
|
||||
|
||||
expect(violations).toEqual([]);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user