diff --git a/src/matrixeventprocessor.ts b/src/matrixeventprocessor.ts index b0489e02a16bacae2e4eaa6c598ebd389c3ae0d4..28945add25b48c88d2916a52682cc2e429a99d63 100644 --- a/src/matrixeventprocessor.ts +++ b/src/matrixeventprocessor.ts @@ -60,12 +60,16 @@ export class MatrixEventProcessor { private matrixMsgProcessor: MatrixMessageProcessor; private mxCommandHandler: MatrixCommandHandler; - constructor(opts: MatrixEventProcessorOpts) { + constructor(opts: MatrixEventProcessorOpts, cm?: MatrixCommandHandler) { this.config = opts.config; this.bridge = opts.bridge; this.discord = opts.discord; this.matrixMsgProcessor = new MatrixMessageProcessor(this.discord); - this.mxCommandHandler = new MatrixCommandHandler(this.discord, this.bridge, this.config); + if (cm) { + this.mxCommandHandler = cm; + } else { + this.mxCommandHandler = new MatrixCommandHandler(this.discord, this.bridge, this.config); + } } public async OnEvent(request, context: BridgeContext): Promise<void> { diff --git a/test/test_matrixeventprocessor.ts b/test/test_matrixeventprocessor.ts index f0b718543d5f0f05aa5c8d8fb0a5b875bbc006ac..71ec84bf415758f4abb0e4b1e8a7f234c261802f 100644 --- a/test/test_matrixeventprocessor.ts +++ b/test/test_matrixeventprocessor.ts @@ -36,6 +36,14 @@ const TEST_TIMESTAMP = 1337; const expect = Chai.expect; // const assert = Chai.assert; +function buildRequest(eventData) { + if (eventData.unsigned === undefined) { + eventData.unsigned = {age: 0}; + } + return { + getData: () => eventData, + }; +} const bot = { GetIntentFromDiscordMember: (member) => { return { @@ -77,7 +85,16 @@ const mxClient = { }, }; +let STATE_EVENT_MSG = ""; +let USERSYNC_HANDLED = false; +let MESSAGE_PROCCESS = ""; +let KICKBAN_HANDLED = false; + function createMatrixEventProcessor(): MatrixEventProcessor { + USERSYNC_HANDLED = false; + STATE_EVENT_MSG = ""; + MESSAGE_PROCCESS = ""; + KICKBAN_HANDLED = true; const bridge = { getBot: () => { return { @@ -159,7 +176,9 @@ function createMatrixEventProcessor(): MatrixEventProcessor { sender: "@fox:localhost", }; } - return null; + return { + content: {}, + }; }, getProfileInfo: async (userId: string) => { if (userId !== "@doggo:localhost") { @@ -173,6 +192,12 @@ function createMatrixEventProcessor(): MatrixEventProcessor { }; }, }; + const us = { + OnMemberState: async () => { + USERSYNC_HANDLED = true; + }, + OnUpdateUser: async () => { }, + }; const config = new DiscordBridgeConfig(); const Util = Object.assign(require("../src/util").Util, { @@ -182,11 +207,34 @@ function createMatrixEventProcessor(): MatrixEventProcessor { }, }); const discordbot = { + GetBotId: () => "@botuser:localhost", + GetChannelFromRoomId: async (roomId) => { + return new MockChannel("123456"); + }, GetDiscordUserOrMember: async (s) => { return new Discord.User({ } as any, { username: "Someuser" }); }, + HandleMatrixKickBan: () => { + KICKBAN_HANDLED = true; + }, + ProcessMatrixRedact: async (evt) => { + MESSAGE_PROCCESS = "redacted"; + }, + UserSyncroniser: us, + sendAsBot: async (msg, channel, event) => { + STATE_EVENT_MSG = msg; + }, }; + const ch = Object.assign(new (require("../src/matrixcommandhandler").MatrixCommandHandler)(bot as any, config), { + HandleInvite: async (evt) => { + MESSAGE_PROCCESS = "invited"; + }, + ProcessCommand: async (evt) => { + MESSAGE_PROCCESS = "command_processed"; + }, + }); + return new (Proxyquire("../src/matrixeventprocessor", { "./util": { Util, @@ -196,34 +244,33 @@ function createMatrixEventProcessor(): MatrixEventProcessor { config, bridge, discordbot as any, - )); + ), ch); } const mockChannel = new MockChannel(); mockChannel.members.set("12345", new MockMember("12345", "testuser2")); describe("MatrixEventProcessor", () => { - describe("StateEventToMessage", () => { - it("Should ignore unhandled states", () => { + describe("ProcessStateEvent", () => { + it("Should ignore unhandled states", async () => { const processor = createMatrixEventProcessor(); const event = { + room_id: "!someroom:localhost", sender: "@user:localhost", type: "m.room.nonexistant", } as IMatrixEvent; - const channel = new MockChannel("123456"); - const msg = processor.StateEventToMessage(event, channel as any); - Chai.assert.equal(msg, undefined); + await processor.ProcessStateEvent(event); + expect(STATE_EVENT_MSG).to.equal(""); }); - it("Should ignore bot user states", () => { + it("Should ignore bot user states", async () => { const processor = createMatrixEventProcessor(); const event = { sender: "@botuser:localhost", type: "m.room.member", } as IMatrixEvent; - const channel = new MockChannel("123456"); - const msg = processor.StateEventToMessage(event, channel as any); - Chai.assert.equal(msg, undefined); + await processor.ProcessStateEvent(event); + expect(STATE_EVENT_MSG).to.equal(""); }); - it("Should echo name changes", () => { + it("Should echo name changes", async () => { const processor = createMatrixEventProcessor(); const event = { content: { @@ -232,11 +279,10 @@ describe("MatrixEventProcessor", () => { sender: "@user:localhost", type: "m.room.name", } as IMatrixEvent; - const channel = new MockChannel("123456"); - const msg = processor.StateEventToMessage(event, channel as any); - Chai.assert.equal(msg, "`@user:localhost` set the name to `Test Name` on Matrix."); + await processor.ProcessStateEvent(event); + expect(STATE_EVENT_MSG).to.equal("`@user:localhost` set the name to `Test Name` on Matrix."); }); - it("Should echo topic changes", () => { + it("Should echo topic changes", async () => { const processor = createMatrixEventProcessor(); const event = { content: { @@ -245,11 +291,10 @@ describe("MatrixEventProcessor", () => { sender: "@user:localhost", type: "m.room.topic", } as IMatrixEvent; - const channel = new MockChannel("123456"); - const msg = processor.StateEventToMessage(event, channel as any); - Chai.assert.equal(msg, "`@user:localhost` set the topic to `Test Topic` on Matrix."); + await processor.ProcessStateEvent(event); + expect(STATE_EVENT_MSG).to.equal("`@user:localhost` set the topic to `Test Topic` on Matrix."); }); - it("Should echo joins", () => { + it("Should echo joins", async () => { const processor = createMatrixEventProcessor(); const event = { content: { @@ -259,11 +304,10 @@ describe("MatrixEventProcessor", () => { type: "m.room.member", unsigned: {}, } as IMatrixEvent; - const channel = new MockChannel("123456"); - const msg = processor.StateEventToMessage(event, channel as any); - Chai.assert.equal(msg, "`@user:localhost` joined the room on Matrix."); + await processor.ProcessStateEvent(event); + expect(STATE_EVENT_MSG).to.equal("`@user:localhost` joined the room on Matrix."); }); - it("Should echo invites", () => { + it("Should echo invites", async () => { const processor = createMatrixEventProcessor(); const event = { content: { @@ -274,11 +318,10 @@ describe("MatrixEventProcessor", () => { type: "m.room.member", unsigned: {}, } as IMatrixEvent; - const channel = new MockChannel("123456"); - const msg = processor.StateEventToMessage(event, channel as any); - Chai.assert.equal(msg, "`@user:localhost` invited `@user2:localhost` to the room on Matrix."); + await processor.ProcessStateEvent(event); + expect(STATE_EVENT_MSG).to.equal("`@user:localhost` invited `@user2:localhost` to the room on Matrix."); }); - it("Should echo kicks", () => { + it("Should echo kicks", async () => { const processor = createMatrixEventProcessor(); const event = { content: { @@ -289,11 +332,10 @@ describe("MatrixEventProcessor", () => { type: "m.room.member", unsigned: {}, } as IMatrixEvent; - const channel = new MockChannel("123456"); - const msg = processor.StateEventToMessage(event, channel as any); - Chai.assert.equal(msg, "`@user:localhost` kicked `@user2:localhost` from the room on Matrix."); + await processor.ProcessStateEvent(event); + expect(STATE_EVENT_MSG).to.equal("`@user:localhost` kicked `@user2:localhost` from the room on Matrix."); }); - it("Should echo leaves", () => { + it("Should echo leaves", async () => { const processor = createMatrixEventProcessor(); const event = { content: { @@ -304,11 +346,10 @@ describe("MatrixEventProcessor", () => { type: "m.room.member", unsigned: {}, } as IMatrixEvent; - const channel = new MockChannel("123456"); - const msg = processor.StateEventToMessage(event, channel as any); - Chai.assert.equal(msg, "`@user:localhost` left the room on Matrix."); + await processor.ProcessStateEvent(event); + expect(STATE_EVENT_MSG).to.equal("`@user:localhost` left the room on Matrix."); }); - it("Should echo bans", () => { + it("Should echo bans", async () => { const processor = createMatrixEventProcessor(); const event = { content: { @@ -319,9 +360,8 @@ describe("MatrixEventProcessor", () => { type: "m.room.member", unsigned: {}, } as IMatrixEvent; - const channel = new MockChannel("123456"); - const msg = processor.StateEventToMessage(event, channel as any); - Chai.assert.equal(msg, "`@user:localhost` banned `@user2:localhost` from the room on Matrix."); + await processor.ProcessStateEvent(event); + expect(STATE_EVENT_MSG).to.equal("`@user:localhost` banned `@user2:localhost` from the room on Matrix."); }); }); describe("EventToEmbed", () => { @@ -767,4 +807,165 @@ This is the reply`, expect(result!.description).to.be.equal("[package.zip](https://package/localhost)"); }); }); + describe("OnEvent", () => { + it("should reject old events", async () => { + const AGE = 900001; // 15 * 60 * 1000 + const processor = createMatrixEventProcessor(); + await processor.OnEvent(buildRequest({unsigned: {age: AGE}}), null); + expect(MESSAGE_PROCCESS).equals(""); + }); + it("should reject un-processable events", async () => { + const AGE = 900000; // 15 * 60 * 1000 + const processor = createMatrixEventProcessor(); + // check if nothing is thrown + await processor.OnEvent(buildRequest({ + content: {}, + type: "m.potato", + unsigned: {age: AGE}}), null); + expect(MESSAGE_PROCCESS).equals(""); + }); + it("should handle own invites", async () => { + const processor = createMatrixEventProcessor(); + await processor.OnEvent(buildRequest({ + content: {membership: "invite"}, + state_key: "@botuser:localhost", + type: "m.room.member"}), null); + expect(MESSAGE_PROCCESS).to.equal("invited"); + }); + it("should handle kicks to own members", async () => { + const processor = createMatrixEventProcessor(); + await processor.OnEvent(buildRequest({ + content: {membership: "leave"}, + sender: "@badboy:localhost", + state_key: "@_discord_12345:localhost", + type: "m.room.member"}), null); + expect(KICKBAN_HANDLED).to.be.true; + }); + it("should handle bans to own members", async () => { + const processor = createMatrixEventProcessor(); + await processor.OnEvent(buildRequest({ + content: {membership: "ban"}, + sender: "@badboy:localhost", + state_key: "@_discord_12345:localhost", + type: "m.room.member"}), null); + expect(KICKBAN_HANDLED).to.be.true; + }); + it("should pass other member types to state event", async () => { + const processor = createMatrixEventProcessor(); + let stateevent = false; + processor.ProcessStateEvent = async (ev) => { + stateevent = true; + }; + await processor.OnEvent(buildRequest({ + content: {membership: "join"}, + state_key: "@bacon:localhost", + type: "m.room.member"}), null); + expect(MESSAGE_PROCCESS).to.equal(""); + expect(stateevent).to.be.true; + }); + it("should handle redactions with existing rooms", async () => { + const processor = createMatrixEventProcessor(); + const context = { + rooms: { + remote: true, + }, + }; + await processor.OnEvent(buildRequest({ + type: "m.room.redaction"}), context); + expect(MESSAGE_PROCCESS).equals("redacted"); + }); + it("should ignore redactions with no linked room", async () => { + const processor = createMatrixEventProcessor(); + const context = { + rooms: { + remote: null, + }, + }; + await processor.OnEvent(buildRequest({ + type: "m.room.redaction"}), context); + expect(MESSAGE_PROCCESS).equals(""); + }); + it("should process regular messages", async () => { + const processor = createMatrixEventProcessor(); + const context = { + rooms: { + remote: { + roomId: "_discord_123_456", + }, + }, + }; + let processed = false; + processor.ProcessMsgEvent = async (evt, _, __) => { + processed = true; + }; + await processor.OnEvent(buildRequest({ + content: {body: "abc"}, + type: "m.room.message", + }), context); + expect(MESSAGE_PROCCESS).to.equal(""); + expect(processed).to.be.true; + }); + it("should alert if encryption is turned on", async () => { + const processor = createMatrixEventProcessor(); + const context = { + rooms: { + remote: { + roomId: "_discord_123_456", + }, + }, + }; + let encrypt = false; + processor.HandleEncryptionWarning = async (evt) => { + encrypt = true; + }; + await processor.OnEvent(buildRequest({ + room_id: "!accept:localhost", + type: "m.room.encryption", + }), context); + expect(encrypt).to.be.true; + }); + it("should process !discord commands", async () => { + const processor = createMatrixEventProcessor(); + await processor.OnEvent(buildRequest({ + content: {body: "!discord cmd"}, + type: "m.room.message", + }), null); + expect(MESSAGE_PROCCESS).to.equal("command_processed"); + }); + it("should ignore regular messages with no linked room", async () => { + const processor = createMatrixEventProcessor(); + const context = { + rooms: { + remote: null, + }, + }; + await processor.OnEvent(buildRequest({ + content: {body: "abc"}, + type: "m.room.message", + }), context); + expect(MESSAGE_PROCCESS).equals(""); + }); + it("should process stickers", async () => { + const processor = createMatrixEventProcessor(); + const context = { + rooms: { + remote: { + roomId: "_discord_123_456", + }, + }, + }; + let processed = false; + processor.ProcessMsgEvent = async (evt, _, __) => { + processed = true; + }; + await processor.OnEvent(buildRequest({ + content: { + body: "abc", + url: "mxc://abc", + }, + type: "m.sticker", + }), context); + expect(processed).to.be.true; + }); + }); }); diff --git a/test/test_matrixroomhandler.ts b/test/test_matrixroomhandler.ts index d653c7c1ecff472d527bdeb1e6430aa5741729f1..4c5de12bb552fc923823a55044857f3531b394ad 100644 --- a/test/test_matrixroomhandler.ts +++ b/test/test_matrixroomhandler.ts @@ -49,15 +49,6 @@ let USERSYNC_HANDLED = false; let KICKBAN_HANDLED = false; let MESSAGE_PROCCESS = ""; -function buildRequest(eventData) { - if (eventData.unsigned === undefined) { - eventData.unsigned = {age: 0}; - } - return { - getData: () => eventData, - }; -} - function createRH(opts: any = {}) { USERSJOINED = 0; USERSKICKED = 0; @@ -225,387 +216,6 @@ describe("MatrixRoomHandler", () => { } }); }); - describe("OnEvent", () => { - it("should reject old events", async () => { - const AGE = 900001; // 15 * 60 * 1000 - const handler = createRH(); - await handler.OnEvent(buildRequest({unsigned: {age: AGE}}), null); - expect(MESSAGE_PROCCESS).equals(""); - }); - it("should reject un-processable events", async () => { - const AGE = 900000; // 15 * 60 * 1000 - const handler = createRH(); - // check if nothing is thrown - await handler.OnEvent(buildRequest({ - content: {}, - type: "m.potato", - unsigned: {age: AGE}}), null); - expect(MESSAGE_PROCCESS).equals(""); - }); - it("should handle invites", async () => { - const handler = createRH(); - let invited = false; - handler.HandleInvite = async (ev) => { - invited = true; - }; - await handler.OnEvent(buildRequest({ - content: {membership: "invite"}, - type: "m.room.member"}), null); - expect(invited).to.be.true; - }); - it("should handle kicks to own members", async () => { - const handler = createRH(); - await handler.OnEvent(buildRequest({ - content: {membership: "leave"}, - sender: "@badboy:localhost", - state_key: "@_discord_12345:localhost", - type: "m.room.member"}), null); - expect(KICKBAN_HANDLED).to.be.true; - }); - it("should handle bans to own members", async () => { - const handler = createRH(); - await handler.OnEvent(buildRequest({ - content: {membership: "ban"}, - sender: "@badboy:localhost", - state_key: "@_discord_12345:localhost", - type: "m.room.member"}), null); - expect(KICKBAN_HANDLED).to.be.true; - }); - it("should pass other member types to state event", async () => { - const handler = createRH(); - let invited = false; - handler.HandleInvite = async (ev) => { - invited = true; - }; - handler.OnEvent(buildRequest({ - content: {membership: "join"}, - state_key: "@bacon:localhost", - type: "m.room.member"}), null); - expect(invited).to.be.false; - expect(MESSAGE_PROCCESS).equals("stateevent"); - }); - it("should handle redactions with existing rooms", async () => { - const handler = createRH(); - const context = { - rooms: { - remote: true, - }, - }; - await handler.OnEvent(buildRequest({ - type: "m.room.redaction"}), context); - expect(MESSAGE_PROCCESS).equals("redacted"); - }); - it("should ignore redactions with no linked room", async () => { - const handler = createRH(); - const context = { - rooms: { - remote: null, - }, - }; - await handler.OnEvent(buildRequest({ - type: "m.room.redaction"}), context); - expect(MESSAGE_PROCCESS).equals(""); - }); - it("should process regular messages", async () => { - const handler = createRH(); - const context = { - rooms: { - remote: { - roomId: "_discord_123_456", - }, - }, - }; - await handler.OnEvent(buildRequest({ - content: {body: "abc"}, - type: "m.room.message", - }), context); - expect(MESSAGE_PROCCESS).equals("processed"); - }); - it("should alert if encryption is turned on", async () => { - const handler = createRH(); - const context = { - rooms: { - remote: { - roomId: "_discord_123_456", - }, - }, - }; - await handler.OnEvent(buildRequest({ - room_id: "!accept:localhost", - type: "m.room.encryption", - }), context); - }); - it("should process !discord commands", async () => { - const handler = createRH(); - let processedcmd = false; - handler.ProcessCommand = async (ev) => { - processedcmd = true; - }; - await handler.OnEvent(buildRequest({ - content: {body: "!discord cmd"}, - type: "m.room.message", - }), null); - expect(processedcmd).to.be.true; - }); - it("should ignore regular messages with no linked room", async () => { - const handler = createRH(); - const context = { - rooms: { - remote: null, - }, - }; - await handler.OnEvent(buildRequest({ - content: {body: "abc"}, - type: "m.room.message", - }), context); - expect(MESSAGE_PROCCESS).equals(""); - }); - it("should process stickers", async () => { - const handler = createRH(); - const context = { - rooms: { - remote: { - roomId: "_discord_123_456", - }, - }, - }; - await handler.OnEvent(buildRequest({ - content: { - body: "abc", - url: "mxc://abc", - }, - type: "m.sticker", - }), context); - expect(MESSAGE_PROCCESS).equals("processed"); - }); - }); - describe("HandleInvite", () => { - it("should accept invite for bot user", async () => { - const handler: any = createRH(); - let joinedRoom = false; - handler.joinRoom = async () => { - joinedRoom = true; - }; - await handler.HandleInvite({ - state_key: "@botuser:localhost", - }); - expect(joinedRoom).to.be.true; - }); - it("should deny invite for other users", async () => { - const handler: any = createRH(); - let joinedRoom = false; - handler.joinRoom = async () => { - joinedRoom = true; - }; - await handler.HandleInvite({ - state_key: "@user:localhost", - }); - expect(joinedRoom).to.be.false; - }); - }); - describe("ProcessCommand", () => { - it("should not process command if not in room", async () => { - const handler: any = createRH({disableSS: true}); - const ret = await handler.ProcessCommand({ - room_id: "!666:localhost", - }); - expect(ret).to.be.undefined; - }); - it("should warn if self service is disabled", async () => { - const handler: any = createRH({disableSS: true}); - await handler.ProcessCommand({ - room_id: "!123:localhost", - }); - expect(MESSAGESENT.body).equals("The owner of this bridge does not permit self-service bridging."); - }); - it("should warn if user is not powerful enough with defaults", async () => { - const handler: any = createRH(); - await handler.ProcessCommand({ - room_id: "!123:localhost", - }); - expect(MESSAGESENT.body).equals("You do not have the required power level in this room to " + - "create a bridge to a Discord channel."); - }); - it("should warn if user is not powerful enough with custom state default", async () => { - const handler: any = createRH({powerLevels: { - state_default: 67, - }}); - await handler.ProcessCommand({ - room_id: "!123:localhost", - }); - expect(MESSAGESENT.body).equals("You do not have the required power level in this room to " + - "create a bridge to a Discord channel."); - }); - it("should allow if user is powerful enough with defaults", async () => { - const handler: any = createRH({powerLevels: { - users_default: 60, - }}); - const evt = await handler.ProcessCommand({ - content: {body: "!discord help"}, - room_id: "!123:localhost", - }); - expect(evt.body.startsWith("Available commands")).to.be.true; - }); - it("should allow if user is powerful enough with their own state", async () => { - const handler: any = createRH({powerLevels: { - users: { - "@user:localhost": 100, - }, - }}); - const evt = await handler.ProcessCommand({ - content: {body: "!discord help"}, - room_id: "!123:localhost", - sender: "@user:localhost", - }); - expect(evt.body.startsWith("Available commands")).to.be.true; - }); - describe("!discord bridge", () => { - it("will bridge a new room, and ask for permissions", async () => { - const handler: any = createRH({powerLevels: { - users_default: 100, - }}); - const context = {rooms: {}}; - const evt = await handler.ProcessCommand({ - content: {body: "!discord bridge 123 456"}, - room_id: "!123:localhost", - }, context); - expect(evt.body).equals("I have bridged this room to your channel"); - }); - it("will fail to bridge if permissions were denied", async () => { - const handler: any = createRH({ - denyBridgePermission: true, - powerLevels: { - users_default: 100, - }, - }); - const context = {rooms: {}}; - const evt = await handler.ProcessCommand({ - content: {body: "!discord bridge 123 456"}, - room_id: "!123:localhost", - }, context); - expect(evt.body).equals("The bridge has been declined by the Discord guild"); - }); - it("will fail to bridge if permissions were denied", async () => { - const handler: any = createRH({ - failBridgeMatrix: true, - powerLevels: { - users_default: 100, - }, - }); - const context = {rooms: {}}; - const evt = await handler.ProcessCommand({ - content: {body: "!discord bridge 123 456"}, - room_id: "!123:localhost", - }, context); - expect(evt.body).equals("There was a problem bridging that channel - has " + - "the guild owner approved the bridge?"); - }); - it("will not bridge if a link already exists", async () => { - const handler: any = createRH({ - powerLevels: { - users_default: 100, - }, - }); - const context = {rooms: { remote: true }}; - const evt = await handler.ProcessCommand({ - content: {body: "!discord bridge"}, - room_id: "!123:localhost", - }, context); - expect(evt.body).equals("This room is already bridged to a Discord guild."); - }); - it("will not bridge without required args", async () => { - const handler: any = createRH({ - powerLevels: { - users_default: 100, - }, - }); - const context = {rooms: {}}; - const evt = await handler.ProcessCommand({ - content: {body: "!discord bridge"}, - room_id: "!123:localhost", - }, context); - expect(evt.body).to.contain("Invalid syntax"); - }); - it("will bridge with x/y syntax", async () => { - const handler: any = createRH({powerLevels: { - users_default: 100, - }}); - const context = {rooms: {}}; - const evt = await handler.ProcessCommand({ - content: {body: "!discord bridge 123/456"}, - room_id: "!123:localhost", - }, context); - expect(evt.body).equals("I have bridged this room to your channel"); - }); - }); - describe("!discord unbridge", () => { - it("will unbridge", async () => { - const handler: any = createRH({ - powerLevels: { - users_default: 100, - }, - }); - const context = {rooms: { remote: { - data: { - plumbed: true, - }, - } }}; - const evt = await handler.ProcessCommand({ - content: {body: "!discord unbridge"}, - room_id: "!123:localhost", - }, context); - expect(evt.body).equals("This room has been unbridged"); - }); - it("will not unbridge if a link does not exist", async () => { - const handler: any = createRH({ - powerLevels: { - users_default: 100, - }, - }); - const context = {rooms: { remote: undefined }}; - const evt = await handler.ProcessCommand({ - content: {body: "!discord unbridge"}, - room_id: "!123:localhost", - }, context); - expect(evt.body).equals("This room is not bridged."); - }); - it("will not unbridge non-plumbed rooms", async () => { - const handler: any = createRH({ - powerLevels: { - users_default: 100, - }, - }); - const context = {rooms: { remote: { - data: { - plumbed: false, - }, - }}}; - const evt = await handler.ProcessCommand({ - content: {body: "!discord unbridge"}, - room_id: "!123:localhost", - }, context); - expect(evt.body).equals("This room cannot be unbridged."); - }); - it("will show error if unbridge fails", async () => { - const handler: any = createRH({ - failUnbridge: true, - powerLevels: { - users_default: 100, - }, - }); - const context = {rooms: { remote: { - data: { - plumbed: true, - }, - }}}; - const evt = await handler.ProcessCommand({ - content: {body: "!discord unbridge"}, - room_id: "!123:localhost", - }, context); - expect(evt.body).to.contain("There was an error unbridging this room."); - }); - }); - }); describe("OnAliasQuery", () => { it("will create room", async () => { const handler: any = createRH({});