diff --git a/src/utils/commandComparing.js b/src/utils/commandComparing.js index 5e0bfd1..9565871 100644 --- a/src/utils/commandComparing.js +++ b/src/utils/commandComparing.js @@ -1,3 +1,13 @@ +function normalizeDefaultMemberPermissions(value) { + if (value == null) return null; + + if (typeof value === "object" && "bitfield" in value) { + return value.bitfield.toString(); + } + + return String(value); +} + module.exports = (existing, local) => { const changed = (a, b) => JSON.stringify(a) !== JSON.stringify(b); @@ -5,12 +15,14 @@ module.exports = (existing, local) => { return true; }; - if ( - changed( - existing.default_member_permissions ?? null, - local.data.default_member_permissions ?? null - ) - ) { + const existingPermissions = normalizeDefaultMemberPermissions( + existing.defaultMemberPermissions ?? existing.default_member_permissions + ); + const localPermissions = normalizeDefaultMemberPermissions( + local.data.default_member_permissions ?? local.data.defaultMemberPermissions + ); + + if (changed(existingPermissions, localPermissions)) { return true; } diff --git a/tests/command-comparing.test.js b/tests/command-comparing.test.js new file mode 100644 index 0000000..2a2892c --- /dev/null +++ b/tests/command-comparing.test.js @@ -0,0 +1,63 @@ +const { test } = require("node:test"); +const assert = require("node:assert"); +const commandComparing = require("../src/utils/commandComparing"); +const { + PermissionFlagsBits, + PermissionsBitField, + SlashCommandBuilder, +} = require("discord.js"); + +function makeLocalCommand(permission) { + return { + data: new SlashCommandBuilder() + .setName("ban") + .setDescription("Ban a user") + .setDefaultMemberPermissions(permission) + .toJSON(), + }; +} + +test("commandComparing treats matching discord.js permissions as unchanged", () => { + const local = makeLocalCommand(PermissionFlagsBits.BanMembers); + const existing = { + name: "ban", + description: "Ban a user", + options: [], + defaultMemberPermissions: new PermissionsBitField( + PermissionFlagsBits.BanMembers + ).freeze(), + }; + + assert.strictEqual(commandComparing(existing, local), false); +}); + +test("commandComparing detects default_member_permissions changes", () => { + const local = makeLocalCommand(PermissionFlagsBits.BanMembers); + const existing = { + name: "ban", + description: "Ban a user", + options: [], + defaultMemberPermissions: new PermissionsBitField( + PermissionFlagsBits.KickMembers + ).freeze(), + }; + + assert.strictEqual(commandComparing(existing, local), true); +}); + +test("commandComparing treats null and missing permissions as equivalent", () => { + const local = { + data: new SlashCommandBuilder() + .setName("ping") + .setDescription("Ping") + .toJSON(), + }; + const existing = { + name: "ping", + description: "Ping", + options: [], + defaultMemberPermissions: null, + }; + + assert.strictEqual(commandComparing(existing, local), false); +});