diff --git a/src/config.ts b/src/config.ts
index 1488f307fce28c7683a0fbc13ff928d4557e810f..0db41c76f83a6c0da6fc2e5ea7ff1dad84026952 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -1,11 +1,11 @@
 /** Type annotations for config/config.schema.yaml */
-
 export class DiscordBridgeConfig {
   public bridge: DiscordBridgeConfigBridge = new DiscordBridgeConfigBridge();
   public auth: DiscordBridgeConfigAuth = new DiscordBridgeConfigAuth();
   public logging: DiscordBridgeConfigLogging = new DiscordBridgeConfigLogging();
   public database: DiscordBridgeConfigDatabase = new DiscordBridgeConfigDatabase();
   public room: DiscordBridgeConfigRoom = new DiscordBridgeConfigRoom();
+  public limits: DiscordBridgeConfigLimits = new DiscordBridgeConfigLimits();
 }
 
 class DiscordBridgeConfigBridge {
@@ -37,3 +37,7 @@ class DiscordBridgeConfigLogging {
 class DiscordBridgeConfigRoom {
   public defaultVisibility: string;
 }
+
+class DiscordBridgeConfigLimits {
+  public roomGhostJoinDelay: number = 6000;
+}
diff --git a/src/matrixroomhandler.ts b/src/matrixroomhandler.ts
index cee2ea5aa33448a414c56c025d34d90a90942529..13940185d67467539f9e0098c21094ae30dd93e2 100644
--- a/src/matrixroomhandler.ts
+++ b/src/matrixroomhandler.ts
@@ -17,7 +17,6 @@ import { Util } from "./util";
 import { Provisioner } from "./provisioner";
 
 const ICON_URL = "https://matrix.org/_matrix/media/r0/download/matrix.org/mlxoESwIsTbJrfXyAAogrNxA";
-const JOIN_DELAY = 6000;
 const HTTP_UNSUPPORTED = 501;
 const ROOM_NAME_PARTS = 2;
 const AGE_LIMIT = 900000; // 15 * 60 * 1000
@@ -65,7 +64,8 @@ export class MatrixRoomHandler {
   public OnAliasQueried (alias: string, roomId: string) {
     // Join a whole bunch of users.
     let promiseChain: any = Bluebird.resolve();
-    let delay = JOIN_DELAY; /* We delay the joins to give some implmentations a chance to breathe */
+    /* We delay the joins to give some implementations a chance to breathe */
+    let delay = this.config.limits.roomGhostJoinDelay;
     return this.discord.GetChannelFromRoomId(roomId).then((channel: Discord.Channel) => {
       for (const member of (<Discord.TextChannel> channel).guild.members.array()) {
         if (member.id === this.discord.GetBotId()) {
@@ -74,7 +74,7 @@ export class MatrixRoomHandler {
         promiseChain = promiseChain.return(Bluebird.delay(delay).then(() => {
           return this.discord.InitJoinUser(member, [roomId]);
         }));
-        delay += JOIN_DELAY;
+        delay += this.config.limits.roomGhostJoinDelay;
       }
     }).catch((err) => {
       log.verbose("OnAliasQueried => %s", err);
diff --git a/test/test_matrixroomhandler.ts b/test/test_matrixroomhandler.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a47fb07588818e9ade624b48a8c454381c23973c
--- /dev/null
+++ b/test/test_matrixroomhandler.ts
@@ -0,0 +1,75 @@
+import * as Chai from "chai";
+import * as ChaiAsPromised from "chai-as-promised";
+import * as Proxyquire from "proxyquire";
+import {DiscordBridgeConfig} from "../src/config";
+import {MockDiscordClient} from "./mocks/discordclient";
+import * as log from "npmlog";
+import {PresenceHandler} from "../src/presencehandler";
+import {DiscordBot} from "../src/bot";
+import {MatrixRoomHandler} from "../src/matrixroomhandler";
+import {MockChannel} from "./mocks/channel";
+import {MockMember} from "./mocks/member";
+
+Chai.use(ChaiAsPromised);
+const expect = Chai.expect;
+
+// const DiscordClientFactory = Proxyquire("../src/clientfactory", {
+//     "discord.js": { Client: require("./mocks/discordclient").MockDiscordClient },
+// }).DiscordClientFactory;
+
+let USERSJOINED = 0;
+
+function createRH(opts: any = {}) {
+    USERSJOINED = 0;
+    const bot = {
+        GetChannelFromRoomId: (roomid: string) => {
+            if (roomid === "!accept:localhost") {
+                const chan = new MockChannel();
+                if (opts.createMembers) {
+                    chan.members.set("12345", new MockMember("12345", "testuser1"));
+                    chan.members.set("54321", new MockMember("54321", "testuser2"));
+                    chan.members.set("bot12345", new MockMember("bot12345", "botuser"));
+                }
+                return Promise.resolve(chan);
+            } else {
+                return Promise.reject("Roomid not found");
+            }
+        },
+        InitJoinUser: (member: MockMember, roomids: string[]) => {
+                if (opts.failUser) {
+                    return Promise.reject("test is rejecting joins");
+                }
+                USERSJOINED++;
+                return Promise.resolve();
+
+        },
+        GetBotId: () => "bot12345",
+    };
+    const config = new DiscordBridgeConfig();
+    config.limits.roomGhostJoinDelay = 0;
+    const provisioner = null;
+    return new MatrixRoomHandler(bot as any, config, "@botuser:localhost", provisioner);
+}
+
+describe("MatrixRoomHandler", () => {
+    describe("OnAliasQueried", () => {
+        it("should join successfully", () => {
+            const handler = createRH();
+            return handler.OnAliasQueried("#accept:localhost", "!accept:localhost")
+                .then(() => {
+                    // test for something
+                    return true;
+            });
+        });
+        it("should join successfully and create ghosts", () => {
+            const EXPECTEDUSERS = 2;
+            const handler = createRH({createMembers: true});
+            return handler.OnAliasQueried("#accept:localhost", "!accept:localhost")
+                .then(() => {
+                    expect(USERSJOINED).to.equal(EXPECTEDUSERS);
+                    // test for something
+                    return true;
+                });
+        });
+    });
+});