mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-22 11:11:10 +00:00
fix(plugin-sdk): preserve runtime contexts in test mocks (#107059)
* test(plugin-sdk): make runtime context mock stateful * docs(agents): record Testbox invocation contracts
This commit is contained in:
committed by
GitHub
parent
66e6923929
commit
be5558cb4e
@@ -172,6 +172,8 @@ Skills own workflows; root owns hard policy and routing.
|
||||
- PR refs: `gh pr view/diff` or `gh api`, not web search. Prefer `gitcrawl` for maintainer discovery; missing/stale `gitcrawl` falls through to live `gh`, not contributor setup. Verify live with `gh` before mutation.
|
||||
- `gh pr view` takes the branch positionally; no `--head` flag.
|
||||
- zsh: quote `gh api` endpoints containing `?` or brackets; otherwise glob expansion corrupts the invocation.
|
||||
- Blacksmith Testbox status/stop: `--id <tbx_id>`; no status JSON flag.
|
||||
- Crabbox final timing JSON = proof complete; if portal sync hangs after it, interrupt wrapper only.
|
||||
- GitHub Actions: resolve workflow files from `.github/workflows` or API; never infer filenames from display names.
|
||||
- zsh: quote command globs; unmatched patterns abort before the tool runs.
|
||||
- zsh: don't use `path` as a variable; it rewrites `$PATH`.
|
||||
|
||||
@@ -49,6 +49,32 @@ describe("createPluginRuntimeMock", () => {
|
||||
expect(vi.isMockFunction(debouncer.cancelKey)).toBe(true);
|
||||
});
|
||||
|
||||
it("tracks channel runtime contexts through the mock registry", () => {
|
||||
const runtime = createPluginRuntimeMock();
|
||||
const key = {
|
||||
channelId: "whatsapp",
|
||||
accountId: "default",
|
||||
capability: "connection-controller",
|
||||
};
|
||||
const context = { getActiveListener: vi.fn() };
|
||||
const onEvent = vi.fn();
|
||||
const unsubscribe = runtime.channel.runtimeContexts.watch({ ...key, onEvent });
|
||||
|
||||
const lease = runtime.channel.runtimeContexts.register({ ...key, context });
|
||||
|
||||
expect(runtime.channel.runtimeContexts.get(key)).toBe(context);
|
||||
expect(onEvent).toHaveBeenCalledWith({ type: "registered", key, context });
|
||||
expect(vi.isMockFunction(runtime.channel.runtimeContexts.register)).toBe(true);
|
||||
expect(vi.isMockFunction(runtime.channel.runtimeContexts.get)).toBe(true);
|
||||
expect(vi.isMockFunction(runtime.channel.runtimeContexts.watch)).toBe(true);
|
||||
|
||||
lease.dispose();
|
||||
|
||||
expect(runtime.channel.runtimeContexts.get(key)).toBeUndefined();
|
||||
expect(onEvent).toHaveBeenLastCalledWith({ type: "unregistered", key });
|
||||
unsubscribe();
|
||||
});
|
||||
|
||||
it("exposes channel inbound helpers without the removed turn aliases", async () => {
|
||||
const runtime = createPluginRuntimeMock();
|
||||
const channel = "test";
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
sanitizeInboundSystemTags,
|
||||
} from "../../auto-reply/reply/inbound-text.js";
|
||||
import { resolveSessionEntryResetFreshness } from "../../config/sessions/entry-freshness.js";
|
||||
import { createChannelRuntimeContextRegistry } from "../../plugins/runtime/channel-runtime-contexts.js";
|
||||
import {
|
||||
implicitMentionKindWhen,
|
||||
resolveInboundMentionDecision,
|
||||
@@ -142,6 +143,7 @@ export function createPluginRuntimeMediaMock(
|
||||
}
|
||||
|
||||
export function createPluginRuntimeMock(overrides: DeepPartial<PluginRuntime> = {}): PluginRuntime {
|
||||
const runtimeContexts = createChannelRuntimeContextRegistry();
|
||||
const runEmbeddedAgentMock = vi.fn().mockResolvedValue({
|
||||
payloads: [],
|
||||
meta: {},
|
||||
@@ -773,14 +775,14 @@ export function createPluginRuntimeMock(overrides: DeepPartial<PluginRuntime> =
|
||||
vi.fn() as unknown as PluginRuntime["channel"]["threadBindings"]["setMaxAgeBySessionKey"],
|
||||
},
|
||||
runtimeContexts: {
|
||||
register: vi.fn(({ abortSignal }: { abortSignal?: AbortSignal }) => {
|
||||
const lease = { dispose: vi.fn() };
|
||||
abortSignal?.addEventListener("abort", lease.dispose, { once: true });
|
||||
return lease;
|
||||
}) as unknown as PluginRuntime["channel"]["runtimeContexts"]["register"],
|
||||
get: vi.fn() as unknown as PluginRuntime["channel"]["runtimeContexts"]["get"],
|
||||
watch: vi.fn(() =>
|
||||
vi.fn(),
|
||||
register: vi.fn(
|
||||
runtimeContexts.register,
|
||||
) as unknown as PluginRuntime["channel"]["runtimeContexts"]["register"],
|
||||
get: vi.fn(
|
||||
runtimeContexts.get,
|
||||
) as unknown as PluginRuntime["channel"]["runtimeContexts"]["get"],
|
||||
watch: vi.fn(
|
||||
runtimeContexts.watch,
|
||||
) as unknown as PluginRuntime["channel"]["runtimeContexts"]["watch"],
|
||||
},
|
||||
activity: {} as PluginRuntime["channel"]["activity"],
|
||||
|
||||
Reference in New Issue
Block a user