const assert = require("assert"); const fs = require("fs"); const path = require("path"); const root = path.join(__dirname, ".."); const sandbox = fs.mkdtempSync(path.join(root, ".tmp-lumi-command-policies-")); const serviceDir = path.join(sandbox, "src", "services"); (async () => { try { fs.cpSync(path.join(root, "src", "services"), serviceDir, { recursive: true }); const database = require(path.join(serviceDir, "db.js")); database.migrate(); const conditional = require(path.join(serviceDir, "command-conditional.js")); const policies = require(path.join(serviceDir, "command-policies.js")); const replies = conditional.normalizeConditionalReplies([ { keyword: "backseating", response: "Please avoid backseating." }, { keyword: "spoilers", response: "No spoilers." } ]); assert.strictEqual(conditional.findConditionalReply(replies, "backseating").match.response, "Please avoid backseating."); const fuzzy = conditional.findConditionalReply(replies, "backseatng"); assert.strictEqual(fuzzy.match.keyword, "backseating"); assert.strictEqual(fuzzy.fuzzy, true); assert.strictEqual(conditional.findConditionalReply(replies, "something unrelated").match, null); const groupId = policies.createGroup({ name: "Verification group", policy: { window: { uses: 3, seconds: 30, scope: "global" }, requirement: { role: "subscriber", subscriberTier: 2 }, cost: { amount: 5 } } }); const key = policies.commandKey("verification", "hello"); policies.saveCommandPolicy(key, { window: { uses: 1, seconds: 60, scope: "user" }, requirement: false, cost: { amount: 2 } }, [groupId]); const resolved = policies.resolvePolicy(key); assert.strictEqual(resolved.windows.length, 1, "a direct rate limit must replace group limits"); assert.strictEqual(resolved.windows[0].value.uses, 1); assert.strictEqual(resolved.requirements.length, 0, "a direct public setting must replace group roles"); assert.strictEqual(resolved.cost, 2, "a direct cost must replace the group cost"); const charges = []; global.lumiFrameworks = { economy: { removeBalance(payload) { charges.push(["charge", payload]); return { ok: true }; }, addBalance(payload) { charges.push(["refund", payload]); return "refund-id"; } } }; const ctx = { platform: "discord", trigger: "hello", raw: "!hello", user: { id: "verification-user", platformId: "platform-user" }, platformUser: { id: "platform-user" }, meta: {} }; const first = await policies.beginCommandUse({ commandKey: key, ctx }); assert.strictEqual(first.allowed, true); assert.strictEqual(charges[0][0], "charge"); const limited = await policies.beginCommandUse({ commandKey: key, ctx }); assert.strictEqual(limited.allowed, false, "the second use inside the window must be denied"); await first.rollback("verification"); assert.strictEqual(charges[1][0], "refund", "failed commands must refund their logged currency cost"); const afterRollback = await policies.beginCommandUse({ commandKey: key, ctx }); assert.strictEqual(afterRollback.allowed, true, "rollback must release the rate-limit reservation"); await afterRollback.commit(); const dbColumns = database.db.prepare("PRAGMA table_info(custom_commands)").all().map((column) => column.name); assert(dbColumns.includes("conditional_replies_json")); assert(dbColumns.includes("conditional_fuzzy")); for (const table of ["command_groups", "command_group_members", "command_policies", "command_policy_uses", "command_stream_sessions"]) { assert(database.db.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?").get(table), `missing ${table}`); } const server = fs.readFileSync(path.join(root, "src", "web", "server.js"), "utf8"); const view = fs.readFileSync(path.join(root, "src", "web", "views", "admin-command-policies.ejs"), "utf8"); const commandView = fs.readFileSync(path.join(root, "src", "web", "views", "admin-commands.ejs"), "utf8"); assert(server.includes('/admin/command-policies') && server.includes('commandPolicyFromBody')); assert(view.includes("Command groups") && view.includes("Save command settings")); assert(commandView.includes('value="conditional"') && commandView.includes("data-conditional-replies")); database.db.close(); console.log("Command policies and conditional commands verified."); } finally { fs.rmSync(sandbox, { recursive: true, force: true }); } })().catch((error) => { console.error(error); process.exitCode = 1; });