mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 18:58:26 +00:00
Discord: add component v2 UI tool support (#17419)
This commit is contained in:
98
src/discord/components.test.ts
Normal file
98
src/discord/components.test.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import { MessageFlags } from "discord-api-types/v10";
|
||||
import { describe, expect, it, beforeEach } from "vitest";
|
||||
import {
|
||||
clearDiscordComponentEntries,
|
||||
registerDiscordComponentEntries,
|
||||
resolveDiscordComponentEntry,
|
||||
resolveDiscordModalEntry,
|
||||
} from "./components-registry.js";
|
||||
import {
|
||||
buildDiscordComponentMessage,
|
||||
buildDiscordComponentMessageFlags,
|
||||
readDiscordComponentSpec,
|
||||
} from "./components.js";
|
||||
|
||||
describe("discord components", () => {
|
||||
it("builds v2 containers with modal trigger", () => {
|
||||
const spec = readDiscordComponentSpec({
|
||||
text: "Choose a path",
|
||||
blocks: [
|
||||
{
|
||||
type: "actions",
|
||||
buttons: [{ label: "Approve", style: "success" }],
|
||||
},
|
||||
],
|
||||
modal: {
|
||||
title: "Details",
|
||||
fields: [{ type: "text", label: "Requester" }],
|
||||
},
|
||||
});
|
||||
if (!spec) {
|
||||
throw new Error("Expected component spec to be parsed");
|
||||
}
|
||||
|
||||
const result = buildDiscordComponentMessage({ spec });
|
||||
expect(result.components).toHaveLength(1);
|
||||
expect(result.components[0]?.isV2).toBe(true);
|
||||
expect(buildDiscordComponentMessageFlags(result.components)).toBe(MessageFlags.IsComponentsV2);
|
||||
expect(result.modals).toHaveLength(1);
|
||||
|
||||
const trigger = result.entries.find((entry) => entry.kind === "modal-trigger");
|
||||
expect(trigger?.modalId).toBe(result.modals[0]?.id);
|
||||
});
|
||||
|
||||
it("requires options for modal select fields", () => {
|
||||
expect(() =>
|
||||
readDiscordComponentSpec({
|
||||
modal: {
|
||||
title: "Details",
|
||||
fields: [{ type: "select", label: "Priority" }],
|
||||
},
|
||||
}),
|
||||
).toThrow("options");
|
||||
});
|
||||
|
||||
it("requires attachment references for file blocks", () => {
|
||||
expect(() =>
|
||||
readDiscordComponentSpec({
|
||||
blocks: [{ type: "file", file: "https://example.com/report.pdf" }],
|
||||
}),
|
||||
).toThrow("attachment://");
|
||||
expect(() =>
|
||||
readDiscordComponentSpec({
|
||||
blocks: [{ type: "file", file: "attachment://" }],
|
||||
}),
|
||||
).toThrow("filename");
|
||||
});
|
||||
});
|
||||
|
||||
describe("discord component registry", () => {
|
||||
beforeEach(() => {
|
||||
clearDiscordComponentEntries();
|
||||
});
|
||||
|
||||
it("registers and consumes component entries", () => {
|
||||
registerDiscordComponentEntries({
|
||||
entries: [{ id: "btn_1", kind: "button", label: "Confirm" }],
|
||||
modals: [
|
||||
{
|
||||
id: "mdl_1",
|
||||
title: "Details",
|
||||
fields: [{ id: "fld_1", name: "name", label: "Name", type: "text" }],
|
||||
},
|
||||
],
|
||||
messageId: "msg_1",
|
||||
ttlMs: 1000,
|
||||
});
|
||||
|
||||
const entry = resolveDiscordComponentEntry({ id: "btn_1", consume: false });
|
||||
expect(entry?.messageId).toBe("msg_1");
|
||||
|
||||
const modal = resolveDiscordModalEntry({ id: "mdl_1", consume: false });
|
||||
expect(modal?.messageId).toBe("msg_1");
|
||||
|
||||
const consumed = resolveDiscordComponentEntry({ id: "btn_1" });
|
||||
expect(consumed?.id).toBe("btn_1");
|
||||
expect(resolveDiscordComponentEntry({ id: "btn_1" })).toBeNull();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user