From a629150cc7082c113096f46e49740ec3641633fa Mon Sep 17 00:00:00 2001
From: Will Hunt <will@half-shot.uk>
Date: Wed, 16 May 2018 16:27:31 +0100
Subject: [PATCH] Complete ClientFactory tests
---
src/clientfactory.ts | 21 +++----
test/mocks/discordclient.ts | 18 ++++--
test/test_clientfactory.ts | 110 ++++++++++++++++++++++++++++++++++++
test/test_discordbot.ts | 2 +-
4 files changed, 134 insertions(+), 17 deletions(-)
create mode 100644 test/test_clientfactory.ts
diff --git a/src/clientfactory.ts b/src/clientfactory.ts
index ec842ec..7055ccf 100644
--- a/src/clientfactory.ts
+++ b/src/clientfactory.ts
@@ -17,7 +17,7 @@ export class DiscordClientFactory {
this.store = store;
}
- public init(): Promise<null> {
+ public async init(): Promise<void> {
if (this.config === undefined) {
return Promise.reject("Client config not supplied.");
}
@@ -28,12 +28,12 @@ export class DiscordClientFactory {
sync: true,
messageCacheLifetime: 5,
}));
- this.botClient.login(this.config.botToken);
- return this.botClient.onAsync("ready")
- .timeout(READY_TIMEOUT, "Bot timed out waiting for ready.")
- .catch((err) => {
- log.error("ClientFactory", "Could not login as the bot user. This is bad!", err);
- throw err;
+ return Bluebird.all([
+ this.botClient.onAsync("ready").timeout(READY_TIMEOUT, "Bot timed out waiting for ready."),
+ this.botClient.login(this.config.botToken),
+ ]).then(() => { return; }).catch((err) => {
+ log.error("ClientFactory", "Could not login as the bot user. This is bad!", err);
+ throw err;
});
}
@@ -44,15 +44,15 @@ export class DiscordClientFactory {
messageCacheLifetime: 5,
});
return new Bluebird<string>((resolve, reject) => {
- client.login(token).catch(reject);
client.on("ready", () => {
const id = client.user.id;
client.destroy();
resolve(id);
});
+ client.login(token).catch(reject);
}).timeout(READY_TIMEOUT).catch((err: Error) => {
log.warn("ClientFactory", "Could not login as a normal user. '%s'", err.message);
- throw Error("Could not retrive ID");
+ throw Error("Could not retrieve ID");
});
}
@@ -81,7 +81,8 @@ export class DiscordClientFactory {
this.clients.set(userId, client);
return client;
} catch (err) {
- log.warn("ClientFactory", `Could not log ${userId} in.`, err);
+ log.warn("ClientFactory", `Could not log ${userId} in. Returning bot user for now.`, err);
+ return this.botClient;
}
}
}
diff --git a/test/mocks/discordclient.ts b/test/mocks/discordclient.ts
index 71ffef6..d431ebf 100644
--- a/test/mocks/discordclient.ts
+++ b/test/mocks/discordclient.ts
@@ -6,7 +6,7 @@ export class MockDiscordClient {
public guilds = new MockCollection<string, MockGuild>();
public user: MockUser;
private testLoggedIn: boolean = false;
- private testCallbacks: Array<() => void> = [];
+ private testCallbacks: Map<string, () => void> = new Map();
constructor() {
const channels = [
@@ -31,13 +31,19 @@ export class MockDiscordClient {
}
public on(event: string, callback: () => void) {
- if (event === "ready") {
- this.testCallbacks[0] = callback;
- }
+ this.testCallbacks.set(event, callback);
}
- public login(token: string) {
+ public async login(token: string): Promise<void> {
+ if (token !== "passme") {
+ throw new Error("Mock Discord Client only logins with the token 'passme'");
+ }
this.testLoggedIn = true;
- this.testCallbacks[0]();
+ if (this.testCallbacks.has("ready")) {
+ this.testCallbacks.get("ready")();
+ }
+ return;
}
+
+ public destroy() { } // no-op
}
diff --git a/test/test_clientfactory.ts b/test/test_clientfactory.ts
new file mode 100644
index 0000000..7219626
--- /dev/null
+++ b/test/test_clientfactory.ts
@@ -0,0 +1,110 @@
+import * as Chai from "chai";
+import * as ChaiAsPromised from "chai-as-promised";
+import * as Proxyquire from "proxyquire";
+import {DiscordBridgeConfigAuth} from "../src/config";
+import {MockDiscordClient} from "./mocks/discordclient";
+import * as log from "npmlog";
+
+Chai.use(ChaiAsPromised);
+const expect = Chai.expect;
+
+const DiscordClientFactory = Proxyquire("../src/clientfactory", {
+ "discord.js": { Client: require("./mocks/discordclient").MockDiscordClient },
+}).DiscordClientFactory;
+
+const STORE = {
+ get_user_discord_ids: (userid: string) => {
+ if (userid === "@valid:localhost") {
+ return Promise.resolve(["12345"]);
+ } else if (userid === "@invalid:localhost") {
+ return Promise.resolve(["1234555"]);
+ }
+ return Promise.resolve([]);
+ },
+ get_token: (discordid: string) => {
+ if (discordid === "12345") {
+ return Promise.resolve("passme");
+ } else if (discordid === "1234555") {
+ return Promise.resolve("failme");
+ }
+ return Promise.reject("Token not found");
+ },
+};
+
+describe("ClientFactory", () => {
+ describe("init", () => {
+ it ("should start successfully", () => {
+ const config = new DiscordBridgeConfigAuth();
+ config.botToken = "passme";
+ const cf = new DiscordClientFactory(null, config);
+ return expect(cf.init()).to.eventually.be.fulfilled;
+ });
+ it ("should fail if a config is not supplied", () => {
+ log.level = "silent";
+ const cf = new DiscordClientFactory(null);
+ return expect(cf.init()).to.eventually.be.rejected;
+ });
+ it ("should fail if the bot fails to connect", () => {
+ log.level = "silent";
+ const config = new DiscordBridgeConfigAuth();
+ config.botToken = "failme";
+ const cf = new DiscordClientFactory(null, config);
+ return expect(cf.init()).to.eventually.be.rejected;
+ });
+ });
+ describe("getDiscordId", () => {
+ it("should fetch id successfully", () => {
+ const config = new DiscordBridgeConfigAuth();
+ const cf = new DiscordClientFactory(null);
+ return expect(cf.getDiscordId("passme")).to.eventually.equal("12345");
+ });
+ it("should fail if the token is not recognised", () => {
+ log.level = "silent";
+ const config = new DiscordBridgeConfigAuth();
+ const cf = new DiscordClientFactory(null);
+ return expect(cf.getDiscordId("failme")).to.eventually.be.rejected;
+ });
+ });
+ describe("getClient", () => {
+ it("should fetch bot client successfully", () => {
+ const config = new DiscordBridgeConfigAuth();
+ config.botToken = "passme";
+ const cf = new DiscordClientFactory(null, config);
+ cf.botClient = 1;
+ return expect(cf.getClient()).to.eventually.equal(cf.botClient);
+ });
+ it("should return cached client", () => {
+ log.level = "silent";
+ const config = new DiscordBridgeConfigAuth();
+ const cf = new DiscordClientFactory(null);
+ cf.clients.set("@user:localhost", "testclient");
+ return expect(cf.getClient("@user:localhost")).to.eventually.equal("testclient");
+ });
+ it("should fetch bot client if userid doesn't match", () => {
+ log.level = "silent";
+ const config = new DiscordBridgeConfigAuth();
+ const cf = new DiscordClientFactory(STORE);
+ cf.botClient = 1;
+ return expect(cf.getClient("@user:localhost")).to.eventually.equal(cf.botClient);
+ });
+ it("should fetch user client if userid matches", () => {
+ log.level = "silent";
+ const config = new DiscordBridgeConfigAuth();
+ const cf = new DiscordClientFactory(STORE);
+ return cf.getClient("@valid:localhost").then((client) => {
+ expect(client).is.not.null;
+ expect(cf.clients.has("@valid:localhost")).to.be.true;
+ });
+ });
+ it("should fail if the user client cannot log in", () => {
+ log.level = "silent";
+ const config = new DiscordBridgeConfigAuth();
+ const cf = new DiscordClientFactory(STORE);
+ cf.botClient = 1;
+ return cf.getClient("@invalid:localhost").then((client) => {
+ expect(client).to.equal(cf.botClient);
+ expect(cf.clients.has("@invalid:localhost")).to.be.false;
+ });
+ });
+ });
+});
diff --git a/test/test_discordbot.ts b/test/test_discordbot.ts
index c11d8a5..95855e7 100644
--- a/test/test_discordbot.ts
+++ b/test/test_discordbot.ts
@@ -25,7 +25,7 @@ const mockBridge = {
};
},
getIntentFromLocalpart: (localpart: string) => {
- return{
+ return {
sendTyping: (room: string, isTyping: boolean) => {
return;
},
--
GitLab