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
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 1s
4777 lines
158 KiB
TypeScript
4777 lines
158 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 { Random } from '@rocket.chat/random';
|
|
import { expect, assert } from 'chai';
|
|
import { after, before, describe, it, beforeEach } from 'mocha';
|
|
|
|
import { getCredentials, api, request, credentials, reservedWords } from '../../data/api-data';
|
|
import { pinMessage, sendMessage, starMessage, updateMessage } from '../../data/chat.helper';
|
|
import { CI_MAX_ROOMS_PER_GUEST as maxRoomsPerGuest } from '../../data/constants';
|
|
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<{ channel: IRoom }>((resolve) => {
|
|
void request
|
|
.get(api('channels.info'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId,
|
|
})
|
|
.end((_err, req) => {
|
|
resolve(req.body);
|
|
});
|
|
});
|
|
}
|
|
|
|
describe('[Channels]', () => {
|
|
let channel: Pick<IRoom, '_id' | 'name'>;
|
|
const apiPublicChannelName = `api-channel-test-${Date.now()}`;
|
|
|
|
before((done) => getCredentials(done));
|
|
|
|
before('Creating channel', (done) => {
|
|
void request
|
|
.post(api('channels.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: apiPublicChannelName,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('channel._id');
|
|
expect(res.body).to.have.nested.property('channel.name', apiPublicChannelName);
|
|
expect(res.body).to.have.nested.property('channel.t', 'c');
|
|
expect(res.body).to.have.nested.property('channel.msgs', 0);
|
|
channel = {
|
|
_id: res.body.channel._id,
|
|
name: res.body.channel.name,
|
|
};
|
|
})
|
|
.end(done);
|
|
});
|
|
|
|
after(async () => {
|
|
await deleteRoom({ type: 'c', roomId: channel._id });
|
|
});
|
|
|
|
it('/channels.invite', async () => {
|
|
const roomInfo = await getRoomInfo(channel._id);
|
|
|
|
return request
|
|
.post(api('channels.invite'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._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('channel._id');
|
|
expect(res.body).to.have.nested.property('channel.name', apiPublicChannelName);
|
|
expect(res.body).to.have.nested.property('channel.t', 'c');
|
|
expect(res.body).to.have.nested.property('channel.msgs', roomInfo.channel.msgs + 1);
|
|
});
|
|
});
|
|
|
|
it('/channels.addModerator', async () => {
|
|
const res = await request
|
|
.post(api('channels.addModerator'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
|
|
it('/channels.addModerator should fail with missing room Id', async () => {
|
|
const res = await request
|
|
.post(api('channels.addModerator'))
|
|
.set(credentials)
|
|
.send({
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400);
|
|
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
|
|
it('/channels.addModerator should fail with missing user Id', async () => {
|
|
const res = await request
|
|
.post(api('channels.addModerator'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400);
|
|
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
|
|
it('/channels.removeModerator', async () => {
|
|
const res = await request
|
|
.post(api('channels.removeModerator'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
|
|
it('/channels.removeModerator should fail on invalid room id', async () => {
|
|
const res = await request
|
|
.post(api('channels.removeModerator'))
|
|
.set(credentials)
|
|
.send({
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400);
|
|
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
|
|
it('/channels.removeModerator should fail on invalid user id', async () => {
|
|
const res = await request
|
|
.post(api('channels.removeModerator'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400);
|
|
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
|
|
it('/channels.addOwner', async () => {
|
|
const res = await request
|
|
.post(api('channels.addOwner'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
|
|
it('/channels.removeOwner', async () => {
|
|
const res = await request
|
|
.post(api('channels.removeOwner'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
|
|
it('/channels.kick', async () => {
|
|
const roomInfo = await getRoomInfo(channel._id);
|
|
|
|
return request
|
|
.post(api('channels.kick'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._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('channel._id');
|
|
expect(res.body).to.have.nested.property('channel.name', apiPublicChannelName);
|
|
expect(res.body).to.have.nested.property('channel.t', 'c');
|
|
expect(res.body).to.have.nested.property('channel.msgs', roomInfo.channel.msgs + 1);
|
|
});
|
|
});
|
|
|
|
it('/channels.invite', async () => {
|
|
const roomInfo = await getRoomInfo(channel._id);
|
|
|
|
return request
|
|
.post(api('channels.invite'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._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('channel._id');
|
|
expect(res.body).to.have.nested.property('channel.name', apiPublicChannelName);
|
|
expect(res.body).to.have.nested.property('channel.t', 'c');
|
|
expect(res.body).to.have.nested.property('channel.msgs', roomInfo.channel.msgs + 1);
|
|
});
|
|
});
|
|
|
|
it('/channels.addOwner', async () => {
|
|
const res = await request
|
|
.post(api('channels.addOwner'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
|
|
it('/channels.archive', async () => {
|
|
const res = await request
|
|
.post(api('channels.archive'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
|
|
it('/channels.unarchive', async () => {
|
|
const res = await request
|
|
.post(api('channels.unarchive'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
|
|
it('/channels.close', async () => {
|
|
const res = await request
|
|
.post(api('channels.close'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
|
|
it('/channels.close', async () => {
|
|
const res = await request
|
|
.post(api('channels.close'))
|
|
.set(credentials)
|
|
.send({
|
|
roomName: apiPublicChannelName,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400);
|
|
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('error', `The channel, ${apiPublicChannelName}, is already closed to the sender`);
|
|
});
|
|
|
|
it('/channels.open', async () => {
|
|
const res = await request
|
|
.post(api('channels.open'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
|
|
describe('/channels.list', () => {
|
|
let testChannel: IRoom;
|
|
before(async () => {
|
|
await updatePermission('view-c-room', ['admin', 'user', 'bot', 'app', 'anonymous']);
|
|
await updatePermission('view-joined-room', ['guest', 'bot', 'app', 'anonymous']);
|
|
testChannel = (await createRoom({ type: 'c', name: `channels.messages.test.${Date.now()}` })).body.channel;
|
|
});
|
|
|
|
after(async () => {
|
|
await updatePermission('view-c-room', ['admin', 'user', 'bot', 'app', 'anonymous']);
|
|
await updatePermission('view-joined-room', ['guest', 'bot', 'app', 'anonymous']);
|
|
await deleteRoom({ type: 'c', roomId: testChannel._id });
|
|
});
|
|
|
|
it('should succesfully return a list of channels', async () => {
|
|
await request
|
|
.get(api('channels.list'))
|
|
.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('channels').that.is.an('array');
|
|
expect(res.body).to.have.property('count');
|
|
expect(res.body).to.have.property('total');
|
|
});
|
|
});
|
|
|
|
it('should correctly filter channel by id', async () => {
|
|
await request
|
|
.get(api('channels.list'))
|
|
.set(credentials)
|
|
.query({
|
|
_id: testChannel._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('channels').that.is.an('array').of.length(1);
|
|
expect(res.body).to.have.property('count', 1);
|
|
expect(res.body).to.have.property('total');
|
|
});
|
|
});
|
|
|
|
it('should not be succesful when user does NOT have the permission to view channels or joined rooms', async () => {
|
|
await updatePermission('view-c-room', []);
|
|
await updatePermission('view-joined-room', []);
|
|
await request
|
|
.get(api('channels.list'))
|
|
.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]');
|
|
});
|
|
});
|
|
|
|
it('should be succesful when user does NOT have the permission to view channels, but can view joined rooms', async () => {
|
|
await updatePermission('view-c-room', []);
|
|
await updatePermission('view-joined-room', ['admin']);
|
|
await request
|
|
.get(api('channels.list'))
|
|
.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('channels').that.is.an('array');
|
|
expect(res.body).to.have.property('count');
|
|
expect(res.body).to.have.property('total');
|
|
});
|
|
});
|
|
|
|
it('should be succesful when user does NOT have the permission to view joined rooms, but can view channels', async () => {
|
|
await updatePermission('view-c-room', ['admin']);
|
|
await updatePermission('view-joined-room', []);
|
|
await request
|
|
.get(api('channels.list'))
|
|
.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('channels').that.is.an('array');
|
|
expect(res.body).to.have.property('count');
|
|
expect(res.body).to.have.property('total');
|
|
});
|
|
});
|
|
|
|
it('should paginate', async () => {
|
|
const {
|
|
body: { channels: channels1 },
|
|
} = await request.get(api('channels.list')).set(credentials);
|
|
const {
|
|
body: { channels: channels2 },
|
|
} = await request.get(api('channels.list')).set(credentials).query({ offset: 1 });
|
|
expect(channels1).to.not.deep.equal(channels2);
|
|
});
|
|
|
|
it('should accept the `fields` query param', async () => {
|
|
await request
|
|
.get(api('channels.list'))
|
|
.set(credentials)
|
|
.query({
|
|
fields: JSON.stringify({ name: 1 }),
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('channels').that.is.an('array');
|
|
expect(res.body).to.have.property('count');
|
|
expect(res.body).to.have.property('total');
|
|
});
|
|
});
|
|
|
|
it('should accept the `fields` query param alongside the other supported params', async () => {
|
|
await request
|
|
.get(api('channels.list'))
|
|
.set(credentials)
|
|
.query({
|
|
_id: testChannel._id,
|
|
query: JSON.stringify({}),
|
|
fields: JSON.stringify({ name: 1 }),
|
|
sort: JSON.stringify({ name: 1 }),
|
|
count: 1,
|
|
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('channels').that.is.an('array');
|
|
});
|
|
});
|
|
|
|
it('should reject unknown query params', async () => {
|
|
await request
|
|
.get(api('channels.list'))
|
|
.set(credentials)
|
|
.query({
|
|
invalidParam: 'invalid',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('error', 'must NOT have additional properties');
|
|
});
|
|
});
|
|
});
|
|
|
|
it('/channels.list.joined', async () => {
|
|
const res = await request
|
|
.get(api('channels.list.joined'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: channel._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');
|
|
});
|
|
|
|
describe('[/channels.list.joined]', () => {
|
|
it('should accept the `fields` query param', async () => {
|
|
const res = await request
|
|
.get(api('channels.list.joined'))
|
|
.set(credentials)
|
|
.query({
|
|
fields: JSON.stringify({ name: 1 }),
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('channels').that.is.an('array');
|
|
expect(res.body).to.have.property('count');
|
|
expect(res.body).to.have.property('total');
|
|
});
|
|
|
|
it('should accept the `fields` query param alongside the other supported params', async () => {
|
|
const res = await request
|
|
.get(api('channels.list.joined'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: channel._id,
|
|
roomName: channel.name,
|
|
_id: channel._id,
|
|
query: JSON.stringify({}),
|
|
fields: JSON.stringify({ name: 1 }),
|
|
sort: JSON.stringify({ name: 1 }),
|
|
count: 1,
|
|
offset: 0,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('channels').that.is.an('array');
|
|
});
|
|
|
|
it('should reject unknown query params', async () => {
|
|
await request
|
|
.get(api('channels.list.joined'))
|
|
.set(credentials)
|
|
.query({
|
|
invalidParam: 'invalid',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('error', 'must NOT have additional properties');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('/channels.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: 'c',
|
|
name: `counters-test-${Date.now()}`,
|
|
members: [user1.username as string, user2.username as string],
|
|
})
|
|
).body.channel;
|
|
});
|
|
|
|
after(async () => {
|
|
// Delete room first
|
|
await deleteRoom({ type: 'c', roomId: room._id });
|
|
// Then delete users
|
|
await Promise.all([deleteUser(user1), deleteUser(user2)]);
|
|
});
|
|
|
|
it('should require auth', async () => {
|
|
await request
|
|
.get(api('channels.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('channels.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('channels.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('channels.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);
|
|
});
|
|
});
|
|
|
|
it('/channels.rename', async () => {
|
|
const roomInfo = await getRoomInfo(channel._id);
|
|
|
|
function failRenameChannel(name: string) {
|
|
it(`should not rename a channel to the reserved name ${name}`, async () => {
|
|
const res = await request
|
|
.post(api('channels.rename'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._id,
|
|
name,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400);
|
|
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('error', `${name} is already in use :( [error-field-unavailable]`);
|
|
});
|
|
}
|
|
|
|
reservedWords.forEach((name) => {
|
|
failRenameChannel(name);
|
|
});
|
|
|
|
return request
|
|
.post(api('channels.rename'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._id,
|
|
name: `EDITED${apiPublicChannelName}`,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('channel._id');
|
|
expect(res.body).to.have.nested.property('channel.name', `EDITED${apiPublicChannelName}`);
|
|
expect(res.body).to.have.nested.property('channel.t', 'c');
|
|
expect(res.body).to.have.nested.property('channel.msgs', roomInfo.channel.msgs + 1);
|
|
});
|
|
});
|
|
|
|
it('/channels.addAll', async () => {
|
|
const res = await request
|
|
.post(api('channels.addAll'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('channel._id');
|
|
expect(res.body).to.have.nested.property('channel.name', `EDITED${apiPublicChannelName}`);
|
|
expect(res.body).to.have.nested.property('channel.t', 'c');
|
|
});
|
|
|
|
it('/channels.addLeader', async () => {
|
|
const res = await request
|
|
.post(api('channels.addLeader'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.a.property('success', true);
|
|
});
|
|
it('/channels.removeLeader', async () => {
|
|
const res = await request
|
|
.post(api('channels.removeLeader'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
|
|
it('/channels.setJoinCode', async () => {
|
|
const roomInfo = await getRoomInfo(channel._id);
|
|
|
|
return request
|
|
.post(api('channels.setJoinCode'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._id,
|
|
joinCode: '123',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('channel._id');
|
|
expect(res.body).to.have.nested.property('channel.name', `EDITED${apiPublicChannelName}`);
|
|
expect(res.body).to.have.nested.property('channel.t', 'c');
|
|
expect(res.body).to.have.nested.property('channel.msgs', roomInfo.channel.msgs);
|
|
});
|
|
});
|
|
|
|
it('/channels.setReadOnly', async () => {
|
|
const roomInfo = await getRoomInfo(channel._id);
|
|
|
|
return request
|
|
.post(api('channels.setReadOnly'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._id,
|
|
readOnly: 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('channel._id');
|
|
expect(res.body).to.have.nested.property('channel.name', `EDITED${apiPublicChannelName}`);
|
|
expect(res.body).to.have.nested.property('channel.t', 'c');
|
|
expect(res.body).to.have.nested.property('channel.msgs', roomInfo.channel.msgs + 1);
|
|
});
|
|
});
|
|
it('/channels.leave', async () => {
|
|
const roomInfo = await getRoomInfo(channel._id);
|
|
|
|
return request
|
|
.post(api('channels.leave'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._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('channel._id');
|
|
expect(res.body).to.have.nested.property('channel.name', `EDITED${apiPublicChannelName}`);
|
|
expect(res.body).to.have.nested.property('channel.t', 'c');
|
|
expect(res.body).to.have.nested.property('channel.msgs', roomInfo.channel.msgs + 1);
|
|
});
|
|
});
|
|
|
|
describe('[/channels.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-channel', ['owner']);
|
|
});
|
|
after(async () => {
|
|
await deleteUser(guestUser);
|
|
await deleteUser(invitedUser);
|
|
await updatePermission('create-team-channel', ['admin', 'owner', 'moderator']);
|
|
});
|
|
|
|
it(`should fail when trying to use an existing room's name`, async () => {
|
|
await request
|
|
.post(api('channels.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 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: 'c',
|
|
name: `channel.test.${Date.now()}-${Math.random()}`,
|
|
members: [guestUser.username],
|
|
}),
|
|
);
|
|
}
|
|
const channelIds = (await Promise.all(promises)).map((r) => r.body.channel).map((channel) => channel._id);
|
|
|
|
void request
|
|
.post(api('channels.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;
|
|
})
|
|
.then(() => {
|
|
void request
|
|
.get(api('channels.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);
|
|
});
|
|
});
|
|
|
|
await Promise.all(channelIds.map((id) => deleteRoom({ type: 'c', roomId: id })));
|
|
});
|
|
|
|
it('should successfully create a channel in a team', async () => {
|
|
await request
|
|
.post(api('channels.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: `team-channel-${Date.now()}`,
|
|
extraData: { teamId },
|
|
})
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('channel');
|
|
expect(res.body.channel).to.have.property('teamId', teamId);
|
|
});
|
|
});
|
|
|
|
it('should fail creating a channel in a team when member does not have the necessary permission', async () => {
|
|
await request
|
|
.post(api('channels.create'))
|
|
.set(invitedUserCredentials)
|
|
.send({
|
|
name: `team-channel-${Date.now()}`,
|
|
extraData: { teamId },
|
|
})
|
|
.expect(403)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('error', 'unauthorized');
|
|
});
|
|
});
|
|
|
|
describe('E2E forced encryption for private rooms', () => {
|
|
let createdRoomId: IRoom['_id'] | undefined;
|
|
|
|
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),
|
|
...(createdRoomId ? [deleteRoom({ type: 'c', roomId: createdRoomId })] : []),
|
|
]);
|
|
});
|
|
|
|
it('should not force encryption on public channels when private room encryption is forced', async () => {
|
|
await request
|
|
.post(api('channels.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: `forced-e2e-public-${Date.now()}`,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
createdRoomId = res.body.channel?._id;
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('channel.t', 'c');
|
|
expect(res.body).to.not.have.nested.property('channel.encrypted', true);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('[/channels.info]', () => {
|
|
const testChannelName = `api-channel-test-${Date.now()}.${Random.id()}`;
|
|
let testChannel: IRoom;
|
|
|
|
after(async () => {
|
|
await deleteRoom({ type: 'c', roomId: testChannel._id });
|
|
});
|
|
|
|
it('creating new channel...', async () => {
|
|
const res = await request
|
|
.post(api('channels.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: testChannelName,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
testChannel = res.body.channel;
|
|
});
|
|
it('should fail to create the same channel twice', async () => {
|
|
const res = await request
|
|
.post(api('channels.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: testChannelName,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400);
|
|
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body.error).to.contain('error-duplicate-channel-name');
|
|
});
|
|
it('should return channel basic structure', async () => {
|
|
const res = await request
|
|
.get(api('channels.info'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testChannel._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('channel._id');
|
|
expect(res.body).to.have.nested.property('channel.name', testChannelName);
|
|
expect(res.body).to.have.nested.property('channel.t', 'c');
|
|
expect(res.body).to.have.nested.property('channel.msgs', 0);
|
|
});
|
|
|
|
let channelMessage: IMessage;
|
|
|
|
it('sending a message...', async () => {
|
|
const res = await request
|
|
.post(api('chat.sendMessage'))
|
|
.set(credentials)
|
|
.send({
|
|
message: {
|
|
text: 'Sample message',
|
|
rid: testChannel._id,
|
|
},
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
channelMessage = res.body.message;
|
|
});
|
|
it('REACTing with last message', async () => {
|
|
const res = await request
|
|
.post(api('chat.react'))
|
|
.set(credentials)
|
|
.send({
|
|
emoji: ':squid:',
|
|
messageId: channelMessage._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
it('STARring last message', async () => {
|
|
const res = await request
|
|
.post(api('chat.starMessage'))
|
|
.set(credentials)
|
|
.send({
|
|
messageId: channelMessage._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
it('PINning last message', async () => {
|
|
const res = await request
|
|
.post(api('chat.pinMessage'))
|
|
.set(credentials)
|
|
.send({
|
|
messageId: channelMessage._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
it('should return channel structure with "lastMessage" object including pin, reactions and star(should be an array) infos', async () => {
|
|
const res = await request
|
|
.get(api('channels.info'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testChannel._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('channel').and.to.be.an('object');
|
|
const { channel } = res.body;
|
|
expect(channel).to.have.property('lastMessage').and.to.be.an('object');
|
|
expect(channel.lastMessage).to.have.property('reactions').and.to.be.an('object');
|
|
expect(channel.lastMessage).to.have.property('pinned').and.to.be.a('boolean');
|
|
expect(channel.lastMessage).to.have.property('pinnedAt').and.to.be.a('string');
|
|
expect(channel.lastMessage).to.have.property('pinnedBy').and.to.be.an('object');
|
|
expect(channel.lastMessage).to.have.property('starred').and.to.be.an('array');
|
|
});
|
|
it('should return all channels messages where the last message of array should have the "star" array with USERS star ONLY', async () => {
|
|
const res = await request
|
|
.get(api('channels.messages'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testChannel._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
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 === channelMessage._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 channels messages where the last message of array should have the "star" array with USERS star ONLY even requested with count and offset params', async () => {
|
|
const res = await request
|
|
.get(api('channels.messages'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testChannel._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').and.to.be.an('array');
|
|
const messages = res.body.messages as IMessage[];
|
|
const lastMessage = messages.filter((message) => message._id === channelMessage._id)[0];
|
|
expect(lastMessage).to.have.property('starred').and.to.be.an('array');
|
|
expect(lastMessage.starred?.[0]._id).to.be.equal(adminUsername);
|
|
});
|
|
describe('Additional Visibility Tests', () => {
|
|
let outsiderUser: IUser;
|
|
let insideUser: IUser;
|
|
let nonTeamUser: IUser;
|
|
let outsiderCredentials: { 'X-Auth-Token': string; 'X-User-Id': string };
|
|
let insideCredentials: { 'X-Auth-Token': string; 'X-User-Id': string };
|
|
let nonTeamCredentials: { 'X-Auth-Token': string; 'X-User-Id': string };
|
|
|
|
let privateChannel: IRoom;
|
|
let publicChannel: IRoom;
|
|
let publicTeam: ITeam;
|
|
let privateTeam: ITeam;
|
|
let privateChannelInPublicTeam: IRoom;
|
|
let publicChannelInPublicTeam: IRoom;
|
|
let privateChannelInPrivateTeam: IRoom;
|
|
let publicChannelInPrivateTeam: IRoom;
|
|
|
|
before(async () => {
|
|
[outsiderUser, insideUser, nonTeamUser] = await Promise.all([
|
|
createUser({ username: `e_${Random.id()}` }),
|
|
createUser({ username: `f_${Random.id()}` }),
|
|
createUser({ username: `g_${Random.id()}` }),
|
|
]);
|
|
[outsiderCredentials, insideCredentials, nonTeamCredentials] = await Promise.all([
|
|
login(outsiderUser.username, password),
|
|
login(insideUser.username, password),
|
|
login(nonTeamUser.username, password),
|
|
]);
|
|
|
|
// Create a public team and a private team
|
|
[publicTeam, privateTeam] = await Promise.all([
|
|
createTeam(insideCredentials, `channels.info.team.public.${Random.id()}`, TeamType.PUBLIC, [outsiderUser.username as string]),
|
|
createTeam(insideCredentials, `channels.info.team.private.${Random.id()}`, TeamType.PRIVATE, [outsiderUser.username as string]),
|
|
]);
|
|
|
|
const [
|
|
privateInPublicResponse,
|
|
publicInPublicResponse,
|
|
privateInPrivateResponse,
|
|
publicInPrivateResponse,
|
|
privateRoomResponse,
|
|
publicRoomResponse,
|
|
] = await Promise.all([
|
|
createRoom({
|
|
type: 'p',
|
|
name: `teamPublic.privateChannel.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
extraData: {
|
|
teamId: publicTeam._id,
|
|
},
|
|
}),
|
|
createRoom({
|
|
type: 'c',
|
|
name: `teamPublic.publicChannel.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
extraData: {
|
|
teamId: publicTeam._id,
|
|
},
|
|
}),
|
|
createRoom({
|
|
type: 'p',
|
|
name: `teamPrivate.privateChannel.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
extraData: {
|
|
teamId: privateTeam._id,
|
|
},
|
|
}),
|
|
createRoom({
|
|
type: 'c',
|
|
name: `teamPrivate.publicChannel.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
extraData: {
|
|
teamId: privateTeam._id,
|
|
},
|
|
}),
|
|
createRoom({
|
|
type: 'p',
|
|
name: `channels.info.private.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
}),
|
|
createRoom({
|
|
type: 'c',
|
|
name: `channels.info.public.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
}),
|
|
]);
|
|
|
|
privateChannelInPublicTeam = privateInPublicResponse.body.group;
|
|
publicChannelInPublicTeam = publicInPublicResponse.body.channel;
|
|
privateChannelInPrivateTeam = privateInPrivateResponse.body.group;
|
|
publicChannelInPrivateTeam = publicInPrivateResponse.body.channel;
|
|
privateChannel = privateRoomResponse.body.group;
|
|
publicChannel = publicRoomResponse.body.channel;
|
|
});
|
|
|
|
after(async () => {
|
|
await Promise.all([
|
|
deleteRoom({ type: 'p', roomId: privateChannel._id }),
|
|
deleteRoom({ type: 'c', roomId: publicChannel._id }),
|
|
deleteRoom({ type: 'p', roomId: privateChannelInPublicTeam._id }),
|
|
deleteRoom({ type: 'c', roomId: publicChannelInPublicTeam._id }),
|
|
deleteRoom({ type: 'p', roomId: privateChannelInPrivateTeam._id }),
|
|
deleteRoom({ type: 'c', roomId: publicChannelInPrivateTeam._id }),
|
|
]);
|
|
|
|
await Promise.all([deleteTeam(credentials, publicTeam.name), deleteTeam(credentials, privateTeam.name)]);
|
|
|
|
await Promise.all([deleteUser(outsiderUser), deleteUser(insideUser), deleteUser(nonTeamUser)]);
|
|
});
|
|
|
|
it('should not fetch private room info by user not part of room', async () => {
|
|
await request
|
|
.get(api('channels.info'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: privateChannel._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch private room info by user who is part of the room', async () => {
|
|
const response = await request
|
|
.get(api('channels.info'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: privateChannel._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400);
|
|
|
|
expect(response.body.success).to.be.false;
|
|
});
|
|
|
|
it('should fetch public room info by user who is part of the room', async () => {
|
|
const response = await request
|
|
.get(api('channels.info'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: publicChannel._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(response.body.success).to.be.true;
|
|
expect(response.body).to.have.property('channel');
|
|
});
|
|
|
|
it('should fetch public room info by user not part of room - because public', async () => {
|
|
const response = await request
|
|
.get(api('channels.info'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: publicChannel._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(response.body.success).to.be.true;
|
|
expect(response.body).to.have.property('channel');
|
|
});
|
|
|
|
it('should not fetch a private channel info inside a public team by someone part of the room ', async () => {
|
|
await request
|
|
.get(api('channels.info'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: privateChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel info inside a public team by someone not part of the room, but part of team', async () => {
|
|
await request
|
|
.get(api('channels.info'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: privateChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel info inside a public team by someone not part of the team ', async () => {
|
|
await request
|
|
.get(api('channels.info'))
|
|
.set(nonTeamCredentials)
|
|
.query({ roomId: privateChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel info inside a public team by someone part of the room ', async () => {
|
|
await request
|
|
.get(api('channels.info'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: publicChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('channel');
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel info inside a public team by someone not part of the room, but part of team', async () => {
|
|
await request
|
|
.get(api('channels.info'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: publicChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('channel');
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel info inside a public team by someone not part of the team ', async () => {
|
|
await request
|
|
.get(api('channels.info'))
|
|
.set(nonTeamCredentials)
|
|
.query({ roomId: publicChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('channel');
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel info inside a private team by someone part of the room', async () => {
|
|
await request
|
|
.get(api('channels.info'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: publicChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('channel');
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel info inside a private team by someone not part of the room, but part of team', async () => {
|
|
await request
|
|
.get(api('channels.info'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: publicChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('channel');
|
|
});
|
|
});
|
|
|
|
it('should not fetch a public channel info inside a private team by someone not part of team', async () => {
|
|
await request
|
|
.get(api('channels.info'))
|
|
.set(nonTeamCredentials)
|
|
.query({ roomId: publicChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(403)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel info inside a private team by someone part of the room', async () => {
|
|
await request
|
|
.get(api('channels.info'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: privateChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel info inside a private team by someone not part of the room, but part of team', async () => {
|
|
await request
|
|
.get(api('channels.info'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: privateChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel info inside a private team by someone not part of team', async () => {
|
|
await request
|
|
.get(api('channels.info'))
|
|
.set(nonTeamCredentials)
|
|
.query({ roomId: privateChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('[/channels.online]', () => {
|
|
const createdChannels: IRoom[] = [];
|
|
const createdUsers: TestUser<IUser>[] = [];
|
|
|
|
const createUserAndChannel = async () => {
|
|
const testUser = await createUser();
|
|
const testUserCredentials = await login(testUser.username, password);
|
|
createdUsers.push(testUser);
|
|
|
|
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: 'c',
|
|
members: [testUser.username],
|
|
});
|
|
createdChannels.push(roomResponse.body.channel);
|
|
|
|
return {
|
|
testUser,
|
|
testUserCredentials,
|
|
room: roomResponse.body.channel,
|
|
};
|
|
};
|
|
|
|
after(async () => {
|
|
await Promise.all([
|
|
createdUsers.map((user) => deleteUser(user)),
|
|
createdChannels.map((channel) => deleteRoom({ type: 'c', roomId: channel._id })),
|
|
]);
|
|
});
|
|
|
|
it('should return an error if no query', () =>
|
|
void request
|
|
.get(api('channels.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', () =>
|
|
void request
|
|
.get(api('channels.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();
|
|
|
|
return request
|
|
.get(api('channels.online'))
|
|
.set(testUserCredentials)
|
|
.query({ _id: 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('online');
|
|
|
|
const expected = {
|
|
_id: testUser._id,
|
|
username: testUser.username,
|
|
};
|
|
expect(res.body.online).to.deep.include(expected);
|
|
});
|
|
});
|
|
|
|
it('should return an empty array if requesting user is not in channel', async () => {
|
|
const outsider = await createUser();
|
|
const outsiderCredentials = await login(outsider.username, password);
|
|
|
|
const { testUser, room } = await createUserAndChannel();
|
|
|
|
return request
|
|
.get(api('channels.online'))
|
|
.set(outsiderCredentials)
|
|
.query({ _id: 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('online');
|
|
|
|
const expected = {
|
|
_id: testUser._id,
|
|
username: testUser.username,
|
|
};
|
|
expect(res.body.online).to.deep.include(expected);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('[/channels.files]', async () => {
|
|
await testFileUploads('channels.files', 'c');
|
|
});
|
|
|
|
describe('[/channels.join]', () => {
|
|
let testChannelNoCode: IRoom;
|
|
let testChannelWithCode: IRoom;
|
|
let testUser: TestUser<IUser>;
|
|
let testUserCredentials: Credentials;
|
|
|
|
before('Create test user', async () => {
|
|
testUser = await createUser();
|
|
testUserCredentials = await login(testUser.username, password);
|
|
testChannelNoCode = (await createRoom({ type: 'c', credentials: testUserCredentials, name: `${apiPublicChannelName}-nojoincode` }))
|
|
.body.channel;
|
|
testChannelWithCode = (
|
|
await createRoom({ type: 'c', credentials: testUserCredentials, name: `${apiPublicChannelName}-withjoincode` })
|
|
).body.channel;
|
|
await updatePermission('edit-room', ['admin', 'owner', 'moderator']);
|
|
});
|
|
|
|
after(async () => {
|
|
await Promise.all([
|
|
deleteRoom({ type: 'c', roomId: testChannelNoCode._id }),
|
|
deleteRoom({ type: 'c', roomId: testChannelWithCode._id }),
|
|
deleteUser(testUser),
|
|
updatePermission('edit-room', ['admin', 'owner', 'moderator']),
|
|
updatePermission('join-without-join-code', ['admin', 'bot', 'app']),
|
|
]);
|
|
});
|
|
|
|
before('Set code for channel', (done) => {
|
|
void request
|
|
.post(api('channels.setJoinCode'))
|
|
.set(testUserCredentials)
|
|
.send({
|
|
roomId: testChannelWithCode._id,
|
|
joinCode: '123',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
})
|
|
.end(done);
|
|
});
|
|
|
|
it('should fail if invalid channel', async () => {
|
|
const res = await request
|
|
.post(api('channels.join'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: 'invalid',
|
|
})
|
|
.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');
|
|
});
|
|
|
|
describe('code-free channel', () => {
|
|
it('should succeed when joining code-free channel without join code', async () => {
|
|
const res = await request
|
|
.post(api('channels.join'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: testChannelNoCode._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('channel._id', testChannelNoCode._id);
|
|
});
|
|
});
|
|
|
|
describe('code-needed channel', () => {
|
|
describe('without join-without-join-code permission', () => {
|
|
before('set join-without-join-code permission to false', async () => {
|
|
await updatePermission('join-without-join-code', []);
|
|
});
|
|
|
|
it('should fail when joining code-needed channel without join code and no join-without-join-code permission', async () => {
|
|
const res = await request
|
|
.post(api('channels.join'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: testChannelWithCode._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400);
|
|
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.nested.property('errorType', 'error-code-required');
|
|
});
|
|
|
|
it('should fail when joining code-needed channel with incorrect join code and no join-without-join-code permission', async () => {
|
|
const res = await request
|
|
.post(api('channels.join'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: testChannelWithCode._id,
|
|
joinCode: 'WRONG_CODE',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400);
|
|
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.nested.property('errorType', 'error-code-invalid');
|
|
});
|
|
|
|
it('should succeed when joining code-needed channel with join code', async () => {
|
|
const res = await request
|
|
.post(api('channels.join'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: testChannelWithCode._id,
|
|
joinCode: '123',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('channel._id', testChannelWithCode._id);
|
|
});
|
|
});
|
|
|
|
describe('with join-without-join-code permission', () => {
|
|
before('set join-without-join-code permission to true', async () => {
|
|
await updatePermission('join-without-join-code', ['admin']);
|
|
});
|
|
|
|
before('leave channel', (done) => {
|
|
void request
|
|
.post(api('channels.leave'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: testChannelWithCode._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
})
|
|
.end(done);
|
|
});
|
|
|
|
it('should succeed when joining code-needed channel without join code and with join-without-join-code permission', async () => {
|
|
const res = await request
|
|
.post(api('channels.join'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: testChannelWithCode._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('channel._id', testChannelWithCode._id);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('/channels.setDescription', () => {
|
|
it('should set the description of the channel with a string', async () => {
|
|
const res = await request
|
|
.post(api('channels.setDescription'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._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 channel with an empty string(remove the description)', async () => {
|
|
const res = await request
|
|
.post(api('channels.setDescription'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._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('/channels.setTopic', () => {
|
|
it('should set the topic of the channel with a string', async () => {
|
|
const res = await request
|
|
.post(api('channels.setTopic'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._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 channel with an empty string(remove the topic)', async () => {
|
|
const res = await request
|
|
.post(api('channels.setTopic'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._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('/channels.setAnnouncement', () => {
|
|
it('should set the announcement of the channel with a string', async () => {
|
|
const res = await request
|
|
.post(api('channels.setAnnouncement'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._id,
|
|
announcement: 'this is an announcement 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('announcement', 'this is an announcement of a channel for api tests');
|
|
});
|
|
it('should set the announcement of the channel with an empty string(remove the announcement)', async () => {
|
|
const res = await request
|
|
.post(api('channels.setAnnouncement'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._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('/channels.setPurpose', () => {
|
|
it('should set the purpose of the channel with a string', async () => {
|
|
const res = await request
|
|
.post(api('channels.setPurpose'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._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 announcement of channel with an empty string(remove the purpose)', async () => {
|
|
const res = await request
|
|
.post(api('channels.setPurpose'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._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('/channels.history', () => {
|
|
it('should return an array of members by channel', async () => {
|
|
const res = await request
|
|
.get(api('channels.history'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: channel._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 an array of members by channel even requested with count and offset params', async () => {
|
|
const res = await request
|
|
.get(api('channels.history'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: channel._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 testChannel: IRoom;
|
|
let oldestMessage: IMessage;
|
|
let middleMessage: IMessage;
|
|
let latestMessage: IMessage;
|
|
|
|
before(async () => {
|
|
const channelRes = await request
|
|
.post(api('channels.create'))
|
|
.set(credentials)
|
|
.send({ name: `inclusive-test-channel-${Date.now()}` });
|
|
testChannel = channelRes.body.channel;
|
|
|
|
// Send messages with small delays to ensure distinct timestamps
|
|
const msg1 = await sendMessage({ message: { rid: testChannel._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: testChannel._id, msg: 'middle message' } });
|
|
middleMessage = msg2.body.message;
|
|
|
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
|
|
const msg3 = await sendMessage({ message: { rid: testChannel._id, msg: 'latest message' } });
|
|
latestMessage = msg3.body.message;
|
|
});
|
|
|
|
after(async () => {
|
|
if (testChannel?._id) {
|
|
await deleteRoom({ type: 'c', roomId: testChannel._id });
|
|
}
|
|
});
|
|
|
|
it('should include boundary messages when inclusive=true', async () => {
|
|
const res = await request
|
|
.get(api('channels.history'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testChannel._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('channels.history'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testChannel._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('channels.history'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testChannel._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('/channels.members', () => {
|
|
let testUser: TestUser<IUser>;
|
|
|
|
before(async () => {
|
|
testUser = await createUser();
|
|
await updateSetting('Accounts_SearchFields', 'username, name, bio, nickname');
|
|
await request
|
|
.post(api('channels.invite'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._id,
|
|
userId: testUser._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
});
|
|
|
|
after(async () => {
|
|
await Promise.all([updateSetting('Accounts_SearchFields', 'username, name, bio, nickname'), deleteUser(testUser)]);
|
|
});
|
|
|
|
it('should return an array of members by channel', async () => {
|
|
const res = await request
|
|
.get(api('channels.members'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: channel._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('members').and.to.be.an('array');
|
|
expect(res.body).to.have.property('count');
|
|
expect(res.body).to.have.property('total');
|
|
expect(res.body).to.have.property('offset');
|
|
});
|
|
|
|
it('should return an array of members by channel even requested with count and offset params', async () => {
|
|
const res = await request
|
|
.get(api('channels.members'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: channel._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('members').and.to.be.an('array');
|
|
expect(res.body).to.have.property('count');
|
|
expect(res.body).to.have.property('total');
|
|
expect(res.body).to.have.property('offset');
|
|
});
|
|
|
|
it('should return an filtered array of members by channel', async () => {
|
|
const res = await request
|
|
.get(api('channels.members'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: channel._id,
|
|
filter: testUser.username,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('members').and.to.be.an('array');
|
|
expect(res.body).to.have.property('count', 1);
|
|
expect(res.body.members[0]._id).to.be.equal(testUser._id);
|
|
expect(res.body).to.have.property('count');
|
|
expect(res.body).to.have.property('total');
|
|
expect(res.body).to.have.property('offset');
|
|
});
|
|
|
|
describe('Additional Visibility Tests', () => {
|
|
let outsiderUser: IUser;
|
|
let insideUser: IUser;
|
|
let nonTeamUser: IUser;
|
|
let outsiderCredentials: { 'X-Auth-Token': string; 'X-User-Id': string };
|
|
let insideCredentials: { 'X-Auth-Token': string; 'X-User-Id': string };
|
|
let nonTeamCredentials: { 'X-Auth-Token': string; 'X-User-Id': string };
|
|
|
|
let privateChannel: IRoom;
|
|
let publicChannel: IRoom;
|
|
let publicTeam: ITeam;
|
|
let privateTeam: ITeam;
|
|
let privateChannelInPublicTeam: IRoom;
|
|
let publicChannelInPublicTeam: IRoom;
|
|
let privateChannelInPrivateTeam: IRoom;
|
|
let publicChannelInPrivateTeam: IRoom;
|
|
|
|
before(async () => {
|
|
[outsiderUser, insideUser, nonTeamUser] = await Promise.all([
|
|
createUser({ username: `e_${Random.id()}` }),
|
|
createUser({ username: `f_${Random.id()}` }),
|
|
createUser({ username: `g_${Random.id()}` }),
|
|
]);
|
|
[outsiderCredentials, insideCredentials, nonTeamCredentials] = await Promise.all([
|
|
login(outsiderUser.username, password),
|
|
login(insideUser.username, password),
|
|
login(nonTeamUser.username, password),
|
|
]);
|
|
|
|
// Create a public team and a private team
|
|
[publicTeam, privateTeam] = await Promise.all([
|
|
createTeam(insideCredentials, `channels.members.team.public.${Random.id()}`, TeamType.PUBLIC, [outsiderUser.username as string]),
|
|
createTeam(insideCredentials, `channels.members.team.private.${Random.id()}`, TeamType.PRIVATE, [
|
|
outsiderUser.username as string,
|
|
]),
|
|
]);
|
|
|
|
const [
|
|
privateInPublicResponse,
|
|
publicInPublicResponse,
|
|
privateInPrivateResponse,
|
|
publicInPrivateResponse,
|
|
privateRoomResponse,
|
|
publicRoomResponse,
|
|
] = await Promise.all([
|
|
createRoom({
|
|
type: 'p',
|
|
name: `teamPublic.privateChannel.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
extraData: {
|
|
teamId: publicTeam._id,
|
|
},
|
|
}),
|
|
createRoom({
|
|
type: 'c',
|
|
name: `teamPublic.publicChannel.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
extraData: {
|
|
teamId: publicTeam._id,
|
|
},
|
|
}),
|
|
createRoom({
|
|
type: 'p',
|
|
name: `teamPrivate.privateChannel.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
extraData: {
|
|
teamId: privateTeam._id,
|
|
},
|
|
}),
|
|
createRoom({
|
|
type: 'c',
|
|
name: `teamPrivate.publicChannel.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
extraData: {
|
|
teamId: privateTeam._id,
|
|
},
|
|
}),
|
|
createRoom({
|
|
type: 'p',
|
|
name: `rooms.members.private.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
}),
|
|
createRoom({
|
|
type: 'c',
|
|
name: `rooms.members.public.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
}),
|
|
]);
|
|
|
|
privateChannelInPublicTeam = privateInPublicResponse.body.group;
|
|
publicChannelInPublicTeam = publicInPublicResponse.body.channel;
|
|
privateChannelInPrivateTeam = privateInPrivateResponse.body.group;
|
|
publicChannelInPrivateTeam = publicInPrivateResponse.body.channel;
|
|
privateChannel = privateRoomResponse.body.group;
|
|
publicChannel = publicRoomResponse.body.channel;
|
|
});
|
|
|
|
after(async () => {
|
|
await Promise.all([
|
|
deleteRoom({ type: 'p', roomId: privateChannel._id }),
|
|
deleteRoom({ type: 'c', roomId: publicChannel._id }),
|
|
deleteRoom({ type: 'p', roomId: privateChannelInPublicTeam._id }),
|
|
deleteRoom({ type: 'c', roomId: publicChannelInPublicTeam._id }),
|
|
deleteRoom({ type: 'p', roomId: privateChannelInPrivateTeam._id }),
|
|
deleteRoom({ type: 'c', roomId: publicChannelInPrivateTeam._id }),
|
|
]);
|
|
|
|
await Promise.all([deleteTeam(credentials, publicTeam.name), deleteTeam(credentials, privateTeam.name)]);
|
|
|
|
await Promise.all([deleteUser(outsiderUser), deleteUser(insideUser), deleteUser(nonTeamUser)]);
|
|
});
|
|
|
|
it('should not fetch private room members by user not part of room', async () => {
|
|
await request
|
|
.get(api('channels.members'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: privateChannel._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch private room members by user who is part of the room', async () => {
|
|
const response = await request
|
|
.get(api('channels.members'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: privateChannel._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400);
|
|
|
|
expect(response.body.success).to.be.false;
|
|
});
|
|
|
|
it('should fetch public room members by user who is part of the room', async () => {
|
|
const response = await request
|
|
.get(api('channels.members'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: publicChannel._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(response.body.success).to.be.true;
|
|
expect(response.body.members).to.be.an('array');
|
|
});
|
|
|
|
it('should fetch public room members by user not part of room - because public', async () => {
|
|
await updatePermission('view-c-room', ['admin', 'user', 'guest']);
|
|
const response = await request
|
|
.get(api('channels.members'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: publicChannel._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(response.body.success).to.be.true;
|
|
expect(response.body.members).to.be.an('array');
|
|
});
|
|
|
|
it('should not fetch a private channel members inside a public team by someone part of the room ', async () => {
|
|
await request
|
|
.get(api('channels.members'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: privateChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel members inside a public team by someone not part of the room, but part of team', async () => {
|
|
await request
|
|
.get(api('channels.members'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: privateChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel members inside a public team by someone not part of the team ', async () => {
|
|
await request
|
|
.get(api('channels.members'))
|
|
.set(nonTeamCredentials)
|
|
.query({ roomId: privateChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel members inside a public team by someone part of the room ', async () => {
|
|
await request
|
|
.get(api('channels.members'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: publicChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body.members).to.be.an('array');
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel members inside a public team by someone not part of the room, but part of team', async () => {
|
|
await request
|
|
.get(api('channels.members'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: publicChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body.members).to.be.an('array');
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel members inside a public team by someone not part of the team ', async () => {
|
|
await request
|
|
.get(api('channels.members'))
|
|
.set(nonTeamCredentials)
|
|
.query({ roomId: publicChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body.members).to.be.an('array');
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel members inside a private team by someone part of the room', async () => {
|
|
await request
|
|
.get(api('channels.members'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: publicChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body.members).to.be.an('array');
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel members inside a private team by someone not part of the room, but part of team', async () => {
|
|
await request
|
|
.get(api('channels.members'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: publicChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body.members).to.be.an('array');
|
|
});
|
|
});
|
|
|
|
it('should not fetch a public channel members inside a private team by someone not part of team', async () => {
|
|
await request
|
|
.get(api('channels.members'))
|
|
.set(nonTeamCredentials)
|
|
.query({ roomId: publicChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(403)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel members inside a private team by someone part of the room', async () => {
|
|
await request
|
|
.get(api('channels.members'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: privateChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel members inside a private team by someone not part of the room, but part of team', async () => {
|
|
await request
|
|
.get(api('channels.members'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: privateChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel members inside a private team by someone not part of team', async () => {
|
|
await request
|
|
.get(api('channels.members'))
|
|
.set(nonTeamCredentials)
|
|
.query({ roomId: privateChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('/channels.getIntegrations', () => {
|
|
let integrationCreatedByAnUser: IIntegration;
|
|
let userCredentials: Credentials;
|
|
let createdChannel: IRoom;
|
|
let user: TestUser<IUser>;
|
|
|
|
before((done) => {
|
|
void createRoom({ name: `test-integration-channel-${Date.now()}`, type: 'c' }).end((_err, res) => {
|
|
createdChannel = res.body.channel;
|
|
void createUser().then((createdUser) => {
|
|
user = createdUser;
|
|
void login(user.username, password).then((credentials) => {
|
|
userCredentials = credentials;
|
|
void updatePermission('manage-incoming-integrations', ['user']).then(() => {
|
|
void updatePermission('manage-own-incoming-integrations', ['user']).then(() => {
|
|
void createIntegration(
|
|
{
|
|
type: 'webhook-incoming',
|
|
name: 'Incoming test',
|
|
enabled: true,
|
|
alias: 'test',
|
|
username: 'rocket.cat',
|
|
scriptEnabled: false,
|
|
overrideDestinationChannelEnabled: true,
|
|
channel: `#${createdChannel.name}`,
|
|
},
|
|
userCredentials,
|
|
).then((integration) => {
|
|
integrationCreatedByAnUser = integration;
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
after(async () => {
|
|
await Promise.all([
|
|
deleteRoom({ type: 'c', roomId: createdChannel._id }),
|
|
removeIntegration(integrationCreatedByAnUser._id, 'incoming'),
|
|
updatePermission('manage-incoming-integrations', ['admin']),
|
|
updatePermission('manage-own-incoming-integrations', ['admin']),
|
|
deleteUser(user),
|
|
]);
|
|
});
|
|
|
|
it('should return the list of integrations of created channel 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('channels.getIntegrations'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: createdChannel._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 updatePermission('manage-own-incoming-integrations', ['admin']);
|
|
await updatePermission('manage-incoming-integrations', []);
|
|
await request
|
|
.get(api('channels.getIntegrations'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: createdChannel._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-own-incoming-integrations', []),
|
|
updatePermission('manage-outgoing-integrations', []),
|
|
updatePermission('manage-own-outgoing-integrations', []),
|
|
]);
|
|
await request
|
|
.get(api('channels.getIntegrations'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: createdChannel._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('Additional Visibility Tests', () => {
|
|
let outsiderUser: IUser;
|
|
let insideUser: IUser;
|
|
let nonTeamUser: IUser;
|
|
let outsiderCredentials: { 'X-Auth-Token': string; 'X-User-Id': string };
|
|
let insideCredentials: { 'X-Auth-Token': string; 'X-User-Id': string };
|
|
let nonTeamCredentials: { 'X-Auth-Token': string; 'X-User-Id': string };
|
|
|
|
let privateChannel: IRoom;
|
|
let publicChannel: IRoom;
|
|
let publicTeam: ITeam;
|
|
let privateTeam: ITeam;
|
|
let privateChannelInPublicTeam: IRoom;
|
|
let publicChannelInPublicTeam: IRoom;
|
|
let privateChannelInPrivateTeam: IRoom;
|
|
let publicChannelInPrivateTeam: IRoom;
|
|
|
|
before(async () => {
|
|
[outsiderUser, insideUser, nonTeamUser] = await Promise.all([
|
|
createUser({ username: `e_${Random.id()}` }),
|
|
createUser({ username: `f_${Random.id()}` }),
|
|
createUser({ username: `g_${Random.id()}` }),
|
|
]);
|
|
[outsiderCredentials, insideCredentials, nonTeamCredentials] = await Promise.all([
|
|
login(outsiderUser.username, password),
|
|
login(insideUser.username, password),
|
|
login(nonTeamUser.username, password),
|
|
]);
|
|
|
|
// Create a public team and a private team
|
|
[publicTeam, privateTeam] = await Promise.all([
|
|
createTeam(insideCredentials, `channels.getIntegrations.team.public.${Random.id()}`, TeamType.PUBLIC, [
|
|
outsiderUser.username as string,
|
|
]),
|
|
createTeam(insideCredentials, `channels.getIntegrations.team.private.${Random.id()}`, TeamType.PRIVATE, [
|
|
outsiderUser.username as string,
|
|
]),
|
|
]);
|
|
|
|
const [
|
|
privateInPublicResponse,
|
|
publicInPublicResponse,
|
|
privateInPrivateResponse,
|
|
publicInPrivateResponse,
|
|
privateRoomResponse,
|
|
publicRoomResponse,
|
|
] = await Promise.all([
|
|
createRoom({
|
|
type: 'p',
|
|
name: `teamPublic.privateChannel.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
extraData: {
|
|
teamId: publicTeam._id,
|
|
},
|
|
}),
|
|
createRoom({
|
|
type: 'c',
|
|
name: `teamPublic.publicChannel.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
extraData: {
|
|
teamId: publicTeam._id,
|
|
},
|
|
}),
|
|
createRoom({
|
|
type: 'p',
|
|
name: `teamPrivate.privateChannel.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
extraData: {
|
|
teamId: privateTeam._id,
|
|
},
|
|
}),
|
|
createRoom({
|
|
type: 'c',
|
|
name: `teamPrivate.publicChannel.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
extraData: {
|
|
teamId: privateTeam._id,
|
|
},
|
|
}),
|
|
createRoom({
|
|
type: 'p',
|
|
name: `channels.getIntegrations.private.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
}),
|
|
createRoom({
|
|
type: 'c',
|
|
name: `channels.getIntegrations.public.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
}),
|
|
]);
|
|
|
|
privateChannelInPublicTeam = privateInPublicResponse.body.group;
|
|
publicChannelInPublicTeam = publicInPublicResponse.body.channel;
|
|
privateChannelInPrivateTeam = privateInPrivateResponse.body.group;
|
|
publicChannelInPrivateTeam = publicInPrivateResponse.body.channel;
|
|
privateChannel = privateRoomResponse.body.group;
|
|
publicChannel = publicRoomResponse.body.channel;
|
|
|
|
await updatePermission('manage-incoming-integrations', ['admin', 'user']);
|
|
});
|
|
|
|
after(async () => {
|
|
await Promise.all([
|
|
deleteRoom({ type: 'p', roomId: privateChannel._id }),
|
|
deleteRoom({ type: 'c', roomId: publicChannel._id }),
|
|
deleteRoom({ type: 'p', roomId: privateChannelInPublicTeam._id }),
|
|
deleteRoom({ type: 'c', roomId: publicChannelInPublicTeam._id }),
|
|
deleteRoom({ type: 'p', roomId: privateChannelInPrivateTeam._id }),
|
|
deleteRoom({ type: 'c', roomId: publicChannelInPrivateTeam._id }),
|
|
]);
|
|
|
|
await Promise.all([deleteTeam(credentials, publicTeam.name), deleteTeam(credentials, privateTeam.name)]);
|
|
|
|
await Promise.all([deleteUser(outsiderUser), deleteUser(insideUser), deleteUser(nonTeamUser)]);
|
|
|
|
await updatePermission('manage-incoming-integrations', ['admin']);
|
|
});
|
|
|
|
it('should not fetch private room integrations by user who is part of the room', async () => {
|
|
const response = await request
|
|
.get(api('channels.getIntegrations'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: privateChannel._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400);
|
|
|
|
expect(response.body.success).to.be.false;
|
|
});
|
|
|
|
it('should fetch public room integrations by user who is part of the room', async () => {
|
|
const response = await request
|
|
.get(api('channels.getIntegrations'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: publicChannel._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(response.body.success).to.be.true;
|
|
expect(response.body).to.have.property('integrations');
|
|
});
|
|
|
|
it('should fetch public room integrations by user not part of room - because public', async () => {
|
|
const response = await request
|
|
.get(api('channels.getIntegrations'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: publicChannel._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(response.body.success).to.be.true;
|
|
expect(response.body).to.have.property('integrations');
|
|
});
|
|
|
|
it('should not fetch a private channel integrations inside a public team by someone part of the room ', async () => {
|
|
await request
|
|
.get(api('channels.getIntegrations'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: privateChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel integrations inside a public team by someone not part of the room, but part of team', async () => {
|
|
await request
|
|
.get(api('channels.getIntegrations'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: privateChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel integrations inside a public team by someone not part of the team ', async () => {
|
|
await request
|
|
.get(api('channels.getIntegrations'))
|
|
.set(nonTeamCredentials)
|
|
.query({ roomId: privateChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel integrations inside a public team by someone part of the room ', async () => {
|
|
await request
|
|
.get(api('channels.getIntegrations'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: publicChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('integrations');
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel integrations inside a public team by someone not part of the room, but part of team', async () => {
|
|
await request
|
|
.get(api('channels.getIntegrations'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: publicChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('integrations');
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel integrations inside a public team by someone not part of the team ', async () => {
|
|
await request
|
|
.get(api('channels.getIntegrations'))
|
|
.set(nonTeamCredentials)
|
|
.query({ roomId: publicChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('integrations');
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel integrations inside a private team by someone part of the room', async () => {
|
|
await request
|
|
.get(api('channels.getIntegrations'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: publicChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('integrations');
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel integrations inside a private team by someone not part of the room, but part of team', async () => {
|
|
await request
|
|
.get(api('channels.getIntegrations'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: publicChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('integrations');
|
|
});
|
|
});
|
|
|
|
it('should not fetch a public channel integrations inside a private team by someone not part of team', async () => {
|
|
await request
|
|
.get(api('channels.getIntegrations'))
|
|
.set(nonTeamCredentials)
|
|
.query({ roomId: publicChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(403)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel integrations inside a private team by someone part of the room', async () => {
|
|
await request
|
|
.get(api('channels.getIntegrations'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: privateChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel integrations inside a private team by someone not part of the room, but part of team', async () => {
|
|
await request
|
|
.get(api('channels.getIntegrations'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: privateChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel integrations inside a private team by someone not part of team', async () => {
|
|
await request
|
|
.get(api('channels.getIntegrations'))
|
|
.set(nonTeamCredentials)
|
|
.query({ roomId: privateChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('/channels.setCustomFields:', () => {
|
|
let withCFChannel: IRoom;
|
|
let withoutCFChannel: IRoom;
|
|
|
|
after(async () => {
|
|
await deleteRoom({ type: 'c', roomId: withCFChannel._id });
|
|
});
|
|
|
|
it('create channel with customFields', (done) => {
|
|
const customFields = { field0: 'value0' };
|
|
void request
|
|
.post(api('channels.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: `channel.cf.${Date.now()}`,
|
|
customFields,
|
|
})
|
|
.end((_err, res) => {
|
|
withCFChannel = res.body.channel;
|
|
done();
|
|
});
|
|
});
|
|
it('get customFields using channels.info', async () => {
|
|
const res = await request
|
|
.get(api('channels.info'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: withCFChannel._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('channel.customFields.field0', 'value0');
|
|
});
|
|
it('change customFields', async () => {
|
|
const customFields = { field9: 'value9' };
|
|
return request
|
|
.post(api('channels.setCustomFields'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: withCFChannel._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('channel._id');
|
|
expect(res.body).to.have.nested.property('channel.name', withCFChannel.name);
|
|
expect(res.body).to.have.nested.property('channel.t', 'c');
|
|
expect(res.body).to.have.nested.property('channel.customFields.field9', 'value9');
|
|
expect(res.body).to.have.not.nested.property('channel.customFields.field0', 'value0');
|
|
});
|
|
});
|
|
it('get customFields using channels.info', async () => {
|
|
const res = await request
|
|
.get(api('channels.info'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: withCFChannel._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('channel.customFields.field9', 'value9');
|
|
});
|
|
it('delete channels with customFields', async () => {
|
|
const res = await request
|
|
.post(api('channels.delete'))
|
|
.set(credentials)
|
|
.send({
|
|
roomName: withCFChannel.name,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
it('create channel without customFields', (done) => {
|
|
void request
|
|
.post(api('channels.create'))
|
|
.set(credentials)
|
|
.send({
|
|
name: `channel.cf.${Date.now()}`,
|
|
})
|
|
.end((_err, res) => {
|
|
withoutCFChannel = res.body.channel;
|
|
done();
|
|
});
|
|
});
|
|
it('set customFields with one nested field', async () => {
|
|
const customFields = { field1: 'value1' };
|
|
return request
|
|
.post(api('channels.setCustomFields'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: withoutCFChannel._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('channel._id');
|
|
expect(res.body).to.have.nested.property('channel.name', withoutCFChannel.name);
|
|
expect(res.body).to.have.nested.property('channel.t', 'c');
|
|
expect(res.body).to.have.nested.property('channel.customFields.field1', 'value1');
|
|
});
|
|
});
|
|
it('set customFields with multiple nested fields', async () => {
|
|
const customFields = { field2: 'value2', field3: 'value3', field4: 'value4' };
|
|
|
|
return request
|
|
.post(api('channels.setCustomFields'))
|
|
.set(credentials)
|
|
.send({
|
|
roomName: withoutCFChannel.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('channel._id');
|
|
expect(res.body).to.have.nested.property('channel.name', withoutCFChannel.name);
|
|
expect(res.body).to.have.nested.property('channel.t', 'c');
|
|
expect(res.body).to.have.nested.property('channel.customFields.field2', 'value2');
|
|
expect(res.body).to.have.nested.property('channel.customFields.field3', 'value3');
|
|
expect(res.body).to.have.nested.property('channel.customFields.field4', 'value4');
|
|
expect(res.body).to.have.not.nested.property('channel.customFields.field1', 'value1');
|
|
});
|
|
});
|
|
it('set customFields to empty object', (done) => {
|
|
const customFields = {};
|
|
|
|
void request
|
|
.post(api('channels.setCustomFields'))
|
|
.set(credentials)
|
|
.send({
|
|
roomName: withoutCFChannel.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('channel._id');
|
|
expect(res.body).to.have.nested.property('channel.name', withoutCFChannel.name);
|
|
expect(res.body).to.have.nested.property('channel.t', 'c');
|
|
expect(res.body).to.have.not.nested.property('channel.customFields.field2', 'value2');
|
|
expect(res.body).to.have.not.nested.property('channel.customFields.field3', 'value3');
|
|
expect(res.body).to.have.not.nested.property('channel.customFields.field4', 'value4');
|
|
})
|
|
.end(done);
|
|
});
|
|
it('set customFields as a string -> should return 400', (done) => {
|
|
const customFields = '';
|
|
|
|
void request
|
|
.post(api('channels.setCustomFields'))
|
|
.set(credentials)
|
|
.send({
|
|
roomName: withoutCFChannel.name,
|
|
customFields,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
})
|
|
.end(done);
|
|
});
|
|
it('delete channel with empty customFields', async () => {
|
|
const res = await request
|
|
.post(api('channels.delete'))
|
|
.set(credentials)
|
|
.send({
|
|
roomName: withoutCFChannel.name,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
|
|
describe('/channels.setDefault', () => {
|
|
let testChannel: IRoom;
|
|
const name = `setDefault-${Date.now()}`;
|
|
|
|
before(async () => {
|
|
testChannel = (await createRoom({ type: 'c', name })).body.channel;
|
|
});
|
|
|
|
after(async () => {
|
|
await deleteRoom({ type: 'c', roomId: testChannel._id });
|
|
});
|
|
|
|
it('should set channel as default', async () => {
|
|
const roomInfo = await getRoomInfo(testChannel._id);
|
|
|
|
return request
|
|
.post(api('channels.setDefault'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: testChannel._id,
|
|
default: 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('channel._id');
|
|
expect(res.body).to.have.nested.property('channel.name', name);
|
|
expect(res.body).to.have.nested.property('channel.t', 'c');
|
|
expect(res.body).to.have.nested.property('channel.msgs', roomInfo.channel.msgs);
|
|
expect(res.body).to.have.nested.property('channel.default', true);
|
|
});
|
|
});
|
|
it('should unset channel as default', async () => {
|
|
const roomInfo = await getRoomInfo(testChannel._id);
|
|
|
|
return request
|
|
.post(api('channels.setDefault'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: testChannel._id,
|
|
default: false,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('channel._id');
|
|
expect(res.body).to.have.nested.property('channel.name', name);
|
|
expect(res.body).to.have.nested.property('channel.t', 'c');
|
|
expect(res.body).to.have.nested.property('channel.msgs', roomInfo.channel.msgs);
|
|
expect(res.body).to.have.nested.property('channel.default', false);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('auto-join default channels', () => {
|
|
let defaultChannel1: IRoom;
|
|
let defaultChannel2: IRoom;
|
|
let nonDefaultChannel: IRoom;
|
|
let userWithJoin: TestUser<IUser>;
|
|
let userWithoutJoin: TestUser<IUser>;
|
|
let userWithJoinCredentials: Credentials;
|
|
let userWithoutJoinCredentials: Credentials;
|
|
|
|
before(async () => {
|
|
const timestamp = Date.now();
|
|
defaultChannel1 = (await createRoom({ type: 'c', name: `auto-join-default-1-${timestamp}` })).body.channel;
|
|
defaultChannel2 = (await createRoom({ type: 'c', name: `auto-join-default-2-${timestamp}` })).body.channel;
|
|
nonDefaultChannel = (await createRoom({ type: 'c', name: `auto-join-non-default-${timestamp}` })).body.channel;
|
|
|
|
await Promise.all([
|
|
request.post(api('channels.setDefault')).set(credentials).send({ roomId: defaultChannel1._id, default: true }).expect(200),
|
|
request.post(api('channels.setDefault')).set(credentials).send({ roomId: defaultChannel2._id, default: true }).expect(200),
|
|
]);
|
|
|
|
[userWithJoin, userWithoutJoin] = await Promise.all([
|
|
createUser({ joinDefaultChannels: true }),
|
|
createUser({ joinDefaultChannels: false }),
|
|
]);
|
|
|
|
[userWithJoinCredentials, userWithoutJoinCredentials] = await Promise.all([
|
|
login(userWithJoin.username, password),
|
|
login(userWithoutJoin.username, password),
|
|
]);
|
|
});
|
|
|
|
after(async () => {
|
|
await Promise.all([
|
|
deleteUser(userWithJoin),
|
|
deleteUser(userWithoutJoin),
|
|
deleteRoom({ type: 'c', roomId: defaultChannel1._id }),
|
|
deleteRoom({ type: 'c', roomId: defaultChannel2._id }),
|
|
deleteRoom({ type: 'c', roomId: nonDefaultChannel._id }),
|
|
]);
|
|
});
|
|
|
|
it('should automatically join new users to default channels when joinDefaultChannels is true', async () => {
|
|
const [subscription1Response, subscription2Response] = await Promise.all([
|
|
request.get(api('subscriptions.getOne')).set(userWithJoinCredentials).query({ roomId: defaultChannel1._id }).expect(200),
|
|
request.get(api('subscriptions.getOne')).set(userWithJoinCredentials).query({ roomId: defaultChannel2._id }).expect(200),
|
|
]);
|
|
|
|
expect(subscription1Response.body).to.have.property('success', true);
|
|
expect(subscription1Response.body).to.have.property('subscription').that.is.an('object');
|
|
expect(subscription1Response.body.subscription).to.have.property('rid', defaultChannel1._id);
|
|
|
|
expect(subscription2Response.body).to.have.property('success', true);
|
|
expect(subscription2Response.body).to.have.property('subscription').that.is.an('object');
|
|
expect(subscription2Response.body.subscription).to.have.property('rid', defaultChannel2._id);
|
|
});
|
|
|
|
it('should not auto-join new users to non-default channels', async () => {
|
|
const subscriptionResponse = await request
|
|
.get(api('subscriptions.getOne'))
|
|
.set(userWithJoinCredentials)
|
|
.query({ roomId: nonDefaultChannel._id })
|
|
.expect(200);
|
|
|
|
expect(subscriptionResponse.body).to.have.property('success', true);
|
|
expect(subscriptionResponse.body).to.have.property('subscription').that.is.null;
|
|
});
|
|
|
|
it('should not auto-join users when joinDefaultChannels is false', async () => {
|
|
const [subscription1Response, subscription2Response] = await Promise.all([
|
|
request.get(api('subscriptions.getOne')).set(userWithoutJoinCredentials).query({ roomId: defaultChannel1._id }).expect(200),
|
|
request.get(api('subscriptions.getOne')).set(userWithoutJoinCredentials).query({ roomId: defaultChannel2._id }).expect(200),
|
|
]);
|
|
|
|
expect(subscription1Response.body).to.have.property('success', true);
|
|
expect(subscription1Response.body).to.have.property('subscription').that.is.null;
|
|
|
|
expect(subscription2Response.body).to.have.property('success', true);
|
|
expect(subscription2Response.body).to.have.property('subscription').that.is.null;
|
|
});
|
|
});
|
|
|
|
describe('/channels.setType', () => {
|
|
let testChannel: IRoom;
|
|
let testRegularChannel: IRoom;
|
|
let testTeamChannelForFailure: IRoom;
|
|
let testTeamChannelForSuccess: IRoom;
|
|
let team: ITeam;
|
|
let testUser: TestUser<IUser>;
|
|
let testUserCredentials: Credentials;
|
|
const name = `setType-${Date.now()}`;
|
|
|
|
beforeEach(async () => {
|
|
await updatePermission('create-p', ['admin', 'user']);
|
|
await updatePermission('create-team-group', ['admin', 'owner', 'moderator']);
|
|
});
|
|
|
|
before(async () => {
|
|
testChannel = (await createRoom({ type: 'c', name })).body.channel;
|
|
|
|
testUser = await createUser();
|
|
testUserCredentials = await login(testUser.username, password);
|
|
|
|
await updatePermission('create-team', ['admin', 'user']);
|
|
team = await createTeam(credentials, `team-setType-${Date.now()}`, TeamType.PUBLIC, [testUser.username]);
|
|
|
|
await request.post(api('channels.addOwner')).set(credentials).send({ roomId: team.roomId, userId: testUser._id });
|
|
|
|
testRegularChannel = (await createRoom({ type: 'c', name: `regular-setType-${Date.now()}`, credentials: testUserCredentials })).body
|
|
.channel;
|
|
|
|
testTeamChannelForFailure = (await createRoom({ type: 'c', name: `teamCh-fail-${Date.now()}`, extraData: { teamId: team._id } })).body
|
|
.channel;
|
|
testTeamChannelForSuccess = (await createRoom({ type: 'c', name: `teamCh-success-${Date.now()}`, extraData: { teamId: team._id } }))
|
|
.body.channel;
|
|
|
|
await request.post(api('channels.invite')).set(credentials).send({ roomId: testTeamChannelForFailure._id, userId: testUser._id });
|
|
await request.post(api('channels.addOwner')).set(credentials).send({ roomId: testTeamChannelForFailure._id, userId: testUser._id });
|
|
await request.post(api('channels.invite')).set(credentials).send({ roomId: testTeamChannelForSuccess._id, userId: testUser._id });
|
|
await request.post(api('channels.addOwner')).set(credentials).send({ roomId: testTeamChannelForSuccess._id, userId: testUser._id });
|
|
});
|
|
|
|
after(async () => {
|
|
await Promise.all(
|
|
['p', 'c'].map(async (type: any) => {
|
|
return Promise.all([
|
|
deleteRoom({ type, roomId: testChannel._id }),
|
|
deleteRoom({ type, roomId: testRegularChannel._id }),
|
|
deleteRoom({ type, roomId: testTeamChannelForFailure._id }),
|
|
deleteRoom({ type, roomId: testTeamChannelForSuccess._id }),
|
|
]);
|
|
}),
|
|
);
|
|
await deleteTeam(credentials, team.name);
|
|
await deleteUser(testUser);
|
|
await updatePermission('create-p', ['admin', 'user']);
|
|
await updatePermission('create-team-group', ['admin', 'owner', 'moderator']);
|
|
});
|
|
|
|
it('should change the type public channel to private', async () => {
|
|
const roomInfo = await getRoomInfo(testChannel._id);
|
|
|
|
void request
|
|
.post(api('channels.setType'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: channel._id,
|
|
type: 'p',
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('channel._id');
|
|
expect(res.body).to.have.nested.property('channel.name', name);
|
|
expect(res.body).to.have.nested.property('channel.t', 'p');
|
|
expect(res.body).to.have.nested.property('channel.msgs', roomInfo.channel.msgs + 1);
|
|
});
|
|
});
|
|
|
|
it('should fail to change a regular channel to private when user lacks create-p permission', async () => {
|
|
await updatePermission('create-p', ['admin']);
|
|
await request
|
|
.post(api('channels.setType'))
|
|
.set(testUserCredentials)
|
|
.send({ roomId: testRegularChannel._id, type: 'p' })
|
|
.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 private when user lacks create-p permission', async () => {
|
|
await updatePermission('create-p', ['admin']);
|
|
await request
|
|
.post(api('channels.setType'))
|
|
.set(testUserCredentials)
|
|
.send({ roomId: team.roomId, type: 'p' })
|
|
.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 private when user has create-team-group but lacks create-p', async () => {
|
|
await updatePermission('create-p', ['admin']);
|
|
await updatePermission('create-team-group', ['owner']);
|
|
await request
|
|
.post(api('channels.setType'))
|
|
.set(testUserCredentials)
|
|
.send({ roomId: team.roomId, type: 'p' })
|
|
.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 channel to private when user lacks create-team-group permission', async () => {
|
|
await updatePermission('create-team-group', []);
|
|
await request
|
|
.post(api('channels.setType'))
|
|
.set(testUserCredentials)
|
|
.send({ roomId: testTeamChannelForFailure._id, type: 'p' })
|
|
.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 channel to private when user has create-team-group but not create-p', async () => {
|
|
await updatePermission('create-p', ['admin']);
|
|
await updatePermission('create-team-group', ['owner']);
|
|
await request
|
|
.post(api('channels.setType'))
|
|
.set(testUserCredentials)
|
|
.send({ roomId: testTeamChannelForSuccess._id, type: 'p' })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.nested.property('channel.t', 'p');
|
|
expect(res.body).to.have.nested.property('channel.teamId', team._id);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('/channels.delete', () => {
|
|
let testChannel: IRoom;
|
|
let testTeamChannel: IRoom;
|
|
let testModeratorTeamChannel: 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 () => {
|
|
testChannel = (await createRoom({ name: `channel.test.${Date.now()}`, type: 'c' })).body.channel;
|
|
invitedUser = await createUser();
|
|
moderatorUser = await createUser();
|
|
invitedUserCredentials = await login(invitedUser.username, password);
|
|
moderatorUserCredentials = await login(moderatorUser.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, moderatorUser.username],
|
|
});
|
|
teamId = teamCreateRes.body.team._id;
|
|
teamMainRoomId = teamCreateRes.body.team.roomId;
|
|
|
|
await updatePermission('delete-team-channel', ['owner', 'moderator']);
|
|
await updatePermission('create-team-channel', ['admin', 'owner', 'moderator', 'user']);
|
|
const teamChannelResponse = await createRoom({
|
|
name: `channel.test.${Date.now()}`,
|
|
type: 'c',
|
|
extraData: { teamId },
|
|
credentials: invitedUserCredentials,
|
|
});
|
|
testTeamChannel = teamChannelResponse.body.channel;
|
|
|
|
await request
|
|
.post(api('channels.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 teamModeratorChannelResponse = await createRoom({
|
|
name: `channel.test.moderator.${Date.now()}`,
|
|
type: 'c',
|
|
extraData: { teamId },
|
|
credentials: moderatorUserCredentials,
|
|
});
|
|
testModeratorTeamChannel = teamModeratorChannelResponse.body.channel;
|
|
});
|
|
after(async () => {
|
|
await deleteUser(invitedUser);
|
|
await deleteUser(moderatorUser);
|
|
await updatePermission('create-team-channel', ['admin', 'owner', 'moderator']);
|
|
await updatePermission('delete-team-channel', ['admin', 'owner', 'moderator']);
|
|
});
|
|
it('should succesfully delete a channel', async () => {
|
|
await request
|
|
.post(api('channels.delete'))
|
|
.set(credentials)
|
|
.send({
|
|
roomName: testChannel.name,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
it(`should fail retrieving a channel's info after it's been deleted`, async () => {
|
|
await request
|
|
.get(api('channels.info'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testChannel._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 channel when member does not have the necessary permission in the team`, async () => {
|
|
await request
|
|
.post(api('channels.delete'))
|
|
.set(invitedUserCredentials)
|
|
.send({
|
|
roomName: testTeamChannel.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');
|
|
expect(res.body.errorType).to.be.equal('error-not-allowed');
|
|
});
|
|
});
|
|
it(`should fail deleting a team's channel when member has the necessary permission in the team, but not in the deleted room`, async () => {
|
|
await request
|
|
.post(api('channels.delete'))
|
|
.set(moderatorUserCredentials)
|
|
.send({
|
|
roomName: testTeamChannel.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');
|
|
expect(res.body.errorType).to.be.equal('error-not-allowed');
|
|
});
|
|
});
|
|
it(`should successfully delete a team's channel when member has both team and channel permissions`, async () => {
|
|
await request
|
|
.post(api('channels.delete'))
|
|
.set(moderatorUserCredentials)
|
|
.send({
|
|
roomId: testModeratorTeamChannel._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('/channels.getAllUserMentionsByChannel', () => {
|
|
it('should return an array of mentions by channel', async () => {
|
|
const res = await request
|
|
.get(api('channels.getAllUserMentionsByChannel'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: channel._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('mentions').and.to.be.an('array');
|
|
expect(res.body).to.have.property('count');
|
|
expect(res.body).to.have.property('offset');
|
|
expect(res.body).to.have.property('total');
|
|
});
|
|
it('should return an array of mentions by channel even requested with count and offset params', async () => {
|
|
const res = await request
|
|
.get(api('channels.getAllUserMentionsByChannel'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: channel._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('mentions').and.to.be.an('array');
|
|
expect(res.body).to.have.property('count');
|
|
expect(res.body).to.have.property('offset');
|
|
expect(res.body).to.have.property('total');
|
|
});
|
|
});
|
|
|
|
describe('/channels.roles', () => {
|
|
let testChannel: IRoom;
|
|
|
|
before(async () => {
|
|
testChannel = (await createRoom({ type: 'c', name: `channel.roles.test.${Date.now()}` })).body.channel;
|
|
});
|
|
|
|
after(async () => {
|
|
await deleteRoom({ type: 'c', roomId: testChannel._id });
|
|
});
|
|
|
|
it('/channels.invite', async () => {
|
|
const res = await request
|
|
.post(api('channels.invite'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: testChannel._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
it('/channels.addModerator', async () => {
|
|
const res = await request
|
|
.post(api('channels.addModerator'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: testChannel._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
it('/channels.addLeader', async () => {
|
|
const res = await request
|
|
.post(api('channels.addLeader'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: testChannel._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
it('should return an array of role <-> user relationships in a channel', async () => {
|
|
const res = await request
|
|
.get(api('channels.roles'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testChannel._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(testChannel._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(testChannel._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('/channels.moderators', () => {
|
|
let testChannel: IRoom;
|
|
|
|
before(async () => {
|
|
testChannel = (await createRoom({ type: 'c', name: `channel.moderators.test.${Date.now()}` })).body.channel;
|
|
});
|
|
|
|
after(async () => {
|
|
await deleteRoom({ type: 'c', roomId: testChannel._id });
|
|
});
|
|
|
|
it('/channels.invite', async () => {
|
|
const res = await request
|
|
.post(api('channels.invite'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: testChannel._id,
|
|
userId: 'rocket.cat',
|
|
})
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
it('/channels.addModerator', async () => {
|
|
const res = await request
|
|
.post(api('channels.addModerator'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: testChannel._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('channels.moderators'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testChannel._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('Additional Visibility Tests', () => {
|
|
let outsiderUser: IUser;
|
|
let insideUser: IUser;
|
|
let nonTeamUser: IUser;
|
|
let outsiderCredentials: { 'X-Auth-Token': string; 'X-User-Id': string };
|
|
let insideCredentials: { 'X-Auth-Token': string; 'X-User-Id': string };
|
|
let nonTeamCredentials: { 'X-Auth-Token': string; 'X-User-Id': string };
|
|
|
|
let privateChannel: IRoom;
|
|
let publicChannel: IRoom;
|
|
let publicTeam: ITeam;
|
|
let privateTeam: ITeam;
|
|
let privateChannelInPublicTeam: IRoom;
|
|
let publicChannelInPublicTeam: IRoom;
|
|
let privateChannelInPrivateTeam: IRoom;
|
|
let publicChannelInPrivateTeam: IRoom;
|
|
|
|
before(async () => {
|
|
[outsiderUser, insideUser, nonTeamUser] = await Promise.all([
|
|
createUser({ username: `e_${Random.id()}` }),
|
|
createUser({ username: `f_${Random.id()}` }),
|
|
createUser({ username: `g_${Random.id()}` }),
|
|
]);
|
|
[outsiderCredentials, insideCredentials, nonTeamCredentials] = await Promise.all([
|
|
login(outsiderUser.username, password),
|
|
login(insideUser.username, password),
|
|
login(nonTeamUser.username, password),
|
|
]);
|
|
|
|
// Create a public team and a private team
|
|
[publicTeam, privateTeam] = await Promise.all([
|
|
createTeam(insideCredentials, `channels.moderators.team.public.${Random.id()}`, TeamType.PUBLIC, [
|
|
outsiderUser.username as string,
|
|
]),
|
|
createTeam(insideCredentials, `channels.moderators.team.private.${Random.id()}`, TeamType.PRIVATE, [
|
|
outsiderUser.username as string,
|
|
]),
|
|
]);
|
|
|
|
const [
|
|
privateInPublicResponse,
|
|
publicInPublicResponse,
|
|
privateInPrivateResponse,
|
|
publicInPrivateResponse,
|
|
privateRoomResponse,
|
|
publicRoomResponse,
|
|
] = await Promise.all([
|
|
createRoom({
|
|
type: 'p',
|
|
name: `teamPublic.privateChannel.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
extraData: {
|
|
teamId: publicTeam._id,
|
|
},
|
|
}),
|
|
createRoom({
|
|
type: 'c',
|
|
name: `teamPublic.publicChannel.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
extraData: {
|
|
teamId: publicTeam._id,
|
|
},
|
|
}),
|
|
createRoom({
|
|
type: 'p',
|
|
name: `teamPrivate.privateChannel.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
extraData: {
|
|
teamId: privateTeam._id,
|
|
},
|
|
}),
|
|
createRoom({
|
|
type: 'c',
|
|
name: `teamPrivate.publicChannel.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
extraData: {
|
|
teamId: privateTeam._id,
|
|
},
|
|
}),
|
|
createRoom({
|
|
type: 'p',
|
|
name: `channels.moderators.private.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
}),
|
|
createRoom({
|
|
type: 'c',
|
|
name: `channels.moderators.public.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
}),
|
|
]);
|
|
|
|
privateChannelInPublicTeam = privateInPublicResponse.body.group;
|
|
publicChannelInPublicTeam = publicInPublicResponse.body.channel;
|
|
privateChannelInPrivateTeam = privateInPrivateResponse.body.group;
|
|
publicChannelInPrivateTeam = publicInPrivateResponse.body.channel;
|
|
privateChannel = privateRoomResponse.body.group;
|
|
publicChannel = publicRoomResponse.body.channel;
|
|
});
|
|
|
|
after(async () => {
|
|
await Promise.all([
|
|
deleteRoom({ type: 'p', roomId: privateChannel._id }),
|
|
deleteRoom({ type: 'c', roomId: publicChannel._id }),
|
|
deleteRoom({ type: 'p', roomId: privateChannelInPublicTeam._id }),
|
|
deleteRoom({ type: 'c', roomId: publicChannelInPublicTeam._id }),
|
|
deleteRoom({ type: 'p', roomId: privateChannelInPrivateTeam._id }),
|
|
deleteRoom({ type: 'c', roomId: publicChannelInPrivateTeam._id }),
|
|
]);
|
|
|
|
await Promise.all([deleteTeam(credentials, publicTeam.name), deleteTeam(credentials, privateTeam.name)]);
|
|
|
|
await Promise.all([deleteUser(outsiderUser), deleteUser(insideUser), deleteUser(nonTeamUser)]);
|
|
});
|
|
|
|
it('should not fetch private room moderators by user not part of room', async () => {
|
|
await request
|
|
.get(api('channels.moderators'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: privateChannel._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch private room moderators by user who is part of the room', async () => {
|
|
const response = await request
|
|
.get(api('channels.moderators'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: privateChannel._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400);
|
|
|
|
expect(response.body.success).to.be.false;
|
|
});
|
|
|
|
it('should fetch public room moderators by user who is part of the room', async () => {
|
|
const response = await request
|
|
.get(api('channels.moderators'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: publicChannel._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(response.body.success).to.be.true;
|
|
expect(response.body).to.have.property('moderators');
|
|
});
|
|
|
|
it('should fetch public room moderators by user not part of room - because public', async () => {
|
|
const response = await request
|
|
.get(api('channels.moderators'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: publicChannel._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(response.body.success).to.be.true;
|
|
expect(response.body).to.have.property('moderators');
|
|
});
|
|
|
|
it('should not fetch a private channel moderators inside a public team by someone part of the room ', async () => {
|
|
await request
|
|
.get(api('channels.moderators'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: privateChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel moderators inside a public team by someone not part of the room, but part of team', async () => {
|
|
await request
|
|
.get(api('channels.moderators'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: privateChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel moderators inside a public team by someone not part of the team ', async () => {
|
|
await request
|
|
.get(api('channels.moderators'))
|
|
.set(nonTeamCredentials)
|
|
.query({ roomId: privateChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel moderators inside a public team by someone part of the room ', async () => {
|
|
await request
|
|
.get(api('channels.moderators'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: publicChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('moderators');
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel moderators inside a public team by someone not part of the room, but part of team', async () => {
|
|
await request
|
|
.get(api('channels.moderators'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: publicChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('moderators');
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel moderators inside a public team by someone not part of the team ', async () => {
|
|
await request
|
|
.get(api('channels.moderators'))
|
|
.set(nonTeamCredentials)
|
|
.query({ roomId: publicChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('moderators');
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel moderators inside a private team by someone part of the room', async () => {
|
|
await request
|
|
.get(api('channels.moderators'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: publicChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('moderators');
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel moderators inside a private team by someone not part of the room, but part of team', async () => {
|
|
await request
|
|
.get(api('channels.moderators'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: publicChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('moderators');
|
|
});
|
|
});
|
|
|
|
it('should not fetch a public channel moderators inside a private team by someone not part of team', async () => {
|
|
await request
|
|
.get(api('channels.moderators'))
|
|
.set(nonTeamCredentials)
|
|
.query({ roomId: publicChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(403)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel moderators inside a private team by someone part of the room', async () => {
|
|
await request
|
|
.get(api('channels.moderators'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: privateChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel moderators inside a private team by someone not part of the room, but part of team', async () => {
|
|
await request
|
|
.get(api('channels.moderators'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: privateChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel moderators inside a private team by someone not part of team', async () => {
|
|
await request
|
|
.get(api('channels.moderators'))
|
|
.set(nonTeamCredentials)
|
|
.query({ roomId: privateChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('/channels.anonymousread', () => {
|
|
let testChannel: IRoom;
|
|
|
|
before(async () => {
|
|
testChannel = (await createRoom({ type: 'c', name: `channel.anonymousread.test.${Date.now()}` })).body.channel;
|
|
});
|
|
|
|
after(async () => {
|
|
await Promise.all([updateSetting('Accounts_AllowAnonymousRead', false), deleteRoom({ type: 'c', roomId: testChannel._id })]);
|
|
});
|
|
|
|
it('should return an error when the setting "Accounts_AllowAnonymousRead" is disabled', async () => {
|
|
await updateSetting('Accounts_AllowAnonymousRead', false);
|
|
|
|
const res = await request
|
|
.get(api('channels.anonymousread'))
|
|
.query({
|
|
roomId: testChannel._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(401);
|
|
|
|
expect(res.body).to.have.a.property('success', false);
|
|
expect(res.body).to.have.a.property('error', 'You must be logged in to do this.');
|
|
});
|
|
it('should return the messages list when the setting "Accounts_AllowAnonymousRead" is enabled', async () => {
|
|
await updateSetting('Accounts_AllowAnonymousRead', true);
|
|
|
|
const res = await request
|
|
.get(api('channels.anonymousread'))
|
|
.query({
|
|
roomId: testChannel._id,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.a.property('success', true);
|
|
expect(res.body).to.have.a.property('messages').that.is.an('array');
|
|
});
|
|
it('should return the messages list when the setting "Accounts_AllowAnonymousRead" is enabled even requested with count and offset params', async () => {
|
|
await updateSetting('Accounts_AllowAnonymousRead', true);
|
|
|
|
const res = await request
|
|
.get(api('channels.anonymousread'))
|
|
.query({
|
|
roomId: testChannel._id,
|
|
count: 5,
|
|
offset: 0,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.a.property('success', true);
|
|
expect(res.body).to.have.a.property('messages').that.is.an('array');
|
|
});
|
|
describe('Additional Visibility Tests', () => {
|
|
let outsiderUser: IUser;
|
|
let insideUser: IUser;
|
|
let nonTeamUser: IUser;
|
|
let outsiderCredentials: { 'X-Auth-Token': string; 'X-User-Id': string };
|
|
let insideCredentials: { 'X-Auth-Token': string; 'X-User-Id': string };
|
|
let nonTeamCredentials: { 'X-Auth-Token': string; 'X-User-Id': string };
|
|
|
|
let privateTeam: ITeam;
|
|
let publicChannelInPrivateTeam: IRoom;
|
|
|
|
before(async () => {
|
|
[outsiderUser, insideUser, nonTeamUser] = await Promise.all([
|
|
createUser({ username: `e_${Random.id()}` }),
|
|
createUser({ username: `f_${Random.id()}` }),
|
|
createUser({ username: `g_${Random.id()}` }),
|
|
]);
|
|
[outsiderCredentials, insideCredentials, nonTeamCredentials] = await Promise.all([
|
|
login(outsiderUser.username, password),
|
|
login(insideUser.username, password),
|
|
login(nonTeamUser.username, password),
|
|
]);
|
|
|
|
// Create a private team
|
|
privateTeam = await createTeam(insideCredentials, `channels.anonymousread.team.private.${Random.id()}`, TeamType.PRIVATE, [
|
|
outsiderUser.username as string,
|
|
]);
|
|
|
|
const publicInPrivateResponse = await createRoom({
|
|
type: 'c',
|
|
name: `teamPrivate.publicChannel.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
extraData: {
|
|
teamId: privateTeam._id,
|
|
},
|
|
});
|
|
|
|
publicChannelInPrivateTeam = publicInPrivateResponse.body.channel;
|
|
|
|
await updateSetting('Accounts_AllowAnonymousRead', true);
|
|
});
|
|
|
|
after(async () => {
|
|
await deleteRoom({ type: 'c', roomId: publicChannelInPrivateTeam._id });
|
|
|
|
await Promise.all([deleteTeam(credentials, privateTeam.name)]);
|
|
|
|
await Promise.all([deleteUser(outsiderUser), deleteUser(insideUser), deleteUser(nonTeamUser)]);
|
|
|
|
await updateSetting('Accounts_AllowAnonymousRead', false);
|
|
});
|
|
|
|
it('should fetch a public channel messages inside a private team by someone part of the room', async () => {
|
|
await request
|
|
.get(api('channels.anonymousread'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: publicChannelInPrivateTeam._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');
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel messages inside a private team by someone not part of the room, but part of team', async () => {
|
|
await request
|
|
.get(api('channels.anonymousread'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: publicChannelInPrivateTeam._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');
|
|
});
|
|
});
|
|
|
|
it('should not fetch a public channel messages inside a private team by someone not part of team', async () => {
|
|
await request
|
|
.get(api('channels.anonymousread'))
|
|
.set(nonTeamCredentials)
|
|
.query({ roomId: publicChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(404)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a public channel messages inside a private team when unauthenticated', async () => {
|
|
await request
|
|
.get(api('channels.anonymousread'))
|
|
.query({ roomId: publicChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(404)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('/channels.convertToTeam', () => {
|
|
let testChannel: IRoom;
|
|
|
|
before(async () => {
|
|
testChannel = (await createRoom({ type: 'c', name: `channel.convertToTeam.test.${Date.now()}` })).body.channel;
|
|
});
|
|
|
|
after(async () => {
|
|
assert.isDefined(testChannel.name);
|
|
await Promise.all([
|
|
updatePermission('create-team', ['admin', 'user']),
|
|
updatePermission('edit-room', ['admin', 'owner', 'moderator']),
|
|
deleteTeam(credentials, testChannel.name),
|
|
]);
|
|
});
|
|
|
|
it('should fail to convert channel if lacking create-team permission', async () => {
|
|
await updatePermission('create-team', []);
|
|
await updatePermission('edit-room', ['admin']);
|
|
|
|
await request
|
|
.post(api('channels.convertToTeam'))
|
|
.set(credentials)
|
|
.send({ channelId: testChannel._id })
|
|
.expect(403)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.a.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should fail to convert channel if lacking edit-room permission', async () => {
|
|
await updatePermission('create-team', ['admin']);
|
|
await updatePermission('edit-room', []);
|
|
|
|
await request
|
|
.post(api('channels.convertToTeam'))
|
|
.set(credentials)
|
|
.send({ channelId: testChannel._id })
|
|
.expect(403)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.a.property('success', false);
|
|
});
|
|
});
|
|
|
|
describe('when a user without edit-room permission on the channel tries to convert it to a team', () => {
|
|
let outsiderChannel: IRoom;
|
|
let outsiderUser: TestUser<IUser>;
|
|
let outsiderCredentials: Credentials;
|
|
|
|
before(async () => {
|
|
await updatePermission('create-team', ['admin', 'user']);
|
|
await updatePermission('edit-room', ['admin', 'owner', 'moderator']);
|
|
|
|
outsiderChannel = (await createRoom({ type: 'c', name: `channel.convertToTeam.outsider.test.${Date.now()}` })).body.channel;
|
|
outsiderUser = await createUser();
|
|
outsiderCredentials = await login(outsiderUser.username, password);
|
|
});
|
|
|
|
after(async () => {
|
|
await Promise.all([deleteRoom({ type: 'c', roomId: outsiderChannel._id }), deleteUser(outsiderUser)]);
|
|
});
|
|
|
|
it('should return 403 when using channelName', async () => {
|
|
await request
|
|
.post(api('channels.convertToTeam'))
|
|
.set(outsiderCredentials)
|
|
.send({ channelName: outsiderChannel.name })
|
|
.expect(403)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.a.property('success', false);
|
|
});
|
|
});
|
|
});
|
|
|
|
it(`should return an error when the channel's name and id are sent as parameter`, async () => {
|
|
const res = await request
|
|
.post(api('channels.convertToTeam'))
|
|
.set(credentials)
|
|
.send({
|
|
channelName: testChannel.name,
|
|
channelId: testChannel._id,
|
|
})
|
|
.expect(400);
|
|
|
|
expect(res.body).to.have.property('success', false);
|
|
expect(res.body).to.have.property('error').include(`must match exactly one schema in oneOf`);
|
|
});
|
|
|
|
it(`should successfully convert a channel to a team when the channel's id is sent as parameter`, async () => {
|
|
await updatePermission('create-team', ['admin']);
|
|
await updatePermission('edit-room', ['admin']);
|
|
|
|
await request
|
|
.post(api('channels.convertToTeam'))
|
|
.set(credentials)
|
|
.send({ channelId: testChannel._id })
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.a.property('success', true);
|
|
});
|
|
});
|
|
|
|
it(`should successfully convert a channel to a team when the channel's name is sent as parameter`, async () => {
|
|
await request
|
|
.post(api('teams.convertToChannel'))
|
|
.set(credentials)
|
|
.send({ teamName: testChannel.name })
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.a.property('success', true);
|
|
});
|
|
|
|
await request
|
|
.post(api('channels.convertToTeam'))
|
|
.set(credentials)
|
|
.send({ channelName: testChannel.name })
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.a.property('success', true);
|
|
});
|
|
});
|
|
|
|
it('should fail to convert channel without the required parameters', (done) => {
|
|
void request.post(api('channels.convertToTeam')).set(credentials).send({}).expect(400).end(done);
|
|
});
|
|
|
|
it("should fail to convert channel if it's already taken", async () => {
|
|
const res = await request.post(api('channels.convertToTeam')).set(credentials).send({ channelId: testChannel._id }).expect(400);
|
|
|
|
expect(res.body).to.have.a.property('success', false);
|
|
});
|
|
});
|
|
|
|
describe("Setting: 'Use Real Name': true", () => {
|
|
let testChannel: IRoom;
|
|
|
|
before(async () => {
|
|
testChannel = (await createRoom({ type: 'c', name: `channel.anonymousread.test.${Date.now()}` })).body.channel;
|
|
});
|
|
before(async () => {
|
|
await updateSetting('UI_Use_Real_Name', true);
|
|
|
|
await request
|
|
.post(api('channels.join'))
|
|
.set(credentials)
|
|
.send({
|
|
roomId: testChannel._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('channel._id', testChannel._id);
|
|
});
|
|
|
|
await request
|
|
.post(api('chat.sendMessage'))
|
|
.set(credentials)
|
|
.send({
|
|
message: {
|
|
text: 'Sample message',
|
|
rid: testChannel._id,
|
|
},
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
});
|
|
});
|
|
|
|
after(async () => {
|
|
await Promise.all([
|
|
updateSetting('Accounts_AllowAnonymousRead', false),
|
|
updateSetting('UI_Use_Real_Name', false),
|
|
deleteRoom({ type: 'c', roomId: testChannel._id }),
|
|
]);
|
|
});
|
|
|
|
it('should return the last message user real name', async () => {
|
|
const res = await request
|
|
.get(api('channels.info'))
|
|
.query({
|
|
roomId: testChannel._id,
|
|
})
|
|
.set(credentials)
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(res.body).to.have.property('success', true);
|
|
const { channel } = res.body;
|
|
|
|
expect(channel._id).to.be.equal(testChannel._id);
|
|
expect(channel).to.have.nested.property('lastMessage.u.name', 'RocketChat Internal Admin Test');
|
|
});
|
|
|
|
it('/channels.list.joined', async () => {
|
|
const res = await request.get(api('channels.list.joined')).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('channels').and.to.be.an('array');
|
|
|
|
const retChannel = (res.body.channels as IRoom[]).find(({ _id }) => _id === testChannel._id);
|
|
|
|
expect(retChannel).to.have.nested.property('lastMessage.u.name', 'RocketChat Internal Admin Test');
|
|
});
|
|
|
|
it('/channels.list.join should return empty list when member of no group', async () => {
|
|
const user = await createUser({ joinDefaultChannels: false });
|
|
const newCreds = await login(user.username, password);
|
|
await request
|
|
.get(api('channels.list.joined'))
|
|
.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').that.is.equal(0);
|
|
expect(res.body).to.have.property('total').that.is.equal(0);
|
|
expect(res.body).to.have.property('channels').and.to.be.an('array').and.that.has.lengthOf(0);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('[/channels.messages]', () => {
|
|
let testChannel: IRoom;
|
|
let emptyChannel: IRoom;
|
|
let firstUser: IUser;
|
|
let secondUser: IUser;
|
|
let pinnedMessageId: IMessage['_id'];
|
|
|
|
before(async () => {
|
|
await updatePermission('view-c-room', ['admin', 'user', 'bot', 'app', 'anonymous']);
|
|
emptyChannel = (await createRoom({ type: 'c', name: `channels.messages.empty.test.${Date.now()}` })).body.channel;
|
|
testChannel = (await createRoom({ type: 'c', name: `channels.messages.test.${Date.now()}` })).body.channel;
|
|
|
|
firstUser = await createUser({ joinDefaultChannels: false });
|
|
secondUser = await createUser({ joinDefaultChannels: false });
|
|
|
|
const messages = [
|
|
{
|
|
rid: testChannel._id,
|
|
msg: `@${firstUser.username} youre being mentioned`,
|
|
mentions: [{ username: firstUser.username, _id: firstUser._id, name: firstUser.name }],
|
|
},
|
|
{
|
|
rid: testChannel._id,
|
|
msg: `@${secondUser.username} youre being mentioned`,
|
|
mentions: [{ username: secondUser.username, _id: secondUser._id, name: secondUser.name }],
|
|
},
|
|
{
|
|
rid: testChannel._id,
|
|
msg: `A simple message`,
|
|
},
|
|
{
|
|
rid: testChannel._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 updatePermission('view-c-room', ['admin', 'user', 'bot', 'app', 'anonymous']);
|
|
await deleteRoom({ type: 'c', roomId: testChannel._id });
|
|
});
|
|
|
|
it('should return an empty array of messages when inspecting a new room', async () => {
|
|
await request
|
|
.get(api('channels.messages'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: emptyChannel._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').that.is.empty;
|
|
expect(res.body).to.have.property('count', 0);
|
|
expect(res.body).to.have.property('total', 0);
|
|
});
|
|
});
|
|
|
|
it('should return an array of messages when inspecting a room with messages', async () => {
|
|
await request
|
|
.get(api('channels.messages'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testChannel._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').that.has.lengthOf(5);
|
|
expect(res.body).to.have.property('count', 5);
|
|
expect(res.body).to.have.property('total', 5);
|
|
|
|
const pinnedMessage = res.body.messages.find((message: any) => message.t === 'message_pinned');
|
|
expect(pinnedMessage).to.not.be.undefined;
|
|
});
|
|
});
|
|
|
|
it('should not return message when the user does NOT have the necessary permission', async () => {
|
|
await updatePermission('view-c-room', []);
|
|
await request
|
|
.get(api('channels.messages'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testChannel._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]');
|
|
});
|
|
await updatePermission('view-c-room', ['admin', 'user', 'bot', 'app', 'anonymous']);
|
|
});
|
|
|
|
it('should return messages that mention a single user', async () => {
|
|
await request
|
|
.get(api('channels.messages'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testChannel._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('channels.messages'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testChannel._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('channels.messages'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testChannel._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);
|
|
});
|
|
});
|
|
|
|
// Return messages that are pinned
|
|
it('should return messages that are pinned', async () => {
|
|
await request
|
|
.get(api('channels.messages'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testChannel._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);
|
|
});
|
|
});
|
|
|
|
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('channels.messages'))
|
|
.set(credentials)
|
|
.query({ roomId: testChannel._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('channels.messages'))
|
|
.set(credentials)
|
|
.query({
|
|
roomId: testChannel._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: testChannel._id });
|
|
|
|
await request
|
|
.get(api('channels.messages'))
|
|
.set(credentials)
|
|
.query({ roomId: testChannel._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('Additional Visibility Tests', () => {
|
|
let outsiderUser: IUser;
|
|
let insideUser: IUser;
|
|
let nonTeamUser: IUser;
|
|
let outsiderCredentials: { 'X-Auth-Token': string; 'X-User-Id': string };
|
|
let insideCredentials: { 'X-Auth-Token': string; 'X-User-Id': string };
|
|
let nonTeamCredentials: { 'X-Auth-Token': string; 'X-User-Id': string };
|
|
|
|
let privateChannel: IRoom;
|
|
let publicChannel: IRoom;
|
|
let publicTeam: ITeam;
|
|
let privateTeam: ITeam;
|
|
let privateChannelInPublicTeam: IRoom;
|
|
let publicChannelInPublicTeam: IRoom;
|
|
let privateChannelInPrivateTeam: IRoom;
|
|
let publicChannelInPrivateTeam: IRoom;
|
|
|
|
before(async () => {
|
|
[outsiderUser, insideUser, nonTeamUser] = await Promise.all([
|
|
createUser({ username: `e_${Random.id()}` }),
|
|
createUser({ username: `f_${Random.id()}` }),
|
|
createUser({ username: `g_${Random.id()}` }),
|
|
]);
|
|
[outsiderCredentials, insideCredentials, nonTeamCredentials] = await Promise.all([
|
|
login(outsiderUser.username, password),
|
|
login(insideUser.username, password),
|
|
login(nonTeamUser.username, password),
|
|
]);
|
|
|
|
// Create a public team and a private team
|
|
[publicTeam, privateTeam] = await Promise.all([
|
|
createTeam(insideCredentials, `channels.messages.team.public.${Random.id()}`, TeamType.PUBLIC, [outsiderUser.username as string]),
|
|
createTeam(insideCredentials, `channels.messages.team.private.${Random.id()}`, TeamType.PRIVATE, [
|
|
outsiderUser.username as string,
|
|
]),
|
|
]);
|
|
|
|
const [
|
|
privateInPublicResponse,
|
|
publicInPublicResponse,
|
|
privateInPrivateResponse,
|
|
publicInPrivateResponse,
|
|
privateRoomResponse,
|
|
publicRoomResponse,
|
|
] = await Promise.all([
|
|
createRoom({
|
|
type: 'p',
|
|
name: `teamPublic.privateChannel.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
extraData: {
|
|
teamId: publicTeam._id,
|
|
},
|
|
}),
|
|
createRoom({
|
|
type: 'c',
|
|
name: `teamPublic.publicChannel.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
extraData: {
|
|
teamId: publicTeam._id,
|
|
},
|
|
}),
|
|
createRoom({
|
|
type: 'p',
|
|
name: `teamPrivate.privateChannel.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
extraData: {
|
|
teamId: privateTeam._id,
|
|
},
|
|
}),
|
|
createRoom({
|
|
type: 'c',
|
|
name: `teamPrivate.publicChannel.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
extraData: {
|
|
teamId: privateTeam._id,
|
|
},
|
|
}),
|
|
createRoom({
|
|
type: 'p',
|
|
name: `channels.messages.private.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
}),
|
|
createRoom({
|
|
type: 'c',
|
|
name: `channels.messages.public.${Date.now()}`,
|
|
credentials: insideCredentials,
|
|
}),
|
|
]);
|
|
|
|
privateChannelInPublicTeam = privateInPublicResponse.body.group;
|
|
publicChannelInPublicTeam = publicInPublicResponse.body.channel;
|
|
privateChannelInPrivateTeam = privateInPrivateResponse.body.group;
|
|
publicChannelInPrivateTeam = publicInPrivateResponse.body.channel;
|
|
privateChannel = privateRoomResponse.body.group;
|
|
publicChannel = publicRoomResponse.body.channel;
|
|
});
|
|
|
|
after(async () => {
|
|
await Promise.all([
|
|
deleteRoom({ type: 'p', roomId: privateChannel._id }),
|
|
deleteRoom({ type: 'c', roomId: publicChannel._id }),
|
|
deleteRoom({ type: 'p', roomId: privateChannelInPublicTeam._id }),
|
|
deleteRoom({ type: 'c', roomId: publicChannelInPublicTeam._id }),
|
|
deleteRoom({ type: 'p', roomId: privateChannelInPrivateTeam._id }),
|
|
deleteRoom({ type: 'c', roomId: publicChannelInPrivateTeam._id }),
|
|
]);
|
|
|
|
await Promise.all([deleteTeam(credentials, publicTeam.name), deleteTeam(credentials, privateTeam.name)]);
|
|
|
|
await Promise.all([deleteUser(outsiderUser), deleteUser(insideUser), deleteUser(nonTeamUser)]);
|
|
});
|
|
|
|
it('should not fetch private room messages by user not part of room', async () => {
|
|
await request
|
|
.get(api('channels.messages'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: privateChannel._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch private room messages by user who is part of the room', async () => {
|
|
const response = await request
|
|
.get(api('channels.messages'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: privateChannel._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400);
|
|
|
|
expect(response.body.success).to.be.false;
|
|
});
|
|
|
|
it('should fetch public room messages by user who is part of the room', async () => {
|
|
const response = await request
|
|
.get(api('channels.messages'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: publicChannel._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(response.body.success).to.be.true;
|
|
expect(response.body.messages).to.be.an('array');
|
|
});
|
|
|
|
it('should fetch public room messages by user not part of room - because public', async () => {
|
|
await updatePermission('view-c-room', ['admin', 'user', 'guest']);
|
|
const response = await request
|
|
.get(api('channels.messages'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: publicChannel._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
expect(response.body.success).to.be.true;
|
|
expect(response.body.messages).to.be.an('array');
|
|
});
|
|
|
|
it('should not fetch a private channel messages inside a public team by someone part of the room ', async () => {
|
|
await request
|
|
.get(api('channels.messages'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: privateChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel messages inside a public team by someone not part of the room, but part of team', async () => {
|
|
await request
|
|
.get(api('channels.messages'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: privateChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel messages inside a public team by someone not part of the team ', async () => {
|
|
await request
|
|
.get(api('channels.messages'))
|
|
.set(nonTeamCredentials)
|
|
.query({ roomId: privateChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel messages inside a public team by someone part of the room ', async () => {
|
|
await request
|
|
.get(api('channels.messages'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: publicChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body.messages).to.be.an('array');
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel messages inside a public team by someone not part of the room, but part of team', async () => {
|
|
await request
|
|
.get(api('channels.messages'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: publicChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body.messages).to.be.an('array');
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel messages inside a public team by someone not part of the team ', async () => {
|
|
await request
|
|
.get(api('channels.messages'))
|
|
.set(nonTeamCredentials)
|
|
.query({ roomId: publicChannelInPublicTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body.messages).to.be.an('array');
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel messages inside a private team by someone part of the room', async () => {
|
|
await request
|
|
.get(api('channels.messages'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: publicChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body.messages).to.be.an('array');
|
|
});
|
|
});
|
|
|
|
it('should fetch a public channel messages inside a private team by someone not part of the room, but part of team', async () => {
|
|
await request
|
|
.get(api('channels.messages'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: publicChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body.messages).to.be.an('array');
|
|
});
|
|
});
|
|
|
|
it('should not fetch a public channel messages inside a private team by someone not part of team', async () => {
|
|
await request
|
|
.get(api('channels.messages'))
|
|
.set(nonTeamCredentials)
|
|
.query({ roomId: publicChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(403)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel messages inside a private team by someone part of the room', async () => {
|
|
await request
|
|
.get(api('channels.messages'))
|
|
.set(insideCredentials)
|
|
.query({ roomId: privateChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel messages inside a private team by someone not part of the room, but part of team', async () => {
|
|
await request
|
|
.get(api('channels.messages'))
|
|
.set(outsiderCredentials)
|
|
.query({ roomId: privateChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
|
|
it('should not fetch a private channel messages inside a private team by someone not part of team', async () => {
|
|
await request
|
|
.get(api('channels.messages'))
|
|
.set(nonTeamCredentials)
|
|
.query({ roomId: privateChannelInPrivateTeam._id })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(400)
|
|
.expect((res) => {
|
|
expect(res.body).to.have.property('success', false);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|