Merge branch 'hotfix/21.56.9' into master
[gitter.git] / modules / rooms / test / room-service-test.js
blobb5de73bc38f2a691aa8e5f65b04beaa8d258835f
1 'use strict';
3 var proxyquireNoCallThru = require('proxyquire').noCallThru();
4 var assert = require('assert');
5 const mongoUtils = require('gitter-web-persistence-utils/lib/mongo-utils');
6 var fixtureLoader = require('gitter-web-test-utils/lib/test-fixtures');
7 var Promise = require('bluebird');
8 var ObjectID = require('mongodb').ObjectID;
9 var StatusError = require('statuserror');
11 var mockito = require('jsmockito').JsMockito;
12 var times = mockito.Verifiers.times;
13 var once = times(1);
15 var persistence = require('gitter-web-persistence');
17 require('../lib/room-service');
19 // to work around proxyquire caching bugs...
20 require('../lib/room-service');
22 describe('room-service', function() {
23   describe('addUserToRoom', function() {
24     function createRoomServiceWithStubs(stubs) {
25       return proxyquireNoCallThru('../lib/room-service', {
26         'gitter-web-permissions/lib/add-invite-policy-factory': {
27           createPolicyForRoomAdd: function() {
28             return Promise.resolve({
29               canJoin: function() {
30                 return Promise.resolve(stubs.canBeInvited);
31               }
32             });
33           }
34         },
35         'gitter-web-email-notifications': {
36           sendInvitation: stubs.onInviteEmail,
37           addedToRoomNotification: function() {
38             return Promise.resolve();
39           }
40         },
41         'gitter-web-email-addresses': function() {
42           return Promise.resolve('a@b.com');
43         }
44       });
45     }
47     it('adds a user to the troupe', function() {
48       var service = createRoomServiceWithStubs({
49         canBeInvited: true,
50         onInviteEmail: function() {
51           return Promise.resolve();
52         }
53       });
55       var _troupId = new ObjectID();
56       var _userId = new ObjectID();
57       var _userToAddId = new ObjectID();
59       var troupe = {
60         _id: _troupId,
61         id: _troupId.toString(),
62         uri: 'user/room',
63         sd: {
64           public: true
65         }
66       };
68       var user = {
69         _id: _userId,
70         id: _userId.toString()
71       };
73       var userToAdd = {
74         _id: _userToAddId,
75         id: _userToAddId.toString(),
76         username: 'test-user'
77       };
79       return service.addUserToRoom(troupe, user, userToAdd);
80     });
82     it('saves troupe changes', function() {
83       var service = createRoomServiceWithStubs({
84         canBeInvited: true,
85         onInviteEmail: function() {
86           return Promise.resolve();
87         }
88       });
90       var _troupId = new ObjectID();
91       var _userId = new ObjectID();
92       var _userToAddId = new ObjectID();
94       var troupe = {
95         _id: _troupId,
96         id: _troupId.toString(),
97         uri: 'user/room',
98         sd: {
99           public: true
100         }
101       };
103       var user = {
104         _id: _userId,
105         id: _userId.toString()
106       };
108       var userToAdd = {
109         _id: _userToAddId,
110         id: _userToAddId.toString(),
111         username: 'test-user'
112       };
114       return service.addUserToRoom(troupe, user, userToAdd);
115     });
117     it('returns the added user and sets the date the user was added', function() {
118       var service = createRoomServiceWithStubs({
119         canBeInvited: true,
120         onInviteEmail: function() {
121           return Promise.resolve();
122         }
123       });
125       var _troupId = new ObjectID();
126       var _userId = new ObjectID();
127       var _userToAddId = new ObjectID();
129       var troupe = {
130         _id: _troupId,
131         uri: 'user/room',
132         sd: {
133           public: true
134         }
135       };
137       var user = {
138         _id: _userId,
139         id: _userId.toString()
140       };
142       var userToAdd = {
143         _id: _userToAddId,
144         id: _userToAddId.toString(),
145         username: 'test-user'
146       };
148       return service
149         .addUserToRoom(troupe, user, userToAdd)
150         .then(function(user) {
151           assert.equal(user.id, _userToAddId);
152           assert.equal(user.username, 'test-user');
154           return persistence.UserTroupeLastAccess.findOne({ userId: user.id }).exec();
155         })
156         .then(function(lastAccess) {
157           assert(lastAccess);
158           assert(lastAccess.added);
159           assert(lastAccess.added[troupe.id]);
160           assert(Date.now() - lastAccess.added[troupe.id] <= 30000);
161         });
162     });
164     it('attempts an email invite for new users', function() {
165       var service = createRoomServiceWithStubs({
166         canBeInvited: true,
167         onInviteEmail: function() {
168           return Promise.resolve();
169         }
170       });
172       var _troupId = new ObjectID();
173       var _userId = new ObjectID();
174       var _userToAddId = new ObjectID();
176       var troupe = {
177         _id: _troupId,
178         uri: 'user/room',
179         sd: {
180           public: true
181         }
182       };
184       var user = {
185         _id: _userId,
186         id: _userId.toString()
187       };
189       var userToAdd = {
190         _id: _userToAddId,
191         id: _userToAddId.toString(),
192         username: 'test-user'
193       };
195       return service.addUserToRoom(troupe, user, userToAdd);
196     });
198     it('fails with 403 when adding someone to who cant be invited', function() {
199       var service = createRoomServiceWithStubs({
200         findByUsernameResult: null,
201         createInvitedUserResult: { username: 'test-user', id: 'test-user-id', state: 'INVITED' },
202         canBeInvited: false,
203         onInviteEmail: function() {
204           return Promise.resolve();
205         }
206       });
208       var _userToAddId = new ObjectID();
210       var troupe = {
211         uri: 'user/room'
212       };
214       var userToAdd = {
215         _id: _userToAddId,
216         id: _userToAddId.toString(),
217         username: 'test-user'
218       };
220       return service.addUserToRoom(troupe, {}, userToAdd).then(
221         function() {
222           assert.ok(false, 'Expected exception');
223         },
224         function(err) {
225           assert.equal(err.status, 403);
226         }
227       );
228     });
230     it('should not fail when adding someone who is already in the room', function() {
231       var service = createRoomServiceWithStubs({
232         canBeInvited: true,
233         onInviteEmail: function() {
234           return Promise.resolve();
235         }
236       });
238       var _troupId = new ObjectID();
239       var _userId = new ObjectID();
240       var _userToAddId = new ObjectID();
242       var troupe = {
243         _id: _troupId,
244         uri: 'user/room',
245         sd: {
246           public: true
247         }
248       };
250       var user = {
251         _id: _userId,
252         id: _userId.toString()
253       };
255       var userToAdd = {
256         _id: _userToAddId,
257         id: _userToAddId.toString(),
258         username: 'test-user'
259       };
261       return service.addUserToRoom(troupe, user, userToAdd);
262     });
263   });
265   describe('removals', function() {
266     var fixture = fixtureLoader.setup({
267       troupeCanRemove: {
268         security: 'PUBLIC',
269         githubType: 'REPO',
270         users: ['userToRemove', 'userRemoveNonAdmin', 'userRemoveAdmin']
271       },
272       troupeCannotRemove: {
273         oneToOne: true,
274         users: ['userToRemove', 'userRemoveAdmin']
275       },
276       userToRemove: {},
277       userRemoveAdmin: {}
278     });
280     var roomService = proxyquireNoCallThru('../lib/room-service', {
281       'gitter-web-permissions/lib/policy-factory': {
282         createPolicyForRoom: function(user /*, room*/) {
283           return Promise.resolve({
284             canAdmin: function() {
285               if (user.id === fixture.userRemoveNonAdmin.id) {
286                 return Promise.resolve(false);
287               } else if (user.id === fixture.userRemoveAdmin.id) {
288                 return Promise.resolve(true);
289               } else {
290                 assert(false, 'Unknown user');
291               }
292               return Promise.resolve(true);
293             }
294           });
295         }
296       }
297     });
299     var roomMembershipService = require('../lib/room-membership-service');
301     it('should prevent from removing users from one-to-one rooms', function() {
302       return roomMembershipService
303         .checkRoomMembership(fixture.troupeCannotRemove._id, fixture.userToRemove._id)
304         .then(function(here) {
305           assert(here);
306           return roomService.removeUserFromRoom(
307             fixture.troupeCannotRemove,
308             fixture.userToRemove,
309             fixture.userRemoveAdmin
310           );
311         })
312         .catch(function(err) {
313           assert.equal(err.status, 400);
314           assert.equal(err.message, 'This room does not support removing.');
315         })
316         .then(function() {
317           return roomMembershipService.checkRoomMembership(
318             fixture.troupeCannotRemove._id,
319             fixture.userToRemove._id
320           );
321         })
322         .then(function(here) {
323           assert(here);
324         });
325     });
327     it('should remove users from rooms', function() {
328       return roomMembershipService
329         .checkRoomMembership(fixture.troupeCanRemove._id, fixture.userToRemove._id)
330         .then(function(here) {
331           assert(here);
332           return roomService.removeUserFromRoom(
333             fixture.troupeCanRemove,
334             fixture.userToRemove,
335             fixture.userRemoveAdmin
336           );
337         })
338         .then(function() {
339           return roomMembershipService.checkRoomMembership(
340             fixture.troupeCanRemove._id,
341             fixture.userToRemove._id
342           );
343         })
344         .then(function(here) {
345           assert(!here);
346         });
347     });
348   });
350   describe('remove and hide #slow', function() {
351     var troupeService = require('../lib/troupe-service');
352     var recentRoomService = require('../lib/recent-room-service');
353     var roomFavouritesCore = require('../lib/room-favourites-core');
354     var roomMembershipService = require('../lib/room-membership-service');
355     var appEvents = require('gitter-web-appevents');
357     describe('room-service #slow', function() {
358       var fixture = fixtureLoader.setup({
359         troupeCanRemove: {
360           security: 'PUBLIC',
361           githubType: 'REPO',
362           users: [
363             'userFavourite',
364             'userLeave',
365             'userToRemove',
366             'userRemoveNonAdmin',
367             'userRemoveAdmin'
368           ]
369         },
370         troupeCannotRemove: {
371           security: 'PRIVATE',
372           githubType: 'ONETOONE',
373           users: ['userToRemove', 'userRemoveAdmin']
374         },
375         troupeEmpty: {
376           security: 'PUBLIC',
377           githubType: 'REPO',
378           users: []
379         },
380         userFavourite: {},
381         userLeave: {},
382         userToRemove: {},
383         userRemoveNonAdmin: {},
384         userRemoveAdmin: {}
385       });
387       describe('#removeFavourite', function() {
388         var roomService = require('../lib/room-service');
390         var getFavs = function() {
391           return roomFavouritesCore.findFavouriteTroupesForUser(fixture.userFavourite.id);
392         };
394         var createFav = function() {
395           return recentRoomService
396             .updateFavourite(fixture.userFavourite.id, fixture.troupeCanRemove.id, true)
397             .then(getFavs)
398             .then(function(favs) {
399               assert(favs[fixture.troupeCanRemove.id]); // Favourite is created
400             });
401         };
403         var checkHere = function() {
404           return roomMembershipService.checkRoomMembership(
405             fixture.troupeCanRemove._id,
406             fixture.userFavourite._id
407           );
408         };
410         beforeEach(function() {
411           if (this._skipFixtureSetup) return;
413           return createFav();
414         });
416         it('should remove favourite', function() {
417           var checkEvent = appEvents.addListener('dataChange2', {
418             url: '/user/' + fixture.userFavourite.id + '/rooms',
419             operation: 'patch',
420             model: {
421               id: fixture.troupeCanRemove.id,
422               favourite: null,
423               lastAccessTime: null,
424               mentions: 0,
425               unreadItems: 0,
426               activity: 0
427             }
428           });
430           return roomService
431             .hideRoomFromUser(fixture.troupeCanRemove, fixture.userFavourite.id)
432             .then(checkEvent) // Ensure event was emitted
433             .then(getFavs)
434             .then(function(favs) {
435               assert(!favs[fixture.troupeCanRemove.id]); // Favourite is removed
436             })
437             .then(checkHere)
438             .then(function(here) {
439               assert(here); // User is still in room
440             });
441         });
443         it('should remove user from the room if mode=mute', function() {
444           // Set user as lurking
445           return roomMembershipService
446             .setMembershipMode(fixture.userFavourite.id, fixture.troupeCanRemove.id, 'mute', false)
447             .then(function() {
448               // Get updated troupe
449               return troupeService.findById(fixture.troupeCanRemove.id);
450             })
451             .then(function(troupe) {
452               return roomService.hideRoomFromUser(troupe, fixture.userFavourite.id);
453             })
454             .then(getFavs)
455             .then(function(favs) {
456               assert(!favs[fixture.troupeCanRemove.id]); // Favourite is removed
457             })
458             .then(checkHere)
459             .then(function(here) {
460               assert(!here); // User has been removed
461             });
462         });
464         it('should remove user from the room if mode=mute', function() {
465           // Set user as lurking
466           return roomMembershipService
467             .setMembershipMode(fixture.userFavourite.id, fixture.troupeCanRemove.id, 'mute', false)
468             .then(function() {
469               // Get updated troupe
470               return troupeService.findById(fixture.troupeCanRemove.id);
471             })
472             .then(function(troupe) {
473               return roomService.hideRoomFromUser(troupe, fixture.userFavourite.id);
474             })
475             .then(getFavs)
476             .then(function(favs) {
477               assert(!favs[fixture.troupeCanRemove.id]); // Favourite is removed
478             })
479             .then(checkHere)
480             .then(function(here) {
481               assert(!here); // User has been removed
482             });
483         });
485         it('should check if the proper event is emitted when the favourite is removed', function() {
486           var checkEvent = appEvents.addListener('dataChange2', {
487             url: '/user/' + fixture.userFavourite.id + '/rooms',
488             operation: 'remove',
489             model: { id: fixture.troupeEmpty.id }
490           });
492           return roomMembershipService
493             .checkRoomMembership(fixture.troupeEmpty._id, fixture.userFavourite._id)
494             .then(function(here) {
495               assert(!here); // Check that user is not in the room
496             })
497             .then(function() {
498               return roomService.hideRoomFromUser(fixture.troupeEmpty, fixture.userFavourite.id);
499             })
500             .then(checkEvent) // Ensure event was emitted
501             .then(getFavs)
502             .then(function(favs) {
503               assert(!favs[fixture.troupeEmpty.id]); // Favourite is removed
504             });
505         });
506       });
508       describe('#removeUserFromRoom', function() {
509         var roomService = require('../lib/room-service');
511         it('should remove user from room', function() {
512           return roomMembershipService
513             .checkRoomMembership(fixture.troupeCanRemove._id, fixture.userLeave._id)
514             .then(function(here) {
515               assert(here);
516               return roomService.removeUserFromRoom(
517                 fixture.troupeCanRemove,
518                 fixture.userLeave,
519                 fixture.userLeave
520               );
521             })
522             .then(function() {
523               return roomMembershipService.checkRoomMembership(
524                 fixture.troupeCanRemove._id,
525                 fixture.userLeave._id
526               );
527             })
528             .then(function(here) {
529               assert(!here);
530             });
531         });
532       });
534       describe('#removeUserFromRoom', function() {
535         var roomService = require('../lib/room-service');
537         it('should remove users from rooms', function() {
538           return roomMembershipService
539             .checkRoomMembership(fixture.troupeCanRemove._id, fixture.userToRemove._id)
540             .then(function(here) {
541               assert(here);
542               return roomService.removeUserFromRoom(
543                 fixture.troupeCanRemove,
544                 fixture.userToRemove,
545                 fixture.userRemoveAdmin
546               );
547             })
548             .then(function() {
549               return roomMembershipService.checkRoomMembership(
550                 fixture.troupeCanRemove._id,
551                 fixture.userToRemove._id
552               );
553             })
554             .then(function(here) {
555               assert(!here);
556             });
557         });
558       });
559     });
560   });
562   describe('findBanByUsername', () => {
563     const roomService = require('../lib/room-service');
565     const banFixtures = fixtureLoader.setup({
566       userAdmin1: {},
567       userBanned1: {},
568       troupeWithBannedUsers1: {
569         bans: [
570           {
571             user: 'userBanned1',
572             dateBanned: Date.now(),
573             bannedBy: 'userAdmin1'
574           }
575         ]
576       },
577       troupeWithBannedVirtualUsers1: {
578         bans: [
579           {
580             virtualUser: {
581               type: 'matrix',
582               externalId: 'banned-user:matrix.org'
583             },
584             dateBanned: Date.now(),
585             bannedBy: 'userAdmin1'
586           }
587         ]
588       }
589     });
591     it('finds ban for normal user', async () => {
592       const ban = await roomService.findBanByUsername(
593         banFixtures.troupeWithBannedUsers1._id,
594         banFixtures.userBanned1.username
595       );
597       assert.strictEqual(mongoUtils.objectIDsEqual(ban.userId, banFixtures.userBanned1._id), true);
598     });
600     it('finds ban for virtual user', async () => {
601       const ban = await roomService.findBanByUsername(
602         banFixtures.troupeWithBannedVirtualUsers1._id,
603         'banned-user:matrix.org'
604       );
606       assert.strictEqual(ban.virtualUser.type, 'matrix', true);
607       assert.strictEqual(ban.virtualUser.externalId, 'banned-user:matrix.org', true);
608     });
610     it('does not find ban when no matching user', async () => {
611       const ban = await roomService.findBanByUsername(
612         banFixtures.troupeWithBannedUsers1._id,
613         'does-not-exist'
614       );
616       assert.strictEqual(ban, undefined);
617     });
619     it('does not find ban when virtualUser.externalId does not match', async () => {
620       const ban = await roomService.findBanByUsername(
621         banFixtures.troupeWithBannedVirtualUsers1._id,
622         'some-other-user:matrix.org'
623       );
625       assert.strictEqual(ban, undefined);
626     });
627   });
629   describe('findAllRoomsIdsForUserIncludingMentions', function() {
630     var getRoomIdsMentioningUserMock, findRoomIdsForUserMock, roomService;
632     beforeEach(function() {
633       getRoomIdsMentioningUserMock = mockito.mockFunction();
634       findRoomIdsForUserMock = mockito.mockFunction();
635       roomService = proxyquireNoCallThru('../lib/room-service', {
636         'gitter-web-unread-items': {
637           getRoomIdsMentioningUser: getRoomIdsMentioningUserMock
638         },
639         './room-membership-service': {
640           findRoomIdsForUser: findRoomIdsForUserMock
641         }
642       });
643     });
645     function runWithValues(roomIdsForUser, roomIdsMentioningUser, expected, expectedNonMembers) {
646       var userId = 'user1';
648       mockito
649         .when(getRoomIdsMentioningUserMock)()
650         .then(function(pUserId) {
651           assert.strictEqual(pUserId, userId);
652           return Promise.resolve(roomIdsMentioningUser);
653         });
655       mockito
656         .when(findRoomIdsForUserMock)()
657         .then(function(pUserId) {
658           assert.strictEqual(pUserId, userId);
659           return Promise.resolve(roomIdsForUser);
660         });
662       return roomService
663         .findAllRoomsIdsForUserIncludingMentions(userId)
664         .spread(function(allTroupeIds, nonMemberTroupeIds) {
665           allTroupeIds.sort();
666           nonMemberTroupeIds.sort();
667           expected.sort();
668           expectedNonMembers.sort();
669           assert.deepEqual(allTroupeIds, expected);
670           assert.deepEqual(nonMemberTroupeIds, expectedNonMembers);
671         });
672     }
674     it('should handle the trivial case of no rooms', function() {
675       return runWithValues([], [], [], []);
676     });
678     it('should handle the non member rooms only case', function() {
679       return runWithValues([], ['1'], ['1'], ['1']);
680     });
682     it('should handle the member rooms only case', function() {
683       return runWithValues(['1'], [], ['1'], []);
684     });
686     it('should handle the member rooms only case with mentions', function() {
687       return runWithValues(['1'], ['1'], ['1'], []);
688     });
690     it('should handle the mixed cases', function() {
691       return runWithValues(['1', '2', '3'], ['2', '3', '4'], ['1', '2', '3', '4'], ['4']);
692     });
693   });
695   describe('joinRoom', function() {
696     describe('unit tests', function() {
697       var roomService;
698       var assertJoinRoomChecks;
699       var recentRoomServiceSaveLastVisitedTroupeforUserId;
700       var roomMembershipServiceAddRoomMember;
701       var troupe;
702       var joinRoomCheckFailed;
703       var user;
704       var userId;
705       var troupeId;
707       beforeEach(function() {
708         userId = 'userId1';
709         troupeId = 'troupeId1';
710         user = {
711           id: userId,
712           _id: userId
713         };
714         troupe = {
715           id: troupeId,
716           _id: troupeId
717         };
719         assertJoinRoomChecks = mockito.mockFunction();
720         recentRoomServiceSaveLastVisitedTroupeforUserId = mockito.mockFunction();
721         roomMembershipServiceAddRoomMember = mockito.mockFunction();
723         mockito
724           .when(assertJoinRoomChecks)()
725           .then(function(pRoom, pUser) {
726             assert.strictEqual(pUser, user);
727             assert.strictEqual(pRoom, troupe);
728             if (joinRoomCheckFailed) return Promise.reject(new StatusError());
729             return Promise.resolve();
730           });
732         mockito
733           .when(recentRoomServiceSaveLastVisitedTroupeforUserId)()
734           .then(function(pUserId, pRoomId, pOptions) {
735             assert.strictEqual(pUserId, userId);
736             assert.strictEqual(pRoomId, troupeId);
737             assert.deepEqual(pOptions, { skipFayeUpdate: true });
738             return Promise.resolve();
739           });
741         mockito
742           .when(roomMembershipServiceAddRoomMember)()
743           .then(function(pRoomId, pUserId) {
744             assert.strictEqual(pUserId, userId);
745             assert.strictEqual(pRoomId, troupeId);
746             return Promise.resolve();
747           });
749         roomService = proxyquireNoCallThru('../lib/room-service', {
750           './room-membership-service': {
751             addRoomMember: roomMembershipServiceAddRoomMember
752           },
753           './assert-join-room-checks': assertJoinRoomChecks,
754           './recent-room-service': {
755             saveLastVisitedTroupeforUserId: recentRoomServiceSaveLastVisitedTroupeforUserId
756           }
757         });
758       });
760       it('should allow a user to join a room', function() {
761         joinRoomCheckFailed = false;
763         return roomService.joinRoom(troupe, user).then(function() {
764           mockito.verify(assertJoinRoomChecks, once)();
765           mockito.verify(recentRoomServiceSaveLastVisitedTroupeforUserId, once)();
766           mockito.verify(roomMembershipServiceAddRoomMember, once)();
767         });
768       });
770       it('should deny a user join room there are too many people in the room', function() {
771         joinRoomCheckFailed = true;
773         return roomService
774           .joinRoom(troupe, user)
775           .then(function() {
776             assert.ok(false, 'Expected an exception');
777           })
778           .catch(() => {
779             // This is what we want...
780           })
781           .then(function() {
782             mockito.verify(assertJoinRoomChecks, once)();
783           });
784       });
785     });
787     describe('integration tests #slow', function() {
788       var roomService;
789       var createPolicyForRoom;
790       var access;
791       var roomMembershipService;
793       var fixture = fixtureLoader.setup({
794         troupeOrg1: {
795           githubType: 'ORG',
796           users: []
797         },
798         user1: {}
799       });
801       beforeEach(function() {
802         roomMembershipService = require('../lib/room-membership-service');
803         createPolicyForRoom = mockito.mockFunction();
805         mockito
806           .when(createPolicyForRoom)()
807           .then(function(pUser, pRoom) {
808             assert.strictEqual(pUser, fixture.user1);
809             assert.strictEqual(pRoom.id, fixture.troupeOrg1.id);
810             return Promise.resolve({
811               canJoin: function() {
812                 return Promise.resolve(access);
813               }
814             });
815           });
817         roomService = proxyquireNoCallThru('../lib/room-service', {
818           'gitter-web-permissions/lib/policy-factory': {
819             createPolicyForRoom: createPolicyForRoom
820           }
821         });
822       });
824       it('should add a member to the room', function() {
825         access = true;
827         return roomService
828           .joinRoom(fixture.troupeOrg1, fixture.user1)
829           .then(function() {
830             return roomMembershipService.checkRoomMembership(
831               fixture.troupeOrg1.id,
832               fixture.user1.id
833             );
834           })
835           .then(function(isMember) {
836             assert.strictEqual(isMember, true);
837           });
838       });
840       it('should be idempotent', function() {
841         access = true;
843         return roomService
844           .joinRoom(fixture.troupeOrg1, fixture.user1)
845           .then(function() {
846             return roomMembershipService.checkRoomMembership(
847               fixture.troupeOrg1.id,
848               fixture.user1.id
849             );
850           })
851           .then(function(isMember) {
852             assert.strictEqual(isMember, true);
853             return roomService.joinRoom(fixture.troupeOrg1, fixture.user1);
854           })
855           .then(function() {
856             return roomMembershipService.checkRoomMembership(
857               fixture.troupeOrg1.id,
858               fixture.user1.id
859             );
860           })
861           .then(function(isMember) {
862             assert.strictEqual(isMember, true);
863           });
864       });
865     });
866   });
868   describe('updateTopic #slow', function() {
869     var roomService = require('../lib/room-service');
871     var fixture = fixtureLoader.setup({
872       troupe1: {}
873     });
875     it('should update the topic', function() {
876       return roomService
877         .updateTopic(fixture.troupe1.id, 'THE TOPIC')
878         .then(function() {
879           return persistence.Troupe.findById(fixture.troupe1.id).exec();
880         })
881         .then(function(troupe) {
882           assert.strictEqual(troupe.topic, 'THE TOPIC');
883         });
884     });
886     it('null should update the topic', function() {
887       return roomService
888         .updateTopic(fixture.troupe1.id, null)
889         .then(function() {
890           return persistence.Troupe.findById(fixture.troupe1.id).exec();
891         })
892         .then(function(troupe) {
893           assert.strictEqual(troupe.topic, '');
894         });
895     });
896   });