mirror of
https://github.com/matrix-org/mjolnir.git
synced 2024-10-01 01:36:06 -04:00
Make the [un]ban command smarter
Fixes https://github.com/matrix-org/mjolnir/issues/11
This commit is contained in:
parent
dd260091bb
commit
66a5775136
10
package.json
10
package.json
@ -9,11 +9,17 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"lint": "tslint --project ./tsconfig.json --type-check -t stylish",
|
||||
"start:dev": "yarn build && node lib/index.js"
|
||||
"lint": "tslint --project ./tsconfig.json -t stylish",
|
||||
"start:dev": "yarn build && node lib/index.js",
|
||||
"test": "ts-mocha --project ./tsconfig.json test/**/*.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/expect": "^24.3.0",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "11",
|
||||
"expect": "^24.9.0",
|
||||
"mocha": "^6.2.2",
|
||||
"ts-mocha": "^6.0.0",
|
||||
"tslint": "^5.20.0",
|
||||
"typescript": "^3.6.3"
|
||||
},
|
||||
|
@ -37,9 +37,9 @@ export async function handleCommand(roomId: string, event: any, mjolnir: Mjolnir
|
||||
try {
|
||||
if (parts.length === 1 || parts[1] === 'status') {
|
||||
return await execStatusCommand(roomId, event, mjolnir);
|
||||
} else if (parts[1] === 'ban' && parts.length > 4) {
|
||||
} else if (parts[1] === 'ban' && parts.length > 2) {
|
||||
return await execBanCommand(roomId, event, mjolnir, parts);
|
||||
} else if (parts[1] === 'unban' && parts.length > 4) {
|
||||
} else if (parts[1] === 'unban' && parts.length > 2) {
|
||||
return await execUnbanCommand(roomId, event, mjolnir, parts);
|
||||
} else if (parts[1] === 'rules') {
|
||||
return await execDumpRulesCommand(roomId, event, mjolnir);
|
||||
|
@ -15,91 +15,121 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import { Mjolnir } from "../Mjolnir";
|
||||
import { RULE_ROOM, RULE_SERVER, RULE_USER, ruleTypeToStable, USER_RULE_TYPES } from "../models/BanList";
|
||||
import { LogLevel, RichReply } from "matrix-bot-sdk";
|
||||
import BanList, { RULE_ROOM, RULE_SERVER, RULE_USER, USER_RULE_TYPES } from "../models/BanList";
|
||||
import { LogLevel, LogService, RichReply } from "matrix-bot-sdk";
|
||||
import { RECOMMENDATION_BAN, recommendationToStable } from "../models/ListRule";
|
||||
import { MatrixGlob } from "matrix-bot-sdk/lib/MatrixGlob";
|
||||
import config from "../config";
|
||||
import { logMessage } from "../LogProxy";
|
||||
import { DEFAULT_LIST_EVENT_TYPE } from "./SetDefaultBanListCommand";
|
||||
|
||||
function parseBits(parts: string[]): { listShortcode: string, entityType: string, ruleType: string, glob: string, reason: string } {
|
||||
const shortcode = parts[2].toLowerCase();
|
||||
const entityType = parts[3].toLowerCase();
|
||||
const glob = parts[4];
|
||||
const reason = parts.slice(5).join(' ') || "<no reason>";
|
||||
interface Arguments {
|
||||
list: BanList;
|
||||
entity: string;
|
||||
ruleType: string;
|
||||
reason: string;
|
||||
}
|
||||
|
||||
let rule = null;
|
||||
if (entityType === "user") {
|
||||
rule = RULE_USER;
|
||||
} else if (entityType === "room") {
|
||||
rule = RULE_ROOM;
|
||||
} else if (entityType === "server") {
|
||||
rule = RULE_SERVER;
|
||||
// Exported for tests
|
||||
export async function parseArguments(roomId: string, event: any, mjolnir: Mjolnir, parts: string[]): Promise<Arguments> {
|
||||
let defaultShortcode = null;
|
||||
try {
|
||||
const data = await mjolnir.client.getAccountData(DEFAULT_LIST_EVENT_TYPE);
|
||||
defaultShortcode = data['shortcode'];
|
||||
} catch (e) {
|
||||
LogService.warn("UnbanBanCommand", "Non-fatal error getting default ban list");
|
||||
LogService.warn("UnbanBanCommand", e);
|
||||
|
||||
// Assume no default.
|
||||
}
|
||||
if (!rule) {
|
||||
return {listShortcode: shortcode, entityType, ruleType: null, glob, reason};
|
||||
}
|
||||
rule = ruleTypeToStable(rule);
|
||||
|
||||
return {listShortcode: shortcode, entityType, ruleType: rule, glob, reason};
|
||||
let argumentIndex = 2;
|
||||
let ruleType = null;
|
||||
let entity = null;
|
||||
let list = null;
|
||||
while (argumentIndex < 6 && argumentIndex < parts.length) {
|
||||
const arg = parts[argumentIndex++];
|
||||
if (!arg) break;
|
||||
if (["user", "room", "server"].includes(arg.toLowerCase())) {
|
||||
if (arg.toLowerCase() === 'user') ruleType = RULE_USER;
|
||||
if (arg.toLowerCase() === 'room') ruleType = RULE_ROOM;
|
||||
if (arg.toLowerCase() === 'server') ruleType = RULE_SERVER;
|
||||
} else if (!entity && (arg[0] === '@' || arg[0] === '!' || arg[0] === '#' || arg.includes("*"))) {
|
||||
entity = arg;
|
||||
if (arg.startsWith("@") && !ruleType) ruleType = RULE_USER;
|
||||
else if (arg.startsWith("#") && !ruleType) ruleType = RULE_ROOM;
|
||||
else if (arg.startsWith("!") && !ruleType) ruleType = RULE_ROOM;
|
||||
else if (!ruleType) ruleType = RULE_SERVER;
|
||||
} else if (!list) {
|
||||
const foundList = mjolnir.lists.find(b => b.listShortcode.toLowerCase() === arg.toLowerCase());
|
||||
if (foundList) {
|
||||
list = foundList;
|
||||
}
|
||||
}
|
||||
|
||||
if (entity) break;
|
||||
}
|
||||
|
||||
if (!list) {
|
||||
list = mjolnir.lists.find(b => b.listShortcode.toLowerCase() === defaultShortcode);
|
||||
}
|
||||
|
||||
if (!entity) {
|
||||
entity = parts[argumentIndex - 1];
|
||||
if (!ruleType) ruleType = RULE_SERVER; // due to the conditions above, it can't be anything else
|
||||
console.log(parts);
|
||||
}
|
||||
|
||||
let replyMessage = null;
|
||||
if (!list) replyMessage = "No ban list matching that shortcode was found";
|
||||
else if (!ruleType) replyMessage = "Please specify the type as either 'user', 'room', or 'server'";
|
||||
else if (!entity) replyMessage = "No entity found to ban";
|
||||
|
||||
if (replyMessage) {
|
||||
const reply = RichReply.createFor(roomId, event, replyMessage, replyMessage);
|
||||
reply["msgtype"] = "m.notice";
|
||||
await mjolnir.client.sendMessage(roomId, reply);
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
list,
|
||||
entity,
|
||||
ruleType,
|
||||
reason: parts.splice(argumentIndex).join(" ").trim(),
|
||||
};
|
||||
}
|
||||
|
||||
// !mjolnir ban <shortcode> <user|server|room> <glob> [reason]
|
||||
export async function execBanCommand(roomId: string, event: any, mjolnir: Mjolnir, parts: string[]) {
|
||||
const bits = parseBits(parts);
|
||||
if (!bits.ruleType) {
|
||||
const replyText = "Unknown entity type '" + bits.entityType + "' - try one of user, room, or server";
|
||||
const reply = RichReply.createFor(roomId, event, replyText, replyText);
|
||||
reply["msgtype"] = "m.notice";
|
||||
return mjolnir.client.sendMessage(roomId, reply);
|
||||
}
|
||||
const bits = await parseArguments(roomId, event, mjolnir, parts);
|
||||
if (!bits) return; // error already handled
|
||||
|
||||
const recommendation = recommendationToStable(RECOMMENDATION_BAN);
|
||||
const ruleContent = {
|
||||
entity: bits.glob,
|
||||
entity: bits.entity,
|
||||
recommendation,
|
||||
reason: bits.reason,
|
||||
};
|
||||
const stateKey = `rule:${bits.glob}`;
|
||||
const stateKey = `rule:${bits.entity}`;
|
||||
|
||||
const list = mjolnir.lists.find(b => b.listShortcode === bits.listShortcode);
|
||||
if (!list) {
|
||||
const replyText = "No ban list with that shortcode was found.";
|
||||
const reply = RichReply.createFor(roomId, event, replyText, replyText);
|
||||
reply["msgtype"] = "m.notice";
|
||||
return mjolnir.client.sendMessage(roomId, reply);
|
||||
}
|
||||
|
||||
await mjolnir.client.sendStateEvent(list.roomId, bits.ruleType, stateKey, ruleContent);
|
||||
await mjolnir.client.sendStateEvent(bits.list.roomId, bits.ruleType, stateKey, ruleContent);
|
||||
await mjolnir.client.unstableApis.addReactionToEvent(roomId, event['event_id'], '✅');
|
||||
}
|
||||
|
||||
// !mjolnir unban <shortcode> <user|server|room> <glob> [apply:t/f]
|
||||
export async function execUnbanCommand(roomId: string, event: any, mjolnir: Mjolnir, parts: string[]) {
|
||||
const bits = parseBits(parts);
|
||||
if (!bits.ruleType) {
|
||||
const replyText = "Unknown entity type '" + bits.entityType + "' - try one of user, room, or server";
|
||||
const reply = RichReply.createFor(roomId, event, replyText, replyText);
|
||||
reply["msgtype"] = "m.notice";
|
||||
return mjolnir.client.sendMessage(roomId, reply);
|
||||
}
|
||||
const bits = await parseArguments(roomId, event, mjolnir, parts);
|
||||
if (!bits) return; // error already handled
|
||||
|
||||
const ruleContent = {}; // empty == clear/unban
|
||||
const stateKey = `rule:${bits.glob}`;
|
||||
const stateKey = `rule:${bits.entity}`;
|
||||
|
||||
const list = mjolnir.lists.find(b => b.listShortcode === bits.listShortcode);
|
||||
if (!list) {
|
||||
const replyText = "No ban list with that shortcode was found.";
|
||||
const reply = RichReply.createFor(roomId, event, replyText, replyText);
|
||||
reply["msgtype"] = "m.notice";
|
||||
return mjolnir.client.sendMessage(roomId, reply);
|
||||
}
|
||||
|
||||
await mjolnir.client.sendStateEvent(list.roomId, bits.ruleType, stateKey, ruleContent);
|
||||
await mjolnir.client.sendStateEvent(bits.list.roomId, bits.ruleType, stateKey, ruleContent);
|
||||
|
||||
if (USER_RULE_TYPES.includes(bits.ruleType) && parts.length > 5 && parts[5] === 'true') {
|
||||
const rule = new MatrixGlob(bits.glob);
|
||||
await logMessage(LogLevel.INFO, "UnbanBanCommand", "Unbanning users that match glob: " + bits.glob);
|
||||
const rule = new MatrixGlob(bits.entity);
|
||||
await logMessage(LogLevel.INFO, "UnbanBanCommand", "Unbanning users that match glob: " + bits.entity);
|
||||
let unbannedSomeone = false;
|
||||
for (const protectedRoomId of Object.keys(mjolnir.protectedRooms)) {
|
||||
const members = await mjolnir.client.getMembers(protectedRoomId, null, ['ban'], null);
|
||||
|
403
test/commands/UnbanBanCommandTest.ts
Normal file
403
test/commands/UnbanBanCommandTest.ts
Normal file
@ -0,0 +1,403 @@
|
||||
/*
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import * as expect from "expect";
|
||||
import { Mjolnir } from "../../src/Mjolnir";
|
||||
import { DEFAULT_LIST_EVENT_TYPE } from "../../src/commands/SetDefaultBanListCommand";
|
||||
import { parseArguments } from "../../src/commands/UnbanBanCommand";
|
||||
import { RULE_ROOM, RULE_SERVER, RULE_USER } from "../../src/models/BanList";
|
||||
|
||||
function createTestMjolnir(defaultShortcode: string = null): Mjolnir {
|
||||
const client = {
|
||||
getAccountData: (eventType: string): Promise<any> => {
|
||||
if (eventType === DEFAULT_LIST_EVENT_TYPE && defaultShortcode) {
|
||||
return Promise.resolve({shortcode: defaultShortcode});
|
||||
}
|
||||
throw new Error("Unknown event type");
|
||||
},
|
||||
};
|
||||
return <Mjolnir>{client};
|
||||
}
|
||||
|
||||
function createFakeEvent(command: string): any {
|
||||
return {
|
||||
sender: "@alice:example.org",
|
||||
event_id: "$example",
|
||||
content: {
|
||||
body: command,
|
||||
msgtype: "m.text",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe("UnbanBanCommand", () => {
|
||||
describe("parseArguments", () => {
|
||||
it("should be able to detect servers", async () => {
|
||||
const mjolnir = createTestMjolnir();
|
||||
(<any>mjolnir).lists = [{listShortcode: "test"}];
|
||||
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
|
||||
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
|
||||
};
|
||||
|
||||
const command = "!mjolnir ban test example.org";
|
||||
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
|
||||
expect(bits).toBeTruthy();
|
||||
expect(bits.reason).toBeFalsy();
|
||||
expect(bits.ruleType).toBe(RULE_SERVER);
|
||||
expect(bits.entity).toBe("example.org");
|
||||
expect(bits.list).toBeDefined();
|
||||
expect(bits.list.listShortcode).toBe("test");
|
||||
});
|
||||
|
||||
it("should be able to detect servers with globs", async () => {
|
||||
const mjolnir = createTestMjolnir();
|
||||
(<any>mjolnir).lists = [{listShortcode: "test"}];
|
||||
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
|
||||
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
|
||||
};
|
||||
|
||||
const command = "!mjolnir ban test *.example.org";
|
||||
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
|
||||
expect(bits).toBeTruthy();
|
||||
expect(bits.reason).toBeFalsy();
|
||||
expect(bits.ruleType).toBe(RULE_SERVER);
|
||||
expect(bits.entity).toBe("*.example.org");
|
||||
expect(bits.list).toBeDefined();
|
||||
expect(bits.list.listShortcode).toBe("test");
|
||||
});
|
||||
|
||||
it("should be able to detect servers with the type specified", async () => {
|
||||
const mjolnir = createTestMjolnir();
|
||||
(<any>mjolnir).lists = [{listShortcode: "test"}];
|
||||
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
|
||||
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
|
||||
};
|
||||
|
||||
const command = "!mjolnir ban test server @*.example.org";
|
||||
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
|
||||
expect(bits).toBeTruthy();
|
||||
expect(bits.reason).toBeFalsy();
|
||||
expect(bits.ruleType).toBe(RULE_SERVER);
|
||||
expect(bits.entity).toBe("@*.example.org");
|
||||
expect(bits.list).toBeDefined();
|
||||
expect(bits.list.listShortcode).toBe("test");
|
||||
});
|
||||
|
||||
it("should be able to detect room IDs", async () => {
|
||||
const mjolnir = createTestMjolnir();
|
||||
(<any>mjolnir).lists = [{listShortcode: "test"}];
|
||||
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
|
||||
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
|
||||
};
|
||||
|
||||
const command = "!mjolnir ban test !example.org";
|
||||
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
|
||||
expect(bits).toBeTruthy();
|
||||
expect(bits.reason).toBeFalsy();
|
||||
expect(bits.ruleType).toBe(RULE_ROOM);
|
||||
expect(bits.entity).toBe("!example.org");
|
||||
expect(bits.list).toBeDefined();
|
||||
expect(bits.list.listShortcode).toBe("test");
|
||||
});
|
||||
|
||||
it("should be able to detect room IDs with globs", async () => {
|
||||
const mjolnir = createTestMjolnir();
|
||||
(<any>mjolnir).lists = [{listShortcode: "test"}];
|
||||
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
|
||||
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
|
||||
};
|
||||
|
||||
const command = "!mjolnir ban test !*.example.org";
|
||||
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
|
||||
expect(bits).toBeTruthy();
|
||||
expect(bits.reason).toBeFalsy();
|
||||
expect(bits.ruleType).toBe(RULE_ROOM);
|
||||
expect(bits.entity).toBe("!*.example.org");
|
||||
expect(bits.list).toBeDefined();
|
||||
expect(bits.list.listShortcode).toBe("test");
|
||||
});
|
||||
|
||||
it("should be able to detect room aliases", async () => {
|
||||
const mjolnir = createTestMjolnir();
|
||||
(<any>mjolnir).lists = [{listShortcode: "test"}];
|
||||
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
|
||||
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
|
||||
};
|
||||
|
||||
const command = "!mjolnir ban test #example.org";
|
||||
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
|
||||
expect(bits).toBeTruthy();
|
||||
expect(bits.reason).toBeFalsy();
|
||||
expect(bits.ruleType).toBe(RULE_ROOM);
|
||||
expect(bits.entity).toBe("#example.org");
|
||||
expect(bits.list).toBeDefined();
|
||||
expect(bits.list.listShortcode).toBe("test");
|
||||
});
|
||||
|
||||
it("should be able to detect room aliases with globs", async () => {
|
||||
const mjolnir = createTestMjolnir();
|
||||
(<any>mjolnir).lists = [{listShortcode: "test"}];
|
||||
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
|
||||
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
|
||||
};
|
||||
|
||||
const command = "!mjolnir ban test #*.example.org";
|
||||
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
|
||||
expect(bits).toBeTruthy();
|
||||
expect(bits.reason).toBeFalsy();
|
||||
expect(bits.ruleType).toBe(RULE_ROOM);
|
||||
expect(bits.entity).toBe("#*.example.org");
|
||||
expect(bits.list).toBeDefined();
|
||||
expect(bits.list.listShortcode).toBe("test");
|
||||
});
|
||||
|
||||
it("should be able to detect rooms with the type specified", async () => {
|
||||
const mjolnir = createTestMjolnir();
|
||||
(<any>mjolnir).lists = [{listShortcode: "test"}];
|
||||
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
|
||||
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
|
||||
};
|
||||
|
||||
const command = "!mjolnir ban test room @*.example.org";
|
||||
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
|
||||
expect(bits).toBeTruthy();
|
||||
expect(bits.reason).toBeFalsy();
|
||||
expect(bits.ruleType).toBe(RULE_ROOM);
|
||||
expect(bits.entity).toBe("@*.example.org");
|
||||
expect(bits.list).toBeDefined();
|
||||
expect(bits.list.listShortcode).toBe("test");
|
||||
});
|
||||
|
||||
it("should be able to detect user IDs", async () => {
|
||||
const mjolnir = createTestMjolnir();
|
||||
(<any>mjolnir).lists = [{listShortcode: "test"}];
|
||||
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
|
||||
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
|
||||
};
|
||||
|
||||
const command = "!mjolnir ban test @example.org";
|
||||
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
|
||||
expect(bits).toBeTruthy();
|
||||
expect(bits.reason).toBeFalsy();
|
||||
expect(bits.ruleType).toBe(RULE_USER);
|
||||
expect(bits.entity).toBe("@example.org");
|
||||
expect(bits.list).toBeDefined();
|
||||
expect(bits.list.listShortcode).toBe("test");
|
||||
});
|
||||
|
||||
it("should be able to detect user IDs with globs", async () => {
|
||||
const mjolnir = createTestMjolnir();
|
||||
(<any>mjolnir).lists = [{listShortcode: "test"}];
|
||||
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
|
||||
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
|
||||
};
|
||||
|
||||
const command = "!mjolnir ban test @*.example.org";
|
||||
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
|
||||
expect(bits).toBeTruthy();
|
||||
expect(bits.reason).toBeFalsy();
|
||||
expect(bits.ruleType).toBe(RULE_USER);
|
||||
expect(bits.entity).toBe("@*.example.org");
|
||||
expect(bits.list).toBeDefined();
|
||||
expect(bits.list.listShortcode).toBe("test");
|
||||
});
|
||||
|
||||
it("should be able to detect user IDs with the type specified", async () => {
|
||||
const mjolnir = createTestMjolnir();
|
||||
(<any>mjolnir).lists = [{listShortcode: "test"}];
|
||||
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
|
||||
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
|
||||
};
|
||||
|
||||
const command = "!mjolnir ban test user #*.example.org";
|
||||
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
|
||||
expect(bits).toBeTruthy();
|
||||
expect(bits.reason).toBeFalsy();
|
||||
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();
|
||||
(<any>mjolnir).lists = [{listShortcode: "test"}];
|
||||
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
|
||||
expect(content).toBeDefined();
|
||||
expect(content['body']).toContain("No ban list matching that shortcode was found");
|
||||
return Promise.resolve("$fake");
|
||||
};
|
||||
|
||||
const command = "!mjolnir ban user @example:example.org";
|
||||
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
|
||||
expect(bits).toBeFalsy();
|
||||
});
|
||||
|
||||
it("should error if no list (without type) is specified", async () => {
|
||||
const mjolnir = createTestMjolnir();
|
||||
(<any>mjolnir).lists = [{listShortcode: "test"}];
|
||||
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
|
||||
expect(content).toBeDefined();
|
||||
expect(content['body']).toContain("No ban list matching that shortcode was found");
|
||||
return Promise.resolve("$fake");
|
||||
};
|
||||
|
||||
const command = "!mjolnir ban @example:example.org";
|
||||
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
|
||||
expect(bits).toBeFalsy();
|
||||
});
|
||||
|
||||
it("should not error if a list (with type) is specified", async () => {
|
||||
const mjolnir = createTestMjolnir();
|
||||
(<any>mjolnir).lists = [{listShortcode: "test"}];
|
||||
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
|
||||
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
|
||||
};
|
||||
|
||||
const command = "!mjolnir ban user test @example:example.org";
|
||||
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
|
||||
expect(bits).toBeTruthy();
|
||||
expect(bits.reason).toBeFalsy();
|
||||
expect(bits.ruleType).toBe(RULE_USER);
|
||||
expect(bits.entity).toBe("@example:example.org");
|
||||
expect(bits.list).toBeDefined();
|
||||
expect(bits.list.listShortcode).toBe("test");
|
||||
});
|
||||
|
||||
it("should not error if a list (without type) is specified", async () => {
|
||||
const mjolnir = createTestMjolnir();
|
||||
(<any>mjolnir).lists = [{listShortcode: "test"}];
|
||||
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
|
||||
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
|
||||
};
|
||||
|
||||
const command = "!mjolnir ban test @example:example.org";
|
||||
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
|
||||
expect(bits).toBeTruthy();
|
||||
expect(bits.reason).toBeFalsy();
|
||||
expect(bits.ruleType).toBe(RULE_USER);
|
||||
expect(bits.entity).toBe("@example:example.org");
|
||||
expect(bits.list).toBeDefined();
|
||||
expect(bits.list.listShortcode).toBe("test");
|
||||
});
|
||||
|
||||
it("should not error if a list (with type reversed) is specified", async () => {
|
||||
const mjolnir = createTestMjolnir();
|
||||
(<any>mjolnir).lists = [{listShortcode: "test"}];
|
||||
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
|
||||
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
|
||||
};
|
||||
|
||||
const command = "!mjolnir ban test user @example:example.org";
|
||||
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
|
||||
expect(bits).toBeTruthy();
|
||||
expect(bits.reason).toBeFalsy();
|
||||
expect(bits.ruleType).toBe(RULE_USER);
|
||||
expect(bits.entity).toBe("@example:example.org");
|
||||
expect(bits.list).toBeDefined();
|
||||
expect(bits.list.listShortcode).toBe("test");
|
||||
});
|
||||
});
|
||||
|
||||
describe("[with default list]", () => {
|
||||
it("should use the default list if no list (with type) is specified", async () => {
|
||||
const mjolnir = createTestMjolnir("test");
|
||||
(<any>mjolnir).lists = [{listShortcode: "test"}, {listShortcode: "other"}];
|
||||
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
|
||||
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
|
||||
};
|
||||
|
||||
const command = "!mjolnir ban user @example:example.org";
|
||||
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
|
||||
expect(bits).toBeTruthy();
|
||||
expect(bits.reason).toBeFalsy();
|
||||
expect(bits.ruleType).toBe(RULE_USER);
|
||||
expect(bits.entity).toBe("@example:example.org");
|
||||
expect(bits.list).toBeDefined();
|
||||
expect(bits.list.listShortcode).toBe("test");
|
||||
});
|
||||
|
||||
it("should use the default list if no list (without type) is specified", async () => {
|
||||
const mjolnir = createTestMjolnir("test");
|
||||
(<any>mjolnir).lists = [{listShortcode: "test"}, {listShortcode: "other"}];
|
||||
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
|
||||
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
|
||||
};
|
||||
|
||||
const command = "!mjolnir ban @example:example.org";
|
||||
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
|
||||
expect(bits).toBeTruthy();
|
||||
expect(bits.reason).toBeFalsy();
|
||||
expect(bits.ruleType).toBe(RULE_USER);
|
||||
expect(bits.entity).toBe("@example:example.org");
|
||||
expect(bits.list).toBeDefined();
|
||||
expect(bits.list.listShortcode).toBe("test");
|
||||
});
|
||||
|
||||
it("should use the specified list if a list (with type) is specified", async () => {
|
||||
const mjolnir = createTestMjolnir("test");
|
||||
(<any>mjolnir).lists = [{listShortcode: "test"}, {listShortcode: "other"}];
|
||||
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
|
||||
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
|
||||
};
|
||||
|
||||
const command = "!mjolnir ban user other @example:example.org";
|
||||
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
|
||||
expect(bits).toBeTruthy();
|
||||
expect(bits.reason).toBeFalsy();
|
||||
expect(bits.ruleType).toBe(RULE_USER);
|
||||
expect(bits.entity).toBe("@example:example.org");
|
||||
expect(bits.list).toBeDefined();
|
||||
expect(bits.list.listShortcode).toBe("other");
|
||||
});
|
||||
|
||||
it("should use the specified list if a list (without type) is specified", async () => {
|
||||
const mjolnir = createTestMjolnir("test");
|
||||
(<any>mjolnir).lists = [{listShortcode: "test"}, {listShortcode: "other"}];
|
||||
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
|
||||
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
|
||||
};
|
||||
|
||||
const command = "!mjolnir ban other @example:example.org";
|
||||
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
|
||||
expect(bits).toBeTruthy();
|
||||
expect(bits.reason).toBeFalsy();
|
||||
expect(bits.ruleType).toBe(RULE_USER);
|
||||
expect(bits.entity).toBe("@example:example.org");
|
||||
expect(bits.list).toBeDefined();
|
||||
expect(bits.list.listShortcode).toBe("other");
|
||||
});
|
||||
|
||||
it("should not error if a list (with type reversed) is specified", async () => {
|
||||
const mjolnir = createTestMjolnir("test");
|
||||
(<any>mjolnir).lists = [{listShortcode: "test"}, {listShortcode: "other"}];
|
||||
mjolnir.client.sendMessage = (roomId: string, content: any): Promise<string> => {
|
||||
throw new Error("sendMessage should not have been called: " + JSON.stringify(content));
|
||||
};
|
||||
|
||||
const command = "!mjolnir ban other user @example:example.org";
|
||||
const bits = await parseArguments("!a", createFakeEvent(command), mjolnir, command.split(' '));
|
||||
expect(bits).toBeTruthy();
|
||||
expect(bits.reason).toBeFalsy();
|
||||
expect(bits.ruleType).toBe(RULE_USER);
|
||||
expect(bits.entity).toBe("@example:example.org");
|
||||
expect(bits.list).toBeDefined();
|
||||
expect(bits.list.listShortcode).toBe("other");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -9,7 +9,8 @@
|
||||
"sourceMap": true,
|
||||
"outDir": "./lib",
|
||||
"types": [
|
||||
"node"
|
||||
"node",
|
||||
"mocha"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
|
Loading…
Reference in New Issue
Block a user