diff --git a/server/client.ts b/server/client.ts index d5ffe84e..f09a5328 100644 --- a/server/client.ts +++ b/server/client.ts @@ -6,7 +6,7 @@ import crypto from "crypto"; import colors from "chalk"; import log from "./log"; -import Chan, {Channel, ChanType} from "./models/chan"; +import Chan, {ChanConfig, Channel, ChanType} from "./models/chan"; import Msg, {MessageType, UserInMessage} from "./models/msg"; import Config from "./config"; import {condensedTypes} from "../shared/irc"; @@ -251,11 +251,13 @@ class Client { let channels: Chan[] = []; if (Array.isArray(args.channels)) { - let badName = false; + let badChanConf = false; - args.channels.forEach((chan: Chan) => { - if (!chan.name) { - badName = true; + args.channels.forEach((chan: ChanConfig) => { + const type = ChanType[(chan.type || "channel").toUpperCase()]; + + if (!chan.name || !type) { + badChanConf = true; return; } @@ -263,13 +265,13 @@ class Client { client.createChannel({ name: chan.name, key: chan.key || "", - type: chan.type, + type: type, muted: chan.muted, }) ); }); - if (badName && client.name) { + if (badChanConf && client.name) { log.warn( "User '" + client.name + diff --git a/test/client.ts b/test/client.ts new file mode 100644 index 00000000..622f47df --- /dev/null +++ b/test/client.ts @@ -0,0 +1,110 @@ +import {expect} from "chai"; +import {NetworkConfig} from "../server/models/network"; +import {ChanConfig, ChanType} from "../server/models/chan"; +import ClientManager from "../server/clientManager"; +import Client from "../server/client"; +import log from "../server/log"; + +import sinon from "ts-sinon"; + +describe("Client", function () { + const commonNetworkConfig: NetworkConfig = { + uuid: "67363f03-d903-498b-8e52-031ebb912791", + awayMessage: "", + name: "Super Nice Network", + nick: "thelounge0001", + host: "example.org", + port: 6667, + tls: false, + userDisconnected: false, + rejectUnauthorized: true, + password: "", + username: "thelounge", + realname: "thelounge26", + leaveMessage: "", + sasl: "", + saslAccount: "", + saslPassword: "", + commands: [], + ignoreList: [], + proxyHost: "", + proxyPort: 1080, + proxyUsername: "", + proxyEnabled: false, + proxyPassword: "", + channels: [], + }; + let logWarnStub: sinon.SinonStub; + + before(function () { + logWarnStub = sinon.stub(log, "warn"); + }); + + after(function () { + logWarnStub.restore(); + }); + + it("should parse channel configuration", function () { + const manager = new ClientManager(); + const channel: ChanConfig = {name: "AAAA!", type: "query"}; + const networkConfig: NetworkConfig = { + ...commonNetworkConfig, + channels: [{name: "AAAA!", type: "query"}, {name: "#thelounge"}, {name: "&foobar"}], + }; + const client = new Client(manager, "test", { + log: false, + password: "foo", + sessions: {}, + clientSettings: {}, + networks: [networkConfig], + }); + + // The client would normally do it as part of client.connect(); + // but this avoids the need to mock the irc-framework connection + const network = client.networkFromConfig(networkConfig); + + sinon.assert.notCalled(logWarnStub); + + expect(network.channels[0].name).to.equal("Super Nice Network"); + expect(network.channels[0].type).to.equal(ChanType.LOBBY); + expect(network.channels[1].name).to.equal("AAAA!"); + expect(network.channels[1].type).to.equal(ChanType.QUERY); + expect(network.channels[2].name).to.equal("#thelounge"); + expect(network.channels[2].type).to.equal(ChanType.CHANNEL); + expect(network.channels[3].name).to.equal("&foobar"); + expect(network.channels[3].type).to.equal(ChanType.CHANNEL); + }); + + it("should ignore invalid channel types", function () { + const manager = new ClientManager(); + const channel: ChanConfig = {name: "AAAA!", type: "query"}; + const networkConfig: NetworkConfig = { + ...commonNetworkConfig, + channels: [ + {name: "AAAA!", type: "query"}, + {name: "#thelounge", type: "wrongtype"}, + {name: "&foobar"}, + ], + }; + const client = new Client(manager, "test", { + log: false, + password: "foo", + sessions: {}, + clientSettings: {}, + networks: [networkConfig], + }); + + // The client would normally do it as part of client.connect(); + // but this avoids the need to mock the irc-framework connection + const network = client.networkFromConfig(networkConfig); + + sinon.assert.calledOnce(logWarnStub); + + expect(network.channels[0].name).to.equal("Super Nice Network"); + expect(network.channels[0].type).to.equal(ChanType.LOBBY); + expect(network.channels[1].name).to.equal("AAAA!"); + expect(network.channels[1].type).to.equal(ChanType.QUERY); + expect(network.channels[2].name).to.equal("&foobar"); + expect(network.channels[2].type).to.equal(ChanType.CHANNEL); + }); +});