"use strict"; const assert = require("assert"); const Database = require("better-sqlite3"); const plugin = require("../index"); async function run() { const { CLAIM_EMOJI, DEFAULT_ROOM_MESSAGE, LOCK_EMOJI, UNLOCK_EMOJI, claimEligibility, ensureTables, normalizeConfig, parseConfigFromForm, registerPlaceholderSupport, renderRoomMessage, setRoomLocked } = plugin._test; const defaults = normalizeConfig({ lobbies: [{ id: "lobby-1" }] }); assert.equal(defaults.lobbies[0].roomMessage, DEFAULT_ROOM_MESSAGE); assert.equal(defaults.lobbies[0].emptyTimeoutSeconds, 30); const parsed = parseConfigFromForm({ lobby_id: ["one", "two"], lobby_channel_id: ["voice-1", "voice-2"], lobby_category_id: ["category-1", "category-2"], lobby_name_template: ["[username] one", "[username] two"], lobby_room_message: ["Hello one", "Hello two"], lobby_empty_timeout: ["45", "60"] }); assert.deepStrictEqual(parsed.lobbies.map((lobby) => lobby.roomMessage), ["Hello one", "Hello two"]); assert.deepStrictEqual(parsed.lobbies.map((lobby) => lobby.emptyTimeoutSeconds), [45, 60]); const database = new Database(":memory:"); database.exec("CREATE TABLE auto_vc_rooms (channel_id TEXT PRIMARY KEY)"); ensureTables(database); const columns = database.prepare("PRAGMA table_info(auto_vc_rooms)").all().map((column) => column.name); assert(columns.includes("control_message_id"), "room controls must survive a restart"); assert(columns.includes("owner_absent_since"), "owner absence must survive a restart"); database.close(); let policy; let definitions; const placeholders = { registerFieldPolicy(value) { policy = value; }, registerPlaceholders(value) { definitions = value; }, async renderTemplate({ template, runtimeContext }) { return { ok: true, rendered: template.replace("{{plugins.auto_vc.channel.owner_username}}", runtimeContext.autoVc.owner_username) }; } }; registerPlaceholderSupport(placeholders); assert.equal(policy.field_id, "plugins.auto_vc.room_message"); assert(policy.allowed_namespaces.includes("plugins.auto_vc.channel")); assert.equal(definitions[0].id, "plugins.auto_vc.channel.owner_username"); const rendered = await renderRoomMessage( { roomMessage: "Welcome {{plugins.auto_vc.channel.owner_username}}" }, { displayName: "Lumi User" }, placeholders ); assert.equal(rendered, "Welcome Lumi User"); const members = new Map([["claimant", { id: "claimant", user: { bot: false } }]]); const channel = { members }; const config = { lobbies: [{ id: "lobby-1", emptyTimeoutSeconds: 30 }] }; const room = { lobby_id: "lobby-1", owner_discord_id: "owner", owner_absent_since: 1_000 }; assert.equal(claimEligibility(channel, room, { id: "claimant" }, config, 30_999).ok, false); assert.equal(claimEligibility(channel, room, { id: "claimant" }, config, 31_000).ok, true); members.set("owner", { id: "owner", user: { bot: false } }); assert.equal(claimEligibility(channel, room, { id: "claimant" }, config, 60_000).ok, false); assert.deepStrictEqual([LOCK_EMOJI, UNLOCK_EMOJI, CLAIM_EMOJI], ["🔒", "🔓", "👑"]); const failedRoom = { channel_id: "room", owner_discord_id: "owner", locked: false, allowed_user_ids: [], base_overwrites: "[]" }; const applied = await setRoomLocked({ id: "room", guild: { roles: { everyone: { id: "everyone" } } }, permissionOverwrites: { async set() { throw new Error("missing permission"); } } }, failedRoom, true, { prepare() { throw new Error("a failed Discord change must not be persisted"); } }, { getSetting() { return ""; } }, { rooms: new Map() }); assert.equal(applied, false); assert.equal(failedRoom.locked, false, "failed permission changes must not report or persist success"); console.log("Auto VC verification passed: welcome placeholders, persisted controls, and timed ownership claims."); } run().catch((error) => { console.error(error); process.exitCode = 1; });