99 lines
2.9 KiB
TypeScript
99 lines
2.9 KiB
TypeScript
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();
|
|
});
|
|
});
|