From 259cdd8c12071543e07b9a67c0a39b6f7c47a4b8 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Fri, 5 Feb 2021 16:59:15 +0000 Subject: [PATCH] Improve force handling This improves the force argument parsing to keep it from getting glued onto the reason. It also adjusts tests for the new behaviour. --- src/commands/UnbanBanCommand.ts | 17 +++++++---- test/commands/UnbanBanCommandTest.ts | 45 +++++++++++++++++++++++----- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/commands/UnbanBanCommand.ts b/src/commands/UnbanBanCommand.ts index 66afcfa..d28145d 100644 --- a/src/commands/UnbanBanCommand.ts +++ b/src/commands/UnbanBanCommand.ts @@ -46,7 +46,8 @@ export async function parseArguments(roomId: string, event: any, mjolnir: Mjolni let ruleType = null; let entity = null; let list = null; - while (argumentIndex < 6 && argumentIndex < parts.length) { + let force = false; + while (argumentIndex < 7 && argumentIndex < parts.length) { const arg = parts[argumentIndex++]; if (!arg) break; if (["user", "room", "server"].includes(arg.toLowerCase())) { @@ -69,6 +70,12 @@ export async function parseArguments(roomId: string, event: any, mjolnir: Mjolni if (entity) break; } + if (parts[parts.length - 1] === "--force") { + force = true; + // Remove from parts to ease reason handling + parts.pop(); + } + if (!entity) { // It'll be a server at this point - figure out which positional argument is the server // name and where the reason starts. @@ -89,10 +96,8 @@ export async function parseArguments(roomId: string, event: any, mjolnir: Mjolni else if (!ruleType) replyMessage = "Please specify the type as either 'user', 'room', or 'server'"; else if (!entity) replyMessage = "No entity found"; - if (config.commands.confirmWildcardBan && /[*?]/.test(entity)) { - if (!parts.includes("--force")) { - replyMessage = "Wildcard bans require an additional `--force` argument to confirm"; - } + if (config.commands.confirmWildcardBan && /[*?]/.test(entity) && !force) { + replyMessage = "Wildcard bans require an additional `--force` argument to confirm"; } if (replyMessage) { @@ -110,7 +115,7 @@ export async function parseArguments(roomId: string, event: any, mjolnir: Mjolni }; } -// !mjolnir ban [reason] +// !mjolnir ban [reason] [--force] export async function execBanCommand(roomId: string, event: any, mjolnir: Mjolnir, parts: string[]) { const bits = await parseArguments(roomId, event, mjolnir, parts); if (!bits) return; // error already handled diff --git a/test/commands/UnbanBanCommandTest.ts b/test/commands/UnbanBanCommandTest.ts index 073ebe1..ce94097 100644 --- a/test/commands/UnbanBanCommandTest.ts +++ b/test/commands/UnbanBanCommandTest.ts @@ -86,7 +86,7 @@ describe("UnbanBanCommand", () => { throw new Error("sendMessage should not have been called: " + JSON.stringify(content)); }; - const command = "!mjolnir ban test *.example.org"; + const command = "!mjolnir ban test *.example.org --force"; const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' ')); expect(bits).toBeTruthy(); expect(bits.reason).toBeFalsy(); @@ -103,7 +103,7 @@ describe("UnbanBanCommand", () => { throw new Error("sendMessage should not have been called: " + JSON.stringify(content)); }; - const command = "!mjolnir ban test server @*.example.org"; + const command = "!mjolnir ban test server @*.example.org --force"; const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' ')); expect(bits).toBeTruthy(); expect(bits.reason).toBeFalsy(); @@ -154,7 +154,7 @@ describe("UnbanBanCommand", () => { throw new Error("sendMessage should not have been called: " + JSON.stringify(content)); }; - const command = "!mjolnir ban test !*.example.org"; + const command = "!mjolnir ban test !*.example.org --force"; const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' ')); expect(bits).toBeTruthy(); expect(bits.reason).toBeFalsy(); @@ -205,7 +205,7 @@ describe("UnbanBanCommand", () => { throw new Error("sendMessage should not have been called: " + JSON.stringify(content)); }; - const command = "!mjolnir ban test #*.example.org"; + const command = "!mjolnir ban test #*.example.org --force"; const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' ')); expect(bits).toBeTruthy(); expect(bits.reason).toBeFalsy(); @@ -222,7 +222,7 @@ describe("UnbanBanCommand", () => { throw new Error("sendMessage should not have been called: " + JSON.stringify(content)); }; - const command = "!mjolnir ban test room @*.example.org"; + const command = "!mjolnir ban test room @*.example.org --force"; const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' ')); expect(bits).toBeTruthy(); expect(bits.reason).toBeFalsy(); @@ -273,7 +273,7 @@ describe("UnbanBanCommand", () => { throw new Error("sendMessage should not have been called: " + JSON.stringify(content)); }; - const command = "!mjolnir ban test @*.example.org"; + const command = "!mjolnir ban test @*.example.org --force"; const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' ')); expect(bits).toBeTruthy(); expect(bits.reason).toBeFalsy(); @@ -290,7 +290,7 @@ describe("UnbanBanCommand", () => { throw new Error("sendMessage should not have been called: " + JSON.stringify(content)); }; - const command = "!mjolnir ban test user #*.example.org"; + const command = "!mjolnir ban test user #*.example.org --force"; const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' ')); expect(bits).toBeTruthy(); expect(bits.reason).toBeFalsy(); @@ -300,6 +300,37 @@ describe("UnbanBanCommand", () => { expect(bits.list.listShortcode).toBe("test"); }); + it("should error if wildcards used without --force", async () => { + const mjolnir = createTestMjolnir(); + (mjolnir).lists = [{listShortcode: "test"}]; + mjolnir.client.sendMessage = (roomId: string, content: any): Promise => { + expect(content).toBeDefined(); + expect(content['body']).toContain("Wildcard bans require an additional `--force` argument to confirm"); + return Promise.resolve("$fake"); + }; + + const command = "!mjolnir ban test *.example.org"; + const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' ')); + expect(bits).toBeFalsy(); + }); + + it("should have correct ban reason with --force after", async () => { + const mjolnir = createTestMjolnir(); + (mjolnir).lists = [{listShortcode: "test"}]; + mjolnir.client.sendMessage = (roomId: string, content: any): Promise => { + throw new Error("sendMessage should not have been called: " + JSON.stringify(content)); + }; + + const command = "!mjolnir ban test user #*.example.org reason here --force"; + const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' ')); + expect(bits).toBeTruthy(); + expect(bits.reason).toBe("reason here"); + expect(bits.ruleType).toBe(RULE_USER); + expect(bits.entity).toBe("#*.example.org"); + expect(bits.list).toBeDefined(); + expect(bits.list.listShortcode).toBe("test"); + }); + describe("[without default list]", () => { it("should error if no list (with type) is specified", async () => { const mjolnir = createTestMjolnir();