diff --git a/lib/components/intent.js b/lib/components/intent.js index 4b2dc8ab..2486a3d7 100644 --- a/lib/components/intent.js +++ b/lib/components/intent.js @@ -1,5 +1,4 @@ "use strict"; -const Promise = require("bluebird"); const MatrixUser = require("../models/users/matrix"); const MatrixEvent = require("matrix-js-sdk").MatrixEvent; const RoomMember = require("matrix-js-sdk").RoomMember; @@ -57,7 +56,8 @@ const DEFAULT_CACHE_SIZE = 1024; * @param {Number} opts.caching.ttl How long requests can stay in the cache, in milliseconds. * @param {Number} opts.caching.size How many entries should be kept in the cache, before the oldest is dropped. */ -function Intent(client, botClient, opts) { +class Intent { +constructor(client, botClient, opts) { this.client = client; this.botClient = botClient; opts = opts || {}; @@ -79,26 +79,25 @@ function Intent(client, botClient, opts) { this._powerLevels = { // room_id: event.content }; - var self = this; opts.backingStore = { - getMembership: function(roomId, userId) { - if (userId !== self.client.credentials.userId) { + getMembership: (roomId, userId) => { + if (userId !== this.client.credentials.userId) { return null; } - return self._membershipStates[roomId]; + return this._membershipStates[roomId]; }, - setMembership: function(roomId, userId, membership) { - if (userId !== self.client.credentials.userId) { + setMembership: (roomId, userId, membership) => { + if (userId !== this.client.credentials.userId) { return; } - self._membershipStates[roomId] = membership; + this._membershipStates[roomId] = membership; }, - setPowerLevelContent: function(roomId, content) { - self._powerLevels[roomId] = content; + setPowerLevelContent: (roomId, content) => { + this._powerLevels[roomId] = content; }, - getPowerLevelContent: function(roomId) { - return self._powerLevels[roomId]; + getPowerLevelContent: (roomId) => { + return this._powerLevels[roomId]; } } } @@ -139,9 +138,9 @@ function Intent(client, botClient, opts) { * Return the client this Intent is acting on behalf of. * @return {MatrixClient} The client */ -Intent.prototype.getClient = function() { +getClient() { return this.client; -}; +} /** *

Send a plaintext message to a room.

@@ -152,12 +151,12 @@ Intent.prototype.getClient = function() { * @param {string} text The text string to send. * @return {Promise} */ -Intent.prototype.sendText = function(roomId, text) { +async sendText(roomId, text) { return this.sendMessage(roomId, { body: text, msgtype: "m.text" }); -}; +} /** *

Set the name of a room.

@@ -168,11 +167,11 @@ Intent.prototype.sendText = function(roomId, text) { * @param {string} name The room name. * @return {Promise} */ -Intent.prototype.setRoomName = function(roomId, name) { +async setRoomName(roomId, name) { return this.sendStateEvent(roomId, "m.room.name", "", { name: name }); -}; +} /** *

Set the topic of a room.

@@ -183,11 +182,11 @@ Intent.prototype.setRoomName = function(roomId, name) { * @param {string} topic The room topic. * @return {Promise} */ -Intent.prototype.setRoomTopic = function(roomId, topic) { +async setRoomTopic(roomId, topic) { return this.sendStateEvent(roomId, "m.room.topic", "", { topic: topic }); -}; +} /** *

Set the avatar of a room.

@@ -199,7 +198,7 @@ Intent.prototype.setRoomTopic = function(roomId, topic) { * @param {string} info Extra information about the image. See m.room.avatar for details. * @return {Promise} */ -Intent.prototype.setRoomAvatar = function(roomId, avatar, info) { +async setRoomAvatar(roomId, avatar, info) { var content = { url: avatar }; @@ -207,7 +206,7 @@ Intent.prototype.setRoomAvatar = function(roomId, avatar, info) { content.info = info; } return this.sendStateEvent(roomId, "m.room.avatar", "", content); -}; +} /** *

Send a typing event to a room.

@@ -217,14 +216,11 @@ Intent.prototype.setRoomAvatar = function(roomId, avatar, info) { * @param {boolean} isTyping True if typing * @return {Promise} */ -Intent.prototype.sendTyping = function(roomId, isTyping) { - var self = this; - return self._ensureJoined(roomId).then(function() { - return self._ensureHasPowerLevelFor(roomId, "m.typing"); - }).then(function() { - return self.client.sendTyping(roomId, isTyping); - }); -}; +async sendTyping(roomId, isTyping) { + return this._ensureJoined(roomId) + .then(() => this._ensureHasPowerLevelFor(roomId, "m.typing")) + .then(() => this.client.sendTyping(roomId, isTyping)) +} /** *

Send a read receipt to a room.

@@ -234,15 +230,12 @@ Intent.prototype.sendTyping = function(roomId, isTyping) { * @param{string} eventId The event ID to set the receipt mark to. * @return {Promise} */ -Intent.prototype.sendReadReceipt = function(roomId, eventId) { - var self = this; +async sendReadReceipt(roomId, eventId) { var event = new MatrixEvent({ room_id: roomId, event_id: eventId, }); - return self._ensureJoined(roomId).then(function() { - return self.client.sendReadReceipt(event); - }); + return this._ensureJoined(roomId).then(() => this.client.sendReadReceipt(event)) } /** @@ -252,14 +245,11 @@ Intent.prototype.sendReadReceipt = function(roomId, eventId) { * @param {number} level The desired level * @return {Promise} */ -Intent.prototype.setPowerLevel = function(roomId, target, level) { - var self = this; - return self._ensureJoined(roomId).then(function() { - return self._ensureHasPowerLevelFor(roomId, "m.room.power_levels"); - }).then(function(event) { - return self.client.setPowerLevel(roomId, target, level, event); - }); -}; +async setPowerLevel(roomId, target, level) { + return this._ensureJoined(roomId) + .then(() => this._ensureHasPowerLevelFor(roomId, "m.room.power_levels")) + .then((event) => this.client.setPowerLevel(roomId, target, level, event)) +} /** *

Send an m.room.message event to a room.

@@ -270,9 +260,9 @@ Intent.prototype.setPowerLevel = function(roomId, target, level) { * @param {Object} content The event content * @return {Promise} */ -Intent.prototype.sendMessage = function(roomId, content) { +async sendMessage(roomId, content) { return this.sendEvent(roomId, "m.room.message", content); -}; +} /** *

Send a message event to a room.

@@ -284,14 +274,16 @@ Intent.prototype.sendMessage = function(roomId, content) { * @param {Object} content The event content * @return {Promise} */ -Intent.prototype.sendEvent = function(roomId, type, content) { - var self = this; - return self._ensureJoined(roomId).then(function() { - return self._ensureHasPowerLevelFor(roomId, type); - }).then(self._joinGuard(roomId, function() { - return self.client.sendEvent(roomId, type, content); - })); -}; +async sendEvent(roomId, type, content) { + return this._ensureJoined(roomId) + .then(() => this._ensureHasPowerLevelFor(roomId, type)) + .then( + this._joinGuard( + roomId, + () => this.client.sendEvent(roomId, type, content), + ), + ) +} /** *

Send a state event to a room.

@@ -304,14 +296,16 @@ Intent.prototype.sendEvent = function(roomId, type, content) { * @param {Object} content The event content * @return {Promise} */ -Intent.prototype.sendStateEvent = function(roomId, type, skey, content) { - var self = this; - return self._ensureJoined(roomId).then(function() { - return self._ensureHasPowerLevelFor(roomId, type); - }).then(self._joinGuard(roomId, function() { - return self.client.sendStateEvent(roomId, type, content, skey); - })); -}; +async sendStateEvent(roomId, type, skey, content) { + return this._ensureJoined(roomId) + .then(() => this._ensureHasPowerLevelFor(roomId, type)) + .then( + this._joinGuard( + roomId, + () => this.client.sendStateEvent(roomId, type, content, skey), + ), + ) +} /** *

Get the current room state for a room.

@@ -322,14 +316,14 @@ Intent.prototype.sendStateEvent = function(roomId, type, skey, content) { * state from the cache. * @return {Promise} */ -Intent.prototype.roomState = function(roomId, useCache=false) { +async roomState(roomId, useCache=false) { return this._ensureJoined(roomId).then(() => { if (useCache) { return this._requestCaches.roomstate.get(roomId); } return this.client.roomState(roomId); }); -}; +} /** * Create a room with a set of options. @@ -340,8 +334,7 @@ Intent.prototype.roomState = function(roomId, useCache=false) { * @param {Object} opts.options Options to pass to the client SDK /createRoom API. * @return {Promise} */ -Intent.prototype.createRoom = function(opts) { - var self = this; +async createRoom(opts) { var cli = opts.createAsClient ? this.client : this.botClient; var options = opts.options || {}; if (!opts.createAsClient) { @@ -357,17 +350,17 @@ Intent.prototype.createRoom = function(opts) { options.invite.splice(options.invite.indexOf(cli.credentials.userId), 1); } - return this._ensureRegistered().then(function() { + return this._ensureRegistered().then(() => { return cli.createRoom(options); - }).then(function(res) { + }).then((res) => { // create a fake power level event to give the room creator ops if we // don't yet have a power level event. - if (self.opts.backingStore.getPowerLevelContent(res.room_id)) { + if (this.opts.backingStore.getPowerLevelContent(res.room_id)) { return res; } var users = {}; users[cli.credentials.userId] = 100; - self.opts.backingStore.setPowerLevelContent(res.room_id, { + this.opts.backingStore.setPowerLevelContent(res.room_id, { users_default: 0, events_default: 0, state_default: 50, @@ -376,7 +369,7 @@ Intent.prototype.createRoom = function(opts) { }); return res; }); -}; +} /** *

Invite a user to a room.

@@ -386,12 +379,10 @@ Intent.prototype.createRoom = function(opts) { * @param {string} target The user ID to invite. * @return {Promise} Resolved when invited, else rejected with an error. */ -Intent.prototype.invite = function(roomId, target) { - var self = this; - return this._ensureJoined(roomId).then(function() { - return self.client.invite(roomId, target); - }); -}; +async invite(roomId, target) { + return this._ensureJoined(roomId) + .then(() => this.client.invite(roomId, target)) +} /** *

Kick a user from a room.

@@ -402,12 +393,10 @@ Intent.prototype.invite = function(roomId, target) { * @param {string} reason Optional. The reason for the kick. * @return {Promise} Resolved when kickked, else rejected with an error. */ -Intent.prototype.kick = function(roomId, target, reason) { - var self = this; - return this._ensureJoined(roomId).then(function() { - return self.client.kick(roomId, target, reason); - }); -}; +async kick(roomId, target, reason) { + return this._ensureJoined(roomId) + .then(() => this.client.kick(roomId, target, reason)) +} /** *

Ban a user from a room.

@@ -418,12 +407,10 @@ Intent.prototype.kick = function(roomId, target, reason) { * @param {string} reason Optional. The reason for the ban. * @return {Promise} Resolved when banned, else rejected with an error. */ -Intent.prototype.ban = function(roomId, target, reason) { - var self = this; - return this._ensureJoined(roomId).then(function() { - return self.client.ban(roomId, target, reason); - }); -}; +async ban(roomId, target, reason) { + return this._ensureJoined(roomId) + .then(() => this.client.ban(roomId, target, reason)) +} /** *

Unban a user from a room.

@@ -433,12 +420,9 @@ Intent.prototype.ban = function(roomId, target, reason) { * @param {string} target The target of the unban operation. * @return {Promise} Resolved when unbanned, else rejected with an error. */ -Intent.prototype.unban = function(roomId, target) { - var self = this; - return this._ensureJoined(roomId).then(function() { - return self.client.unban(roomId, target); - }); -}; +async unban(roomId, target) { + return this._ensureJoined(roomId).then(() => this.client.unban(roomId, target)) +} /** *

Join a room

@@ -449,9 +433,9 @@ Intent.prototype.unban = function(roomId, target) { * addition to those that are automatically chosen. * @return {Promise} */ -Intent.prototype.join = function(roomId, viaServers) { +async join(roomId, viaServers) { return this._ensureJoined(roomId, false, viaServers); -}; +} /** *

Leave a room

@@ -459,9 +443,9 @@ Intent.prototype.join = function(roomId, viaServers) { * @param {string} roomId The room to leave. * @return {Promise} */ -Intent.prototype.leave = function(roomId) { +async leave(roomId) { return this.client.leave(roomId); -}; +} /** *

Get a user's profile information

@@ -473,38 +457,32 @@ Intent.prototype.leave = function(roomId) { * @return {Promise} A Promise that resolves with the requested user's profile * information */ -Intent.prototype.getProfileInfo = function(userId, info, useCache=true) { +async getProfileInfo(userId, info, useCache=true) { return this._ensureRegistered().then(() => { if (useCache) { return this._requestCaches.profile.get(`${userId}:${info}`, userId, info); } return this.client.getProfileInfo(userId, info); }); -}; +} /** *

Set the user's display name

* @param {string} name The new display name * @return {Promise} */ -Intent.prototype.setDisplayName = function(name) { - var self = this; - return self._ensureRegistered().then(function() { - return self.client.setDisplayName(name); - }); -}; +async setDisplayName(name) { + return this._ensureRegistered().then(() => this.client.setDisplayName(name)) +} /** *

Set the user's avatar URL

* @param {string} url The new avatar URL * @return {Promise} */ -Intent.prototype.setAvatarUrl = function(url) { - var self = this; - return self._ensureRegistered().then(function() { - return self.client.setAvatarUrl(url); - }); -}; +async setAvatarUrl(url) { + return this._ensureRegistered().then(() => this.client.setAvatarUrl(url)) +} /** * Create a new alias mapping. @@ -512,12 +490,9 @@ Intent.prototype.setAvatarUrl = function(url) { * @param {string} roomId The room ID the alias should point at. * @return {Promise} */ -Intent.prototype.createAlias = function(alias, roomId) { - var self = this; - return self._ensureRegistered().then(function() { - return self.client.createAlias(alias, roomId); - }); -}; +async createAlias(alias, roomId) { + return this._ensureRegistered().then(() => this.client.createAlias(alias, roomId)) +} /** * Set the presence of this user. @@ -525,7 +500,7 @@ Intent.prototype.createAlias = function(alias, roomId) { * @param {string} status_msg The status message to attach. * @return {Promise} Resolves if the presence was set or no-oped, rejects otherwise. */ -Intent.prototype.setPresence = function(presence, status_msg=undefined) { +async setPresence(presence, status_msg=undefined) { if (!this.opts.enablePresence) { return Promise.resolve(); } @@ -533,7 +508,7 @@ Intent.prototype.setPresence = function(presence, status_msg=undefined) { return this._ensureRegistered().then(() => { return this.client.setPresence({presence, status_msg}); }); -}; +} /** * @typedef { @@ -558,7 +533,7 @@ Intent.prototype.setPresence = function(presence, status_msg=undefined) { * @param {string[]} affectedUsers Array of regex matching all affected users. * @return {Promise} */ -Intent.prototype.unstableSignalBridgeError = function( +async unstableSignalBridgeError( roomID, eventID, networkName, @@ -589,14 +564,14 @@ Intent.prototype.unstableSignalBridgeError = function( * @param {boolean} [useCache=true] Should the request attempt to lookup from the cache. * @return {Promise} Resolves with the content of the event, or rejects if not found. */ -Intent.prototype.getEvent = function(roomId, eventId, useCache=true) { +async getEvent(roomId, eventId, useCache=true) { return this._ensureRegistered().then(() => { if (useCache) { return this._requestCaches.event.get(`${roomId}:${eventId}`, roomId, eventId); } return this.client.fetchRoomEvent(roomId, eventId); }); -}; +} /** * Get a state event in a room. @@ -607,11 +582,10 @@ Intent.prototype.getEvent = function(roomId, eventId, useCache=true) { * @param {string} [stateKey=""] The state key of the event to fetch. * @return {Promise} */ -Intent.prototype.getStateEvent = function(roomId, eventType, stateKey = "") { - return this._ensureJoined(roomId).then(() => { - return this.client.getStateEvent(roomId, eventType, stateKey); - }); -}; +async getStateEvent(roomId, eventType, stateKey = "") { + return this._ensureJoined(roomId) + .then(() => this.client.getStateEvent(roomId, eventType, stateKey)) +} /** * Inform this Intent class of an incoming event. Various optimisations will be @@ -620,7 +594,7 @@ Intent.prototype.getStateEvent = function(roomId, eventType, stateKey = "") { * if a backing store was provided to the Intent. * @param {Object} event The incoming event JSON */ -Intent.prototype.onEvent = function(event) { +onEvent(event) { if (!this._membershipStates || !this._powerLevels) { return; } @@ -631,30 +605,28 @@ Intent.prototype.onEvent = function(event) { else if (event.type === "m.room.power_levels") { this._powerLevels[event.room_id] = event.content; } -}; +} // Guard a function which returns a promise which may reject if the user is not // in the room. If the promise rejects, join the room and retry the function. -Intent.prototype._joinGuard = function(roomId, promiseFn) { - var self = this; - return function() { - return promiseFn().catch(function(err) { +_joinGuard(roomId, promiseFn) { + return () => ( + promiseFn() + .catch((err) => { if (err.errcode !== "M_FORBIDDEN") { // not a guardable error throw err; } - return self._ensureJoined(roomId, true).then(function() { - return promiseFn(); - }) - }); - }; -}; + return this._ensureJoined(roomId, true) + .then(promiseFn) + }) + ) +} -Intent.prototype._ensureJoined = function( +async _ensureJoined ( roomId, ignoreCache = false, viaServers = undefined, passthroughError = false ) { - var self = this; - var userId = self.client.credentials.userId; + const userId = this.client.credentials.userId; const opts = { syncRoom: false, }; @@ -682,71 +654,64 @@ Intent.prototype._ensureJoined = function( FAIL (bot can't get into the room) */ - var d = new Promise.defer(); - - function mark(r, state) { - self.opts.backingStore.setMembership(r, userId, state); - if (state === "join") { - d.resolve(); + return new Promise((resolve, reject) => { + const mark = (r, state) => { + this.opts.backingStore.setMembership(r, userId, state); + if (state === "join") { + resolve(); + } } - } - var dontJoin = this.opts.dontJoin; - - self._ensureRegistered().done(function() { - if (dontJoin) { - d.resolve(); - return; - } + const dontJoin = this.opts.dontJoin; - self.client.joinRoom(roomId, opts).then(function() { - mark(roomId, "join"); - }, function(e) { - if (e.errcode !== "M_FORBIDDEN" || self.botClient === self) { - d.reject(passthroughError ? e : new Error("Failed to join room")); + this._ensureRegistered() + .then(() => { + if (dontJoin) { + resolve(); return; } - // Try bot inviting client - self.botClient.invite(roomId, userId).then(function() { - return self.client.joinRoom(roomId, opts); - }).done(function() { - mark(roomId, "join"); - }, function(invErr) { - // Try bot joining - self.botClient.joinRoom(roomId, opts) - .then(function() { - return self.botClient.invite(roomId, userId); - }).then(function() { - return self.client.joinRoom(roomId, opts); - }).done(function() { - mark(roomId, "join"); - }, function(finalErr) { - d.reject(passthroughError ? e : new Error("Failed to join room")); + this.client.joinRoom(roomId, opts) + .then(() => mark(roomId, "join")) + .catch((e) => { + if (e.errcode !== "M_FORBIDDEN" || this.botClient === this) { + reject(passthroughError ? e : new Error("Failed to join room")); return; - }); - }); - }); - }, function(e) { - d.reject(e); - }); + } - return d.promise; -}; + // Try bot inviting client + this.botClient.invite(roomId, userId) + .then(() => this.client.joinRoom(roomId, opts)) + .then(() => mark(roomId, "join")) + .catch((invErr) => { + // Try bot joining + this.botClient.joinRoom(roomId, opts) + .then(() => this.botClient.invite(roomId, userId)) + .then(() => this.client.joinRoom(roomId, opts)) + .then(() => mark(roomId, "join")) + .catch((finalErr) => + reject(passthroughError ? e : new Error("Failed to join room")) + ) + }) + }) + }, + (e) => reject(e) + ) + }); +} -Intent.prototype._ensureHasPowerLevelFor = function(roomId, eventType) { +_ensureHasPowerLevelFor(roomId, eventType) { if (this.opts.dontCheckPowerLevel && eventType !== "m.room.power_levels") { return Promise.resolve(); } - var self = this; var userId = this.client.credentials.userId; var plContent = this.opts.backingStore.getPowerLevelContent(roomId); var promise = Promise.resolve(plContent); if (!plContent) { promise = this.client.getStateEvent(roomId, "m.room.power_levels", ""); } - return promise.then(function(eventContent) { - self.opts.backingStore.setPowerLevelContent(roomId, eventContent); + return promise.then((eventContent) => { + this.opts.backingStore.setPowerLevelContent(roomId, eventContent); const event = { content: eventContent, room_id: roomId, @@ -769,7 +734,7 @@ Intent.prototype._ensureHasPowerLevelFor = function(roomId, eventType) { if (requiredLevel > roomMember.powerLevel) { // can the bot update our power level? - var bot = new RoomMember(roomId, self.botClient.credentials.userId); + var bot = new RoomMember(roomId, this.botClient.credentials.userId); bot.setPowerLevelEvent(powerLevelEvent); var levelRequiredToModifyPowerLevels = event.content.events[ "m.room.power_levels" @@ -784,9 +749,9 @@ Intent.prototype._ensureHasPowerLevelFor = function(roomId, eventType) { ); } // update the client's power level first - return self.botClient.setPowerLevel( + return this.botClient.setPowerLevel( roomId, userId, requiredLevel, powerLevelEvent - ).then(function() { + ).then(() => { // tweak the level for the client to reflect the new reality var userLevels = powerLevelEvent.getContent().users || {}; userLevels[userId] = requiredLevel; @@ -796,9 +761,9 @@ Intent.prototype._ensureHasPowerLevelFor = function(roomId, eventType) { } return Promise.resolve(powerLevelEvent); }); -}; +} -Intent.prototype._ensureRegistered = function() { +_ensureRegistered() { if (this.opts.registered) { return Promise.resolve("registered=true"); } @@ -814,6 +779,7 @@ Intent.prototype._ensureRegistered = function() { } throw err; }); -}; +} +} module.exports = Intent; diff --git a/spec/integ/bridge.spec.js b/spec/integ/bridge.spec.js index a351f955..a99a3ccb 100644 --- a/spec/integ/bridge.spec.js +++ b/spec/integ/bridge.spec.js @@ -111,7 +111,7 @@ describe("Bridge", function() { clientFactory: clientFactory }); done(); - }).done(); + }).then(); }); afterEach(function() { @@ -157,7 +157,7 @@ describe("Bridge", function() { bridgeCtrl.onUserQuery.and.returnValue({}); clients["bot"].register.and.returnValue(Promise.resolve({})); bridge.run(101, {}, appService); - appService.onUserQuery("@alice:bar").done(function() { + appService.onUserQuery("@alice:bar").then(function() { expect(clients["bot"].register).toHaveBeenCalledWith("alice"); done(); }); @@ -195,7 +195,7 @@ describe("Bridge", function() { }); bridgeCtrl.onAliasQuery.and.returnValue(provisionedRoom); bridge.run(101, {}, appService); - appService.onAliasQuery("#foo:bar").done(function() { + appService.onAliasQuery("#foo:bar").then(function() { expect(clients["bot"].createRoom).toHaveBeenCalledWith( provisionedRoom.creationOpts ); @@ -215,7 +215,7 @@ describe("Bridge", function() { bridge.run(101, {}, appService); appService.onAliasQuery("#foo:bar").then(function() { return bridge.getRoomStore().getMatrixRoom("!abc123:bar"); - }).done(function(room) { + }).then(function(room) { expect(room).toBeDefined(); if (!room) { done(); return; } expect(room.getId()).toEqual("!abc123:bar"); @@ -237,7 +237,7 @@ describe("Bridge", function() { bridge.run(101, {}, appService); appService.onAliasQuery("#foo:bar").then(function() { return bridge.getRoomStore().getLinkedRemoteRooms("!abc123:bar"); - }).done(function(rooms) { + }).then(function(rooms) { expect(rooms.length).toEqual(1); if (!rooms.length) { done(); return; } expect(rooms[0].getId()).toEqual("__abc__"); @@ -260,7 +260,7 @@ describe("Bridge", function() { }; bridge.run(101, {}, appService).then(function() { return appService.emit("event", event); - }).done(function() { + }).then(function() { expect(bridgeCtrl.onEvent).not.toHaveBeenCalled(); done(); }); @@ -281,7 +281,7 @@ describe("Bridge", function() { bridge.run(101, {}, appService).then(function() { return appService.emit("event", event); - }).done(function() { + }).then(function() { expect(bridgeCtrl.onEvent).toHaveBeenCalled(); var call = bridgeCtrl.onEvent.calls.argsFor(0); var req = call[0]; @@ -313,7 +313,7 @@ describe("Bridge", function() { ); }).then(function() { return appService.emit("event", event); - }).done(function() { + }).then(function() { expect(bridgeCtrl.onEvent).toHaveBeenCalled(); var call = bridgeCtrl.onEvent.calls.argsFor(0); var req = call[0]; @@ -345,7 +345,7 @@ describe("Bridge", function() { ); }).then(function() { return appService.emit("event", event); - }).done(function() { + }).then(function() { expect(bridgeCtrl.onEvent).toHaveBeenCalled(); var call = bridgeCtrl.onEvent.calls.argsFor(0); var req = call[0]; @@ -377,7 +377,7 @@ describe("Bridge", function() { ); }).then(function() { return appService.emit("event", event); - }).done(function() { + }).then(function() { expect(bridgeCtrl.onEvent).toHaveBeenCalled(); var call = bridgeCtrl.onEvent.calls.argsFor(0); var req = call[0]; @@ -415,7 +415,7 @@ describe("Bridge", function() { bridge.run(101, {}, appService).then(function() { return appService.emit("event", event); - }).done(function() { + }).then(function() { expect(bridgeCtrl.onEvent).toHaveBeenCalled(); var call = bridgeCtrl.onEvent.calls.argsFor(0); var req = call[0]; @@ -440,28 +440,28 @@ describe("Bridge", function() { describe("getters", function() { it("should be able to getRoomStore", function(done) { - bridge.run(101, {}, appService).done(function() { + bridge.run(101, {}, appService).then(function() { expect(bridge.getRoomStore()).toEqual(roomStore); done(); }); }); it("should be able to getUserStore", function(done) { - bridge.run(101, {}, appService).done(function() { + bridge.run(101, {}, appService).then(function() { expect(bridge.getUserStore()).toEqual(userStore); done(); }); }); it("should be able to getRequestFactory", function(done) { - bridge.run(101, {}, appService).done(function() { + bridge.run(101, {}, appService).then(function() { expect(bridge.getRequestFactory()).toBeDefined(); done(); }); }); it("should be able to getBot", function(done) { - bridge.run(101, {}, appService).done(function() { + bridge.run(101, {}, appService).then(function() { expect(bridge.getBot()).toBeDefined(); done(); }); @@ -475,7 +475,7 @@ describe("Bridge", function() { beforeEach(function(done) { jasmine.clock().install(); jasmine.clock().mockDate(); - bridge.run(101, {}, appService).done(function() { + bridge.run(101, {}, appService).then(function() { done(); }); }); @@ -535,7 +535,7 @@ describe("Bridge", function() { type: "m.room.member" }; appService.emit("event", joinEvent); - intent.join("!flibble:bar").done(function() { + intent.join("!flibble:bar").then(function() { expect(client.joinRoom).not.toHaveBeenCalled(); done(); }); @@ -570,7 +570,7 @@ describe("Bridge", function() { // wait the cull time again and use a new intent, still shouldn't join. jasmine.clock().tick(cullTimeMs); return bridge.getIntent("@foo:bar").join("!flibble:bar"); - }).done(function() { + }).then(function() { expect(client.joinRoom).not.toHaveBeenCalled(); done(); }); @@ -603,7 +603,7 @@ describe("Bridge", function() { describe("provisionUser", function() { beforeEach(function(done) { - bridge.run(101, {}, appService).done(function() { + bridge.run(101, {}, appService).then(function() { done(); }); }); @@ -617,7 +617,7 @@ describe("Bridge", function() { expect(botClient.register).toHaveBeenCalledWith(mxUser.localpart); // should also be persisted in storage return bridge.getUserStore().getMatrixUser("@foo:bar"); - }).done(function(usr) { + }).then(function(usr) { expect(usr).toBeDefined(); expect(usr.getId()).toEqual("@foo:bar"); done(); @@ -634,7 +634,7 @@ describe("Bridge", function() { var client = mkMockMatrixClient("@foo:bar"); client.setDisplayName.and.returnValue(Promise.resolve({})); clients["@foo:bar"] = client; - bridge.provisionUser(mxUser, provisionedUser).done(function() { + bridge.provisionUser(mxUser, provisionedUser).then(function() { expect(botClient.register).toHaveBeenCalledWith(mxUser.localpart); expect(client.setDisplayName).toHaveBeenCalledWith("Foo Bar"); done(); @@ -651,7 +651,7 @@ describe("Bridge", function() { var client = mkMockMatrixClient("@foo:bar"); client.setAvatarUrl.and.returnValue(Promise.resolve({})); clients["@foo:bar"] = client; - bridge.provisionUser(mxUser, provisionedUser).done(function() { + bridge.provisionUser(mxUser, provisionedUser).then(function() { expect(botClient.register).toHaveBeenCalledWith(mxUser.localpart); expect(client.setAvatarUrl).toHaveBeenCalledWith("http://avatar.jpg"); done(); @@ -671,7 +671,7 @@ describe("Bridge", function() { bridge.provisionUser(mxUser, provisionedUser).then(function() { expect(botClient.register).toHaveBeenCalledWith(mxUser.localpart); return bridge.getUserStore().getRemoteUsersFromMatrixId("@foo:bar"); - }).done(function(users) { + }).then(function(users) { expect(users.length).toEqual(1); if (users.length > 0) { expect(users[0].getId()).toEqual("__remote__"); diff --git a/spec/unit/intent.spec.js b/spec/unit/intent.spec.js index 713db210..bf8fd958 100644 --- a/spec/unit/intent.spec.js +++ b/spec/unit/intent.spec.js @@ -1,6 +1,5 @@ "use strict"; var Intent = require("../..").Intent; -var Promise = require("bluebird"); var log = require("../log"); describe("Intent", function() { @@ -30,18 +29,16 @@ describe("Intent", function() { describe("join", function() { - it("should /join/$ROOMID if it doesn't know it is already joined", - function(done) { - client.joinRoom.and.returnValue(Promise.resolve({})); - intent.join(roomId).done(function() { + it("should /join/$ROOMID if it doesn't know it is already joined", () => { + client.joinRoom.and.callFake(() => Promise.resolve({})); + return intent.join(roomId).then(function() { expect(client.joinRoom).toHaveBeenCalledWith( roomId, { syncRoom: false } ); - done(); }); }); - it("should no-op if it knows it is already joined", function(done) { + it("should no-op if it knows it is already joined", () => { intent.onEvent({ event_id: "test", type: "m.room.member", @@ -51,27 +48,25 @@ describe("Intent", function() { membership: "join" } }); - intent.join(roomId).done(function() { + return intent.join(roomId).then(function() { expect(client.joinRoom).not.toHaveBeenCalled(); - done(); }); }); it("should fail if the join returned an error other than forbidden", - function(done) { - client.joinRoom.and.returnValue(Promise.reject({ + () => { + client.joinRoom.and.callFake(() => Promise.reject({ errcode: "M_YOU_ARE_A_FISH", error: "you're a fish" })); - intent.join(roomId).catch(function() { + return intent.join(roomId).then(fail, function() { expect(client.joinRoom).toHaveBeenCalled(); - done(); }); }); describe("client join failed", function() { - it("should make the bot invite then the client join", function(done) { + it("should make the bot invite then the client join", () => { client.joinRoom.and.callFake(function() { if (botClient.invite.calls.count() === 0) { return Promise.reject({ @@ -81,20 +76,19 @@ describe("Intent", function() { } return Promise.resolve({}); }); - botClient.invite.and.returnValue(Promise.resolve({})); + botClient.invite.and.callFake(() => Promise.resolve({})); - intent.join(roomId).done(function() { + return intent.join(roomId).then(function() { expect(client.joinRoom).toHaveBeenCalledWith( roomId, { syncRoom: false } ); expect(botClient.invite).toHaveBeenCalledWith(roomId, userId); - done(); }); }); describe("bot invite failed", function() { it("should make the bot join then invite then the client join", - function(done) { + () => { client.joinRoom.and.callFake(function() { if (botClient.invite.calls.count() === 0) { return Promise.reject({ @@ -113,9 +107,9 @@ describe("Intent", function() { } return Promise.resolve({}); }); - botClient.joinRoom.and.returnValue(Promise.resolve({})); + botClient.joinRoom.and.callFake(() => Promise.resolve({})); - intent.join(roomId).done(function() { + return intent.join(roomId).then(function() { expect(client.joinRoom).toHaveBeenCalledWith( roomId, { syncRoom: false } ); @@ -123,25 +117,24 @@ describe("Intent", function() { expect(botClient.joinRoom).toHaveBeenCalledWith( roomId, { syncRoom: false } ); - done(); }); }); - it("should give up if the bot cannot join the room", function(done) { - client.joinRoom.and.returnValue(Promise.reject({ + it("should give up if the bot cannot join the room", () => { + client.joinRoom.and.callFake(() => Promise.reject({ errcode: "M_FORBIDDEN", error: "Join first" })); - botClient.invite.and.returnValue(Promise.reject({ + botClient.invite.and.callFake(() => Promise.reject({ errcode: "M_FORBIDDEN", error: "No invites kthx" })); - botClient.joinRoom.and.returnValue(Promise.reject({ + botClient.joinRoom.and.callFake(() => Promise.reject({ errcode: "M_FORBIDDEN", error: "No bots allowed!" })); - intent.join(roomId).catch(function() { + return intent.join(roomId).then(fail, function() { expect(client.joinRoom).toHaveBeenCalledWith( roomId, { syncRoom: false } ); @@ -149,7 +142,6 @@ describe("Intent", function() { expect(botClient.joinRoom).toHaveBeenCalledWith( roomId, { syncRoom: false } ); - done(); }); }); }); @@ -199,38 +191,36 @@ describe("Intent", function() { }); it("should directly send the event if it thinks power levels are ok", - function(done) { - client.sendStateEvent.and.returnValue(Promise.resolve({})); + () => { + client.sendStateEvent.and.callFake(() => Promise.resolve({})); intent.onEvent(validPowerLevels); - intent.setRoomTopic(roomId, "Hello world").done(function() { + return intent.setRoomTopic(roomId, "Hello world").then(function() { expect(client.sendStateEvent).toHaveBeenCalledWith( roomId, "m.room.topic", {topic: "Hello world"}, "" ); - done(); }) }); it("should get the power levels before sending if it doesn't know them", - function(done) { - client.sendStateEvent.and.returnValue(Promise.resolve({})); - client.getStateEvent.and.returnValue( - Promise.resolve(validPowerLevels.content) + () => { + client.sendStateEvent.and.callFake(() => Promise.resolve({})); + client.getStateEvent.and.callFake( + () => Promise.resolve(validPowerLevels.content) ); - intent.setRoomTopic(roomId, "Hello world").done(function() { + return intent.setRoomTopic(roomId, "Hello world").then(function() { expect(client.getStateEvent).toHaveBeenCalledWith( roomId, "m.room.power_levels", "" ); expect(client.sendStateEvent).toHaveBeenCalledWith( roomId, "m.room.topic", {topic: "Hello world"}, "" ); - done(); }) }); it("should modify power levels before sending if client is too low", - function(done) { + () => { client.sendStateEvent.and.callFake(function() { if (botClient.setPowerLevel.calls.count() > 0) { return Promise.resolve({}); @@ -240,31 +230,29 @@ describe("Intent", function() { error: "Not enough powaaaaaa" }); }); - botClient.setPowerLevel.and.returnValue(Promise.resolve({})); + botClient.setPowerLevel.and.callFake(() => Promise.resolve({})); // give the power to the bot invalidPowerLevels.content.users[botUserId] = 100; intent.onEvent(invalidPowerLevels); - intent.setRoomTopic(roomId, "Hello world").done(function() { + return intent.setRoomTopic(roomId, "Hello world").then(function() { expect(client.sendStateEvent).toHaveBeenCalledWith( roomId, "m.room.topic", {topic: "Hello world"}, "" ); expect(botClient.setPowerLevel).toHaveBeenCalledWith( roomId, userId, 50, jasmine.any(Object) ); - done(); }) }); it("should fail if the bot cannot modify power levels and the client is too low", - function(done) { + () => { // bot has NO power intent.onEvent(invalidPowerLevels); - intent.setRoomTopic(roomId, "Hello world").catch(function() { + return intent.setRoomTopic(roomId, "Hello world").then(fail, function() { expect(client.sendStateEvent).not.toHaveBeenCalled(); expect(botClient.setPowerLevel).not.toHaveBeenCalled(); - done(); }) }); }); @@ -289,34 +277,32 @@ describe("Intent", function() { }); }); - it("should immediately try to send the event if joined/have pl", function(done) { - client.sendEvent.and.returnValue(Promise.resolve({ + it("should immediately try to send the event if joined/have pl", () => { + client.sendEvent.and.callFake(() => Promise.resolve({ event_id: "$abra:kadabra" })); - intent.sendMessage(roomId, content).done(function() { + return intent.sendMessage(roomId, content).then(function() { expect(client.sendEvent).toHaveBeenCalledWith( roomId, "m.room.message", content ); expect(client.joinRoom).not.toHaveBeenCalled(); - done(); }); }); - it("should fail if get an error that isn't M_FORBIDDEN", function(done) { - client.sendEvent.and.returnValue(Promise.reject({ + it("should fail if get an error that isn't M_FORBIDDEN", () => { + client.sendEvent.and.callFake(() => Promise.reject({ error: "Oh no", errcode: "M_UNKNOWN" })); - intent.sendMessage(roomId, content).catch(function() { + return intent.sendMessage(roomId, content).then(fail, function() { expect(client.sendEvent).toHaveBeenCalledWith( roomId, "m.room.message", content ); expect(client.joinRoom).not.toHaveBeenCalled(); - done(); }); }); - it("should try to join the room on M_FORBIDDEN then resend", function(done) { + it("should try to join the room on M_FORBIDDEN then resend", () => { var isJoined = false; client.sendEvent.and.callFake(function() { if (isJoined) { @@ -335,36 +321,34 @@ describe("Intent", function() { room_id: joinRoomId, }); }); - intent.sendMessage(roomId, content).done(function() { + return intent.sendMessage(roomId, content).then(function() { expect(client.sendEvent).toHaveBeenCalledWith( roomId, "m.room.message", content ); expect(client.joinRoom).toHaveBeenCalledWith(roomId, { syncRoom: false }); - done(); }); }); - it("should fail if the join on M_FORBIDDEN fails", function(done) { + it("should fail if the join on M_FORBIDDEN fails", () => { client.sendEvent.and.callFake(function() { return Promise.reject({ error: "You are not joined", errcode: "M_FORBIDDEN" }); }); - client.joinRoom.and.returnValue(Promise.reject({ + client.joinRoom.and.callFake(() => Promise.reject({ error: "Never!", errcode: "M_YOU_ARE_A_FISH" })); - intent.sendMessage(roomId, content).catch(function() { + return intent.sendMessage(roomId, content).then(fail, function() { expect(client.sendEvent).toHaveBeenCalledWith( roomId, "m.room.message", content ); expect(client.joinRoom).toHaveBeenCalledWith(roomId, { syncRoom: false }); - done(); }); }); - it("should fail if the resend after M_FORBIDDEN fails", function(done) { + it("should fail if the resend after M_FORBIDDEN fails", () => { var isJoined = false; client.sendEvent.and.callFake(function() { if (isJoined) { @@ -384,12 +368,11 @@ describe("Intent", function() { room_id: joinRoomId, }); }); - intent.sendMessage(roomId, content).catch(function() { + return intent.sendMessage(roomId, content).then(fail, function() { expect(client.sendEvent).toHaveBeenCalledWith( roomId, "m.room.message", content ); expect(client.joinRoom).toHaveBeenCalledWith(roomId, { syncRoom: false }); - done(); }); }); }); @@ -415,12 +398,17 @@ describe("Intent", function() { affectedUsers = ["@_pidgeonpost_.*:home.server"]; }); - it("should send an event", function(done) { - client.sendEvent.and.returnValue(Promise.resolve({ + it("should send an event", () => { + client.sendEvent.and.callFake(() => Promise.resolve({ event_id: "$abra:kadabra" })); - intent - .unstableSignalBridgeError(roomId, eventId, bridge, reason, affectedUsers) + return intent.unstableSignalBridgeError( + roomId, + eventId, + bridge, + reason, + affectedUsers, + ) .then(() => { expect(client.sendEvent).toHaveBeenCalledWith( roomId, @@ -436,7 +424,6 @@ describe("Intent", function() { } ); expect(client.joinRoom).not.toHaveBeenCalled(); - done(); }); }); });