diff --git a/src/discordcommandhandler.ts b/src/discordcommandhandler.ts
index d3c00a319eef1f6c9d90d52e75fb7f5deefee60a..efcb53fc637140d1663042d2b88b44aa3d04bede 100644
--- a/src/discordcommandhandler.ts
+++ b/src/discordcommandhandler.ts
@@ -1,6 +1,6 @@
 import { DiscordBot } from "./bot";
 import * as Discord from "discord.js";
-import { Util, ICommandActions, ICommandParameters, ICommandPermissonCheck } from "./util";
+import { Util, ICommandActions, ICommandParameters, CommandPermissonCheck } from "./util";
 import { Bridge } from "matrix-appservice-bridge";
 export class DiscordCommandHandler {
     constructor(
@@ -48,9 +48,9 @@ export class DiscordCommandHandler {
             },
         };
 
-        const permissionCheck: ICommandPermissonCheck = async (permission) => {
+        const permissionCheck: CommandPermissonCheck = async (permission) => {
             return msg.member.hasPermission(permission as Discord.PermissionResolvable);
-        }
+        };
 
         const reply = await Util.ParseCommand("!matrix", msg.content, actions, parameters, permissionCheck);
         await msg.channel.send(reply);
diff --git a/src/matrixcommandhandler.ts b/src/matrixcommandhandler.ts
index 9402a9ea3098b60d047eceefb111cc66aedd09b0..b2bbcf040a959d60547099fbed09493835974541 100644
--- a/src/matrixcommandhandler.ts
+++ b/src/matrixcommandhandler.ts
@@ -4,7 +4,7 @@ import { DiscordBridgeConfig } from "./config";
 import { Bridge, BridgeContext } from "matrix-appservice-bridge";
 import { IMatrixEvent } from "./matrixtypes";
 import { Provisioner } from "./provisioner";
-import { Util, ICommandActions, ICommandParameters, ICommandPermissonCheck } from "./util";
+import { Util, ICommandActions, ICommandParameters, CommandPermissonCheck } from "./util";
 import * as Discord from "discord.js";
 const log = new Log("MatrixCommandHandler");
 
@@ -123,7 +123,7 @@ export class MatrixCommandHandler {
                         return "There was an error unbridging this room. " +
                             "Please try again later or contact the bridge operator.";
                     }
-                }
+                },
             },
         };
 
@@ -132,8 +132,17 @@ export class MatrixCommandHandler {
         we do this by assuming that guildId is parsed first, and split the / off and then pass
         that on to channelId, if applicable
         */
-        let guildIdRemainder: string | undefined = undefined;
+        let guildIdRemainder: string | undefined;
         const parameters: ICommandParameters = {
+            channelId: {
+                description: "The ID of a channel on discord",
+                get: async (s) => {
+                    if (!s && guildIdRemainder) {
+                        return guildIdRemainder;
+                    }
+                    return s;
+                },
+            },
             guildId: {
                 description: "The ID of a guild/server on discord",
                 get: async (s) => {
@@ -145,18 +154,9 @@ export class MatrixCommandHandler {
                     return parts[0];
                 },
             },
-            channelId: {
-                description: "The ID of a channel on discord",
-                get: async (s) => {
-                    if (!s && guildIdRemainder) {
-                        return guildIdRemainder;
-                    }
-                    return s;
-                },
-            },
         };
 
-        const permissionCheck: ICommandPermissonCheck = async (permission) => {
+        const permissionCheck: CommandPermissonCheck = async (permission) => {
             if (permission.selfService && !this.config.bridge.enableSelfServiceBridging) {
                 return "The owner of this bridge does not permit self-service bridging.";
             }
diff --git a/src/matrixtypes.ts b/src/matrixtypes.ts
index f71d7debdce3c15efe449f2208264a2efa44a004..7535b59a89063a02e1f1946321550287f483dd94 100644
--- a/src/matrixtypes.ts
+++ b/src/matrixtypes.ts
@@ -42,7 +42,7 @@ export interface IMatrixEvent {
     unsigned?: any; // tslint:disable-line no-any
     origin_server_ts?: number;
     users?: any; // tslint:disable-line no-any
-    users_default?: any // tslint:disable-line no-any
+    users_default?: any; // tslint:disable-line no-any
     notifications?: any; // tslint:disable-line no-any
 }
 
diff --git a/src/util.ts b/src/util.ts
index 8df0d180186d03a927dad2ba02208dd65a8422d5..80dc32ca65eeae9bd19dd62ae667e1e511c2f815 100644
--- a/src/util.ts
+++ b/src/util.ts
@@ -32,11 +32,11 @@ const log = new Log("Util");
 type PERMISSIONTYPES = any; // tslint:disable-line no-any
 
 export interface ICommandAction {
-    params: string[];
     description?: string;
+    help?: string;
+    params: string[];
     permission?: PERMISSIONTYPES;
     run(params: any): Promise<any>; // tslint:disable-line no-any
-    help?: string;
 }
 
 export interface ICommandActions {
@@ -52,9 +52,7 @@ export interface ICommandParameters {
     [index: string]: ICommandParameter;
 }
 
-export interface ICommandPermissonCheck {
-    (permission: PERMISSIONTYPES): Promise<boolean | string>;
-}
+export type CommandPermissonCheck = (permission: PERMISSIONTYPES) => Promise<boolean | string>;
 
 export interface IPatternMap {
     [index: string]: string;
@@ -242,7 +240,7 @@ export class Util {
         actions: ICommandActions,
         parameters: ICommandParameters,
         args: string[],
-        permissionCheck?: ICommandPermissonCheck,
+        permissionCheck?: CommandPermissonCheck,
     ): Promise<string> {
         let reply = "";
         if (args[0]) {
@@ -298,7 +296,7 @@ export class Util {
         msg: string,
         actions: ICommandActions,
         parameters: ICommandParameters,
-        permissionCheck?: ICommandPermissonCheck,
+        permissionCheck?: CommandPermissonCheck,
     ): Promise<string> {
         const {command, args} = Util.MsgToArgs(msg, prefix);
 
@@ -316,7 +314,8 @@ export class Util {
                 return `**ERROR:** ${permCheck}`;
             }
             if (!permCheck) {
-                return `**ERROR:** insufficiant permissions to use this command! Try \`${prefix} help\` to see all available commands`;
+                return `**ERROR:** insufficiant permissions to use this command! ` +
+                    `Try \`${prefix} help\` to see all available commands`;
             }
         }
         if (action.params.length === 1) {
diff --git a/test/test_discordbot.ts b/test/test_discordbot.ts
index 6cf8e29f9642534d52a1121cddad377f4dc148e8..09088f4ceaa59f9ba5af3472b0aa73dfff3efe6e 100644
--- a/test/test_discordbot.ts
+++ b/test/test_discordbot.ts
@@ -1,5 +1,5 @@
 /*
-Copyright 2017, 2018 matrix-appservice-discord
+Copyright 2017 - 2019 matrix-appservice-discord
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
diff --git a/test/test_discordcommandhandler.ts b/test/test_discordcommandhandler.ts
new file mode 100644
index 0000000000000000000000000000000000000000..eb4b725130353a170934152abd2a0a60eca986f6
--- /dev/null
+++ b/test/test_discordcommandhandler.ts
@@ -0,0 +1,162 @@
+/*
+Copyright 2019 matrix-appservice-discord
+
+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 Chai from "chai";
+import * as Proxyquire from "proxyquire";
+
+import { DiscordCommandHandler } from "../src/discordcommandhandler";
+import { MockChannel } from "./mocks/channel";
+import { MockMember } from "./mocks/member";
+import { MockGuild } from "./mocks/guild";
+import { Util } from "../src/util";
+
+// we are a test file and thus need those
+/* tslint:disable:no-unused-expression max-file-line-count no-any */
+
+const expect = Chai.expect;
+
+let USERSJOINED = 0;
+let USERSKICKED = 0;
+let USERSBANNED = 0;
+let USERSUNBANNED = 0;
+let MESSAGESENT: any = {};
+function createCH(opts: any = {}) {
+    USERSJOINED = 0;
+    USERSKICKED = 0;
+    USERSBANNED = 0;
+    USERSUNBANNED = 0;
+    MESSAGESENT = {};
+    const bridge = {
+        getIntent: () => {
+            return {
+                ban: async () => { USERSBANNED++; },
+                getEvent: () => ({ content: { } }),
+                join: () => { USERSJOINED++; },
+                kick: async () => { USERSKICKED++; },
+                leave: () => { },
+                sendMessage: async (roomId, content) => { MESSAGESENT = content; return content; },
+                unban: async () => { USERSUNBANNED++; },
+            };
+        },
+    };
+    const cs = {
+        GetRoomIdsFromChannel: async (chan) => {
+            return [`#${chan.id}:localhost`];
+        },
+    };
+    const discord = {
+        ChannelSyncroniser: cs,
+    };
+    const discordCommandHndlr = (Proxyquire("../src/discordcommandhandler", {
+        "./util": {
+            Util: {
+                GetMxidFromName: () => {
+                    return "@123456:localhost";
+                },
+                ParseCommand: Util.ParseCommand,
+            },
+        },
+    })).DiscordCommandHandler;
+    return new discordCommandHndlr(bridge as any, discord as any);
+}
+
+describe("DiscordCommandHandler", () => {
+    it("will kick a member", async () => {
+        const handler: any = createCH();
+        const channel = new MockChannel("123");
+        const guild = new MockGuild("456", [channel]);
+        channel.guild = guild;
+        const member: any = new MockMember("123456", "blah");
+        member.hasPermission = () => {
+            return true;
+        };
+        const message = {
+            channel,
+            content: "!matrix kick someuser",
+            member,
+        };
+        await handler.Process(message);
+        expect(USERSKICKED).equals(1);
+    });
+    it("will kick a member in all guild rooms", async () => {
+        const handler: any = createCH();
+        const channel = new MockChannel("123");
+        const guild = new MockGuild("456", [channel, (new MockChannel("456"))]);
+        channel.guild = guild;
+        const member: any = new MockMember("123456", "blah");
+        member.hasPermission = () => {
+            return true;
+        };
+        const message = {
+            channel,
+            content: "!matrix kick someuser",
+            member,
+        };
+        await handler.Process(message);
+        // tslint:disable-next-line:no-magic-numbers
+        expect(USERSKICKED).equals(2);
+    });
+    it("will deny permission", async () => {
+        const handler: any = createCH();
+        const channel = new MockChannel("123");
+        const guild = new MockGuild("456", [channel]);
+        channel.guild = guild;
+        const member: any = new MockMember("123456", "blah");
+        member.hasPermission = () => {
+            return false;
+        };
+        const message = {
+            channel,
+            content: "!matrix kick someuser",
+            member,
+        };
+        await handler.Process(message);
+        expect(USERSKICKED).equals(0);
+    });
+    it("will ban a member", async () => {
+        const handler: any = createCH();
+        const channel = new MockChannel("123");
+        const guild = new MockGuild("456", [channel]);
+        channel.guild = guild;
+        const member: any = new MockMember("123456", "blah");
+        member.hasPermission = () => {
+            return true;
+        };
+        const message = {
+            channel,
+            content: "!matrix ban someuser",
+            member,
+        };
+        await handler.Process(message);
+        expect(USERSBANNED).equals(1);
+    });
+    it("will unban a member", async () => {
+        const handler: any = createCH();
+        const channel = new MockChannel("123");
+        const guild = new MockGuild("456", [channel]);
+        channel.guild = guild;
+        const member: any = new MockMember("123456", "blah");
+        member.hasPermission = () => {
+            return true;
+        };
+        const message = {
+            channel,
+            content: "!matrix unban someuser",
+            member,
+        };
+        await handler.Process(message);
+        expect(USERSUNBANNED).equals(1);
+    });
+});
diff --git a/test/test_matrixcommandhandler.ts b/test/test_matrixcommandhandler.ts
index 3468a4b3a69df899609f97b80d319db940a500ae..70359d79ea92db5e15064a97fed075edc9589f11 100644
--- a/test/test_matrixcommandhandler.ts
+++ b/test/test_matrixcommandhandler.ts
@@ -1,3 +1,19 @@
+/*
+Copyright 2019 matrix-appservice-discord
+
+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 Chai from "chai";
 import { Util } from "../src/util";
 import { DiscordBridgeConfig } from "../src/config";
@@ -99,19 +115,19 @@ function createCH(opts: any = {}) {
                 },
                 GetBotLink: Util.GetBotLink,
                 ParseCommand: Util.ParseCommand,
-            }
-        }
+            },
+        },
     })).MatrixCommandHandler;
     return new MatrixCommandHndl(bot as any, bridge, config);
 }
 
-function createEvent(msg: string, room?: string, user_id?: string) {
+function createEvent(msg: string, room?: string, userId?: string) {
     return {
         content: {
             body: msg,
         },
         room_id: room ? room : "!123:localhost",
-        sender: user_id,
+        sender: userId,
     };
 }
 
@@ -133,14 +149,16 @@ describe("MatrixCommandHandler", () => {
         it("should warn if self service is disabled", async () => {
             const handler: any = createCH({disableSS: true});
             await handler.Process(createEvent("!discord bridge"), createContext());
-            expect(MESSAGESENT.body).to.equal("**ERROR:** The owner of this bridge does not permit self-service bridging.");
+            expect(MESSAGESENT.body).to.equal("**ERROR:** The owner of this bridge does " +
+                "not permit self-service bridging.");
         });
         it("should warn if user is not powerful enough", async () => {
             const handler: any = createCH({
                 power: false,
             });
             await handler.Process(createEvent("!discord bridge"), createContext());
-            expect(MESSAGESENT.body).to.equal("**ERROR:** insufficiant permissions to use this command! Try `!discord help` to see all available commands");
+            expect(MESSAGESENT.body).to.equal("**ERROR:** insufficiant permissions to use this " +
+                "command! Try `!discord help` to see all available commands");
         });
         describe("!discord bridge", () => {
             it("will bridge a new room, and ask for permissions", async () => {
@@ -184,7 +202,7 @@ describe("MatrixCommandHandler", () => {
         describe("!discord unbridge", () => {
             it("will unbridge", async () => {
                 const handler: any = createCH();
-                await handler.Process(createEvent("!discord unbridge"), createContext({data:{plumbed:true}}));
+                await handler.Process(createEvent("!discord unbridge"), createContext({data: {plumbed: true}}));
                 expect(MESSAGESENT.body).equals("This room has been unbridged");
             });
             it("will not unbridge if a link does not exist", async () => {
@@ -194,14 +212,14 @@ describe("MatrixCommandHandler", () => {
             });
             it("will not unbridge non-plumbed rooms", async () => {
                 const handler: any = createCH();
-                await handler.Process(createEvent("!discord unbridge"), createContext({data:{plumbed:false}}));
+                await handler.Process(createEvent("!discord unbridge"), createContext({data: {plumbed: false}}));
                 expect(MESSAGESENT.body).equals("This room cannot be unbridged.");
             });
             it("will show error if unbridge fails", async () => {
                 const handler: any = createCH({
                     failUnbridge: true,
                 });
-                await handler.Process(createEvent("!discord unbridge"), createContext({data:{plumbed:true}}));
+                await handler.Process(createEvent("!discord unbridge"), createContext({data: {plumbed: true}}));
                 expect(MESSAGESENT.body).to.contain("There was an error unbridging this room.");
             });
         });
diff --git a/test/test_matrixeventprocessor.ts b/test/test_matrixeventprocessor.ts
index eefa16106ec3cb60dc45886d4726299950a33e08..a5d109b5b78402eea68858b1d5615683e5a51d49 100644
--- a/test/test_matrixeventprocessor.ts
+++ b/test/test_matrixeventprocessor.ts
@@ -89,7 +89,6 @@ let STATE_EVENT_MSG = "";
 let USERSYNC_HANDLED = false;
 let MESSAGE_PROCCESS = "";
 let KICKBAN_HANDLED = false;
-let COMMAND_PROCESSED = false;
 
 function createMatrixEventProcessor(): MatrixEventProcessor {
     USERSYNC_HANDLED = false;
diff --git a/test/test_matrixroomhandler.ts b/test/test_matrixroomhandler.ts
index 4c5de12bb552fc923823a55044857f3531b394ad..d8fa8d04ab87923b35586e366cb775d55d3fe894 100644
--- a/test/test_matrixroomhandler.ts
+++ b/test/test_matrixroomhandler.ts
@@ -1,5 +1,5 @@
 /*
-Copyright 2018 matrix-appservice-discord
+Copyright 2018, 2019 matrix-appservice-discord
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
@@ -16,10 +16,10 @@ limitations under the License.
 
 import * as Chai from "chai";
 import * as Proxyquire from "proxyquire";
-import {DiscordBridgeConfig} from "../src/config";
-import {MockChannel} from "./mocks/channel";
-import {MockMember} from "./mocks/member";
-import {MockGuild} from "./mocks/guild";
+import { DiscordBridgeConfig } from "../src/config";
+import { MockChannel } from "./mocks/channel";
+import { MockMember } from "./mocks/member";
+import { MockGuild } from "./mocks/guild";
 import { Util } from "../src/util";
 
 // we are a test file and thus need those
@@ -54,6 +54,7 @@ function createRH(opts: any = {}) {
     USERSKICKED = 0;
     USERSBANNED = 0;
     USERSUNBANNED = 0;
+    MESSAGESENT = {};
     USERSYNC_HANDLED = false;
     KICKBAN_HANDLED = false;
     MESSAGE_PROCCESS = "";
@@ -354,92 +355,4 @@ describe("MatrixRoomHandler", () => {
             expect(roomOpts.creationOpts).to.exist;
         });
     });
-    describe("HandleDiscordCommand", () => {
-        it("will kick a member", async () => {
-            const handler: any = createRH({});
-            const channel = new MockChannel("123");
-            const guild = new MockGuild("456", [channel]);
-            channel.guild = guild;
-            const member: any = new MockMember("123456", "blah");
-            member.hasPermission = () => {
-                return true;
-            };
-            const message = {
-                channel,
-                content: "!matrix kick someuser",
-                member,
-            };
-            await handler.HandleDiscordCommand(message);
-            expect(USERSKICKED).equals(1);
-        });
-        it("will kick a member in all guild rooms", async () => {
-            const handler: any = createRH({});
-            const channel = new MockChannel("123");
-            const guild = new MockGuild("456", [channel, (new MockChannel("456"))]);
-            channel.guild = guild;
-            const member: any = new MockMember("123456", "blah");
-            member.hasPermission = () => {
-                return true;
-            };
-            const message = {
-                channel,
-                content: "!matrix kick someuser",
-                member,
-            };
-            await handler.HandleDiscordCommand(message);
-            // tslint:disable-next-line:no-magic-numbers
-            expect(USERSKICKED).equals(2);
-        });
-        it("will deny permission", async () => {
-            const handler: any = createRH({});
-            const channel = new MockChannel("123");
-            const guild = new MockGuild("456", [channel]);
-            channel.guild = guild;
-            const member: any = new MockMember("123456", "blah");
-            member.hasPermission = () => {
-                return false;
-            };
-            const message = {
-                channel,
-                content: "!matrix kick someuser",
-                member,
-            };
-            await handler.HandleDiscordCommand(message);
-            expect(USERSKICKED).equals(0);
-        });
-        it("will ban a member", async () => {
-            const handler: any = createRH({});
-            const channel = new MockChannel("123");
-            const guild = new MockGuild("456", [channel]);
-            channel.guild = guild;
-            const member: any = new MockMember("123456", "blah");
-            member.hasPermission = () => {
-                return true;
-            };
-            const message = {
-                channel,
-                content: "!matrix ban someuser",
-                member,
-            };
-            await handler.HandleDiscordCommand(message);
-            expect(USERSBANNED).equals(1);
-        });
-        it("will unban a member", async () => {
-            const handler: any = createRH({});
-            const channel = new MockChannel("123");
-            const guild = new MockGuild("456", [channel]);
-            channel.guild = guild;
-            const member: any = new MockMember("123456", "blah");
-            member.hasPermission = () => {
-                return true;
-            };
-            const message = {
-                channel,
-                content: "!matrix unban someuser",
-                member,
-            };
-            await handler.HandleDiscordCommand(message);
-            expect(USERSUNBANNED).equals(1);
-        });
-    });
 });
diff --git a/test/test_util.ts b/test/test_util.ts
index 70c8d7b57a7c8572d45155ce9c114f4e18973c4a..5f294efe3f2b63137e7494bbcc39366f3feb4115 100644
--- a/test/test_util.ts
+++ b/test/test_util.ts
@@ -1,5 +1,5 @@
 /*
-Copyright 2018 matrix-appservice-discord
+Copyright 2018, 2019 matrix-appservice-discord
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.