import type { Credentials } from '@rocket.chat/api-client'; import type { IRole, IRoom, ITeam, IUser } from '@rocket.chat/core-typings'; import { TeamType } from '@rocket.chat/core-typings'; import { Random } from '@rocket.chat/random'; import { expect } from 'chai'; import { after, afterEach, before, beforeEach, describe, it } from 'mocha'; import { getCredentials, api, request, credentials, methodCall } from '../../data/api-data'; import { updatePermission, updateSetting } from '../../data/permissions.helper'; import { createRoom, deleteRoom } from '../../data/rooms.helper'; import { createTeam, deleteTeam } from '../../data/teams.helper'; import { adminUsername, password } from '../../data/user'; import type { TestUser } from '../../data/users.helper'; import { createUser, deleteUser, login } from '../../data/users.helper'; interface IUserInfo { _id: string; username?: string; name?: string; status?: string; settings?: Record; } interface ITeamMemberInfo { user: IUserInfo; roles?: IRole['_id'][] | null; createdBy: Omit; createdAt: Date; } const addMembers = async (credentials: Record, teamName: string, members: IUser['_id'][]): Promise => { await request .post(api('teams.addMembers')) .set(credentials) .send({ teamName, members: members.map((userId) => ({ userId, roles: ['member'] })), }); }; describe('[Teams]', () => { before((done) => getCredentials(done)); describe('/teams.create', () => { const name = `test-team-create-${Date.now()}`; const createdTeams: ITeam[] = []; let testUser: TestUser; before(async () => { testUser = await createUser(); await updateSetting('UTF8_Channel_Names_Validation', '[0-9a-zA-Z-_.]+'); }); after(async () => { await Promise.all([ ...createdTeams.map((team) => deleteTeam(credentials, team.name)), deleteUser(testUser), updateSetting('UTF8_Channel_Names_Validation', '[0-9a-zA-Z-_.]+'), ]); }); before(async () => { return updatePermission('create-team', ['admin', 'user']); }); after(async () => { return updatePermission('create-team', ['admin', 'user']); }); it('should create a public team', async () => { const res = await request .post(api('teams.create')) .set(credentials) .send({ name, type: 0, }) .expect('Content-Type', 'application/json') .expect(200); expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('team'); expect(res.body).to.have.nested.property('team._id'); createdTeams.push(res.body.team); }); it('should create a public team with a member', (done) => { void request .post(api('teams.create')) .set(credentials) .send({ name: `test-team-${Date.now()}`, type: 0, members: [testUser.username], }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('team'); expect(res.body).to.have.nested.property('team._id'); createdTeams.push(res.body.team); }) .then((response) => { const teamId = response.body.team._id; return request .get(api('teams.members')) .set(credentials) .query({ teamId }) .expect(200) .expect((response) => { expect(response.body).to.have.property('success', true); expect(response.body).to.have.property('members'); // remove admin user from members because it's added automatically as owner const members = (response.body.members as ITeamMemberInfo[]).filter(({ user }) => user.username !== adminUsername); const [member] = members; expect(member.user.username).to.be.equal(testUser.username); }); }) .then(() => done()) .catch(done); }); it('should create private team with a defined owner', (done) => { void request .post(api('teams.create')) .set(credentials) .send({ name: `test-team-private-owner-${Date.now()}`, type: 1, }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('team'); expect(res.body).to.have.nested.property('team._id'); createdTeams.push(res.body.team); }) .then((response) => { const teamId = response.body.team._id; return request .get(api('teams.members')) .set(credentials) .query({ teamId }) .expect(200) .expect((response) => { expect(response.body).to.have.property('success', true); expect(response.body).to.have.property('members'); const member = response.body.members[0]; expect(member).to.have.property('user'); expect(member).to.have.property('roles'); expect(member).to.have.property('createdBy'); expect(member).to.have.property('createdAt'); expect(member.user).to.have.property('_id'); expect(member.user).to.have.property('username'); expect(member.user).to.have.property('name'); expect(member.user).to.have.property('status'); expect(member.createdBy).to.have.property('_id'); expect(member.createdBy).to.have.property('username'); expect(member.roles).to.have.length(1); expect(member.roles[0]).to.be.equal('owner'); }); }) .then(() => done()) .catch(done); }); it('should throw an error if the team already exists', async () => { const res = await request .post(api('teams.create')) .set(credentials) .send({ name, type: 0, }) .expect('Content-Type', 'application/json') .expect(400); expect(res.body).to.have.property('success', false); expect(res.body).to.have.property('error'); expect(res.body.error).to.be.equal('team-name-already-exists'); }); it('should not create a team with no associated room', async () => { const teamName = 'invalid*team*name'; await request .post(api('teams.create')) .set(credentials) .send({ name: teamName, type: 0, }) .expect('Content-Type', 'application/json') .expect(400) .expect((response) => { expect(response.body).to.have.property('success', false); expect(response.body).to.have.property('error'); expect(response.body.error).to.be.equal('error-team-creation'); }); await request .get(api('teams.info')) .set(credentials) .query({ teamName, }) .expect('Content-Type', 'application/json') .expect(400) .expect((response) => { expect(response.body).to.have.property('success', false); expect(response.body).to.have.property('error', 'Team not found'); }); await request .get(api('teams.members')) .set(credentials) .query({ teamName, }) .expect('Content-Type', 'application/json') .expect(400) .expect((response) => { expect(response.body).to.have.property('success', false); expect(response.body).to.have.property('error', 'team-does-not-exist'); }); }); it('should not allow creating a team when the user does NOT have the create-team permission', async () => { await updatePermission('create-team', []); await request .post(api('teams.create')) .set(credentials) .send({ name: `test-team-${Date.now()}`, type: 0, }) .expect('Content-Type', 'application/json') .expect(403) .expect((res) => { expect(res.body).to.have.property('success', false); expect(res.body).to.have.property('error', 'User does not have the permissions required for this action [error-unauthorized]'); }); }); }); describe('/teams.create - existing room ownership check', () => { let roomOwner: TestUser; let roomOwnerCredentials: Credentials; let attacker: TestUser; let attackerCredentials: Credentials; let targetRoom: IRoom; const teamName = `test-team-hijack-${Date.now()}`; before(async () => { [roomOwner, attacker] = await Promise.all([createUser(), createUser()]); [roomOwnerCredentials, attackerCredentials] = await Promise.all([ login(roomOwner.username, password), login(attacker.username, password), ]); targetRoom = (await createRoom({ type: 'c', name: `test-room-hijack-${Date.now()}`, credentials: roomOwnerCredentials })).body .channel; }); before(() => updatePermission('create-team', ['admin', 'user'])); after(async () => { await Promise.all([ deleteRoom({ type: 'c', roomId: targetRoom._id }), deleteUser(roomOwner), deleteUser(attacker), updatePermission('create-team', ['admin', 'user']), ]); }); it('should not allow a user with no ownership/moderation of a room to hijack it into a new team by passing room.id', async () => { await request .post(api('teams.create')) .set(attackerCredentials) .send({ name: teamName, type: 0, room: { id: targetRoom._id }, }) .expect('Content-Type', 'application/json') .expect(403) .expect((res) => { expect(res.body).to.have.property('success', false); }); await request .get(api('channels.info')) .set(credentials) .query({ roomId: targetRoom._id }) .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body.channel).to.not.have.property('teamId'); expect(res.body.channel).to.not.have.property('teamMain'); }); }); }); }); describe('/teams.convertToChannel', () => { let testTeam: ITeam; let channelToEraseId: IRoom['_id']; let channelToKeepId: IRoom['_id']; const teamName = `test-team-convert-to-channel-${Date.now()}`; const channelToEraseName = `${teamName}-channelToErase`; const channelToKeepName = `${teamName}-channelToKeep`; before('Create test team', (done) => { void request .post(api('teams.create')) .set(credentials) .send({ name: teamName, type: 1, }) .end((_err, res) => { testTeam = res.body.team; done(); }); }); before('create channel (to erase after its team is converted to a channel)', (done) => { void request .post(api('channels.create')) .set(credentials) .send({ name: channelToEraseName, }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { channelToEraseId = res.body.channel._id; expect(res.body).to.have.property('success', true); expect(res.body).to.have.nested.property('channel._id'); expect(res.body).to.have.nested.property('channel.name', channelToEraseName); expect(res.body).to.have.nested.property('channel.t', 'c'); expect(res.body).to.have.nested.property('channel.msgs', 0); }) .then(() => done()); }); before('add first channel to team', (done) => { void request .post(api('teams.addRooms')) .set(credentials) .send({ rooms: [channelToEraseId], teamId: testTeam._id, }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('rooms'); expect(res.body.rooms[0]).to.have.property('teamId', testTeam._id); expect(res.body.rooms[0]).to.not.have.property('teamDefault'); }) .then(() => done()) .catch(done); }); before('create channel (to keep after its team is converted to a channel)', (done) => { void request .post(api('channels.create')) .set(credentials) .send({ name: channelToKeepName, }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { channelToKeepId = res.body.channel._id; expect(res.body).to.have.property('success', true); expect(res.body).to.have.nested.property('channel._id'); expect(res.body).to.have.nested.property('channel.name', channelToKeepName); expect(res.body).to.have.nested.property('channel.t', 'c'); expect(res.body).to.have.nested.property('channel.msgs', 0); }) .then(() => done()); }); before('add second channel to team', (done) => { void request .post(api('teams.addRooms')) .set(credentials) .send({ rooms: [channelToKeepId], teamId: testTeam._id, }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('rooms'); expect(res.body.rooms[0]).to.have.property('teamId', testTeam._id); expect(res.body.rooms[0]).to.not.have.property('teamDefault'); }) .then(() => done()); }); after(() => Promise.all([ deleteTeam(credentials, teamName), deleteRoom({ type: 'p', roomId: testTeam.roomId }), deleteRoom({ type: 'c', roomId: channelToKeepId }), ]), ); it('should convert the team to a channel, delete the specified room and move the other back to the workspace', (done) => { void request .post(api('teams.convertToChannel')) .set(credentials) .send({ teamName, roomsToRemove: [channelToEraseId], }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); }) .then(() => { void request .get(api('channels.info')) .set(credentials) .query({ roomId: channelToEraseId, }) .expect('Content-Type', 'application/json') .expect(400) .expect((response) => { expect(response.body).to.have.property('success', false); expect(response.body).to.have.property('error'); expect(response.body.error).to.include('[error-room-not-found]'); }); }) .then(() => { void request .get(api('channels.info')) .set(credentials) .query({ roomId: channelToKeepId, }) .expect('Content-Type', 'application/json') .expect(200) .expect((response) => { expect(response.body).to.have.property('success', true); expect(response.body).to.have.property('channel'); expect(response.body.channel).to.have.property('_id', channelToKeepId); expect(response.body.channel).to.not.have.property('teamId'); }); }) .then(() => { void request .get(api('channels.info')) .set(credentials) .query({ roomId: testTeam.roomId, }) .expect('Content-Type', 'application/json') .expect(200) .expect((response) => { expect(response.body).to.have.property('success', true); expect(response.body).to.have.property('channel'); expect(response.body.channel).to.have.property('_id', testTeam.roomId); expect(response.body.channel).to.not.have.property('teamId'); expect(response.body.channel).to.not.have.property('teamMain'); }); }) .then(() => done()) .catch(done); }); }); describe('/teams.addMembers', () => { let testTeam: ITeam; const teamName = `test-team-add-members-${Date.now()}`; let testUser: TestUser; let testUser2: TestUser; before('Create test team', (done) => { void request .post(api('teams.create')) .set(credentials) .send({ name: teamName, type: 0, }) .end((_err, res) => { testTeam = res.body.team; done(); }); }); after(() => deleteTeam(credentials, teamName)); beforeEach(async () => { testUser = await createUser(); testUser2 = await createUser(); }); afterEach(() => Promise.all([deleteUser(testUser), deleteUser(testUser2)])); it('should add members to a public team', (done) => { void request .post(api('teams.addMembers')) .set(credentials) .send({ teamName: testTeam.name, members: [ { userId: testUser._id, roles: ['member'], }, { userId: testUser2._id, roles: ['member'], }, ], }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); }) .then( () => void request .get(api('teams.members')) .set(credentials) .query({ teamName: testTeam.name, }) .expect('Content-Type', 'application/json') .expect(200) .expect((response) => { expect(response.body).to.have.property('success', true); expect(response.body).to.have.property('members'); expect(response.body.members).to.have.length(3); expect(response.body.members[1]).to.have.property('user'); expect(response.body.members[1]).to.have.property('roles'); expect(response.body.members[1]).to.have.property('createdBy'); expect(response.body.members[1]).to.have.property('createdAt'); const members = (response.body.members as ITeamMemberInfo[]).map(({ user, roles }) => ({ _id: user._id, username: user.username, name: user.name, roles, })); expect(members).to.deep.own.include({ _id: testUser._id, username: testUser.username, name: testUser.name, roles: ['member'], }); expect(members).to.deep.own.include({ _id: testUser2._id, username: testUser2.username, name: testUser2.name, roles: ['member'], }); }), ) .then(() => done()) .catch(done); }); it('should add members and assign roles to them properly', (done) => { void request .post(api('teams.addMembers')) .set(credentials) .send({ teamName: testTeam.name, members: [ { userId: testUser._id, roles: ['owner', 'leader'], }, { userId: testUser2._id, roles: ['moderator'], }, ], }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); }) .then(() => request .get(api('rooms.membersOrderedByRole')) .set(credentials) .query({ roomId: testTeam.roomId, }) .expect('Content-Type', 'application/json') .expect(200) .expect((response) => { expect(response.body).to.have.property('success', true); expect(response.body).to.have.property('members'); expect(response.body.members).to.have.length(3); expect(response.body.members[1]).to.have.property('_id'); expect(response.body.members[1]).to.have.property('roles'); expect(response.body.members[1]).to.have.property('username'); expect(response.body.members[1]).to.have.property('name'); const members = (response.body.members as IUser[]).map(({ _id, username, name, roles }) => ({ _id, username, name, roles, })); expect(members).to.deep.own.include({ _id: testUser._id, username: testUser.username, name: testUser.name, roles: ['owner', 'leader'], }); expect(members).to.deep.own.include({ _id: testUser2._id, username: testUser2.username, name: testUser2.name, roles: ['moderator'], }); }), ) .then(() => done()) .catch(done); }); }); describe('/teams.members', () => { let testTeam: ITeam; const teamName = `test-team-members-${Date.now()}`; let testUser: TestUser; let testUser2: TestUser; before(async () => { testUser = await createUser(); testUser2 = await createUser(); }); before('Create test team', (done) => { void request .post(api('teams.create')) .set(credentials) .send({ name: teamName, type: 0, }) .end((_err, res) => { testTeam = res.body.team; done(); }); }); before('Add members to team', (done) => { void request .post(api('teams.addMembers')) .set(credentials) .send({ teamName: testTeam.name, members: [ { userId: testUser._id, roles: ['member'], }, { userId: testUser2._id, roles: ['member'], }, ], }) .end(done); }); after(() => Promise.all([deleteUser(testUser), deleteUser(testUser2), deleteTeam(credentials, teamName)])); it('should list all the members from a public team', async () => { const res = await request .get(api('teams.members')) .set(credentials) .query({ teamName: testTeam.name, }) .expect('Content-Type', 'application/json') .expect(200); expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('count', 3); expect(res.body).to.have.property('offset', 0); expect(res.body).to.have.property('total', 3); expect(res.body).to.have.property('members'); expect(res.body.members).to.have.length(3); expect(res.body.members[0]).to.have.property('user'); expect(res.body.members[0]).to.have.property('roles'); expect(res.body.members[0]).to.have.property('createdBy'); expect(res.body.members[0]).to.have.property('createdAt'); expect(res.body.members[0].user).to.have.property('_id'); expect(res.body.members[0].user).to.have.property('username'); expect(res.body.members[0].user).to.have.property('name'); expect(res.body.members[0].user).to.have.property('status'); expect(res.body.members[0].createdBy).to.have.property('_id'); expect(res.body.members[0].createdBy).to.have.property('username'); }); }); describe('/teams.list', () => { const teamName = `test-team-list-${Date.now()}`; let testUser1: TestUser; let testUser1Credentials: Credentials; let testTeamAdmin: TestUser; let testTeam1: IRoom; before('Create test team', (done) => { void request .post(api('teams.create')) .set(credentials) .send({ name: teamName, type: 0, }) .end(done); }); before('Create test users', async () => { testUser1 = await createUser(); }); before('login test users', async () => { testUser1Credentials = await login(testUser1.username, password); }); before('Create test team', async () => { await request.post(api('teams.create')).set(credentials).send({ name: teamName, type: 0, }); const team1Name = `test-team-1-${Date.now()}`; const teamAdminName = `test-team-admin-${Date.now()}`; testTeam1 = ( await request.post(api('teams.create')).set(testUser1Credentials).send({ name: team1Name, type: 0, }) ).body.team; testTeamAdmin = ( await request.post(api('teams.create')).set(credentials).send({ name: teamAdminName, type: 0, }) ).body.team; }); after(() => Promise.all([ deleteTeam(credentials, teamName), deleteTeam(testUser1Credentials, testTeam1.name!), deleteTeam(credentials, testTeamAdmin.name!), ]), ); after('delete test users', () => deleteUser(testUser1)); it('should list all teams', async () => { const res = await request.get(api('teams.list')).set(credentials).expect('Content-Type', 'application/json').expect(200); expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('count'); expect(res.body).to.have.property('offset', 0); expect(res.body).to.have.property('total'); expect(res.body).to.have.property('teams'); expect(res.body.teams.length).to.be.gte(1); expect(res.body.teams[0]).to.have.property('_id'); expect(res.body.teams[0]).to.have.property('_updatedAt'); expect(res.body.teams[0]).to.have.property('name'); expect(res.body.teams[0]).to.have.property('type'); expect(res.body.teams[0]).to.have.property('roomId'); expect(res.body.teams[0]).to.have.property('createdBy'); expect(res.body.teams[0].createdBy).to.have.property('_id'); expect(res.body.teams[0].createdBy).to.have.property('username'); expect(res.body.teams[0]).to.have.property('createdAt'); expect(res.body.teams[0]).to.have.property('rooms'); expect(res.body.teams[0]).to.have.property('numberOfUsers'); }); it("should prevent users from accessing unrelated teams via 'query' parameter", () => { return request .get(api('teams.list')) .set(testUser1Credentials) .query({ query: JSON.stringify({ _id: { $regex: '.*' } }), }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body.teams.length).to.be.gte(1); expect(res.body.teams) .to.be.an('array') .and.to.satisfy( (teams: ITeam[]) => teams.every((team) => team.createdBy._id === testUser1._id), `Expected only user's own teams to be returned, but found unowned teams.\n${JSON.stringify( res.body.teams.filter((team: ITeam) => team.createdBy._id !== testUser1._id), null, 2, )}`, ); }); }); it("should prevent admins from accessing unrelated teams via 'query' parameter", () => { return request .get(api('teams.list')) .set(credentials) .query({ query: JSON.stringify({ _id: { $regex: '.*' } }), }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body.teams.length).to.be.gte(1); expect(res.body.teams) .to.be.an('array') .and.to.satisfy( (teams: ITeam[]) => teams.every((team) => team.createdBy._id === credentials['X-User-Id']), `Expected only admin's own teams to be returned, but found unowned teams.\n${JSON.stringify( res.body.teams.filter((team: ITeam) => team.createdBy._id !== credentials['X-User-Id']), null, 2, )}`, ); }); }); }); describe('/teams.listAll', () => { let teamName: string; before(async () => { await updatePermission('view-all-teams', ['admin']); teamName = `test-team-${Date.now()}`; await request.post(api('teams.create')).set(credentials).send({ name: teamName, type: 0, }); }); after(() => Promise.all([deleteTeam(credentials, teamName), updatePermission('view-all-teams', ['admin'])])); it('should list all teams', async () => { await request .get(api('teams.listAll')) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('count'); expect(res.body).to.have.property('offset', 0); expect(res.body).to.have.property('total'); expect(res.body).to.have.property('teams'); expect(res.body.teams).to.be.an('array').that.is.not.empty; expect(res.body.teams[0]).to.have.property('_id'); expect(res.body.teams[0]).to.have.property('_updatedAt'); expect(res.body.teams[0]).to.have.property('name'); expect(res.body.teams[0]).to.have.property('type'); expect(res.body.teams[0]).to.have.property('roomId'); expect(res.body.teams[0]).to.have.property('createdBy'); expect(res.body.teams[0].createdBy).to.have.property('_id'); expect(res.body.teams[0].createdBy).to.have.property('username'); expect(res.body.teams[0]).to.have.property('createdAt'); expect(res.body.teams[0]).to.have.property('rooms'); expect(res.body.teams[0]).to.have.property('numberOfUsers'); }); }); it('should return an error when the user does NOT have the view-all-teams permission', async () => { await updatePermission('view-all-teams', []); await request .get(api('teams.listAll')) .set(credentials) .expect('Content-Type', 'application/json') .expect(403) .expect((res) => { expect(res.body).to.have.property('success', false); expect(res.body).to.have.property('error', 'User does not have the permissions required for this action [error-unauthorized]'); }); }); }); describe('/teams.updateMember', () => { let testTeam: ITeam; const teamName = `test-team-update-member-${Date.now()}`; let testUser: TestUser; let testUser2: TestUser; before(async () => { testUser = await createUser(); testUser2 = await createUser(); }); before('Create test team', (done) => { void request .post(api('teams.create')) .set(credentials) .send({ name: teamName, type: 0, }) .end((_err, res) => { testTeam = res.body.team; done(); }); }); before('Add members to team', (done) => { void request .post(api('teams.addMembers')) .set(credentials) .send({ teamName: testTeam.name, members: [ { userId: testUser._id, roles: ['member'], }, { userId: testUser2._id, roles: ['member'], }, ], }) .end(done); }); after(() => Promise.all([deleteUser(testUser), deleteUser(testUser2), deleteTeam(credentials, teamName)])); it("should update member's data in a public team", (done) => { void request .post(api('teams.updateMember')) .set(credentials) .send({ teamName: testTeam.name, member: { userId: testUser._id, roles: ['member', 'owner'], }, }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); }) .then( () => void request .get(api('teams.members')) .set(credentials) .query({ teamName: testTeam.name, }) .expect('Content-Type', 'application/json') .expect(200) .expect((response) => { expect(response.body).to.have.property('success', true); expect(response.body).to.have.property('members'); expect(response.body.members).to.have.length(3); const members = (response.body.members as ITeamMemberInfo[]).map(({ user, roles }) => ({ _id: user._id, username: user.username, name: user.name, roles, })); expect(members).to.deep.own.include({ _id: testUser._id, username: testUser.username, name: testUser.name, roles: ['member', 'owner'], }); }), ) .then(() => done()) .catch(done); }); }); describe('/teams.removeMember', () => { let testTeam: ITeam; const teamName = `test-team-remove-member-${Date.now()}`; let testUser: TestUser; let testUser2: TestUser; before(async () => { testUser = await createUser(); testUser2 = await createUser(); }); before('Create test team', (done) => { void request .post(api('teams.create')) .set(credentials) .send({ name: teamName, type: 0, }) .end((_err, res) => { testTeam = res.body.team; done(); }); }); after(() => Promise.all([deleteUser(testUser), deleteUser(testUser2), deleteTeam(credentials, teamName)])); it('should not be able to remove the last owner', (done) => { void request .post(api('teams.removeMember')) .set(credentials) .send({ teamName: testTeam.name, userId: credentials['X-User-Id'], }) .expect('Content-Type', 'application/json') .expect(400) .expect((res) => { expect(res.body).to.have.property('success', false); expect(res.body).to.have.property('error'); expect(res.body.error).to.be.equal('last-owner-can-not-be-removed'); }) .then(() => done()) .catch(done); }); it('should not be able to remove if rooms is empty', (done) => { void request .post(api('teams.removeMember')) .set(credentials) .send({ teamName: testTeam.name, userId: credentials['X-User-Id'], rooms: [], }) .expect('Content-Type', 'application/json') .expect(400) .expect((res) => { expect(res.body).to.have.property('success', false); expect(res.body).to.have.property('error'); expect(res.body.errorType).to.be.equal('invalid-params'); }) .then(() => done()) .catch(done); }); it('should remove one member from a public team', (done) => { void request .post(api('teams.addMembers')) .set(credentials) .send({ teamName: testTeam.name, members: [ { userId: testUser._id, roles: ['member'], }, { userId: testUser2._id, roles: ['member', 'owner'], }, ], }) .then(() => request .post(api('teams.removeMember')) .set(credentials) .send({ teamName: testTeam.name, userId: testUser2._id, }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); }) .then(() => request .get(api('teams.members')) .set(credentials) .query({ teamName: testTeam.name, }) .expect('Content-Type', 'application/json') .expect(200) .expect((response) => { expect(response.body).to.have.property('success', true); expect(response.body).to.have.property('members'); expect(response.body.members).to.have.length(2); }), ) .then(() => done()), ) .catch(done); }); }); describe('/teams.leave', () => { let testTeam: ITeam; const teamName = `test-team-leave-${Date.now()}`; let testUser: TestUser; let testUser2: TestUser; before(async () => { testUser = await createUser(); testUser2 = await createUser(); }); before('Create test team', (done) => { void request .post(api('teams.create')) .set(credentials) .send({ name: teamName, type: 0, }) .end((_err, res) => { testTeam = res.body.team; done(); }); }); after(() => Promise.all([deleteUser(testUser), deleteUser(testUser2), deleteTeam(credentials, teamName)])); it('should not be able to remove the last owner', (done) => { request .post(api('teams.leave')) .set(credentials) .send({ teamName: testTeam.name, }) .expect('Content-Type', 'application/json') .expect(400) .expect((res) => { expect(res.body).to.have.property('success', false); expect(res.body).to.have.property('error'); expect(res.body.error).to.be.equal('last-owner-can-not-be-removed'); }) .then(() => done()) .catch(done); }); it('should remove the calling user from the team', (done) => { request .post(api('teams.addMembers')) .set(credentials) .send({ teamName: testTeam.name, members: [ { userId: testUser._id, roles: ['member'], }, { userId: testUser2._id, roles: ['member', 'owner'], }, ], }) .then(() => request .post(api('teams.leave')) .set(credentials) .send({ teamName: testTeam.name, }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); }) .then(() => done()), ) .catch(done); }); it('should not be able to leave if rooms is empty', (done) => { request .post(api('teams.leave')) .set(credentials) .send({ teamName: testTeam.name, userId: credentials['X-User-Id'], rooms: [], }) .expect('Content-Type', 'application/json') .expect(400) .expect((res) => { expect(res.body).to.have.property('success', false); expect(res.body).to.have.property('error'); expect(res.body.errorType).to.be.equal('invalid-params'); }) .then(() => done()) .catch(done); }); }); describe('/teams.info', () => { const teamName = `test-team-info-${Date.now()}`; let testTeam: ITeam; let testTeam2: ITeam; let testUser: TestUser; let testUserCredentials: Credentials; before(async () => { testUser = await createUser(); testUserCredentials = await login(testUser.username, password); testTeam = await createTeam(credentials, teamName, TeamType.PUBLIC); testTeam2 = await createTeam(credentials, `${teamName}-2`, TeamType.PRIVATE); }); after(() => Promise.all([deleteTeam(credentials, testTeam.name), deleteTeam(credentials, testTeam2.name), deleteUser(testUser)])); it('should successfully get a team info by name', (done) => { request .get(api('teams.info')) .set(credentials) .query({ teamName: testTeam.name, }) .expect('Content-Type', 'application/json') .expect(200) .expect((response) => { expect(response.body).to.have.property('success', true); expect(response.body).to.have.property('teamInfo'); expect(response.body.teamInfo).to.have.property('_id', testTeam._id); expect(response.body.teamInfo).to.have.property('name', testTeam.name); }) .then(() => done()) .catch(done); }); it('should successfully get a team info by id', (done) => { request .get(api('teams.info')) .set(credentials) .query({ teamId: testTeam._id, }) .expect('Content-Type', 'application/json') .expect(200) .expect((response) => { expect(response.body).to.have.property('success', true); expect(response.body).to.have.property('teamInfo'); expect(response.body.teamInfo).to.have.property('_id', testTeam._id); expect(response.body.teamInfo).to.have.property('name', testTeam.name); }) .then(() => done()) .catch(done); }); it('should fail if a team is not found', (done) => { request .get(api('teams.info')) .set(credentials) .query({ teamName: '', }) .expect('Content-Type', 'application/json') .expect(400) .expect((response) => { expect(response.body).to.have.property('success', false); expect(response.body).to.have.property('error', 'Team not found'); }) .then(() => done()) .catch(done); }); it('should fail if a user doesnt belong to a team', (done) => { request .get(api('teams.info')) .set(testUserCredentials) .query({ teamName: testTeam2.name, }) .expect('Content-Type', 'application/json') .expect(403) .expect((response) => { expect(response.body).to.have.property('success', false); expect(response.body).to.have.property('error', 'unauthorized'); }) .then(() => done()) .catch(done); }); }); describe('/teams.delete', () => { describe('deleting an empty team', () => { let roomId: IRoom['_id']; const tempTeamName = `temporaryTeam-${Date.now()}`; before('create team', (done) => { void request .post(api('teams.create')) .set(credentials) .send({ name: tempTeamName, type: 0, }) .expect('Content-Type', 'application/json') .expect(200) .expect((resp) => { expect(resp.body).to.have.property('success', true); expect(resp.body).to.have.property('team'); expect(resp.body.team).to.have.property('name', tempTeamName); expect(resp.body.team).to.have.property('_id'); expect(resp.body.team).to.have.property('roomId'); roomId = resp.body.team.roomId; }) .then(() => done()); }); after(() => deleteTeam(credentials, tempTeamName)); it('should delete the team and the main room', (done) => { request .post(api('teams.delete')) .set(credentials) .send({ teamName: tempTeamName, }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); }) .then(() => { void request .get(api('teams.info')) .set(credentials) .query({ teamName: tempTeamName, }) .expect('Content-Type', 'application/json') .expect(400) .expect((response) => { expect(response.body).to.have.property('success', false); expect(response.body).to.have.property('error'); expect(response.body.error).to.be.equal('Team not found'); }) .then(() => { void request .get(api('channels.info')) .set(credentials) .query({ roomId, }) .expect('Content-Type', 'application/json') .expect(400) .expect((response) => { expect(response.body).to.have.property('success', false); expect(response.body).to.have.property('error'); expect(response.body.error).to.include('[error-room-not-found]'); }) .then(() => done()); }); }) .catch(done); }); }); describe('delete team with two rooms', () => { const tempTeamName = `temporaryTeam-${Date.now()}`; const channel1Name = `${tempTeamName}-channel1`; const channel2Name = `${tempTeamName}-channel2`; let teamId: ITeam['_id']; let channel1Id: IRoom['_id']; let channel2Id: IRoom['_id']; before('create team', (done) => { void request .post(api('teams.create')) .set(credentials) .send({ name: tempTeamName, type: 0, }) .then((response) => { teamId = response.body.team._id; }) .then(() => done()); }); before('create channel 1', (done) => { void request .post(api('channels.create')) .set(credentials) .send({ name: channel1Name, }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { channel1Id = res.body.channel._id; expect(res.body).to.have.property('success', true); expect(res.body).to.have.nested.property('channel._id'); expect(res.body).to.have.nested.property('channel.name', channel1Name); expect(res.body).to.have.nested.property('channel.t', 'c'); expect(res.body).to.have.nested.property('channel.msgs', 0); }) .then(() => done()); }); before('add channel 1 to team', (done) => { request .post(api('teams.addRooms')) .set(credentials) .send({ rooms: [channel1Id], teamId, }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('rooms'); expect(res.body.rooms[0]).to.have.property('teamId', teamId); expect(res.body.rooms[0]).to.not.have.property('teamDefault'); }) .then(() => done()) .catch(done); }); before('create channel 2', (done) => { void request .post(api('channels.create')) .set(credentials) .send({ name: channel2Name, }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { channel2Id = res.body.channel._id; expect(res.body).to.have.property('success', true); expect(res.body).to.have.nested.property('channel._id'); expect(res.body).to.have.nested.property('channel.name', channel2Name); expect(res.body).to.have.nested.property('channel.t', 'c'); expect(res.body).to.have.nested.property('channel.msgs', 0); }) .then(() => done()); }); before('add channel 2 to team', (done) => { void request .post(api('teams.addRooms')) .set(credentials) .send({ rooms: [channel2Id], teamId, }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('rooms'); expect(res.body.rooms[0]).to.have.property('teamId', teamId); expect(res.body.rooms[0]).to.not.have.property('teamDefault'); }) .then(() => done()); }); after(() => deleteRoom({ type: 'c', roomId: channel1Id })); it('should delete the specified room and move the other back to the workspace', (done) => { request .post(api('teams.delete')) .set(credentials) .send({ teamName: tempTeamName, roomsToRemove: [channel2Id], }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); }) .then(() => { void request .get(api('channels.info')) .set(credentials) .query({ roomId: channel2Id, }) .expect('Content-Type', 'application/json') .expect(400) .expect((response) => { expect(response.body).to.have.property('success', false); expect(response.body).to.have.property('error'); expect(response.body.error).to.include('[error-room-not-found]'); }) .then(() => { void request .get(api('channels.info')) .set(credentials) .query({ roomId: channel1Id, }) .expect('Content-Type', 'application/json') .expect(200) .expect((response) => { expect(response.body).to.have.property('success', true); expect(response.body).to.have.property('channel'); expect(response.body.channel).to.have.property('_id', channel1Id); expect(response.body.channel).to.not.have.property('teamId'); }) .then(() => done()); }); }) .catch(done); }); }); describe("delete team when team's main room id is provided in roomsToRemove", () => { const tempTeamName = `temporaryTeam-${Random.id()}`; const channel1Name = `${tempTeamName}-channel1`; const channel2Name = `${tempTeamName}-channel2`; let teamId: ITeam['_id']; let channel1Id: IRoom['_id']; let channel2Id: IRoom['_id']; let teamMainRoomId: IRoom['_id']; before('create team', async () => { await request .post(api('teams.create')) .set(credentials) .send({ name: tempTeamName, type: 0, }) .then((response) => { teamId = response.body.team._id; teamMainRoomId = response.body.team.roomId; }); }); before('create channel 1', async () => { await request .post(api('channels.create')) .set(credentials) .send({ name: channel1Name, }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { channel1Id = res.body.channel._id; expect(res.body).to.have.property('success', true); expect(res.body).to.have.nested.property('channel._id'); expect(res.body).to.have.nested.property('channel.name', channel1Name); expect(res.body).to.have.nested.property('channel.t', 'c'); expect(res.body).to.have.nested.property('channel.msgs', 0); }); }); before('add channel 1 to team', async () => { await request .post(api('teams.addRooms')) .set(credentials) .send({ rooms: [channel1Id], teamId, }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('rooms'); expect(res.body.rooms[0]).to.have.property('teamId', teamId); expect(res.body.rooms[0]).to.not.have.property('teamDefault'); }); }); before('create channel 2', async () => { await request .post(api('channels.create')) .set(credentials) .send({ name: channel2Name, }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { channel2Id = res.body.channel._id; expect(res.body).to.have.property('success', true); expect(res.body).to.have.nested.property('channel._id'); expect(res.body).to.have.nested.property('channel.name', channel2Name); expect(res.body).to.have.nested.property('channel.t', 'c'); expect(res.body).to.have.nested.property('channel.msgs', 0); }); }); before('add channel 2 to team', async () => { await request .post(api('teams.addRooms')) .set(credentials) .send({ rooms: [channel2Id], teamId, }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('rooms'); expect(res.body.rooms[0]).to.have.property('teamId', teamId); expect(res.body.rooms[0]).to.not.have.property('teamDefault'); }); }); after(() => deleteRoom({ type: 'c', roomId: channel1Id })); it('should delete the specified room and move the other back to the workspace', async () => { await request .post(api('teams.delete')) .set(credentials) .send({ teamName: tempTeamName, roomsToRemove: [channel2Id, teamMainRoomId], }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); }); await request .get(api('channels.info')) .set(credentials) .query({ roomId: teamMainRoomId, }) .expect('Content-Type', 'application/json') .expect(400) .expect((response) => { expect(response.body).to.have.property('success', false); expect(response.body).to.have.property('error'); expect(response.body.error).to.include('[error-room-not-found]'); }); await request .get(api('channels.info')) .set(credentials) .query({ roomId: channel2Id, }) .expect('Content-Type', 'application/json') .expect(400) .expect((response) => { expect(response.body).to.have.property('success', false); expect(response.body).to.have.property('error'); expect(response.body.error).to.include('[error-room-not-found]'); }); await request .get(api('channels.info')) .set(credentials) .query({ roomId: channel1Id, }) .expect('Content-Type', 'application/json') .expect(200) .expect((response) => { expect(response.body).to.have.property('success', true); expect(response.body).to.have.property('channel'); expect(response.body.channel).to.have.property('_id', channel1Id); expect(response.body.channel).to.not.have.property('teamId'); }); }); }); }); describe('/teams.addRooms', () => { let privateRoom: IRoom & { t: 'p' }; let privateRoom2: IRoom & { t: 'p' }; let privateRoom3: IRoom & { t: 'p' }; let publicRoom: IRoom & { t: 'c' }; let publicRoom2: IRoom & { t: 'c' }; let publicTeam: ITeam; let privateTeam: ITeam; let testUser: TestUser; let testUserCredentials: Credentials; before(async () => { testUser = await createUser(); testUserCredentials = await login(testUser.username, password); privateRoom = (await createRoom({ type: 'p', name: `community-channel-private-1-${Date.now()}` })).body.group; privateRoom2 = (await createRoom({ type: 'p', name: `community-channel-private-2-${Date.now()}` })).body.group; privateRoom3 = (await createRoom({ type: 'p', name: `community-channel-private-3-${Date.now()}` })).body.group; publicRoom = (await createRoom({ type: 'c', name: `community-channel-public-1-${Date.now()}` })).body.channel; publicRoom2 = (await createRoom({ type: 'c', name: `community-channel-public-2-${Date.now()}` })).body.channel; publicTeam = await createTeam(credentials, `team-name-c-${Date.now()}`, TeamType.PUBLIC); privateTeam = await createTeam(credentials, `team-name-p-${Date.now()}`, TeamType.PRIVATE); }); after(async () => { await Promise.all([deleteTeam(credentials, publicTeam.name), deleteTeam(credentials, privateTeam.name)]); await Promise.all([ updatePermission('move-room-to-team', ['admin', 'owner', 'moderator']), ...[privateRoom, privateRoom2, privateRoom3, publicRoom, publicRoom2].map((room) => deleteRoom({ type: room.t, roomId: room._id })), deleteUser(testUser), ]); }); it('should throw an error if no permission', async () => { await updatePermission('move-room-to-team', []); const res = await request .post(api('teams.addRooms')) .set(credentials) .send({ rooms: [publicRoom._id], teamId: publicTeam._id, }) .expect('Content-Type', 'application/json') .expect(403); expect(res.body).to.have.property('success', false); expect(res.body).to.have.property('error'); expect(res.body.error).to.be.equal('error-no-permission-team-channel'); }); it('should add public and private rooms to team', async () => { await updatePermission('move-room-to-team', ['admin']); const res = await request .post(api('teams.addRooms')) .set(credentials) .send({ rooms: [publicRoom._id, privateRoom._id], teamId: publicTeam._id, }) .expect('Content-Type', 'application/json') .expect(200); expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('rooms'); expect(res.body.rooms).to.have.length(2); expect(res.body.rooms[0]).to.have.property('_id'); expect(res.body.rooms[0]).to.have.property('teamId', publicTeam._id); expect(res.body.rooms[1]).to.have.property('_id'); expect(res.body.rooms[1]).to.have.property('teamId', publicTeam._id); const rids = (res.body.rooms as IRoom[]).map(({ _id }) => _id); expect(rids).to.include(publicRoom._id); expect(rids).to.include(privateRoom._id); }); it('should add public room to private team', async () => { await updatePermission('move-room-to-team', ['admin']); const res = await request .post(api('teams.addRooms')) .set(credentials) .send({ rooms: [publicRoom2._id], teamId: privateTeam._id, }) .expect('Content-Type', 'application/json') .expect(200); expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('rooms'); expect(res.body.rooms[0]).to.have.property('teamId', privateTeam._id); expect(res.body.rooms[0]).to.not.have.property('teamDefault'); }); it('should add private room to team', async () => { await updatePermission('move-room-to-team', ['admin']); const res = await request .post(api('teams.addRooms')) .set(credentials) .send({ rooms: [privateRoom2._id], teamId: privateTeam._id, }) .expect('Content-Type', 'application/json') .expect(200); expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('rooms'); expect(res.body.rooms[0]).to.have.property('teamId', privateTeam._id); expect(res.body.rooms[0]).to.not.have.property('teamDefault'); }); it('should fail if the user cannot access the channel', (done) => { void updatePermission('move-room-to-team', ['admin', 'user']) .then(() => { void request .post(api('teams.addRooms')) .set(testUserCredentials) .send({ rooms: [privateRoom3._id], teamId: privateTeam._id, }) .expect('Content-Type', 'application/json') .expect(400) .expect((res) => { expect(res.body).to.have.property('success', false); expect(res.body).to.have.property('error'); expect(res.body.error).to.be.equal('invalid-room'); }) .end(done); }) .catch(done); }); it('should fail if the user is not the owner of the channel', (done) => { void request .post(methodCall('addUsersToRoom')) .set(credentials) .send({ message: JSON.stringify({ method: 'addUsersToRoom', params: [{ rid: privateRoom3._id, users: [testUser.username] }], id: 'id', msg: 'method', }), }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); }) .then(() => { void request .post(api('teams.addRooms')) .set(testUserCredentials) .send({ rooms: [privateRoom3._id], teamId: privateTeam._id, }) .expect('Content-Type', 'application/json') .expect(400) .expect((res) => { expect(res.body).to.have.property('success', false); expect(res.body).to.have.property('error'); expect(res.body.error).to.be.equal('error-no-owner-channel'); }) .end(done); }) .catch(done); }); }); describe('/teams.listRooms', () => { let testUser: TestUser; let testUserCredentials: Credentials; let privateTeam: ITeam; let publicTeam: ITeam; let privateRoom: IRoom; let publicRoom: IRoom; let publicRoom2: IRoom; before(async () => { testUser = await createUser(); testUserCredentials = await login(testUser.username, password); privateTeam = await createTeam(credentials, `teamName-private-${Date.now()}`, TeamType.PRIVATE); publicTeam = await createTeam(testUserCredentials, `teamName-public-${Date.now()}`, TeamType.PUBLIC); privateRoom = (await createRoom({ type: 'p', name: `test-p-${Date.now()}` })).body.group; publicRoom = (await createRoom({ type: 'c', name: `test-c-${Date.now()}` })).body.channel; publicRoom2 = (await createRoom({ type: 'c', name: `test-c2-${Date.now()}` })).body.channel; await request .post(api('teams.addRooms')) .set(credentials) .send({ rooms: [privateRoom._id], teamId: publicTeam._id, }); await request .post(api('teams.addRooms')) .set(credentials) .send({ rooms: [publicRoom._id], teamId: publicTeam._id, }); await request .post(api('teams.addRooms')) .set(credentials) .send({ rooms: [publicRoom2._id], teamId: privateTeam._id, }); }); after(() => Promise.all([ updatePermission('view-all-teams', ['admin']), updatePermission('view-all-team-channels', ['admin', 'owner']), deleteUser(testUser), deleteTeam(credentials, privateTeam.name), deleteTeam(credentials, publicTeam.name), deleteRoom({ type: 'p', roomId: privateRoom._id }), deleteRoom({ type: 'c', roomId: publicRoom._id }), deleteRoom({ type: 'c', roomId: publicRoom2._id }), ]), ); it('should throw an error if team is private and no permission', async () => { await updatePermission('view-all-teams', []); const res = await request .get(api('teams.listRooms')) .set(testUserCredentials) .query({ teamId: privateTeam._id, }) .expect('Content-Type', 'application/json') .expect(400); expect(res.body).to.have.property('success', false); expect(res.body).to.have.property('error'); expect(res.body.error).to.be.equal('user-not-on-private-team'); }); it('should return only public rooms for public team', async () => { await updatePermission('view-all-team-channels', []); const res = await request .get(api('teams.listRooms')) .set(testUserCredentials) .query({ teamId: publicTeam._id, }) .expect('Content-Type', 'application/json') .expect(200); expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('rooms'); expect(res.body.rooms).to.be.an('array'); // main room should not be returned here expect(res.body.rooms.length).to.equal(1); }); it('should return all rooms for public team', async () => { await updatePermission('view-all-team-channels', ['user']); const res = await request .get(api('teams.listRooms')) .set(testUserCredentials) .query({ teamId: publicTeam._id, }) .expect('Content-Type', 'application/json') .expect(200); expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('rooms'); expect(res.body.rooms).to.be.an('array'); expect(res.body.rooms.length).to.equal(2); }); it('should return all rooms for public team even requested with count and offset params', async () => { await updatePermission('view-all-team-channels', ['user']); const res = await request .get(api('teams.listRooms')) .set(testUserCredentials) .query({ teamId: publicTeam._id, count: 5, offset: 0, }) .expect('Content-Type', 'application/json') .expect(200); expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('rooms'); expect(res.body.rooms).to.be.an('array'); expect(res.body.rooms.length).to.equal(2); }); it('should return public rooms for private team', async () => { await updatePermission('view-all-team-channels', []); await updatePermission('view-all-teams', ['admin']); const res = await request .get(api('teams.listRooms')) .set(credentials) .query({ teamId: privateTeam._id, }) .expect('Content-Type', 'application/json') .expect(200); expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('rooms'); expect(res.body.rooms).to.be.an('array'); expect(res.body.rooms.length).to.equal(1); }); it('should return public rooms for private team even requested with count and offset params', async () => { await updatePermission('view-all-team-channels', []); await updatePermission('view-all-teams', ['admin']); const res = await request .get(api('teams.listRooms')) .set(credentials) .query({ teamId: privateTeam._id, count: 5, offset: 0, }) .expect('Content-Type', 'application/json') .expect(200); expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('rooms'); expect(res.body.rooms).to.be.an('array'); expect(res.body.rooms.length).to.equal(1); }); describe('[teams.listChildren]', () => { const teamName = `team-${Date.now()}`; let testTeam: ITeam; let testPrivateTeam: ITeam; let testUser: IUser; let testUserCredentials: Credentials; let privateRoom: IRoom; let privateRoom2: IRoom; let publicRoom: IRoom; let publicRoom2: IRoom; let discussionOnPrivateRoom: IRoom; let discussionOnPublicRoom: IRoom; let discussionOnMainRoom: IRoom; before('Create test team', async () => { testUser = await createUser(); testUserCredentials = await login(testUser.username, password); const members = testUser.username ? [testUser.username] : []; testTeam = await createTeam(credentials, teamName, 0, members); testPrivateTeam = await createTeam(testUserCredentials, `${teamName}private`, 1, []); }); before('make user owner', async () => { await request .post(api('teams.updateMember')) .set(credentials) .send({ teamName: testTeam.name, member: { userId: testUser._id, roles: ['member', 'owner'], }, }) .expect('Content-Type', 'application/json') .expect(200); }); before('create rooms', async () => { privateRoom = (await createRoom({ type: 'p', name: `test-p-${Date.now()}` })).body.group; privateRoom2 = (await createRoom({ type: 'p', name: `test-p2-${Date.now()}`, credentials: testUserCredentials })).body.group; publicRoom = (await createRoom({ type: 'c', name: `test-c-${Date.now()}` })).body.channel; publicRoom2 = (await createRoom({ type: 'c', name: `test-c2-${Date.now()}` })).body.channel; await Promise.all([ request .post(api('teams.addRooms')) .set(credentials) .send({ rooms: [privateRoom._id, publicRoom._id, publicRoom2._id], teamId: testTeam._id, }) .expect(200), request .post(api('teams.addRooms')) .set(testUserCredentials) .send({ rooms: [privateRoom2._id], teamId: testTeam._id, }) .expect(200), ]); }); before('Create discussions', async () => { discussionOnPrivateRoom = ( await request .post(api('rooms.createDiscussion')) .set(credentials) .send({ prid: privateRoom._id, t_name: `test-d-${Date.now()}`, }) ).body.discussion; discussionOnPublicRoom = ( await request .post(api('rooms.createDiscussion')) .set(credentials) .send({ prid: publicRoom._id, t_name: `test-d-${Date.now()}`, }) ).body.discussion; discussionOnMainRoom = ( await request .post(api('rooms.createDiscussion')) .set(credentials) .send({ prid: testTeam.roomId, t_name: `test-d-${Date.now()}`, }) ).body.discussion; }); after(async () => { await Promise.all([ deleteRoom({ type: 'p', roomId: privateRoom._id }), deleteRoom({ type: 'p', roomId: privateRoom2._id }), deleteRoom({ type: 'c', roomId: publicRoom._id }), deleteRoom({ type: 'c', roomId: publicRoom2._id }), deleteRoom({ type: 'p', roomId: discussionOnPrivateRoom._id }), deleteRoom({ type: 'c', roomId: discussionOnPublicRoom._id }), deleteRoom({ type: 'c', roomId: discussionOnMainRoom._id }), deleteTeam(credentials, teamName), deleteTeam(credentials, testPrivateTeam.name), deleteUser({ _id: testUser._id }), ]); }); it('should fail if user is not logged in', async () => { await request.get(api('teams.listChildren')).expect(401); }); it('should fail if teamId is not passed as queryparam', async () => { await request.get(api('teams.listChildren')).set(credentials).expect(400); }); it('should fail if teamId is not valid', async () => { await request.get(api('teams.listChildren')).set(credentials).query({ teamId: 'invalid' }).expect(404); }); it('should fail if teamId is empty', async () => { await request.get(api('teams.listChildren')).set(credentials).query({ teamId: '' }).expect(404); }); it('should fail if both properties are passed', async () => { await request.get(api('teams.listChildren')).set(credentials).query({ teamId: testTeam._id, teamName: testTeam.name }).expect(400); }); it('should fail if teamName is empty', async () => { await request.get(api('teams.listChildren')).set(credentials).query({ teamName: '' }).expect(404); }); it('should fail if teamName is invalid', async () => { await request.get(api('teams.listChildren')).set(credentials).query({ teamName: 'invalid' }).expect(404); }); it('should fail if roomId is empty', async () => { await request.get(api('teams.listChildren')).set(credentials).query({ roomId: '' }).expect(404); }); it('should fail if roomId is invalid', async () => { await request.get(api('teams.listChildren')).set(credentials).query({ teamName: 'invalid' }).expect(404); }); it('should return a list of valid rooms for user', async () => { const res = await request.get(api('teams.listChildren')).query({ teamId: testTeam._id }).set(credentials).expect(200); expect(res.body).to.have.property('total').to.be.equal(5); expect(res.body).to.have.property('data').to.be.an('array'); expect(res.body.data).to.have.lengthOf(5); const mainRoom = res.body.data.find((room: IRoom) => room._id === testTeam.roomId); expect(mainRoom).to.be.an('object'); const publicChannel1 = res.body.data.find((room: IRoom) => room._id === publicRoom._id); expect(publicChannel1).to.be.an('object'); const publicChannel2 = res.body.data.find((room: IRoom) => room._id === publicRoom2._id); expect(publicChannel2).to.be.an('object'); const privateChannel1 = res.body.data.find((room: IRoom) => room._id === privateRoom._id); expect(privateChannel1).to.be.an('object'); const privateChannel2 = res.body.data.find((room: IRoom) => room._id === privateRoom2._id); expect(privateChannel2).to.be.undefined; const discussionOnP = res.body.data.find((room: IRoom) => room._id === discussionOnPrivateRoom._id); expect(discussionOnP).to.be.undefined; const discussionOnC = res.body.data.find((room: IRoom) => room._id === discussionOnPublicRoom._id); expect(discussionOnC).to.be.undefined; const mainDiscussion = res.body.data.find((room: IRoom) => room._id === discussionOnMainRoom._id); expect(mainDiscussion).to.be.an('object'); }); it('should return a valid list of rooms for non admin member too', async () => { const res = await request.get(api('teams.listChildren')).query({ teamName: testTeam.name }).set(testUserCredentials).expect(200); expect(res.body).to.have.property('total').to.be.equal(5); expect(res.body).to.have.property('data').to.be.an('array'); expect(res.body.data).to.have.lengthOf(5); const mainRoom = res.body.data.find((room: IRoom) => room._id === testTeam.roomId); expect(mainRoom).to.be.an('object'); const publicChannel1 = res.body.data.find((room: IRoom) => room._id === publicRoom._id); expect(publicChannel1).to.be.an('object'); const publicChannel2 = res.body.data.find((room: IRoom) => room._id === publicRoom2._id); expect(publicChannel2).to.be.an('object'); const privateChannel1 = res.body.data.find((room: IRoom) => room._id === privateRoom._id); expect(privateChannel1).to.be.undefined; const privateChannel2 = res.body.data.find((room: IRoom) => room._id === privateRoom2._id); expect(privateChannel2).to.be.an('object'); const discussionOnP = res.body.data.find((room: IRoom) => room._id === discussionOnPrivateRoom._id); expect(discussionOnP).to.be.undefined; const discussionOnC = res.body.data.find((room: IRoom) => room._id === discussionOnPublicRoom._id); expect(discussionOnC).to.be.undefined; const mainDiscussion = res.body.data.find((room: IRoom) => room._id === discussionOnMainRoom._id); expect(mainDiscussion).to.be.an('object'); }); it('should return a valid list of rooms for non admin member too when filtering by teams main room id', async () => { const res = await request.get(api('teams.listChildren')).query({ roomId: testTeam.roomId }).set(testUserCredentials).expect(200); expect(res.body).to.have.property('total').to.be.equal(5); expect(res.body).to.have.property('data').to.be.an('array'); expect(res.body.data).to.have.lengthOf(5); const mainRoom = res.body.data.find((room: IRoom) => room._id === testTeam.roomId); expect(mainRoom).to.be.an('object'); const publicChannel1 = res.body.data.find((room: IRoom) => room._id === publicRoom._id); expect(publicChannel1).to.be.an('object'); const publicChannel2 = res.body.data.find((room: IRoom) => room._id === publicRoom2._id); expect(publicChannel2).to.be.an('object'); const privateChannel1 = res.body.data.find((room: IRoom) => room._id === privateRoom._id); expect(privateChannel1).to.be.undefined; const privateChannel2 = res.body.data.find((room: IRoom) => room._id === privateRoom2._id); expect(privateChannel2).to.be.an('object'); const discussionOnP = res.body.data.find((room: IRoom) => room._id === discussionOnPrivateRoom._id); expect(discussionOnP).to.be.undefined; const discussionOnC = res.body.data.find((room: IRoom) => room._id === discussionOnPublicRoom._id); expect(discussionOnC).to.be.undefined; const mainDiscussion = res.body.data.find((room: IRoom) => room._id === discussionOnMainRoom._id); expect(mainDiscussion).to.be.an('object'); }); it('should return a list of rooms filtered by name using the filter parameter', async () => { const res = await request .get(api('teams.listChildren')) .query({ teamId: testTeam._id, filter: 'test-p' }) .set(credentials) .expect(200); expect(res.body).to.have.property('total').to.be.equal(1); expect(res.body).to.have.property('data').to.be.an('array'); expect(res.body.data[0]._id).to.be.equal(privateRoom._id); expect(res.body.data.find((room: IRoom) => room._id === privateRoom2._id)).to.be.undefined; }); it('should paginate results', async () => { const res = await request .get(api('teams.listChildren')) .query({ teamId: testTeam._id, offset: 1, count: 2 }) .set(credentials) .expect(200); expect(res.body).to.have.property('total').to.be.equal(5); expect(res.body).to.have.property('data').to.be.an('array'); expect(res.body.data).to.have.lengthOf(2); }); it('should return only items of type channel', async () => { const res = await request .get(api('teams.listChildren')) .query({ teamId: testTeam._id, type: 'channels' }) .set(credentials) .expect(200); expect(res.body).to.have.property('total').to.be.equal(4); expect(res.body).to.have.property('data').to.be.an('array'); expect(res.body.data).to.have.lengthOf(4); expect(res.body.data.some((room: IRoom) => !!room.prid)).to.be.false; }); it('should return only items of type discussion', async () => { const res = await request .get(api('teams.listChildren')) .query({ teamId: testTeam._id, type: 'discussions' }) .set(credentials) .expect(200); expect(res.body).to.have.property('total').to.be.equal(1); expect(res.body).to.have.property('data').to.be.an('array'); expect(res.body.data).to.have.lengthOf(1); expect(res.body.data.every((room: IRoom) => !!room.prid)).to.be.true; }); it('should return both when type is not passed', async () => { const res = await request.get(api('teams.listChildren')).query({ teamId: testTeam._id }).set(credentials).expect(200); expect(res.body).to.have.property('total').to.be.equal(5); expect(res.body).to.have.property('data').to.be.an('array'); expect(res.body.data).to.have.lengthOf(5); expect(res.body.data.some((room: IRoom) => !!room.prid)).to.be.true; expect(res.body.data.some((room: IRoom) => !room.prid)).to.be.true; }); it('should fail if type is other than channel or discussion', async () => { await request.get(api('teams.listChildren')).query({ teamId: testTeam._id, type: 'other' }).set(credentials).expect(400); }); it('should properly list children of a private team', async () => { const res = await request.get(api('teams.listChildren')).query({ teamId: testPrivateTeam._id }).set(testUserCredentials).expect(200); expect(res.body).to.have.property('total').to.be.equal(1); expect(res.body).to.have.property('data').to.be.an('array'); expect(res.body.data).to.have.lengthOf(1); }); it('should throw an error when a non member user tries to fetch info for team', async () => { await request.get(api('teams.listChildren')).query({ teamId: testPrivateTeam._id }).set(credentials).expect(400); }); }); }); describe('/teams.updateRoom', () => { let publicRoom: IRoom; let publicTeam: ITeam; const name = `teamName-update-room-${Date.now()}`; before(async () => { publicRoom = (await createRoom({ type: 'c', name: `public-update-room-${Date.now()}` })).body.channel; publicTeam = await createTeam(credentials, name, TeamType.PUBLIC); await request .post(api('teams.addRooms')) .set(credentials) .send({ rooms: [publicRoom._id], teamId: publicTeam._id, }); }); after(async () => { await deleteTeam(credentials, name); await Promise.all([ updatePermission('edit-team-channel', ['admin', 'owner', 'moderator']), deleteRoom({ type: 'c', roomId: publicRoom._id }), ]); }); it('should throw an error if no permission', async () => { await updatePermission('edit-team-channel', []); const res = await request .post(api('teams.updateRoom')) .set(credentials) .send({ roomId: publicRoom._id, isDefault: true, }) .expect('Content-Type', 'application/json') .expect(403); expect(res.body).to.have.property('success', false); expect(res.body).to.have.property('error'); expect(res.body.error).to.be.equal('unauthorized'); }); it('should set room to team default', async () => { await updatePermission('edit-team-channel', ['admin']); const res = await request .post(api('teams.updateRoom')) .set(credentials) .send({ roomId: publicRoom._id, isDefault: true, }) .expect('Content-Type', 'application/json') .expect(200); expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('room'); expect(res.body.room).to.have.property('teamId', publicTeam._id); expect(res.body.room).to.have.property('teamDefault', true); }); describe('team auto-join', () => { let testTeam: ITeam; let createdRoom: IRoom; let testUser1: TestUser; let testUser2: TestUser; let additionalRoom: IRoom; let memberTestUser1: TestUser; let memberTestUser1Credentials: Credentials; let testUser1Credentials: Credentials; let testUser2Credentials: Credentials; before(async () => { [testUser1, testUser2, memberTestUser1] = await Promise.all([createUser(), createUser(), createUser()]); [memberTestUser1Credentials, testUser1Credentials, testUser2Credentials] = await Promise.all([ login(memberTestUser1.username, password), login(testUser1.username, password), login(testUser2.username, password), ]); }); beforeEach(async () => { const timestamp = Date.now(); testTeam = await createTeam(credentials, `test-team-name${timestamp}`, 0); createdRoom = (await createRoom({ name: `test-room-name${timestamp}`, type: 'c' })).body.channel; additionalRoom = (await createRoom({ name: `additional-room-name${timestamp}`, type: 'c' })).body.channel; await request .post(api('teams.addRooms')) .set(credentials) .expect(200) .send({ rooms: [createdRoom._id, additionalRoom._id], teamName: testTeam.name, }); }); afterEach(() => Promise.all([ deleteTeam(credentials, testTeam.name), deleteRoom({ roomId: createdRoom._id, type: 'c' }), deleteRoom({ roomId: additionalRoom._id, type: 'c' }), ]), ); after(() => Promise.all([updateSetting('API_User_Limit', 500), deleteUser(testUser1), deleteUser(testUser2), deleteUser(memberTestUser1)]), ); it('should add members when the members count is less than or equal to the API_User_Limit setting', async () => { await updateSetting('API_User_Limit', 2); await addMembers(credentials, testTeam.name, [testUser1._id, testUser2._id]); await request .post(api('teams.updateRoom')) .set(credentials) .send({ roomId: createdRoom._id, isDefault: true, }) .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.nested.property('room.usersCount').and.to.be.equal(3); }); }); it('should not add all members when we update a team channel to be auto-join and the members count is greater than the API_User_Limit setting', async () => { await updateSetting('API_User_Limit', 1); await addMembers(credentials, testTeam.name, [testUser1._id, testUser2._id]); await request .post(api('teams.updateRoom')) .set(credentials) .send({ roomId: createdRoom._id, isDefault: true, }) .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.nested.property('room.usersCount').and.to.be.equal(2); }); }); it('should auto-join users to auto-join channels when added to team', async () => { await request .post(api('teams.updateRoom')) .set(credentials) .send({ roomId: createdRoom._id, isDefault: true, }) .expect(200); await request .post(api('teams.addMembers')) .set(credentials) .send({ teamId: testTeam._id, members: [{ userId: memberTestUser1._id, roles: ['member'] }], }) .expect(200); const subscriptionResponse = await request .get(api('subscriptions.getOne')) .set(memberTestUser1Credentials) .query({ roomId: createdRoom._id }) .expect(200); expect(subscriptionResponse.body).to.have.property('success', true); expect(subscriptionResponse.body).to.have.property('subscription').that.is.an('object'); expect(subscriptionResponse.body.subscription).to.have.property('u').that.is.an('object'); expect(subscriptionResponse.body.subscription.u).to.have.property('_id', memberTestUser1._id); }); it('should auto-join users to multiple auto-join channels when added to team', async () => { await Promise.all([ request .post(api('teams.updateRoom')) .set(credentials) .send({ roomId: createdRoom._id, isDefault: true, }) .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('room').that.is.an('object'); expect(res.body.room).to.have.property('teamDefault', true); }), request .post(api('teams.updateRoom')) .set(credentials) .send({ roomId: additionalRoom._id, isDefault: true, }) .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('room').that.is.an('object'); expect(res.body.room).to.have.property('teamDefault', true); }), ]); await request .post(api('teams.addMembers')) .set(credentials) .send({ teamId: testTeam._id, members: [{ userId: memberTestUser1._id, roles: ['member'] }], }) .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); }); await request .get(api('teams.members')) .set(credentials) .query({ teamId: testTeam._id }) .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('members').that.is.an('array'); const userMember = res.body.members.find((member: any) => member.user._id === memberTestUser1._id); expect(userMember).to.exist; expect(userMember).to.have.property('roles').that.includes('member'); }); const [subscription1Response, subscription2Response] = await Promise.all([ request.get(api('subscriptions.getOne')).set(memberTestUser1Credentials).query({ roomId: createdRoom._id }).expect(200), request.get(api('subscriptions.getOne')).set(memberTestUser1Credentials).query({ roomId: additionalRoom._id }).expect(200), ]); expect(subscription1Response.body).to.have.property('success', true); expect(subscription1Response.body).to.have.property('subscription').that.is.an('object'); expect(subscription1Response.body.subscription.u).to.have.property('_id', memberTestUser1._id); expect(subscription2Response.body).to.have.property('success', true); expect(subscription2Response.body).to.have.property('subscription').that.is.an('object'); expect(subscription2Response.body.subscription.u).to.have.property('_id', memberTestUser1._id); }); it('should not auto-join users to non-default team channels when added to team', async () => { await request .post(api('teams.updateRoom')) .set(credentials) .send({ roomId: createdRoom._id, isDefault: true, }) .expect(200); await request .post(api('teams.addMembers')) .set(credentials) .send({ teamId: testTeam._id, members: [{ userId: memberTestUser1._id, roles: ['member'] }], }) .expect(200); const createdRoomResponse = await request.get(api('channels.info')).set(credentials).query({ roomId: createdRoom._id }).expect(200); expect(createdRoomResponse.body).to.have.property('success', true); expect(createdRoomResponse.body.channel).to.have.property('usersCount').that.is.at.least(2); const additionalRoomResponse = await request .get(api('channels.info')) .set(credentials) .query({ roomId: additionalRoom._id }) .expect(200); expect(additionalRoomResponse.body).to.have.property('success', true); expect(additionalRoomResponse.body.channel).to.have.property('usersCount', 1); // Only admin, user not auto-joined }); it('should add multiple users to auto-join channels when added to team', async () => { await request .post(api('teams.updateRoom')) .set(credentials) .send({ roomId: createdRoom._id, isDefault: true, }) .expect(200); await request .post(api('teams.addMembers')) .set(credentials) .send({ teamId: testTeam._id, members: [ { userId: testUser1._id, roles: ['member'] }, { userId: testUser2._id, roles: ['member'] }, ], }) .expect(200); const [testUser1SubscriptionResponse, testUser2SubscriptionResponse] = await Promise.all([ request.get(api('subscriptions.getOne')).set(testUser1Credentials).query({ roomId: createdRoom._id }).expect(200), request.get(api('subscriptions.getOne')).set(testUser2Credentials).query({ roomId: createdRoom._id }).expect(200), ]); expect(testUser1SubscriptionResponse.body).to.have.property('success', true); expect(testUser1SubscriptionResponse.body).to.have.property('subscription').that.is.an('object'); expect(testUser1SubscriptionResponse.body.subscription.u).to.have.property('_id', testUser1._id); expect(testUser2SubscriptionResponse.body).to.have.property('success', true); expect(testUser2SubscriptionResponse.body).to.have.property('subscription').that.is.an('object'); expect(testUser2SubscriptionResponse.body.subscription.u).to.have.property('_id', testUser2._id); const roomInfoResponse = await request.get(api('channels.info')).set(credentials).query({ roomId: createdRoom._id }).expect(200); expect(roomInfoResponse.body).to.have.property('success', true); expect(roomInfoResponse.body).to.have.property('channel').that.is.an('object'); expect(roomInfoResponse.body.channel).to.have.property('usersCount').that.is.at.least(3); // admin + testUser1 + testUser2 }); it('should not remove existing members when disabling auto-join on a channel', async () => { await request .post(api('teams.updateRoom')) .set(credentials) .send({ roomId: createdRoom._id, isDefault: true, }) .expect(200); await request .post(api('teams.addMembers')) .set(credentials) .send({ teamId: testTeam._id, members: [{ userId: memberTestUser1._id, roles: ['member'] }], }) .expect(200); const initialSubscriptionResponse = await request .get(api('subscriptions.getOne')) .set(memberTestUser1Credentials) .query({ roomId: createdRoom._id }) .expect(200); expect(initialSubscriptionResponse.body).to.have.property('success', true); expect(initialSubscriptionResponse.body).to.have.property('subscription').that.is.an('object'); await request .post(api('teams.updateRoom')) .set(credentials) .send({ roomId: createdRoom._id, isDefault: false, }) .expect(200); // Verify user is still subscribed to the channel after disabling auto-join const finalSubscriptionResponse = await request .get(api('subscriptions.getOne')) .set(memberTestUser1Credentials) .query({ roomId: createdRoom._id }) .expect(200); expect(finalSubscriptionResponse.body).to.have.property('success', true); expect(finalSubscriptionResponse.body).to.have.property('subscription').that.is.an('object'); expect(finalSubscriptionResponse.body.subscription.u).to.have.property('_id', memberTestUser1._id); }); }); }); describe('/teams.removeRoom', () => { let publicRoom: IRoom; let publicTeam: ITeam; const name = `teamName-remove-room-${Date.now()}`; before(async () => { publicRoom = (await createRoom({ type: 'c', name: `public-remove-room-${Date.now()}` })).body.channel; publicTeam = await createTeam(credentials, name, TeamType.PUBLIC); await request .post(api('teams.addRooms')) .set(credentials) .send({ rooms: [publicRoom._id], teamId: publicTeam._id, }); }); after(async () => { await deleteTeam(credentials, name); await Promise.all([ updatePermission('edit-team-channel', ['admin', 'owner', 'moderator']), deleteRoom({ type: 'c', roomId: publicRoom._id }), ]); }); after(() => Promise.all([ updatePermission('remove-team-channel', ['admin', 'owner', 'moderator']), deleteRoom({ type: 'c', roomId: publicRoom._id }), deleteTeam(credentials, name), ]), ); it('should throw an error if no permission', async () => { await updatePermission('remove-team-channel', []); const res = await request .post(api('teams.removeRoom')) .set(credentials) .send({ roomId: publicRoom._id, teamId: publicTeam._id, }) .expect('Content-Type', 'application/json') .expect(403); expect(res.body).to.have.property('success', false); expect(res.body).to.have.property('error'); expect(res.body.error).to.be.equal('unauthorized'); }); it('should remove room from team', async () => { await updatePermission('remove-team-channel', ['admin']); const res = await request .post(api('teams.removeRoom')) .set(credentials) .send({ roomId: publicRoom._id, teamId: publicTeam._id, }) .expect('Content-Type', 'application/json') .expect(200); expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('room'); expect(res.body.room).to.not.have.property('teamId'); expect(res.body.room).to.not.have.property('teamDefault'); }); }); describe('/teams.update', () => { let testTeam: ITeam; let testTeam2: ITeam; let testTeam3: ITeam; const teamName = `test-team-name1${Date.now()}`; const teamName2 = `test-team-name2${Date.now()}`; const teamName3 = `test-team-name3${Date.now()}`; const testTeamName = `test-team-name-changed${Date.now()}-1`; const testTeamName2 = `test-team-name-changed${Date.now()}-2`; let unauthorizedUser: TestUser; before('Create test team', (done) => { void request .post(api('teams.create')) .set(credentials) .send({ name: teamName, type: 0, }) .end((_err, res) => { testTeam = res.body.team; done(); }); }); before('Create test team', (done) => { void request .post(api('teams.create')) .set(credentials) .send({ name: teamName2, type: 0, }) .end((_err, res) => { testTeam2 = res.body.team; done(); }); }); before('Create test team', (done) => { void request .post(api('teams.create')) .set(credentials) .send({ name: teamName3, type: 0, }) .end((_err, res) => { testTeam3 = res.body.team; done(); }); }); before(async () => { unauthorizedUser = await createUser(); }); after(() => Promise.all([...[testTeamName, testTeamName2, teamName3].map((name) => deleteTeam(credentials, name)), deleteUser(unauthorizedUser)]), ); it('should update team name', async () => { const updateResponse = await request .post(api('teams.update')) .set(credentials) .send({ teamId: testTeam._id, data: { name: testTeamName, }, }); expect(updateResponse.body).to.have.property('success', true); const infoResponse = await request.get(api('teams.info')).set(credentials).query({ teamId: testTeam._id }); expect(infoResponse.body).to.have.property('success', true); const { teamInfo } = infoResponse.body; expect(teamInfo).to.have.property('name', testTeamName); }); it('should update team type', async () => { const updateResponse = await request .post(api('teams.update')) .set(credentials) .send({ teamId: testTeam._id, data: { type: 1, }, }); expect(updateResponse.body).to.have.property('success', true); const infoResponse = await request.get(api('teams.info')).set(credentials).query({ teamId: testTeam._id }); expect(infoResponse.body).to.have.property('success', true); const { teamInfo } = infoResponse.body; expect(teamInfo).to.have.property('type', 1); }); it('should update team name and type at once', async () => { const updateResponse = await request .post(api('teams.update')) .set(credentials) .send({ teamId: testTeam2._id, data: { name: testTeamName2, type: 1, }, }); expect(updateResponse.body).to.have.property('success', true); const infoResponse = await request.get(api('teams.info')).set(credentials).query({ teamId: testTeam2._id }); expect(infoResponse.body).to.have.property('success', true); const { teamInfo } = infoResponse.body; expect(teamInfo).to.have.property('type', 1); }); it('should not update team if permissions are not met', async () => { const unauthorizedUserCredentials = await login(unauthorizedUser.username, password); const res = await request .post(api('teams.update')) .set(unauthorizedUserCredentials) .send({ teamId: testTeam._id, data: { name: 'anyname', }, }) .expect('Content-Type', 'application/json') .expect(403); expect(res.body).to.have.property('success', false); }); describe('should update team room to default and invite users with the right notification preferences', () => { let userWithPrefs: TestUser; let userCredentials: Credentials; let createdRoom: IRoom; before(async () => { userWithPrefs = await createUser(); userCredentials = await login(userWithPrefs.username, password); createdRoom = (await createRoom({ type: 'c', name: `${Date.now()}-testTeam3` })).body.channel; await request .post(api('teams.addRooms')) .set(credentials) .send({ rooms: [createdRoom._id], teamId: testTeam3._id, }); }); after(() => Promise.all([deleteUser(userWithPrefs), deleteRoom({ type: 'c', roomId: createdRoom._id })])); it('should update user prefs', async () => { await request .post(methodCall('saveUserPreferences')) .set(userCredentials) .send({ message: JSON.stringify({ method: 'saveUserPreferences', params: [{ emailNotificationMode: 'nothing' }], id: 'id', msg: 'method', }), }) .expect(200); }); it('should add user with prefs to team', async () => { await request .post(api('teams.addMembers')) .set(credentials) .send({ teamName: testTeam3.name, members: [ { userId: userWithPrefs._id, roles: ['member'], }, ], }); }); it('should update team channel to auto-join', async () => { const response = await request.post(api('teams.updateRoom')).set(credentials).send({ roomId: createdRoom._id, isDefault: true, }); expect(response.body).to.have.property('success', true); }); it('should return the user subscription with the right notification preferences', async () => { const res = await request .get(api('subscriptions.getOne')) .set(userCredentials) .query({ roomId: createdRoom._id, }) .expect('Content-Type', 'application/json') .expect(200); expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('subscription').and.to.be.an('object'); expect(res.body).to.have.nested.property('subscription.emailNotifications').and.to.be.equal('nothing'); }); }); });