mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-18 00:23:25 -06:00
af3d796e19
* refactor(discord): trim internal exports * refactor(discord): use canonical approval helper * chore(deadcode): refresh export baseline
108 lines
3.5 KiB
TypeScript
108 lines
3.5 KiB
TypeScript
// Discord tests cover native command.command arg plugin behavior.
|
|
import type { ChatCommandDefinition } from "openclaw/plugin-sdk/command-auth-native";
|
|
import * as commandRegistryModule from "openclaw/plugin-sdk/command-auth-native";
|
|
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
|
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
import type { DispatchDiscordCommandInteraction } from "./native-command-dispatch.js";
|
|
import { createDiscordCommandArgFallbackButton } from "./native-command-ui.js";
|
|
import { createNoopThreadBindingManager } from "./thread-bindings.js";
|
|
|
|
type CommandArgContext = Parameters<typeof createDiscordCommandArgFallbackButton>[0]["ctx"];
|
|
type CommandArgButton = ReturnType<typeof createDiscordCommandArgFallbackButton>;
|
|
type CommandArgInteraction = Parameters<CommandArgButton["run"]>[0];
|
|
type CommandArgData = Parameters<CommandArgButton["run"]>[1];
|
|
|
|
function createCommandDefinition(): ChatCommandDefinition {
|
|
return {
|
|
key: "think",
|
|
nativeName: "think",
|
|
description: "Set thinking level",
|
|
textAliases: ["/think"],
|
|
acceptsArgs: true,
|
|
args: [
|
|
{
|
|
name: "level",
|
|
description: "Thinking level",
|
|
type: "string",
|
|
required: true,
|
|
},
|
|
],
|
|
argsParsing: "none",
|
|
scope: "native",
|
|
};
|
|
}
|
|
|
|
function createContext(
|
|
discordConfig: NonNullable<OpenClawConfig["channels"]>["discord"],
|
|
): CommandArgContext {
|
|
const cfg = {
|
|
channels: {
|
|
discord: discordConfig,
|
|
},
|
|
} as OpenClawConfig;
|
|
return {
|
|
cfg,
|
|
discordConfig,
|
|
accountId: "default",
|
|
sessionPrefix: "discord:slash",
|
|
threadBindings: createNoopThreadBindingManager("default"),
|
|
};
|
|
}
|
|
|
|
function createInteraction(): CommandArgInteraction {
|
|
return {
|
|
user: {
|
|
id: "owner",
|
|
username: "tester",
|
|
globalName: "Tester",
|
|
},
|
|
update: vi.fn().mockResolvedValue({ ok: true }),
|
|
} as unknown as CommandArgInteraction;
|
|
}
|
|
|
|
async function safeInteractionCall<T>(_label: string, fn: () => Promise<T>): Promise<T | null> {
|
|
return await fn();
|
|
}
|
|
|
|
function firstDispatchCall(dispatchSpy: { mock: { calls: unknown[][] } }) {
|
|
const firstCall = dispatchSpy.mock.calls.at(0);
|
|
if (!firstCall) {
|
|
throw new Error("expected Discord command interaction dispatch");
|
|
}
|
|
return firstCall[0] as Parameters<DispatchDiscordCommandInteraction>[0];
|
|
}
|
|
|
|
describe("discord command argument fallback", () => {
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
it("preserves public slash command visibility for selected argument follow-ups", async () => {
|
|
const commandDefinition = createCommandDefinition();
|
|
vi.spyOn(commandRegistryModule, "findCommandByNativeName").mockReturnValue(commandDefinition);
|
|
const dispatchSpy = vi
|
|
.fn<DispatchDiscordCommandInteraction>()
|
|
.mockResolvedValue({ accepted: true });
|
|
const button = createDiscordCommandArgFallbackButton({
|
|
ctx: createContext({ slashCommand: { ephemeral: false } }),
|
|
safeInteractionCall,
|
|
dispatchCommandInteraction: dispatchSpy,
|
|
});
|
|
|
|
await button.run(createInteraction(), {
|
|
command: "think",
|
|
arg: "level",
|
|
value: "high",
|
|
user: "owner",
|
|
} satisfies CommandArgData);
|
|
|
|
expect(dispatchSpy).toHaveBeenCalledTimes(1);
|
|
const dispatchCall = firstDispatchCall(dispatchSpy);
|
|
expect(dispatchCall?.prompt).toBe("/think high");
|
|
expect(dispatchCall?.responseEphemeral).toBe(false);
|
|
expect(dispatchCall?.accountId).toBe("default");
|
|
expect(dispatchCall?.sessionPrefix).toBe("discord:slash");
|
|
expect(dispatchCall?.preferFollowUp).toBe(true);
|
|
});
|
|
});
|