mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 22:04:30 +00:00
refactor(discord): dedupe native command ACP routing test setup
This commit is contained in:
@@ -87,6 +87,75 @@ function createConfig(): OpenClawConfig {
|
|||||||
} as OpenClawConfig;
|
} as OpenClawConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createStatusCommand(cfg: OpenClawConfig) {
|
||||||
|
const commandSpec: NativeCommandSpec = {
|
||||||
|
name: "status",
|
||||||
|
description: "Status",
|
||||||
|
acceptsArgs: false,
|
||||||
|
};
|
||||||
|
return createDiscordNativeCommand({
|
||||||
|
command: commandSpec,
|
||||||
|
cfg,
|
||||||
|
discordConfig: cfg.channels?.discord ?? {},
|
||||||
|
accountId: "default",
|
||||||
|
sessionPrefix: "discord:slash",
|
||||||
|
ephemeralDefault: true,
|
||||||
|
threadBindings: createNoopThreadBindingManager("default"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setConfiguredBinding(channelId: string, boundSessionKey: string) {
|
||||||
|
persistentBindingMocks.resolveConfiguredAcpBindingRecord.mockReturnValue({
|
||||||
|
spec: {
|
||||||
|
channel: "discord",
|
||||||
|
accountId: "default",
|
||||||
|
conversationId: channelId,
|
||||||
|
agentId: "codex",
|
||||||
|
mode: "persistent",
|
||||||
|
},
|
||||||
|
record: {
|
||||||
|
bindingId: `config:acp:discord:default:${channelId}`,
|
||||||
|
targetSessionKey: boundSessionKey,
|
||||||
|
targetKind: "session",
|
||||||
|
conversation: {
|
||||||
|
channel: "discord",
|
||||||
|
accountId: "default",
|
||||||
|
conversationId: channelId,
|
||||||
|
},
|
||||||
|
status: "active",
|
||||||
|
boundAt: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
persistentBindingMocks.ensureConfiguredAcpBindingSession.mockResolvedValue({
|
||||||
|
ok: true,
|
||||||
|
sessionKey: boundSessionKey,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDispatchSpy() {
|
||||||
|
return vi.spyOn(dispatcherModule, "dispatchReplyWithDispatcher").mockResolvedValue({
|
||||||
|
counts: {
|
||||||
|
final: 1,
|
||||||
|
block: 0,
|
||||||
|
tool: 0,
|
||||||
|
},
|
||||||
|
} as never);
|
||||||
|
}
|
||||||
|
|
||||||
|
function expectBoundSessionDispatch(
|
||||||
|
dispatchSpy: ReturnType<typeof createDispatchSpy>,
|
||||||
|
boundSessionKey: string,
|
||||||
|
) {
|
||||||
|
expect(dispatchSpy).toHaveBeenCalledTimes(1);
|
||||||
|
const dispatchCall = dispatchSpy.mock.calls[0]?.[0] as {
|
||||||
|
ctx?: { SessionKey?: string; CommandTargetSessionKey?: string };
|
||||||
|
};
|
||||||
|
expect(dispatchCall.ctx?.SessionKey).toBe(boundSessionKey);
|
||||||
|
expect(dispatchCall.ctx?.CommandTargetSessionKey).toBe(boundSessionKey);
|
||||||
|
expect(persistentBindingMocks.resolveConfiguredAcpBindingRecord).toHaveBeenCalledTimes(1);
|
||||||
|
expect(persistentBindingMocks.ensureConfiguredAcpBindingSession).toHaveBeenCalledTimes(1);
|
||||||
|
}
|
||||||
|
|
||||||
describe("Discord native plugin command dispatch", () => {
|
describe("Discord native plugin command dispatch", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.restoreAllMocks();
|
vi.restoreAllMocks();
|
||||||
@@ -169,20 +238,7 @@ describe("Discord native plugin command dispatch", () => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
} as OpenClawConfig;
|
} as OpenClawConfig;
|
||||||
const commandSpec: NativeCommandSpec = {
|
const command = createStatusCommand(cfg);
|
||||||
name: "status",
|
|
||||||
description: "Status",
|
|
||||||
acceptsArgs: false,
|
|
||||||
};
|
|
||||||
const command = createDiscordNativeCommand({
|
|
||||||
command: commandSpec,
|
|
||||||
cfg,
|
|
||||||
discordConfig: cfg.channels?.discord ?? {},
|
|
||||||
accountId: "default",
|
|
||||||
sessionPrefix: "discord:slash",
|
|
||||||
ephemeralDefault: true,
|
|
||||||
threadBindings: createNoopThreadBindingManager("default"),
|
|
||||||
});
|
|
||||||
const interaction = createInteraction({
|
const interaction = createInteraction({
|
||||||
channelType: ChannelType.GuildText,
|
channelType: ChannelType.GuildText,
|
||||||
channelId,
|
channelId,
|
||||||
@@ -190,53 +246,14 @@ describe("Discord native plugin command dispatch", () => {
|
|||||||
guildName: "Ops",
|
guildName: "Ops",
|
||||||
});
|
});
|
||||||
|
|
||||||
persistentBindingMocks.resolveConfiguredAcpBindingRecord.mockReturnValue({
|
setConfiguredBinding(channelId, boundSessionKey);
|
||||||
spec: {
|
|
||||||
channel: "discord",
|
|
||||||
accountId: "default",
|
|
||||||
conversationId: channelId,
|
|
||||||
agentId: "codex",
|
|
||||||
mode: "persistent",
|
|
||||||
},
|
|
||||||
record: {
|
|
||||||
bindingId: "config:acp:discord:default:1478836151241412759",
|
|
||||||
targetSessionKey: boundSessionKey,
|
|
||||||
targetKind: "session",
|
|
||||||
conversation: {
|
|
||||||
channel: "discord",
|
|
||||||
accountId: "default",
|
|
||||||
conversationId: channelId,
|
|
||||||
},
|
|
||||||
status: "active",
|
|
||||||
boundAt: 0,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
persistentBindingMocks.ensureConfiguredAcpBindingSession.mockResolvedValue({
|
|
||||||
ok: true,
|
|
||||||
sessionKey: boundSessionKey,
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.spyOn(pluginCommandsModule, "matchPluginCommand").mockReturnValue(null);
|
vi.spyOn(pluginCommandsModule, "matchPluginCommand").mockReturnValue(null);
|
||||||
const dispatchSpy = vi
|
const dispatchSpy = createDispatchSpy();
|
||||||
.spyOn(dispatcherModule, "dispatchReplyWithDispatcher")
|
|
||||||
.mockResolvedValue({
|
|
||||||
counts: {
|
|
||||||
final: 1,
|
|
||||||
block: 0,
|
|
||||||
tool: 0,
|
|
||||||
},
|
|
||||||
} as never);
|
|
||||||
|
|
||||||
await (command as { run: (interaction: unknown) => Promise<void> }).run(interaction as unknown);
|
await (command as { run: (interaction: unknown) => Promise<void> }).run(interaction as unknown);
|
||||||
|
|
||||||
expect(dispatchSpy).toHaveBeenCalledTimes(1);
|
expectBoundSessionDispatch(dispatchSpy, boundSessionKey);
|
||||||
const dispatchCall = dispatchSpy.mock.calls[0]?.[0] as {
|
|
||||||
ctx?: { SessionKey?: string; CommandTargetSessionKey?: string };
|
|
||||||
};
|
|
||||||
expect(dispatchCall.ctx?.SessionKey).toBe(boundSessionKey);
|
|
||||||
expect(dispatchCall.ctx?.CommandTargetSessionKey).toBe(boundSessionKey);
|
|
||||||
expect(persistentBindingMocks.resolveConfiguredAcpBindingRecord).toHaveBeenCalledTimes(1);
|
|
||||||
expect(persistentBindingMocks.ensureConfiguredAcpBindingSession).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("routes Discord DM native slash commands through configured ACP bindings", async () => {
|
it("routes Discord DM native slash commands through configured ACP bindings", async () => {
|
||||||
@@ -266,71 +283,19 @@ describe("Discord native plugin command dispatch", () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as OpenClawConfig;
|
} as OpenClawConfig;
|
||||||
const commandSpec: NativeCommandSpec = {
|
const command = createStatusCommand(cfg);
|
||||||
name: "status",
|
|
||||||
description: "Status",
|
|
||||||
acceptsArgs: false,
|
|
||||||
};
|
|
||||||
const command = createDiscordNativeCommand({
|
|
||||||
command: commandSpec,
|
|
||||||
cfg,
|
|
||||||
discordConfig: cfg.channels?.discord ?? {},
|
|
||||||
accountId: "default",
|
|
||||||
sessionPrefix: "discord:slash",
|
|
||||||
ephemeralDefault: true,
|
|
||||||
threadBindings: createNoopThreadBindingManager("default"),
|
|
||||||
});
|
|
||||||
const interaction = createInteraction({
|
const interaction = createInteraction({
|
||||||
channelType: ChannelType.DM,
|
channelType: ChannelType.DM,
|
||||||
channelId,
|
channelId,
|
||||||
});
|
});
|
||||||
|
|
||||||
persistentBindingMocks.resolveConfiguredAcpBindingRecord.mockReturnValue({
|
setConfiguredBinding(channelId, boundSessionKey);
|
||||||
spec: {
|
|
||||||
channel: "discord",
|
|
||||||
accountId: "default",
|
|
||||||
conversationId: channelId,
|
|
||||||
agentId: "codex",
|
|
||||||
mode: "persistent",
|
|
||||||
},
|
|
||||||
record: {
|
|
||||||
bindingId: "config:acp:discord:default:dm-1",
|
|
||||||
targetSessionKey: boundSessionKey,
|
|
||||||
targetKind: "session",
|
|
||||||
conversation: {
|
|
||||||
channel: "discord",
|
|
||||||
accountId: "default",
|
|
||||||
conversationId: channelId,
|
|
||||||
},
|
|
||||||
status: "active",
|
|
||||||
boundAt: 0,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
persistentBindingMocks.ensureConfiguredAcpBindingSession.mockResolvedValue({
|
|
||||||
ok: true,
|
|
||||||
sessionKey: boundSessionKey,
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.spyOn(pluginCommandsModule, "matchPluginCommand").mockReturnValue(null);
|
vi.spyOn(pluginCommandsModule, "matchPluginCommand").mockReturnValue(null);
|
||||||
const dispatchSpy = vi
|
const dispatchSpy = createDispatchSpy();
|
||||||
.spyOn(dispatcherModule, "dispatchReplyWithDispatcher")
|
|
||||||
.mockResolvedValue({
|
|
||||||
counts: {
|
|
||||||
final: 1,
|
|
||||||
block: 0,
|
|
||||||
tool: 0,
|
|
||||||
},
|
|
||||||
} as never);
|
|
||||||
|
|
||||||
await (command as { run: (interaction: unknown) => Promise<void> }).run(interaction as unknown);
|
await (command as { run: (interaction: unknown) => Promise<void> }).run(interaction as unknown);
|
||||||
|
|
||||||
expect(dispatchSpy).toHaveBeenCalledTimes(1);
|
expectBoundSessionDispatch(dispatchSpy, boundSessionKey);
|
||||||
const dispatchCall = dispatchSpy.mock.calls[0]?.[0] as {
|
|
||||||
ctx?: { SessionKey?: string; CommandTargetSessionKey?: string };
|
|
||||||
};
|
|
||||||
expect(dispatchCall.ctx?.SessionKey).toBe(boundSessionKey);
|
|
||||||
expect(dispatchCall.ctx?.CommandTargetSessionKey).toBe(boundSessionKey);
|
|
||||||
expect(persistentBindingMocks.resolveConfiguredAcpBindingRecord).toHaveBeenCalledTimes(1);
|
|
||||||
expect(persistentBindingMocks.ensureConfiguredAcpBindingSession).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user