test(discord): isolate ACP binding routing seam

This commit is contained in:
Vincent Koc
2026-03-31 20:48:33 +09:00
parent b4ac69c652
commit 62c28c0708

View File

@@ -13,17 +13,12 @@ vi.mock("openclaw/plugin-sdk/config-runtime", async (importOriginal) => {
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import {
__testing as sessionBindingTesting,
getSessionBindingService,
registerSessionBindingAdapter,
type SessionBindingBindInput,
type SessionBindingRecord,
} from "openclaw/plugin-sdk/conversation-runtime";
import { __testing as acpManagerTesting } from "openclaw/plugin-sdk/testing";
import { handleAcpCommand } from "openclaw/plugin-sdk/testing";
import { buildCommandTestParams } from "openclaw/plugin-sdk/testing";
import { setDefaultChannelPluginRegistryForTests } from "openclaw/plugin-sdk/testing";
import * as gatewayCall from "openclaw/plugin-sdk/testing";
import { __testing as sessionBindingTesting } from "openclaw/plugin-sdk/conversation-runtime";
import { preflightDiscordMessage } from "./message-handler.preflight.js";
import {
createDiscordMessage,
@@ -33,8 +28,6 @@ import {
type DiscordMessageEvent,
} from "./message-handler.preflight.test-helpers.js";
const callGatewaySpy = vi.spyOn(gatewayCall, "callGateway");
const baseCfg = {
session: {
mainKey: "main",
@@ -56,18 +49,6 @@ const baseCfg = {
},
} satisfies OpenClawConfig;
function createDiscordDmCommandParams(commandBody: string, cfg: OpenClawConfig = baseCfg) {
const params = buildCommandTestParams(commandBody, cfg, {
Provider: "discord",
Surface: "discord",
OriginatingChannel: "discord",
OriginatingTo: "user:user-1",
AccountId: "default",
});
params.command.senderId = "user-1";
return params;
}
function createDmClient(channelId: string): DiscordClient {
return {
fetchChannel: async (id: string) => {
@@ -149,44 +130,32 @@ function createInMemoryDiscordBindingAdapter() {
describe("Discord ACP bind here end-to-end flow", () => {
beforeEach(() => {
setDefaultChannelPluginRegistryForTests();
sessionBindingTesting.resetSessionBindingAdaptersForTests();
acpManagerTesting.resetAcpSessionManagerForTests();
loadConfigMock.mockReset().mockReturnValue(baseCfg);
callGatewaySpy.mockReset().mockResolvedValue({ ok: true } as never);
acpManagerTesting.setAcpSessionManagerForTests({
initializeSession: async (input: { sessionKey: string; agent: string; mode: string }) => ({
runtime: {} as never,
handle: {
backend: "acpx",
runtimeSessionName: `${input.sessionKey}:runtime`,
},
meta: {
backend: "acpx",
agent: input.agent,
runtimeSessionName: `${input.sessionKey}:runtime`,
mode: input.mode,
state: "idle",
lastActivityAt: 1,
},
}),
});
});
it("binds a Discord DM through /acp spawn --bind here and routes the next DM turn to that ACP session", async () => {
it("routes the next Discord DM turn to an existing ACP session binding", async () => {
const adapter = createInMemoryDiscordBindingAdapter();
const binding = await getSessionBindingService().bind({
targetSessionKey: "agent:codex:acp:test-session",
targetKind: "session",
conversation: {
channel: "discord",
accountId: "default",
conversationId: "user:user-1",
parentConversationId: "user:user-1",
},
placement: "current",
metadata: {
boundBy: "user-1",
agentId: "codex",
label: "codex",
},
});
const commandResult = await handleAcpCommand(
createDiscordDmCommandParams("/acp spawn codex --bind here"),
true,
);
expect(commandResult?.reply?.text).toContain("Bound this conversation to");
expect(adapter.bindings).toHaveLength(1);
const binding = adapter.bindings[0];
expect(binding).toMatchObject({
targetSessionKey: expect.stringMatching(/^agent:codex:acp:/),
targetSessionKey: "agent:codex:acp:test-session",
conversation: {
channel: "discord",
accountId: "default",