





















@@ -0,0 +1,135 @@
1+import { describe, expect, it, vi } from "vitest";
2+3+const mocks = vi.hoisted(() => {
4+const runtimeConfig = { channels: { discord: { token: "token" } } };
5+const apiModule = {
6+collectDiscordStatusIssues: vi.fn(() => []),
7+discordOnboardingAdapter: { kind: "legacy-onboarding" },
8+inspectDiscordAccount: vi.fn(() => ({ accountId: "default" })),
9+listDiscordAccountIds: vi.fn(() => ["default"]),
10+listDiscordDirectoryGroupsFromConfig: vi.fn(() => []),
11+listDiscordDirectoryPeersFromConfig: vi.fn(() => []),
12+looksLikeDiscordTargetId: vi.fn(() => true),
13+normalizeDiscordMessagingTarget: vi.fn(() => "channel:123"),
14+normalizeDiscordOutboundTarget: vi.fn(() => ({ ok: true, to: "channel:123" })),
15+resolveDefaultDiscordAccountId: vi.fn(() => "default"),
16+resolveDiscordAccount: vi.fn(() => ({
17+accountId: "default",
18+config: {},
19+enabled: true,
20+token: "token",
21+tokenSource: "config",
22+})),
23+resolveDiscordGroupRequireMention: vi.fn(() => true),
24+resolveDiscordGroupToolPolicy: vi.fn(() => undefined),
25+};
26+const runtimeModule = {
27+autoBindSpawnedDiscordSubagent: vi.fn(async (params) => ({
28+accountId: params.accountId ?? "default",
29+channelId: "123",
30+targetKind: "subagent",
31+targetSessionKey: params.childSessionKey,
32+threadId: "456",
33+cfg: params.cfg,
34+})),
35+collectDiscordAuditChannelIds: vi.fn(() => ({ channelIds: [], unresolvedChannels: [] })),
36+listThreadBindingsBySessionKey: vi.fn(() => []),
37+unbindThreadBindingsBySessionKey: vi.fn(() => []),
38+};
39+40+return {
41+ apiModule,
42+ runtimeModule,
43+ runtimeConfig,
44+loadBundledPluginPublicSurfaceModuleSync: vi.fn((params: { artifactBasename: string }) => {
45+if (params.artifactBasename === "runtime-api.js") {
46+return runtimeModule;
47+}
48+return apiModule;
49+}),
50+};
51+});
52+53+vi.mock("./facade-loader.js", () => ({
54+createLazyFacadeObjectValue: (load: () => object) =>
55+new Proxy(
56+{},
57+{
58+get(_target, property) {
59+return Reflect.get(load(), property);
60+},
61+},
62+),
63+loadBundledPluginPublicSurfaceModuleSync: mocks.loadBundledPluginPublicSurfaceModuleSync,
64+}));
65+66+vi.mock("./runtime-config-snapshot.js", () => ({
67+getRuntimeConfig: () => mocks.runtimeConfig,
68+getRuntimeConfigSnapshot: () => mocks.runtimeConfig,
69+}));
70+71+describe("discord plugin-sdk compatibility facade", () => {
72+it("exports the @openclaw/discord 2026.3.13 import surface", async () => {
73+const discordSdk = await import("./discord.js");
74+75+for (const exportName of [
76+"DEFAULT_ACCOUNT_ID",
77+"DiscordConfigSchema",
78+"PAIRING_APPROVED_MESSAGE",
79+"applyAccountNameToChannelSection",
80+"autoBindSpawnedDiscordSubagent",
81+"buildChannelConfigSchema",
82+"buildComputedAccountStatusSnapshot",
83+"buildTokenChannelStatusSummary",
84+"collectDiscordAuditChannelIds",
85+"collectDiscordStatusIssues",
86+"discordOnboardingAdapter",
87+"emptyPluginConfigSchema",
88+"getChatChannelMeta",
89+"inspectDiscordAccount",
90+"listDiscordAccountIds",
91+"listDiscordDirectoryGroupsFromConfig",
92+"listDiscordDirectoryPeersFromConfig",
93+"listThreadBindingsBySessionKey",
94+"looksLikeDiscordTargetId",
95+"migrateBaseNameToDefaultAccount",
96+"normalizeAccountId",
97+"normalizeDiscordMessagingTarget",
98+"normalizeDiscordOutboundTarget",
99+"projectCredentialSnapshotFields",
100+"resolveConfiguredFromCredentialStatuses",
101+"resolveDefaultDiscordAccountId",
102+"resolveDiscordAccount",
103+"resolveDiscordGroupRequireMention",
104+"resolveDiscordGroupToolPolicy",
105+"unbindThreadBindingsBySessionKey",
106+]) {
107+expect(discordSdk).toHaveProperty(exportName);
108+}
109+});
110+111+it("keeps legacy Discord subagent auto-bind calls working without cfg", async () => {
112+const { autoBindSpawnedDiscordSubagent } = await import("./discord.js");
113+114+const binding = await autoBindSpawnedDiscordSubagent({
115+agentId: "agent",
116+channel: "discord",
117+childSessionKey: "child",
118+});
119+120+expect(mocks.runtimeModule.autoBindSpawnedDiscordSubagent).toHaveBeenCalledWith(
121+expect.objectContaining({
122+agentId: "agent",
123+cfg: mocks.runtimeConfig,
124+childSessionKey: "child",
125+}),
126+);
127+expect(binding).toEqual(
128+expect.objectContaining({
129+cfg: mocks.runtimeConfig,
130+targetKind: "subagent",
131+targetSessionKey: "child",
132+}),
133+);
134+});
135+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。