Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Code scanning - action / CodeQL-Build (push) Failing after 2s
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
2923 lines
90 KiB
TypeScript
2923 lines
90 KiB
TypeScript
import type { Credentials } from '@rocket.chat/api-client';
|
|
import { TeamType, type IIntegration, type IMessage, type IRoom, type ITeam, type IUser } from '@rocket.chat/core-typings';
|
|
import { assert, expect } from 'chai';
|
|
import { after, before, describe, it, beforeEach } from 'mocha';
|
|
|
|
import { getCredentials, api, request, credentials, apiPrivateChannelName } from '../../data/api-data';
|
|
import { pinMessage, starMessage, sendMessage, updateMessage } from '../../data/chat.helper';
|
|
import { CI_MAX_ROOMS_PER_GUEST as maxRoomsPerGuest } from '../../data/constants';
|
|
import { createGroup, deleteGroup } from '../../data/groups.helper';
|
|
import { createIntegration, removeIntegration } from '../../data/integration.helper';
|
|
import { updatePermission, updateSetting } from '../../data/permissions.helper';
|
|
import { createRoom, deleteRoom } from '../../data/rooms.helper';
|
|
import { createTeam, deleteTeam } from '../../data/teams.helper';
|
|
import { testFileUploads } from '../../data/uploads.helper';
|
|
import { adminUsername, password } from '../../data/user';
|
|
import type { TestUser } from '../../data/users.helper';
|
|
import { createUser, login, deleteUser } from '../../data/users.helper';
|
|
|
|
function getRoomInfo(roomId: IRoom['_id']) {
|
|
return new Promise<{ group: IRoom }>((resolve) => {
|
|
void request
|
|
.get(api('groups.info'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId,
|
|
})
|
|
.end((_err, req) => {
|
|
resolve(req.body);
|
|
});
|
|
});
|
|
}
|
|
|
|
describe('[Groups]', () => {
|
|
let group: {
|
|
_id: string;
|
|
name: string;
|
|
};
|
|
|
|
before((done) => getCredentials(done));
|
|
|
|
before(async () => {
|
|
await request
|
|
.post(api('groups.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: apiPrivateChannelName,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('group._id');
|
|
expect(res.body).to.have.nested.property('group.name', apiPrivateChannelName);
|
|
expect(res.body).to.have.nested.property('group.t', 'p');
|
|
expect(res.body).to.have.nested.property('group.msgs', 0);
|
|
group = {
|
|
_id: res.body.group._id,
|
|
name: res.body.group.name,
|
|
};
|
|
});
|
|
});
|
|
|
|
after(async () => {
|
|
await request
|
|
.post(api('groups.delete'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
});
|
|
|
|
describe('/groups.create', () => {
|
|
let guestUser: TestUser<IUser>;
|
|
let invitedUser: TestUser<IUser>;
|
|
let invitedUserCredentials: Credentials;
|
|
let room: IRoom;
|
|
let teamId: ITeam['_id'];
|
|
|
|
before(async () => {
|
|
guestUser = await createUser({ roles: ['guest'] });
|
|
invitedUser = await createUser();
|
|
invitedUserCredentials = await login(invitedUser.username, password);
|
|
|
|
await updatePermission('create-team', ['admin', 'user']);
|
|
const teamCreateRes = await request
|
|
.post(api('teams.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: `team-${Date.now()}`,
|
|
type: 0,
|
|
members: [invitedUser.username],
|
|
});
|
|
|
|
teamId = teamCreateRes.body.team._id;
|
|
await updatePermission('create-team-group', ['owner']);
|
|
});
|
|
|
|
after(async () => {
|
|
await deleteUser(guestUser);
|
|
await deleteUser(invitedUser);
|
|
await updatePermission('create-team-group', ['admin', 'owner', 'moderator']);
|
|
});
|
|
|
|
describe('guest users', () => {
|
|
it('should not add guest users to more rooms than defined in the license', async function () {
|
|
// TODO this is not the right way to do it. We're doing this way for now just because we have separate CI jobs for EE and CE,
|
|
// ideally we should have a single CI job that adds a license and runs both CE and EE tests.
|
|
if (!process.env.IS_EE) {
|
|
this.skip();
|
|
}
|
|
const promises = [];
|
|
|
|
for (let i = 0; i < maxRoomsPerGuest; i++) {
|
|
promises.push(
|
|
createRoom({
|
|
type: 'p',
|
|
name: `channel.test.${Date.now()}-${Math.random()}`,
|
|
members: [guestUser.username],
|
|
}),
|
|
);
|
|
}
|
|
await Promise.all(promises);
|
|
|
|
await request
|
|
.post(api('groups.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: `channel.test.${Date.now()}-${Math.random()}`,
|
|
members: [guestUser.username],
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
room = res.body.group;
|
|
});
|
|
|
|
await request
|
|
.get(api('groups.members'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: room._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('members').and.to.be.an('array');
|
|
expect(res.body.members).to.have.lengthOf(1);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('validate E2E rooms', () => {
|
|
before(async () => {
|
|
await Promise.all([updateSetting('E2E_Enable', true), updateSetting('E2E_Allow_Unencrypted_Messages', false)]);
|
|
});
|
|
|
|
after(async () => {
|
|
await Promise.all([updateSetting('E2E_Enable', false), updateSetting('E2E_Allow_Unencrypted_Messages', true)]);
|
|
});
|
|
|
|
let rid: IRoom['_id'];
|
|
|
|
it('should create a new encrypted group', async () => {
|
|
await request
|
|
.post(api('groups.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: `encrypted-${apiPrivateChannelName}`,
|
|
extraData: {
|
|
encrypted: true,
|
|
},
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('group.name', `encrypted-${apiPrivateChannelName}`);
|
|
expect(res.body).to.have.nested.property('group.t', 'p');
|
|
expect(res.body).to.have.nested.property('group.msgs', 0);
|
|
expect(res.body).to.have.nested.property('group.encrypted', true);
|
|
rid = res.body.group._id;
|
|
});
|
|
});
|
|
|
|
it('should send an encrypted message in encrypted group', async () => {
|
|
await request
|
|
.post(api('chat.sendMessage'))
|
|
.set(credentials)
|
|
.send({
|
|
message: {
|
|
text: 'Encrypted Message',
|
|
t: 'e2e',
|
|
e2e: 'pending',
|
|
rid,
|
|
},
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('message');
|
|
expect(res.body).to.have.nested.property('message.text', 'Encrypted Message');
|
|
expect(res.body).to.have.nested.property('message.t', 'e2e');
|
|
expect(res.body).to.have.nested.property('message.e2e', 'pending');
|
|
});
|
|
});
|
|
|
|
it('should give an error on sending un-encrypted message in encrypted room', async () => {
|
|
await request
|
|
.post(api('chat.sendMessage'))
|
|
.set(credentials)
|
|
.send({
|
|
message: {
|
|
text: 'Unencrypted Message',
|
|
rid,
|
|
},
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('error').that.is.a('string');
|
|
});
|
|
});
|
|
|
|
it('should allow sending un-encrypted messages in encrypted room when setting is enabled', async () => {
|
|
await updateSetting('E2E_Allow_Unencrypted_Messages', true);
|
|
await request
|
|
.post(api('chat.sendMessage'))
|
|
.set(credentials)
|
|
.send({
|
|
message: {
|
|
text: 'Unencrypted Message',
|
|
rid,
|
|
},
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('message');
|
|
expect(res.body).to.have.nested.property('message.text', 'Unencrypted Message');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('E2E enabled by default', () => {
|
|
before(async () => {
|
|
await Promise.all([updateSetting('E2E_Enable', true), updateSetting('E2E_Enabled_Default_PrivateRooms', true)]);
|
|
});
|
|
|
|
after(async () => {
|
|
await Promise.all([updateSetting('E2E_Enable', false), updateSetting('E2E_Enabled_Default_PrivateRooms', false)]);
|
|
});
|
|
|
|
it('should create the encrypted room by default', async () => {
|
|
await request
|
|
.post(api('groups.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: `default-encrypted-${apiPrivateChannelName}`,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('group.name', `default-encrypted-${apiPrivateChannelName}`);
|
|
expect(res.body).to.have.nested.property('group.t', 'p');
|
|
expect(res.body).to.have.nested.property('group.msgs', 0);
|
|
expect(res.body).to.have.nested.property('group.encrypted', true);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('E2E forced encryption for private rooms', () => {
|
|
const createdRoomIds: IRoom['_id'][] = [];
|
|
|
|
before(async () => {
|
|
await Promise.all([updateSetting('E2E_Enable', true), updateSetting('E2E_Force_Encryption_For_Private_Rooms', true)]);
|
|
});
|
|
|
|
after(async () => {
|
|
await Promise.all([
|
|
updateSetting('E2E_Enable', false),
|
|
updateSetting('E2E_Force_Encryption_For_Private_Rooms', false),
|
|
...createdRoomIds.map((roomId) => deleteRoom({ type: 'p', roomId })),
|
|
]);
|
|
});
|
|
|
|
it('should reject creating a private room with encrypted=false when private room encryption is forced', async () => {
|
|
await request
|
|
.post(api('groups.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: `forced-unencrypted-${apiPrivateChannelName}`,
|
|
extraData: {
|
|
encrypted: false,
|
|
},
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('errorType', 'error-encrypted-private-rooms-enforced');
|
|
});
|
|
});
|
|
|
|
it('should create an encrypted private room when encrypted is omitted and private room encryption is forced', async () => {
|
|
await request
|
|
.post(api('groups.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: `forced-default-${apiPrivateChannelName}`,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
if (res.body.group?._id) {
|
|
createdRoomIds.push(res.body.group._id);
|
|
}
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('group.t', 'p');
|
|
expect(res.body).to.have.nested.property('group.encrypted', true);
|
|
});
|
|
});
|
|
|
|
it('should allow creating a private room with encrypted=true when private room encryption is forced', async () => {
|
|
await request
|
|
.post(api('groups.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: `forced-encrypted-${apiPrivateChannelName}`,
|
|
extraData: {
|
|
encrypted: true,
|
|
},
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
if (res.body.group?._id) {
|
|
createdRoomIds.push(res.body.group._id);
|
|
}
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('group.t', 'p');
|
|
expect(res.body).to.have.nested.property('group.encrypted', true);
|
|
});
|
|
});
|
|
|
|
it('should not enforce encryption on federated private rooms', async () => {
|
|
// Federated rooms do not support E2EE, so the forced-encryption policy exempts them.
|
|
// Depending on the environment the creation may still fail further down the pipeline
|
|
// (federation unavailable), but it must never fail with the forced-encryption error,
|
|
// and if it succeeds the room must not have been force-encrypted.
|
|
await request
|
|
.post(api('groups.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: `forced-federated-${apiPrivateChannelName}`,
|
|
extraData: {
|
|
broadcast: false,
|
|
encrypted: false,
|
|
federated: true,
|
|
},
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect((res) => {
|
|
if (res.body.group?._id) {
|
|
createdRoomIds.push(res.body.group._id);
|
|
}
|
|
expect(res.body).to.not.have.property('errorType', 'error-encrypted-private-rooms-enforced');
|
|
if (res.body.success) {
|
|
expect(res.body).to.not.have.nested.property('group.encrypted', true);
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
it(`should fail when trying to use an existing room's name`, async () => {
|
|
await request
|
|
.post(api('groups.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: 'general',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.nested.property('errorType', 'error-duplicate-channel-name');
|
|
});
|
|
});
|
|
|
|
it('should successfully create a group in a team', async () => {
|
|
await request
|
|
.post(api('groups.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: `team-group-${Date.now()}`,
|
|
extraData: { teamId },
|
|
})
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('group');
|
|
expect(res.body.group).to.have.property('teamId', teamId);
|
|
});
|
|
});
|
|
|
|
it('should fail creating a group in a team when member does not have the necessary permission', async () => {
|
|
await request
|
|
.post(api('groups.create'))
|
|
.set(invitedUserCredentials)
|
|
.send({
|
|
name: `team-group-${Date.now()}`,
|
|
extraData: { teamId },
|
|
})
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('errorType', 'error-not-allowed');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('/groups.info', () => {
|
|
let testGroup: IRoom;
|
|
|
|
const newGroupInfoName = `info-private-channel-test-${Date.now()}`;
|
|
|
|
before('creating new group...', async () => {
|
|
await request
|
|
.post(api('groups.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: newGroupInfoName,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
testGroup = res.body.group;
|
|
});
|
|
});
|
|
|
|
after('deleting group...', async () => {
|
|
await request
|
|
.post(api('groups.delete'))
|
|
.set(credentials)
|
|
.send({
|
|
roomName: newGroupInfoName,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
});
|
|
|
|
it('should return group basic structure', async () => {
|
|
await request
|
|
.get(api('groups.info'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testGroup._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('group._id');
|
|
expect(res.body).to.have.nested.property('group.name', newGroupInfoName);
|
|
expect(res.body).to.have.nested.property('group.t', 'p');
|
|
expect(res.body).to.have.nested.property('group.msgs', 0);
|
|
});
|
|
});
|
|
|
|
let groupMessage: IMessage;
|
|
|
|
it('sending a message...', async () => {
|
|
await request
|
|
.post(api('chat.sendMessage'))
|
|
.set(credentials)
|
|
.send({
|
|
message: {
|
|
text: 'Sample message',
|
|
rid: testGroup._id,
|
|
},
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
groupMessage = res.body.message;
|
|
});
|
|
});
|
|
|
|
it('REACTing with last message', async () => {
|
|
await request
|
|
.post(api('chat.react'))
|
|
.set(credentials)
|
|
.send({
|
|
emoji: ':squid:',
|
|
messageId: groupMessage._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
|
|
it('STARring last message', async () => {
|
|
await request
|
|
.post(api('chat.starMessage'))
|
|
.set(credentials)
|
|
.send({
|
|
messageId: groupMessage._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
|
|
it('PINning last message', async () => {
|
|
await request
|
|
.post(api('chat.pinMessage'))
|
|
.set(credentials)
|
|
.send({
|
|
messageId: groupMessage._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
|
|
it('should return group structure with "lastMessage" object including pin, reaction and star(should be an array) infos', async () => {
|
|
await request
|
|
.get(api('groups.info'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testGroup._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('group').and.to.be.an('object');
|
|
const { group } = res.body;
|
|
expect(group).to.have.property('lastMessage').and.to.be.an('object');
|
|
expect(group.lastMessage).to.have.property('reactions').and.to.be.an('object');
|
|
expect(group.lastMessage).to.have.property('pinned').and.to.be.a('boolean');
|
|
expect(group.lastMessage).to.have.property('pinnedAt').and.to.be.a('string');
|
|
expect(group.lastMessage).to.have.property('pinnedBy').and.to.be.an('object');
|
|
expect(group.lastMessage).to.have.property('starred').and.to.be.an('array');
|
|
});
|
|
});
|
|
it('should return all groups messages where the last message of array should have the "star" array with USERS star ONLY', async () => {
|
|
await request
|
|
.get(api('groups.messages'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testGroup._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('messages').and.to.be.an('array');
|
|
const messages = res.body.messages as IMessage[];
|
|
const lastMessage = messages.filter((message) => message._id === groupMessage._id)[0];
|
|
expect(lastMessage).to.have.property('starred').and.to.be.an('array');
|
|
expect(lastMessage.starred?.[0]._id).to.be.equal(adminUsername);
|
|
});
|
|
});
|
|
|
|
it('should return all groups messages where the last message of array should have the "star" array with USERS star ONLY even requested with count and offset params', async () => {
|
|
await request
|
|
.get(api('groups.messages'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testGroup._id,
|
|
count: 5,
|
|
offset: 0,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('messages').and.to.be.an('array');
|
|
const messages = res.body.messages as IMessage[];
|
|
const lastMessage = messages.filter((message) => message._id === groupMessage._id)[0];
|
|
expect(lastMessage).to.have.property('starred').and.to.be.an('array');
|
|
expect(lastMessage.starred?.[0]._id).to.be.equal(adminUsername);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('/groups.messages', () => {
|
|
let testGroup: IRoom;
|
|
let firstUser: IUser;
|
|
let secondUser: IUser;
|
|
let pinnedMessageId: IMessage['_id'];
|
|
|
|
before(async () => {
|
|
testGroup = (await createGroup({ name: `test-group-${Date.now()}` })).body.group;
|
|
firstUser = await createUser({ joinDefaultChannels: false });
|
|
secondUser = await createUser({ joinDefaultChannels: false });
|
|
|
|
const messages = [
|
|
{
|
|
rid: testGroup._id,
|
|
msg: `@${firstUser.username} youre being mentioned`,
|
|
mentions: [{ username: firstUser.username, _id: firstUser._id, name: firstUser.name }],
|
|
},
|
|
{
|
|
rid: testGroup._id,
|
|
msg: `@${secondUser.username} youre being mentioned`,
|
|
mentions: [{ username: secondUser.username, _id: secondUser._id, name: secondUser.name }],
|
|
},
|
|
{
|
|
rid: testGroup._id,
|
|
msg: `A simple message`,
|
|
},
|
|
{
|
|
rid: testGroup._id,
|
|
msg: `A pinned simple message`,
|
|
},
|
|
];
|
|
|
|
const [, , starredMessage, pinnedMessage] = await Promise.all(messages.map((message) => sendMessage({ message })));
|
|
|
|
await Promise.all([
|
|
starMessage({ messageId: starredMessage.body.message._id }),
|
|
pinMessage({ messageId: pinnedMessage.body.message._id }),
|
|
]);
|
|
|
|
pinnedMessageId = pinnedMessage.body.message._id;
|
|
});
|
|
|
|
after(async () => {
|
|
await deleteGroup({ roomName: testGroup.name });
|
|
});
|
|
|
|
it('should return all messages from a group', async () => {
|
|
await request
|
|
.get(api('groups.messages'))
|
|
.set(credentials)
|
|
.query({ roomId: testGroup._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('messages').and.to.be.an('array');
|
|
expect(res.body.messages).to.have.lengthOf(5);
|
|
});
|
|
});
|
|
|
|
it('should return messages that mention a single user', async () => {
|
|
await request
|
|
.get(api('groups.messages'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testGroup._id,
|
|
mentionIds: firstUser._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body.messages).to.have.lengthOf(1);
|
|
expect(res.body.messages[0]).to.have.nested.property('mentions').that.is.an('array').and.to.have.lengthOf(1);
|
|
expect(res.body.messages[0].mentions[0]).to.have.property('_id', firstUser._id);
|
|
expect(res.body).to.have.property('count', 1);
|
|
expect(res.body).to.have.property('total', 1);
|
|
});
|
|
});
|
|
|
|
it('should return messages that mention multiple users', async () => {
|
|
await request
|
|
.get(api('groups.messages'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testGroup._id,
|
|
mentionIds: `${firstUser._id},${secondUser._id}`,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body.messages).to.have.lengthOf(2);
|
|
expect(res.body).to.have.property('count', 2);
|
|
expect(res.body).to.have.property('total', 2);
|
|
|
|
const mentionIds = res.body.messages.map((message: any) => message.mentions[0]._id);
|
|
expect(mentionIds).to.include.members([firstUser._id, secondUser._id]);
|
|
});
|
|
});
|
|
|
|
it('should return messages that are starred by a specific user', async () => {
|
|
await request
|
|
.get(api('groups.messages'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testGroup._id,
|
|
starredIds: 'rocketchat.internal.admin.test',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body.messages).to.have.lengthOf(1);
|
|
expect(res.body.messages[0]).to.have.nested.property('starred').that.is.an('array').and.to.have.lengthOf(1);
|
|
expect(res.body).to.have.property('count', 1);
|
|
expect(res.body).to.have.property('total', 1);
|
|
});
|
|
});
|
|
|
|
it('should return messages that are pinned', async () => {
|
|
await request
|
|
.get(api('groups.messages'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testGroup._id,
|
|
pinned: true,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body.messages).to.have.lengthOf(1);
|
|
expect(res.body.messages[0]).to.have.nested.property('pinned').that.is.an('boolean').and.to.be.true;
|
|
expect(res.body.messages[0]).to.have.nested.property('pinnedBy').that.is.an('object');
|
|
expect(res.body.messages[0].pinnedBy).to.have.property('_id', 'rocketchat.internal.admin.test');
|
|
expect(res.body).to.have.property('count', 1);
|
|
expect(res.body).to.have.property('total', 1);
|
|
});
|
|
});
|
|
|
|
it('should return all messages from a group using roomName parameter', async () => {
|
|
await request
|
|
.get(api('groups.messages'))
|
|
.set(credentials)
|
|
.query({ roomName: testGroup.name })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('messages').and.to.be.an('array');
|
|
expect(res.body.messages).to.have.lengthOf(5);
|
|
});
|
|
});
|
|
|
|
it('should return error if both roomId and roomName are provided', async () => {
|
|
const thirdGroup = (await createGroup({ name: `test-priority-${Date.now()}` })).body.group;
|
|
const secondGroup = (await createGroup({ name: `test-priority-${Date.now()}` })).body.group;
|
|
|
|
try {
|
|
await request
|
|
.get(api('groups.messages'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: thirdGroup._id,
|
|
roomName: secondGroup.name,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('errorType', 'error-invalid-params');
|
|
});
|
|
} finally {
|
|
await Promise.all([deleteGroup({ roomName: secondGroup.name }), deleteGroup({ roomName: thirdGroup.name })]);
|
|
}
|
|
});
|
|
|
|
describe('_hidden messages behavior when Message_KeepHistory is enabled', async () => {
|
|
before(async () => {
|
|
await updateSetting('Message_KeepHistory', true);
|
|
await pinMessage({ messageId: pinnedMessageId, unpin: true });
|
|
});
|
|
|
|
after(async () => {
|
|
await updateSetting('Message_KeepHistory', false);
|
|
});
|
|
|
|
it('should return all messages, without any pinned messages', async () => {
|
|
await request
|
|
.get(api('groups.messages'))
|
|
.set(credentials)
|
|
.query({ roomId: testGroup._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('messages').and.to.be.an('array');
|
|
expect(res.body.messages).to.have.lengthOf(5);
|
|
|
|
res.body.messages.forEach((msg: IMessage) => {
|
|
expect(msg).to.not.have.property('pinned', true);
|
|
expect(msg).to.not.have.property('_hidden');
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should return no pinned messages', async () => {
|
|
await request
|
|
.get(api('groups.messages'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testGroup._id,
|
|
pinned: true,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body.messages).to.have.lengthOf(0);
|
|
expect(res.body).to.have.property('count', 0);
|
|
expect(res.body).to.have.property('total', 0);
|
|
});
|
|
});
|
|
|
|
it('should not return old message when updating a message', async () => {
|
|
await updateMessage({ msgId: pinnedMessageId, updatedMessage: 'message was unpinned', roomId: testGroup._id });
|
|
|
|
await request
|
|
.get(api('groups.messages'))
|
|
.set(credentials)
|
|
.query({ roomId: testGroup._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('messages').and.to.be.an('array');
|
|
expect(res.body.messages).to.have.lengthOf(5);
|
|
|
|
const updatedMessage = res.body.messages.find((msg: IMessage) => msg._id === pinnedMessageId);
|
|
|
|
expect(updatedMessage).to.have.property('msg', 'message was unpinned');
|
|
expect(updatedMessage).to.have.property('editedAt');
|
|
|
|
res.body.messages.forEach((msg: IMessage) => {
|
|
expect(msg).to.not.have.property('_hidden');
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('/groups.invite', async () => {
|
|
let roomInfo: { group: IRoom };
|
|
|
|
before(async () => {
|
|
roomInfo = await getRoomInfo(group._id);
|
|
});
|
|
|
|
it('should invite user to group', async () => {
|
|
await request
|
|
.post(api('groups.invite'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('group._id');
|
|
expect(res.body).to.have.nested.property('group.name', apiPrivateChannelName);
|
|
expect(res.body).to.have.nested.property('group.t', 'p');
|
|
expect(res.body).to.have.nested.property('group.msgs', roomInfo.group.msgs + 1);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('/groups.addModerator', () => {
|
|
it('should make user a moderator', async () => {
|
|
const res = await request
|
|
.post(api('groups.addModerator'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
|
|
describe('/groups.removeModerator', () => {
|
|
it('should remove user from moderator', async () => {
|
|
const res = await request
|
|
.post(api('groups.removeModerator'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
|
|
describe('/groups.addOwner', () => {
|
|
it('should add user as owner', async () => {
|
|
const res = await request
|
|
.post(api('groups.addOwner'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
|
|
describe('/groups.removeOwner', () => {
|
|
it('should remove user from owner', async () => {
|
|
const res = await request
|
|
.post(api('groups.removeOwner'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
|
|
describe('/groups.addLeader', () => {
|
|
it('should add user as leader', async () => {
|
|
const res = await request
|
|
.post(api('groups.addLeader'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.a.property('success', true);
|
|
});
|
|
});
|
|
|
|
describe('/groups.removeLeader', () => {
|
|
it('should remove user from leader', async () => {
|
|
const res = await request
|
|
.post(api('groups.removeLeader'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
|
|
describe('/groups.kick', () => {
|
|
let testUserModerator: TestUser<IUser>;
|
|
let credsModerator: Credentials;
|
|
let testUserOwner: TestUser<IUser>;
|
|
let credsOwner: Credentials;
|
|
let testUserMember: TestUser<IUser>;
|
|
let groupTest: IRoom;
|
|
|
|
const inviteUser = async (userId: IUser['_id']) => {
|
|
await request
|
|
.post(api('groups.invite'))
|
|
.set(credsOwner)
|
|
.send({
|
|
roomId: groupTest._id,
|
|
userId,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
};
|
|
|
|
before(async () => {
|
|
// had to do them in serie because calling them with Promise.all was failing some times
|
|
testUserModerator = await createUser();
|
|
testUserOwner = await createUser();
|
|
testUserMember = await createUser();
|
|
|
|
credsModerator = await login(testUserModerator.username, password);
|
|
credsOwner = await login(testUserOwner.username, password);
|
|
|
|
await request
|
|
.post(api('groups.create'))
|
|
.set(credsOwner)
|
|
.send({
|
|
name: `kick-test-group-${Date.now()}`,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('group._id');
|
|
expect(res.body).to.have.nested.property('group.t', 'p');
|
|
expect(res.body).to.have.nested.property('group.msgs', 0);
|
|
groupTest = res.body.group;
|
|
});
|
|
|
|
await inviteUser(testUserModerator._id);
|
|
|
|
await request
|
|
.post(api('groups.addModerator'))
|
|
.set(credsOwner)
|
|
.send({
|
|
roomId: groupTest._id,
|
|
userId: testUserModerator._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
});
|
|
|
|
after(async () => {
|
|
await Promise.all([
|
|
request
|
|
.post(api('groups.delete'))
|
|
.set(credsOwner)
|
|
.send({
|
|
roomId: groupTest._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200),
|
|
updatePermission('kick-user-from-any-p-room', []),
|
|
updatePermission('remove-user', ['admin', 'owner', 'moderator']),
|
|
deleteUser(testUserModerator),
|
|
deleteUser(testUserOwner),
|
|
deleteUser(testUserMember),
|
|
]);
|
|
});
|
|
|
|
it("should return an error when user is not a member of the group and doesn't have permission", async () => {
|
|
await updatePermission('kick-user-from-any-p-room', []);
|
|
await request
|
|
.post(api('groups.kick'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: groupTest._id,
|
|
userId: testUserMember._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('errorType', 'error-room-not-found');
|
|
});
|
|
});
|
|
|
|
it('should allow a moderator to remove user from group', async () => {
|
|
await inviteUser(testUserMember._id);
|
|
|
|
await request
|
|
.post(api('groups.kick'))
|
|
.set(credsModerator)
|
|
.send({
|
|
roomId: groupTest._id,
|
|
userId: testUserMember._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
});
|
|
|
|
it('should allow an owner to remove user from group', async () => {
|
|
await inviteUser(testUserMember._id);
|
|
|
|
await request
|
|
.post(api('groups.kick'))
|
|
.set(credsOwner)
|
|
.send({
|
|
roomId: groupTest._id,
|
|
userId: testUserMember._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
});
|
|
|
|
it('should kick user from group if not a member of the room but has the required permission', async () => {
|
|
await updatePermission('kick-user-from-any-p-room', ['admin']);
|
|
await inviteUser(testUserMember._id);
|
|
|
|
await request
|
|
.post(api('groups.kick'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
userId: testUserMember._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
});
|
|
|
|
it("should return an error when the owner doesn't have the required permission", async () => {
|
|
await updatePermission('remove-user', ['admin', 'moderator']);
|
|
await inviteUser(testUserMember._id);
|
|
|
|
await request
|
|
.post(api('groups.kick'))
|
|
.set(credsOwner)
|
|
.send({
|
|
roomId: groupTest._id,
|
|
userId: testUserMember._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('errorType', 'error-not-allowed');
|
|
});
|
|
});
|
|
|
|
it('should return an error when trying to kick the last owner from a group', async () => {
|
|
await updatePermission('kick-user-from-any-p-room', ['admin']);
|
|
|
|
await request
|
|
.post(api('groups.kick'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: groupTest._id,
|
|
userId: testUserOwner._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('errorType', 'error-you-are-last-owner');
|
|
});
|
|
});
|
|
|
|
it('should return an error when trying to kick user that does not exist');
|
|
it('should return an error when trying to kick user from a group that does not exist');
|
|
it('should return an error when trying to kick user from a group that the user is not in the room');
|
|
});
|
|
|
|
describe('/groups.setDescription', () => {
|
|
it('should set the description of the group with a string', async () => {
|
|
const res = await request
|
|
.post(api('groups.setDescription'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
description: 'this is a description for a channel for api tests',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('description', 'this is a description for a channel for api tests');
|
|
});
|
|
it('should set the description of the group with an empty string(remove the description)', async () => {
|
|
const res = await request
|
|
.post(api('groups.setDescription'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
description: '',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('description', '');
|
|
});
|
|
});
|
|
|
|
describe('/groups.setTopic', () => {
|
|
it('should set the topic of the group with a string', async () => {
|
|
const res = await request
|
|
.post(api('groups.setTopic'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
topic: 'this is a topic of a channel for api tests',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('topic', 'this is a topic of a channel for api tests');
|
|
});
|
|
it('should set the topic of the group with an empty string(remove the topic)', async () => {
|
|
const res = await request
|
|
.post(api('groups.setTopic'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
topic: '',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('topic', '');
|
|
});
|
|
});
|
|
|
|
describe('/groups.setPurpose', () => {
|
|
it('should set the purpose of the group with a string', async () => {
|
|
const res = await request
|
|
.post(api('groups.setPurpose'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
purpose: 'this is a purpose of a channel for api tests',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('purpose', 'this is a purpose of a channel for api tests');
|
|
});
|
|
it('should set the purpose of the group with an empty string(remove the purpose)', async () => {
|
|
const res = await request
|
|
.post(api('groups.setPurpose'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
purpose: '',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('purpose', '');
|
|
});
|
|
});
|
|
|
|
describe('/groups.history', () => {
|
|
it('should return groups history when searching by roomId', async () => {
|
|
const res = await request
|
|
.get(api('groups.history'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: group._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('messages');
|
|
});
|
|
it('should return groups history when searching by roomId even requested with count and offset params', async () => {
|
|
const res = await request
|
|
.get(api('groups.history'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: group._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('messages');
|
|
});
|
|
|
|
describe('inclusive parameter', () => {
|
|
let testGroup: IRoom;
|
|
let oldestMessage: IMessage;
|
|
let middleMessage: IMessage;
|
|
let latestMessage: IMessage;
|
|
|
|
before(async () => {
|
|
const groupRes = await request
|
|
.post(api('groups.create'))
|
|
.set(credentials)
|
|
.send({ name: `inclusive-test-group-${Date.now()}` });
|
|
testGroup = groupRes.body.group;
|
|
|
|
// Send messages with small delays to ensure distinct timestamps
|
|
const msg1 = await sendMessage({ message: { rid: testGroup._id, msg: 'oldest message' } });
|
|
oldestMessage = msg1.body.message;
|
|
|
|
// Small delay to ensure timestamps are different
|
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
|
|
const msg2 = await sendMessage({ message: { rid: testGroup._id, msg: 'middle message' } });
|
|
middleMessage = msg2.body.message;
|
|
|
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
|
|
const msg3 = await sendMessage({ message: { rid: testGroup._id, msg: 'latest message' } });
|
|
latestMessage = msg3.body.message;
|
|
});
|
|
|
|
after(async () => {
|
|
if (testGroup?._id) {
|
|
await request.post(api('groups.delete')).set(credentials).send({ roomId: testGroup._id });
|
|
}
|
|
});
|
|
|
|
it('should include boundary messages when inclusive=true', async () => {
|
|
const res = await request
|
|
.get(api('groups.history'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testGroup._id,
|
|
oldest: oldestMessage.ts,
|
|
latest: latestMessage.ts,
|
|
inclusive: 'true',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('messages').that.is.an('array');
|
|
|
|
const messageIds = res.body.messages.map((m: IMessage) => m._id);
|
|
expect(messageIds).to.include(oldestMessage._id, 'oldest message should be included');
|
|
expect(messageIds).to.include(latestMessage._id, 'latest message should be included');
|
|
});
|
|
|
|
it('should exclude boundary messages when inclusive=false', async () => {
|
|
const res = await request
|
|
.get(api('groups.history'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testGroup._id,
|
|
oldest: oldestMessage.ts,
|
|
latest: latestMessage.ts,
|
|
inclusive: 'false',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('messages').that.is.an('array');
|
|
|
|
const messageIds = res.body.messages.map((m: IMessage) => m._id);
|
|
expect(messageIds).to.not.include(oldestMessage._id, 'oldest message should be excluded');
|
|
expect(messageIds).to.not.include(latestMessage._id, 'latest message should be excluded');
|
|
// Middle message should still be included if it exists in the range
|
|
expect(messageIds).to.include(middleMessage._id, 'middle message should be included');
|
|
});
|
|
|
|
it('should exclude boundary messages by default (no inclusive param)', async () => {
|
|
const res = await request
|
|
.get(api('groups.history'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testGroup._id,
|
|
oldest: oldestMessage.ts,
|
|
latest: latestMessage.ts,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('messages').that.is.an('array');
|
|
|
|
const messageIds = res.body.messages.map((m: IMessage) => m._id);
|
|
expect(messageIds).to.not.include(oldestMessage._id, 'oldest message should be excluded by default');
|
|
expect(messageIds).to.not.include(latestMessage._id, 'latest message should be excluded by default');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('/groups.archive', () => {
|
|
it('should archive the group', async () => {
|
|
const res = await request
|
|
.post(api('groups.archive'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
|
|
describe('/groups.unarchive', () => {
|
|
it('should unarchive the group', async () => {
|
|
const res = await request
|
|
.post(api('groups.unarchive'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
|
|
describe('/groups.close', () => {
|
|
it('should close the group', async () => {
|
|
const res = await request
|
|
.post(api('groups.close'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
|
|
it('should return an error when trying to close a private group that is already closed', async () => {
|
|
const res = await request
|
|
.post(api('groups.close'))
|
|
.set(credentials)
|
|
.send({
|
|
roomName: apiPrivateChannelName,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400);
|
|
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('error', `The private group, ${apiPrivateChannelName}, is already closed to the sender`);
|
|
});
|
|
});
|
|
|
|
describe('/groups.open', () => {
|
|
it('should open the group', async () => {
|
|
const res = await request
|
|
.post(api('groups.open'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
|
|
describe('group access as a regular member', () => {
|
|
let testGroup: IRoom;
|
|
let member: TestUser<IUser>;
|
|
let memberCredentials: Credentials;
|
|
let outsider: TestUser<IUser>;
|
|
let outsiderCredentials: Credentials;
|
|
const memberGroupName = `member-access-group-${Date.now()}-${Math.random()}`;
|
|
|
|
before(async () => {
|
|
member = await createUser();
|
|
memberCredentials = await login(member.username, password);
|
|
outsider = await createUser();
|
|
outsiderCredentials = await login(outsider.username, password);
|
|
|
|
const result = await createRoom({ type: 'p', name: memberGroupName, members: [member.username] });
|
|
testGroup = result.body.group;
|
|
});
|
|
|
|
after(async () => {
|
|
await deleteRoom({ type: 'p', roomId: testGroup._id });
|
|
await Promise.all([deleteUser(member), deleteUser(outsider)]);
|
|
});
|
|
|
|
it('should return the group info to a regular member', async () => {
|
|
const res = await request
|
|
.get(api('groups.info'))
|
|
.set(memberCredentials)
|
|
.query({
|
|
roomId: testGroup._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('group._id', testGroup._id);
|
|
expect(res.body).to.have.nested.property('group.name', memberGroupName);
|
|
expect(res.body).to.have.nested.property('group.t', 'p');
|
|
});
|
|
|
|
it('should not return the group info to a non-member', async () => {
|
|
const res = await request
|
|
.get(api('groups.info'))
|
|
.set(outsiderCredentials)
|
|
.query({
|
|
roomId: testGroup._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400);
|
|
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('errorType', 'error-room-not-found');
|
|
});
|
|
|
|
it('should return the group history to a regular member', async () => {
|
|
const res = await request
|
|
.get(api('groups.history'))
|
|
.set(memberCredentials)
|
|
.query({
|
|
roomId: testGroup._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('messages').that.is.an('array');
|
|
});
|
|
|
|
it('should close the group for a regular member', async () => {
|
|
await request
|
|
.post(api('groups.close'))
|
|
.set(memberCredentials)
|
|
.send({
|
|
roomId: testGroup._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
|
|
it('should report the group as already closed on a second close (subscription open flag is read)', async () => {
|
|
await request
|
|
.post(api('groups.close'))
|
|
.set(memberCredentials)
|
|
.send({
|
|
roomId: testGroup._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', `The private group, ${memberGroupName}, is already closed to the sender`);
|
|
});
|
|
});
|
|
|
|
it('should open the group back for a regular member', async () => {
|
|
await request
|
|
.post(api('groups.open'))
|
|
.set(memberCredentials)
|
|
.send({
|
|
roomId: testGroup._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
|
|
it('should report the group as already open on a second open (subscription open flag is read)', async () => {
|
|
await request
|
|
.post(api('groups.open'))
|
|
.set(memberCredentials)
|
|
.send({
|
|
roomId: testGroup._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', `The private group, ${memberGroupName}, is already open for the sender`);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('/groups.list', () => {
|
|
it('should list the groups the caller is part of', async () => {
|
|
const res = await request.get(api('groups.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('total');
|
|
expect(res.body).to.have.property('groups').and.to.be.an('array');
|
|
});
|
|
|
|
it('should return a list of zero length if not a member of any group', async () => {
|
|
const user = await createUser();
|
|
const newCreds = await login(user.username, password);
|
|
await request
|
|
.get(api('groups.list'))
|
|
.set(newCreds)
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('count').and.to.equal(0);
|
|
expect(res.body).to.have.property('total').and.to.equal(0);
|
|
expect(res.body).to.have.property('groups').and.to.be.an('array').and.that.has.lengthOf(0);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('/groups.online', () => {
|
|
const createUserAndChannel = async (setAsOnline = true) => {
|
|
const testUser = await createUser();
|
|
const testUserCredentials = await login(testUser.username, password);
|
|
|
|
if (setAsOnline) {
|
|
await request.post(api('users.setStatus')).set(testUserCredentials).send({
|
|
message: '',
|
|
status: 'online',
|
|
});
|
|
}
|
|
|
|
const roomName = `group-test-${Date.now()}`;
|
|
|
|
const roomResponse = await createRoom({
|
|
name: roomName,
|
|
type: 'p',
|
|
members: [testUser.username],
|
|
credentials: testUserCredentials,
|
|
});
|
|
|
|
return {
|
|
testUser,
|
|
testUserCredentials,
|
|
room: roomResponse.body.group,
|
|
};
|
|
};
|
|
|
|
it('should return an error if no query', () =>
|
|
request
|
|
.get(api('groups.online'))
|
|
.set(credentials)
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('error', 'Invalid query');
|
|
}));
|
|
|
|
it('should return an error if passing an empty query', () =>
|
|
request
|
|
.get(api('groups.online'))
|
|
.set(credentials)
|
|
.query('query={}')
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('error', 'Invalid query');
|
|
}));
|
|
|
|
it('should return an array with online members', async () => {
|
|
const { testUser, testUserCredentials, room } = await createUserAndChannel();
|
|
|
|
const response = await request.get(api('groups.online')).set(testUserCredentials).query({
|
|
_id: room._id,
|
|
});
|
|
|
|
const { body } = response;
|
|
|
|
const expected = {
|
|
_id: testUser._id,
|
|
username: testUser.username,
|
|
};
|
|
|
|
expect(body.online).to.deep.include(expected);
|
|
});
|
|
|
|
it('should return an empty array if members are offline', async () => {
|
|
const { testUserCredentials, room } = await createUserAndChannel(false);
|
|
|
|
const response = await request.get(api('groups.online')).set(testUserCredentials).query({
|
|
_id: room._id,
|
|
});
|
|
|
|
const { body } = response;
|
|
|
|
expect(body.online).to.deep.equal([]);
|
|
});
|
|
|
|
it('should return an error if requesting user is not in group', async () => {
|
|
const outsider = await createUser();
|
|
const outsiderCredentials = await login(outsider.username, password);
|
|
|
|
const { room } = await createUserAndChannel();
|
|
|
|
await request
|
|
.get(api('groups.online'))
|
|
.set(outsiderCredentials)
|
|
.query({
|
|
_id: room._id,
|
|
})
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('errorType', 'error-not-allowed');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('/groups.members', () => {
|
|
it('should return group members when searching by roomId', async () => {
|
|
const res = await request
|
|
.get(api('groups.members'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: group._id,
|
|
})
|
|
.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('total');
|
|
expect(res.body).to.have.property('offset');
|
|
expect(res.body).to.have.property('members').and.to.be.an('array');
|
|
});
|
|
it('should return group members when searching by roomId even requested with count and offset params', async () => {
|
|
const res = await request
|
|
.get(api('groups.members'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: group._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('count');
|
|
expect(res.body).to.have.property('total');
|
|
expect(res.body).to.have.property('offset');
|
|
expect(res.body).to.have.property('members').and.to.be.an('array');
|
|
});
|
|
});
|
|
|
|
describe('/groups.files', async () => {
|
|
await testFileUploads('groups.files', 'p');
|
|
});
|
|
|
|
describe('/groups.listAll', () => {
|
|
before(async () => {
|
|
return updatePermission('view-room-administration', ['admin']);
|
|
});
|
|
|
|
after(async () => {
|
|
return updatePermission('view-room-administration', ['admin']);
|
|
});
|
|
|
|
it('should succeed if user has view-room-administration permission', async () => {
|
|
await request
|
|
.get(api('groups.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('groups').and.to.be.an('array');
|
|
});
|
|
});
|
|
|
|
it('should fail if the user doesnt have view-room-administration permission', async () => {
|
|
await updatePermission('view-room-administration', []);
|
|
await request
|
|
.get(api('groups.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('/groups.counters', () => {
|
|
let room: IRoom;
|
|
let user1: IUser;
|
|
let user2: IUser;
|
|
let user1Creds: { 'X-Auth-Token': string; 'X-User-Id': string };
|
|
|
|
before(async () => {
|
|
// Create two users
|
|
user1 = await createUser();
|
|
user2 = await createUser();
|
|
user1Creds = await login(user1.username, password);
|
|
|
|
// Create a new public channel with both users as members
|
|
room = (
|
|
await createRoom({
|
|
type: 'p',
|
|
name: `counters-test-${Date.now()}`,
|
|
members: [user1.username as string, user2.username as string],
|
|
})
|
|
).body.group;
|
|
});
|
|
|
|
after(async () => {
|
|
// Delete room first
|
|
await deleteRoom({ type: 'p', roomId: room._id });
|
|
// Then delete users
|
|
await Promise.all([deleteUser(user1), deleteUser(user2)]);
|
|
});
|
|
|
|
it('should require auth', async () => {
|
|
await request
|
|
.get(api('groups.counters'))
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(401)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('status', 'error');
|
|
});
|
|
});
|
|
|
|
it('should require a roomId', async () => {
|
|
await request
|
|
.get(api('groups.counters'))
|
|
.set(credentials)
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should return counters for a channel with correct fields', async () => {
|
|
await request
|
|
.get(api('groups.counters'))
|
|
.set(user1Creds)
|
|
.query({ roomId: room._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('members').that.is.a('number').and.equals(3);
|
|
expect(res.body).to.have.property('unreads').that.is.a('number');
|
|
expect(res.body).to.have.property('unreadsFrom');
|
|
expect(res.body).to.have.property('msgs').that.is.a('number');
|
|
expect(res.body).to.have.property('latest');
|
|
expect(res.body).to.have.property('joined', true);
|
|
});
|
|
});
|
|
|
|
it('should not include deactivated users in members count', async () => {
|
|
// Deactivate the second user
|
|
await request.post(api('users.setActiveStatus')).set(credentials).send({ userId: user2._id, activeStatus: false });
|
|
|
|
const res = await request.get(api('groups.counters')).set(user1Creds).query({ roomId: room._id });
|
|
|
|
expect(res.status).to.equal(200);
|
|
expect(res.body.success).to.be.true;
|
|
// Only user1 and admin remain active
|
|
expect(res.body.members).to.equal(2);
|
|
});
|
|
});
|
|
|
|
describe('/groups.rename', async () => {
|
|
let roomInfo: { group: IRoom };
|
|
before(async () => {
|
|
roomInfo = await getRoomInfo(group._id);
|
|
});
|
|
|
|
it('should return the group rename with an additional message', async () => {
|
|
await request
|
|
.post(api('groups.rename'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
name: `EDITED${apiPrivateChannelName}`,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('group._id');
|
|
expect(res.body).to.have.nested.property('group.name', `EDITED${apiPrivateChannelName}`);
|
|
expect(res.body).to.have.nested.property('group.t', 'p');
|
|
expect(res.body).to.have.nested.property('group.msgs', roomInfo.group.msgs + 1);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('/groups.getIntegrations', () => {
|
|
let integrationCreatedByAnUser: IIntegration;
|
|
let createdGroup: IRoom;
|
|
|
|
before(async () => {
|
|
const resRoom = await createRoom({ name: `test-integration-group-${Date.now()}`, type: 'p' });
|
|
|
|
createdGroup = resRoom.body.group;
|
|
|
|
const user = await createUser();
|
|
|
|
const userCredentials = await login(user.username, password);
|
|
|
|
await Promise.all([
|
|
updatePermission('manage-incoming-integrations', ['user']),
|
|
updatePermission('manage-own-incoming-integrations', ['user']),
|
|
]);
|
|
|
|
integrationCreatedByAnUser = await createIntegration(
|
|
{
|
|
type: 'webhook-incoming',
|
|
name: 'Incoming test',
|
|
enabled: true,
|
|
alias: 'test',
|
|
username: 'rocket.cat',
|
|
scriptEnabled: false,
|
|
overrideDestinationChannelEnabled: true,
|
|
channel: `#${createdGroup.name}`,
|
|
},
|
|
userCredentials,
|
|
);
|
|
});
|
|
|
|
after(async () => {
|
|
await removeIntegration(integrationCreatedByAnUser._id, 'incoming');
|
|
|
|
await Promise.all([
|
|
updatePermission('manage-incoming-integrations', ['admin']),
|
|
updatePermission('manage-outgoing-integrations', ['admin']),
|
|
updatePermission('manage-own-incoming-integrations', ['admin']),
|
|
updatePermission('manage-own-outgoing-integrations', ['admin']),
|
|
]);
|
|
});
|
|
|
|
it('should return the list of integrations of create group and it should contain the integration created by user when the admin DOES have the permission', async () => {
|
|
await updatePermission('manage-incoming-integrations', ['admin']);
|
|
|
|
await request
|
|
.get(api('groups.getIntegrations'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: createdGroup._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
const integrationCreated = (res.body.integrations as IIntegration[]).find(
|
|
(createdIntegration) => createdIntegration._id === integrationCreatedByAnUser._id,
|
|
);
|
|
assert.isDefined(integrationCreated);
|
|
expect(integrationCreated).to.be.an('object');
|
|
expect(integrationCreated._id).to.be.equal(integrationCreatedByAnUser._id);
|
|
expect(res.body).to.have.property('offset');
|
|
expect(res.body).to.have.property('total');
|
|
});
|
|
});
|
|
|
|
it('should return the list of integrations created by the user only', async () => {
|
|
await Promise.all([
|
|
updatePermission('manage-own-incoming-integrations', ['admin']),
|
|
updatePermission('manage-incoming-integrations', []),
|
|
]);
|
|
|
|
await request
|
|
.get(api('groups.getIntegrations'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: createdGroup._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
const integrationCreated = (res.body.integrations as IIntegration[]).find(
|
|
(createdIntegration) => createdIntegration._id === integrationCreatedByAnUser._id,
|
|
);
|
|
expect(integrationCreated).to.be.equal(undefined);
|
|
expect(res.body).to.have.property('offset');
|
|
expect(res.body).to.have.property('total');
|
|
});
|
|
});
|
|
|
|
it('should return unauthorized error when the user does not have any integrations permissions', async () => {
|
|
await Promise.all([
|
|
updatePermission('manage-incoming-integrations', []),
|
|
updatePermission('manage-outgoing-integrations', []),
|
|
updatePermission('manage-own-incoming-integrations', []),
|
|
updatePermission('manage-own-outgoing-integrations', []),
|
|
]);
|
|
|
|
await request
|
|
.get(api('groups.getIntegrations'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: createdGroup._id,
|
|
})
|
|
.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('/groups.setReadOnly', () => {
|
|
it('should set the group as read only', async () => {
|
|
const res = await request
|
|
.post(api('groups.setReadOnly'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
readOnly: true,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
|
|
describe.skip('/groups.leave', () => {
|
|
it('should allow the user to leave the group', async () => {
|
|
const res = await request
|
|
.post(api('groups.leave'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
|
|
describe('/groups.setAnnouncement', () => {
|
|
it('should set the announcement of the group with a string', async () => {
|
|
const res = await request
|
|
.post(api('groups.setAnnouncement'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
announcement: 'this is an announcement of a group for api tests',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('announcement', 'this is an announcement of a group for api tests');
|
|
});
|
|
it('should set the announcement of the group with an empty string(remove the announcement)', async () => {
|
|
const res = await request
|
|
.post(api('groups.setAnnouncement'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: group._id,
|
|
announcement: '',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('announcement', '');
|
|
});
|
|
});
|
|
|
|
describe('/groups.setType', () => {
|
|
let roomTypeId: IRoom['_id'];
|
|
let testRegularGroup: IRoom;
|
|
let testTeamGroupForFailure: IRoom;
|
|
let testTeamGroupForSuccess: IRoom;
|
|
let team: ITeam;
|
|
let testUser: TestUser<IUser>;
|
|
let testUserCredentials: Credentials;
|
|
|
|
beforeEach(async () => {
|
|
await updatePermission('create-c', ['admin', 'user']);
|
|
await updatePermission('create-team-channel', ['admin', 'owner', 'moderator']);
|
|
});
|
|
|
|
before(async () => {
|
|
await request
|
|
.post(api('groups.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: `channel.type.${Date.now()}`,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
roomTypeId = res.body.group._id;
|
|
});
|
|
|
|
testUser = await createUser();
|
|
testUserCredentials = await login(testUser.username, password);
|
|
|
|
await updatePermission('create-team', ['admin', 'user']);
|
|
team = await createTeam(credentials, `team-setType-${Date.now()}`, TeamType.PRIVATE, [testUser.username]);
|
|
|
|
await request.post(api('groups.addOwner')).set(credentials).send({ roomId: team.roomId, userId: testUser._id });
|
|
|
|
testRegularGroup = (await createRoom({ type: 'p', name: `regular-setType-${Date.now()}`, credentials: testUserCredentials })).body
|
|
.group;
|
|
|
|
testTeamGroupForFailure = (await createRoom({ type: 'p', name: `teamGrp-fail-${Date.now()}`, extraData: { teamId: team._id } })).body
|
|
.group;
|
|
testTeamGroupForSuccess = (await createRoom({ type: 'p', name: `teamGrp-success-${Date.now()}`, extraData: { teamId: team._id } }))
|
|
.body.group;
|
|
|
|
await request.post(api('groups.invite')).set(credentials).send({ roomId: testTeamGroupForFailure._id, userId: testUser._id });
|
|
await request.post(api('groups.addOwner')).set(credentials).send({ roomId: testTeamGroupForFailure._id, userId: testUser._id });
|
|
await request.post(api('groups.invite')).set(credentials).send({ roomId: testTeamGroupForSuccess._id, userId: testUser._id });
|
|
await request.post(api('groups.addOwner')).set(credentials).send({ roomId: testTeamGroupForSuccess._id, userId: testUser._id });
|
|
});
|
|
|
|
after(async () => {
|
|
await request
|
|
.post(api('channels.delete'))
|
|
.set(credentials)
|
|
.send({ roomId: roomTypeId })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
await Promise.all(
|
|
['p', 'c'].map(async (type: any) => {
|
|
return Promise.all([
|
|
deleteRoom({ type, roomId: testRegularGroup._id }),
|
|
deleteRoom({ type, roomId: testTeamGroupForFailure._id }),
|
|
deleteRoom({ type, roomId: testTeamGroupForSuccess._id }),
|
|
]);
|
|
}),
|
|
);
|
|
await deleteTeam(credentials, team.name);
|
|
await deleteUser(testUser);
|
|
await updatePermission('create-c', ['admin', 'user']);
|
|
await updatePermission('create-team-channel', ['admin', 'owner', 'moderator']);
|
|
});
|
|
|
|
it('should change the type of the group to a channel', async () => {
|
|
await request
|
|
.post(api('groups.setType'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: roomTypeId,
|
|
type: 'c',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('group.t', 'c');
|
|
});
|
|
});
|
|
|
|
it('should fail to change a regular group to channel when user lacks create-c permission', async () => {
|
|
await updatePermission('create-c', ['admin']);
|
|
await request
|
|
.post(api('groups.setType'))
|
|
.set(testUserCredentials)
|
|
.send({ roomId: testRegularGroup._id, type: 'c' })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('errorType', 'error-action-not-allowed');
|
|
});
|
|
});
|
|
|
|
it('should fail to change a team main room to channel when user lacks create-c permission', async () => {
|
|
await updatePermission('create-c', ['admin']);
|
|
await request
|
|
.post(api('groups.setType'))
|
|
.set(testUserCredentials)
|
|
.send({ roomId: team.roomId, type: 'c' })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('errorType', 'error-action-not-allowed');
|
|
});
|
|
});
|
|
|
|
it('should fail to change a team main room to channel when user has create-team-channel but lacks create-c', async () => {
|
|
await updatePermission('create-c', ['admin']);
|
|
await updatePermission('create-team-channel', ['owner']);
|
|
await request
|
|
.post(api('groups.setType'))
|
|
.set(testUserCredentials)
|
|
.send({ roomId: team.roomId, type: 'c' })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('errorType', 'error-action-not-allowed');
|
|
});
|
|
});
|
|
|
|
it('should fail to change a team group to channel when user lacks create-team-channel permission', async () => {
|
|
await updatePermission('create-team-channel', []);
|
|
await request
|
|
.post(api('groups.setType'))
|
|
.set(testUserCredentials)
|
|
.send({ roomId: testTeamGroupForFailure._id, type: 'c' })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('errorType', 'error-action-not-allowed');
|
|
});
|
|
});
|
|
|
|
it('should succeed changing a team group to channel when user has create-team-channel but not create-c', async () => {
|
|
await updatePermission('create-c', ['admin']);
|
|
await updatePermission('create-team-channel', ['owner']);
|
|
await request
|
|
.post(api('groups.setType'))
|
|
.set(testUserCredentials)
|
|
.send({ roomId: testTeamGroupForSuccess._id, type: 'c' })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('group.t', 'c');
|
|
expect(res.body).to.have.nested.property('group.teamId', team._id);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('/groups.setCustomFields', () => {
|
|
let cfchannel: IRoom;
|
|
let groupWithoutCustomFields: IRoom;
|
|
|
|
before('create group with customFields', async () => {
|
|
const customFields = { field0: 'value0' };
|
|
|
|
await request
|
|
.post(api('groups.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: `channel.cf.${Date.now()}`,
|
|
customFields,
|
|
})
|
|
.expect((res) => {
|
|
cfchannel = res.body.group;
|
|
});
|
|
|
|
await request
|
|
.post(api('groups.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: `channel.cf.${Date.now()}`,
|
|
})
|
|
.expect((res) => {
|
|
groupWithoutCustomFields = res.body.group;
|
|
});
|
|
});
|
|
|
|
after('delete group with customFields', async () => {
|
|
await request
|
|
.post(api('groups.delete'))
|
|
.set(credentials)
|
|
.send({
|
|
roomName: cfchannel.name,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
await request
|
|
.post(api('groups.delete'))
|
|
.set(credentials)
|
|
.send({
|
|
roomName: groupWithoutCustomFields.name,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
});
|
|
|
|
it('get customFields using groups.info', async () => {
|
|
const res = await request
|
|
.get(api('groups.info'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: cfchannel._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('group.customFields.field0', 'value0');
|
|
});
|
|
it('change customFields', async () => {
|
|
const customFields = { field9: 'value9' };
|
|
await request
|
|
.post(api('groups.setCustomFields'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: cfchannel._id,
|
|
customFields,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('group._id');
|
|
expect(res.body).to.have.nested.property('group.name', cfchannel.name);
|
|
expect(res.body).to.have.nested.property('group.t', 'p');
|
|
expect(res.body).to.have.nested.property('group.customFields.field9', 'value9');
|
|
expect(res.body).to.have.not.nested.property('group.customFields.field0', 'value0');
|
|
});
|
|
});
|
|
it('get customFields using groups.info', async () => {
|
|
const res = await request
|
|
.get(api('groups.info'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: cfchannel._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('group.customFields.field9', 'value9');
|
|
});
|
|
|
|
it('set customFields with one nested field', async () => {
|
|
const customFields = { field1: 'value1' };
|
|
await request
|
|
.post(api('groups.setCustomFields'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: groupWithoutCustomFields._id,
|
|
customFields,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('group._id');
|
|
expect(res.body).to.have.nested.property('group.name', groupWithoutCustomFields.name);
|
|
expect(res.body).to.have.nested.property('group.t', 'p');
|
|
expect(res.body).to.have.nested.property('group.customFields.field1', 'value1');
|
|
});
|
|
});
|
|
it('set customFields with multiple nested fields', async () => {
|
|
const customFields = { field2: 'value2', field3: 'value3', field4: 'value4' };
|
|
|
|
await request
|
|
.post(api('groups.setCustomFields'))
|
|
.set(credentials)
|
|
.send({
|
|
roomName: groupWithoutCustomFields.name,
|
|
customFields,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('group._id');
|
|
expect(res.body).to.have.nested.property('group.name', groupWithoutCustomFields.name);
|
|
expect(res.body).to.have.nested.property('group.t', 'p');
|
|
expect(res.body).to.have.nested.property('group.customFields.field2', 'value2');
|
|
expect(res.body).to.have.nested.property('group.customFields.field3', 'value3');
|
|
expect(res.body).to.have.nested.property('group.customFields.field4', 'value4');
|
|
expect(res.body).to.have.not.nested.property('group.customFields.field1', 'value1');
|
|
});
|
|
});
|
|
it('set customFields to empty object', async () => {
|
|
const customFields = {};
|
|
|
|
await request
|
|
.post(api('groups.setCustomFields'))
|
|
.set(credentials)
|
|
.send({
|
|
roomName: groupWithoutCustomFields.name,
|
|
customFields,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('group._id');
|
|
expect(res.body).to.have.nested.property('group.name', groupWithoutCustomFields.name);
|
|
expect(res.body).to.have.nested.property('group.t', 'p');
|
|
expect(res.body).to.have.not.nested.property('group.customFields.field2', 'value2');
|
|
expect(res.body).to.have.not.nested.property('group.customFields.field3', 'value3');
|
|
expect(res.body).to.have.not.nested.property('group.customFields.field4', 'value4');
|
|
});
|
|
});
|
|
it('set customFields as a string -> should return 400', (done) => {
|
|
const customFields = '';
|
|
|
|
void request
|
|
.post(api('groups.setCustomFields'))
|
|
.set(credentials)
|
|
.send({
|
|
roomName: groupWithoutCustomFields.name,
|
|
customFields,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
})
|
|
.end(done);
|
|
});
|
|
});
|
|
|
|
describe('/groups.delete', () => {
|
|
let testGroup: IRoom;
|
|
let testTeamGroup: IRoom;
|
|
let testModeratorTeamGroup: IRoom;
|
|
let invitedUser: TestUser<IUser>;
|
|
let moderatorUser: TestUser<IUser>;
|
|
let invitedUserCredentials: Credentials;
|
|
let moderatorUserCredentials: Credentials;
|
|
let teamId: ITeam['_id'];
|
|
let teamMainRoomId: IRoom['_id'];
|
|
|
|
before(async () => {
|
|
testGroup = (await createRoom({ name: `group.test.${Date.now()}`, type: 'p' })).body.group;
|
|
invitedUser = await createUser();
|
|
moderatorUser = await createUser();
|
|
invitedUserCredentials = await login(invitedUser.username, password);
|
|
moderatorUserCredentials = await login(moderatorUser.username, password);
|
|
|
|
const teamCreateRes = await request
|
|
.post(api('teams.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: `team-${Date.now()}`,
|
|
type: 1,
|
|
members: [invitedUser.username, moderatorUser.username],
|
|
});
|
|
teamId = teamCreateRes.body.team._id;
|
|
teamMainRoomId = teamCreateRes.body.team.roomId;
|
|
|
|
await updatePermission('delete-team-group', ['owner', 'moderator']);
|
|
await updatePermission('create-team-group', ['admin', 'owner', 'moderator', 'user']);
|
|
const teamGroupResponse = await createRoom({
|
|
name: `group.test.${Date.now()}`,
|
|
type: 'p',
|
|
extraData: { teamId },
|
|
credentials: invitedUserCredentials,
|
|
});
|
|
testTeamGroup = teamGroupResponse.body.group;
|
|
|
|
await request
|
|
.post(api('groups.addModerator'))
|
|
.set(credentials)
|
|
.send({
|
|
userId: moderatorUser._id,
|
|
roomId: teamMainRoomId,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
const teamModeratorGroupResponse = await createRoom({
|
|
name: `group.test.moderator.${Date.now()}`,
|
|
type: 'p',
|
|
extraData: { teamId },
|
|
credentials: moderatorUserCredentials,
|
|
});
|
|
testModeratorTeamGroup = teamModeratorGroupResponse.body.group;
|
|
});
|
|
after(async () => {
|
|
await deleteUser(invitedUser);
|
|
await deleteUser(moderatorUser);
|
|
await updatePermission('create-team-group', ['admin', 'owner', 'moderator']);
|
|
await updatePermission('delete-team-group', ['admin', 'owner', 'moderator']);
|
|
});
|
|
it('should succesfully delete a group', async () => {
|
|
await request
|
|
.post(api('groups.delete'))
|
|
.set(credentials)
|
|
.send({
|
|
roomName: testGroup.name,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
it(`should fail retrieving a group's info after it's been deleted`, async () => {
|
|
await request
|
|
.get(api('groups.info'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testGroup._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('errorType', 'error-room-not-found');
|
|
});
|
|
});
|
|
it(`should fail deleting a team's group when member does not have the necessary permission in the team`, async () => {
|
|
await request
|
|
.post(api('groups.delete'))
|
|
.set(invitedUserCredentials)
|
|
.send({
|
|
roomName: testTeamGroup.name,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.a.property('error');
|
|
expect(res.body).to.have.a.property('errorType', 'error-not-allowed');
|
|
});
|
|
});
|
|
it(`should fail deleting a team's group when member has the necessary permission in the team, but not in the deleted room`, async () => {
|
|
await request
|
|
.post(api('groups.delete'))
|
|
.set(moderatorUserCredentials)
|
|
.send({
|
|
roomName: testTeamGroup.name,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.a.property('error');
|
|
expect(res.body).to.have.a.property('errorType', 'error-room-not-found');
|
|
});
|
|
});
|
|
it(`should successfully delete a team's group when member has both team and group permissions`, async () => {
|
|
await request
|
|
.post(api('groups.delete'))
|
|
.set(moderatorUserCredentials)
|
|
.send({
|
|
roomId: testModeratorTeamGroup._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('/groups.roles', () => {
|
|
let testGroup: IRoom;
|
|
before(async () => {
|
|
await request
|
|
.post(api('groups.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: `group.roles.test.${Date.now()}`,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
testGroup = res.body.group;
|
|
});
|
|
});
|
|
|
|
after(async () => {
|
|
await request
|
|
.post(api('groups.delete'))
|
|
.set(credentials)
|
|
.send({
|
|
roomName: testGroup.name,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
});
|
|
|
|
it('/groups.invite', async () => {
|
|
const res = await request
|
|
.post(api('groups.invite'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: testGroup._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
it('/groups.addModerator', async () => {
|
|
const res = await request
|
|
.post(api('groups.addModerator'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: testGroup._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
it('/groups.addLeader', async () => {
|
|
const res = await request
|
|
.post(api('groups.addLeader'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: testGroup._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
it('should return an array of roles <-> user relationships in a private group', async () => {
|
|
const res = await request
|
|
.get(api('groups.roles'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testGroup._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.a.property('success', true);
|
|
expect(res.body).to.have.a.property('roles').that.is.an('array').that.has.lengthOf(2);
|
|
|
|
expect(res.body.roles[0]).to.have.a.property('_id').that.is.a('string');
|
|
expect(res.body.roles[0]).to.have.a.property('rid').that.is.equal(testGroup._id);
|
|
expect(res.body.roles[0]).to.have.a.property('roles').that.is.an('array').that.includes('moderator', 'leader');
|
|
expect(res.body.roles[0]).to.have.a.property('u').that.is.an('object');
|
|
expect(res.body.roles[0].u).to.have.a.property('_id').that.is.a('string');
|
|
expect(res.body.roles[0].u).to.have.a.property('username').that.is.a('string');
|
|
|
|
expect(res.body.roles[1]).to.have.a.property('_id').that.is.a('string');
|
|
expect(res.body.roles[1]).to.have.a.property('rid').that.is.equal(testGroup._id);
|
|
expect(res.body.roles[1]).to.have.a.property('roles').that.is.an('array').that.includes('owner');
|
|
expect(res.body.roles[1]).to.have.a.property('u').that.is.an('object');
|
|
expect(res.body.roles[1].u).to.have.a.property('_id').that.is.a('string');
|
|
expect(res.body.roles[1].u).to.have.a.property('username').that.is.a('string');
|
|
});
|
|
});
|
|
|
|
describe('/groups.moderators', () => {
|
|
let testGroup: IRoom;
|
|
before(async () => {
|
|
await request
|
|
.post(api('groups.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: `group.roles.test.${Date.now()}`,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
testGroup = res.body.group;
|
|
});
|
|
});
|
|
|
|
after(async () => {
|
|
await request
|
|
.post(api('groups.delete'))
|
|
.set(credentials)
|
|
.send({
|
|
roomName: testGroup.name,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
});
|
|
|
|
it('/groups.invite', async () => {
|
|
const res = await request
|
|
.post(api('groups.invite'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: testGroup._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
it('/groups.addModerator', async () => {
|
|
const res = await request
|
|
.post(api('groups.addModerator'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: testGroup._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
it('should return an array of moderators with rocket.cat as a moderator', async () => {
|
|
const res = await request
|
|
.get(api('groups.moderators'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testGroup._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.a.property('success', true);
|
|
expect(res.body).to.have.a.property('moderators').that.is.an('array').that.has.lengthOf(1);
|
|
expect(res.body.moderators[0].username).to.be.equal('rocket.cat');
|
|
});
|
|
});
|
|
|
|
describe('/groups.setEncrypted', () => {
|
|
let testGroup: IRoom;
|
|
|
|
before(async () => {
|
|
await request
|
|
.post(api('groups.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: `group.encrypted.test.${Date.now()}`,
|
|
})
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('group._id');
|
|
|
|
testGroup = res.body.group;
|
|
});
|
|
|
|
await updateSetting('E2E_Enable', true);
|
|
});
|
|
|
|
after(async () => {
|
|
await updateSetting('E2E_Enable', false);
|
|
|
|
await request
|
|
.post(api('groups.delete'))
|
|
.set(credentials)
|
|
.send({
|
|
roomName: testGroup.name,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
});
|
|
|
|
it('should return an error when passing no boolean param', async () => {
|
|
const res = await request
|
|
.post(api('groups.setEncrypted'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: testGroup._id,
|
|
encrypted: 'no-boolean',
|
|
})
|
|
.expect(400);
|
|
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('error', 'must be boolean');
|
|
});
|
|
|
|
it('should set group as encrypted correctly and return the new data', async () => {
|
|
const res = await request
|
|
.post(api('groups.setEncrypted'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: testGroup._id,
|
|
encrypted: true,
|
|
})
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('group');
|
|
expect(res.body.group).to.have.property('_id', testGroup._id);
|
|
expect(res.body.group).to.have.property('encrypted', true);
|
|
});
|
|
|
|
it('should return the updated room encrypted', async () => {
|
|
const roomInfo = await getRoomInfo(testGroup._id);
|
|
expect(roomInfo).to.have.a.property('success', true);
|
|
expect(roomInfo.group).to.have.a.property('_id', testGroup._id);
|
|
expect(roomInfo.group).to.have.a.property('encrypted', true);
|
|
});
|
|
|
|
it('should set group as unencrypted correctly and return the new data', async () => {
|
|
const res = await request
|
|
.post(api('groups.setEncrypted'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: testGroup._id,
|
|
encrypted: false,
|
|
})
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('group');
|
|
expect(res.body.group).to.have.property('_id', testGroup._id);
|
|
expect(res.body.group).to.have.property('encrypted', false);
|
|
});
|
|
|
|
it('should return the updated room unencrypted', async () => {
|
|
const roomInfo = await getRoomInfo(testGroup._id);
|
|
expect(roomInfo).to.have.a.property('success', true);
|
|
expect(roomInfo.group).to.have.a.property('_id', testGroup._id);
|
|
expect(roomInfo.group).to.have.a.property('encrypted', false);
|
|
});
|
|
});
|
|
|
|
describe('/groups.convertToTeam', () => {
|
|
let newGroup: IRoom;
|
|
|
|
before(async () => {
|
|
await request
|
|
.post(api('groups.create'))
|
|
.set(credentials)
|
|
.send({ name: `group-${Date.now()}` })
|
|
.expect(200)
|
|
.expect((response) => {
|
|
newGroup = response.body.group;
|
|
});
|
|
});
|
|
|
|
after(() => {
|
|
assert.isDefined(newGroup.name);
|
|
return Promise.all([deleteTeam(credentials, newGroup.name), updatePermission('create-team', ['admin', 'user'])]);
|
|
});
|
|
|
|
it('should fail to convert group if lacking edit-room permission', async () => {
|
|
await updatePermission('create-team', []);
|
|
|
|
await updatePermission('edit-room', ['admin']);
|
|
|
|
const res = await request.post(api('groups.convertToTeam')).set(credentials).send({ roomId: newGroup._id }).expect(403);
|
|
|
|
expect(res.body).to.have.a.property('success', false);
|
|
});
|
|
|
|
it('should fail to convert group if lacking create-team permission', async () => {
|
|
await updatePermission('create-team', ['admin']);
|
|
|
|
await updatePermission('edit-room', []);
|
|
|
|
const res = await request.post(api('groups.convertToTeam')).set(credentials).send({ roomId: newGroup._id }).expect(403);
|
|
|
|
expect(res.body).to.have.a.property('success', false);
|
|
});
|
|
|
|
it('should successfully convert a group to a team', async () => {
|
|
await updatePermission('create-team', ['admin']);
|
|
|
|
await updatePermission('edit-room', ['admin']);
|
|
|
|
const res = await request.post(api('groups.convertToTeam')).set(credentials).send({ roomId: newGroup._id }).expect(200);
|
|
|
|
expect(res.body).to.have.a.property('success', true);
|
|
});
|
|
|
|
it('should fail to convert group without the required parameters', (done) => {
|
|
void request.post(api('groups.convertToTeam')).set(credentials).send({}).expect(400).end(done);
|
|
});
|
|
|
|
it("should fail to convert group if it's already taken", async () => {
|
|
const res = await request.post(api('groups.convertToTeam')).set(credentials).send({ roomId: newGroup._id }).expect(400);
|
|
|
|
expect(res.body).to.have.a.property('success', false);
|
|
});
|
|
});
|
|
|
|
describe("Setting: 'Use Real Name': true", () => {
|
|
let realNameGroup: IRoom;
|
|
|
|
before(async () => {
|
|
await updateSetting('UI_Use_Real_Name', true);
|
|
|
|
await request
|
|
.post(api('groups.create'))
|
|
.set(credentials)
|
|
.send({ name: `group-${Date.now()}` })
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
|
|
realNameGroup = res.body.group;
|
|
});
|
|
|
|
await request
|
|
.post(api('chat.sendMessage'))
|
|
.set(credentials)
|
|
.send({
|
|
message: {
|
|
text: 'Sample message',
|
|
rid: realNameGroup._id,
|
|
},
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
|
|
after(async () => {
|
|
await updateSetting('UI_Use_Real_Name', false);
|
|
|
|
await request
|
|
.post(api('groups.delete'))
|
|
.set(credentials)
|
|
.send({ roomId: realNameGroup._id })
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
|
|
it('should return the last message user real name', async () => {
|
|
const res = await request
|
|
.get(api('groups.info'))
|
|
.query({
|
|
roomId: realNameGroup._id,
|
|
})
|
|
.set(credentials)
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
const { group } = res.body;
|
|
|
|
expect(group._id).to.be.equal(realNameGroup._id);
|
|
expect(group).to.have.nested.property('lastMessage.u.name', 'RocketChat Internal Admin Test');
|
|
});
|
|
});
|
|
});
|