import { describe, expect, it } from "vitest"; import { renderHelp } from "../../../src/modules/util/help-command.js"; const noop = async () => {}; /** * Build a synthetic registry directly — no loader involved. Lets us test * the pure renderer with exact inputs. */ function makeRegistry(modules) { const publicCommands = new Map(); const protectedCommands = new Map(); const privateCommands = new Map(); const allCommands = new Map(); for (const mod of modules) { for (const cmd of mod.commands) { const entry = { module: mod, cmd, visibility: cmd.visibility }; allCommands.set(cmd.name, entry); if (cmd.visibility === "public") publicCommands.set(cmd.name, entry); else if (cmd.visibility === "protected") protectedCommands.set(cmd.name, entry); else privateCommands.set(cmd.name, entry); } } return { publicCommands, protectedCommands, privateCommands, allCommands, modules, }; } const cmd = (name, visibility, description) => ({ name, visibility, description, handler: noop, }); describe("renderHelp", () => { it("groups commands by module in env.MODULES order", () => { const reg = makeRegistry([ { name: "a", commands: [cmd("one", "public", "A-one")] }, { name: "b", commands: [cmd("two", "public", "B-two")] }, ]); const out = renderHelp(reg); const aIdx = out.indexOf("a"); const bIdx = out.indexOf("b"); expect(aIdx).toBeGreaterThanOrEqual(0); expect(bIdx).toBeGreaterThanOrEqual(0); expect(aIdx).toBeLessThan(bIdx); }); it("appends (protected) suffix to protected commands", () => { const reg = makeRegistry([{ name: "a", commands: [cmd("admin", "protected", "Admin tool")] }]); const out = renderHelp(reg); expect(out).toContain("/admin — Admin tool (protected)"); }); it("hides modules whose only commands are private", () => { const reg = makeRegistry([ { name: "a", commands: [cmd("visible", "public", "V")] }, { name: "b", commands: [cmd("hidden", "private", "H")] }, ]); const out = renderHelp(reg); expect(out).toContain("a"); expect(out).not.toContain("b"); expect(out).not.toContain("hidden"); }); it("NEVER leaks private command names into output", () => { const reg = makeRegistry([ { name: "a", commands: [cmd("show", "public", "Public"), cmd("secret", "private", "Secret")], }, ]); const out = renderHelp(reg); expect(out).toContain("/show"); expect(out).not.toContain("/secret"); expect(out).not.toContain("Secret"); }); it("HTML-escapes module name and description", () => { const reg = makeRegistry([ { name: "a&b", commands: [cmd("foo", "public", "runs