Discord: log rejected native command deploy failures (#54118)

Merged via squash.

Prepared head SHA: be250f9620
Co-authored-by: huntharo <5617868+huntharo@users.noreply.github.com>
Co-authored-by: huntharo <5617868+huntharo@users.noreply.github.com>
Reviewed-by: @huntharo
This commit is contained in:
Harold Hunt
2026-03-25 09:19:46 -04:00
committed by GitHub
parent 436aa838fe
commit 3c3fd8c386
5 changed files with 267 additions and 10 deletions

View File

@@ -1,6 +1,31 @@
import { ChannelType } from "discord-api-types/v10";
import { beforeAll, describe, expect, it, vi } from "vitest";
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig, loadConfig } from "../../../../src/config/config.js";
const { logVerboseMock } = vi.hoisted(() => ({
logVerboseMock: vi.fn(),
}));
const { loggerWarnMock } = vi.hoisted(() => ({
loggerWarnMock: vi.fn(),
}));
vi.mock("openclaw/plugin-sdk/runtime-env", async () => {
const actual = await vi.importActual<typeof import("openclaw/plugin-sdk/runtime-env")>(
"openclaw/plugin-sdk/runtime-env",
);
return {
...actual,
createSubsystemLogger: () => ({
child: vi.fn(),
info: vi.fn(),
error: vi.fn(),
warn: loggerWarnMock,
debug: vi.fn(),
}),
logVerbose: logVerboseMock,
};
});
let listNativeCommandSpecs: typeof import("../../../../src/auto-reply/commands-registry.js").listNativeCommandSpecs;
let createDiscordNativeCommand: typeof import("./native-command.js").createDiscordNativeCommand;
let createNoopThreadBindingManager: typeof import("./thread-bindings.js").createNoopThreadBindingManager;
@@ -77,6 +102,11 @@ describe("createDiscordNativeCommand option wiring", () => {
({ createNoopThreadBindingManager } = await import("./thread-bindings.js"));
});
beforeEach(() => {
logVerboseMock.mockReset();
loggerWarnMock.mockReset();
});
it("uses autocomplete for /acp action so inline action values are accepted", async () => {
const command = createNativeCommand("acp");
const action = requireOption(command, "action");
@@ -168,4 +198,42 @@ describe("createDiscordNativeCommand option wiring", () => {
expect(respond).toHaveBeenCalledWith([]);
});
it("truncates Discord command and option descriptions to Discord's limit", () => {
const longDescription = "x".repeat(140);
const cfg = {} as ReturnType<typeof loadConfig>;
const discordConfig = {} as NonNullable<OpenClawConfig["channels"]>["discord"];
const command = createDiscordNativeCommand({
command: {
name: "longdesc",
description: longDescription,
acceptsArgs: true,
args: [
{
name: "input",
description: longDescription,
type: "string",
required: false,
},
],
},
cfg,
discordConfig,
accountId: "default",
sessionPrefix: "discord:slash",
ephemeralDefault: true,
threadBindings: createNoopThreadBindingManager("default"),
});
expect(command.description).toHaveLength(100);
expect(command.description).toBe("x".repeat(100));
expect(requireOption(command, "input").description).toHaveLength(100);
expect(requireOption(command, "input").description).toBe("x".repeat(100));
expect(loggerWarnMock).toHaveBeenCalledWith(
expect.stringContaining("truncating native command description (command:longdesc)"),
);
expect(loggerWarnMock).toHaveBeenCalledWith(
expect.stringContaining("truncating native command description (command:longdesc arg:input)"),
);
});
});