Skip to content

Commit

Permalink
test: read receipts (#30637)
Browse files Browse the repository at this point in the history
Co-authored-by: Matheus Barbosa Silva <[email protected]>
  • Loading branch information
heitortanoue and matheusbsilva137 authored Oct 31, 2023
1 parent 6167ddf commit afdcad7
Show file tree
Hide file tree
Showing 2 changed files with 326 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/ninety-carrots-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/meteor": patch
---

test: read receipts
323 changes: 321 additions & 2 deletions apps/meteor/tests/end-to-end/api/24-methods.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { expect } from 'chai';
import { after, before, beforeEach, describe, it } from 'mocha';

import { getCredentials, request, methodCall, api, credentials } from '../../data/api-data.js';
import { api, credentials, getCredentials, methodCall, request } from '../../data/api-data.js';
import { sendSimpleMessage } from '../../data/chat.helper.js';
import { CI_MAX_ROOMS_PER_GUEST as maxRoomsPerGuest } from '../../data/constants';
import { updatePermission, updateSetting } from '../../data/permissions.helper';
import { createRoom } from '../../data/rooms.helper';
import { createRoom, deleteRoom } from '../../data/rooms.helper';
import { password } from '../../data/user';
import { createUser, deleteUser, login } from '../../data/users.helper.js';
import { IS_EE } from '../../e2e/config/constants';

describe('Meteor.methods', function () {
this.retries(0);
Expand Down Expand Up @@ -123,6 +126,322 @@ describe('Meteor.methods', function () {
});
});

describe('[@getReadReceipts]', () => {
it('should fail if not logged in', async () => {
await request
.post(methodCall('getReadReceipts'))
.send({
message: JSON.stringify({
method: 'getReadReceipts',
params: [{ messageId: 'test' }],
id: 'id',
msg: 'method',
}),
})
.expect('Content-Type', 'application/json')
.expect(401)
.expect((res) => {
expect(res.body).to.have.property('status', 'error');
expect(res.body).to.have.property('message', 'You must be logged in to do this.');
});
});

(!IS_EE ? describe : describe.skip)('[@getReadReceipts] CE', () => {
it('should fail if there is no enterprise license', async () => {
await request
.post(methodCall('getReadReceipts'))
.set(credentials)
.send({
message: JSON.stringify({
method: 'getReadReceipts',
params: [{ messageId: 'test' }],
id: 'id',
msg: 'method',
}),
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
const data = JSON.parse(res.body.message);
expect(data).to.have.property('error').that.is.an('object');
expect(data.error).to.have.property('error', 'error-action-not-allowed');
expect(data.error).to.have.property('message', 'This is an enterprise feature [error-action-not-allowed]');
});
});
});

(IS_EE ? describe : describe.skip)('[@getReadReceipts] EE', () => {
let user = null;
let userCredentials = null;
let room = null;
let firstMessage = null;
let firstThreadMessage = null;

const roomName = `methods-test-channel-${Date.now()}`;
before(async () => {
await updateSetting('Message_Read_Receipt_Enabled', true);
await updateSetting('Message_Read_Receipt_Store_Users', true);

user = await createUser();
userCredentials = await login(user.username, password);
room = (await createRoom({ type: 'p', name: roomName, members: [user.username] })).body.group;
firstMessage = (await sendSimpleMessage({ roomId: room._id })).body.message;
firstThreadMessage = (await sendSimpleMessage({ roomId: room._id, tmid: firstMessage._id })).body.message;
});

after(async () => {
await deleteRoom({ type: 'p', roomId: room._id });
await deleteUser(user);
});

describe('simple message and thread that nobody has read yet', () => {
it("should return only the sender's read receipt for a message sent in the main room", async () => {
await request
.post(methodCall('getReadReceipts'))
.set(credentials)
.send({
message: JSON.stringify({
method: 'getReadReceipts',
params: [{ messageId: firstMessage._id }],
id: 'id',
msg: 'method',
}),
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.a.property('success', true);
expect(res.body).to.have.a.property('message').that.is.a('string');

const data = JSON.parse(res.body.message);
expect(data).to.have.a.property('result').that.is.an('array');
expect(data.result.length).to.equal(1);
expect(data.result[0]).to.have.property('userId', credentials['X-User-Id']);
});
});

it("should return only the sender's read receipt for a message sent in a thread", async () => {
await request
.post(methodCall('getReadReceipts'))
.set(credentials)
.send({
message: JSON.stringify({
method: 'getReadReceipts',
params: [{ messageId: firstThreadMessage._id }],
id: 'id',
msg: 'method',
}),
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.a.property('success', true);
expect(res.body).to.have.a.property('message').that.is.a('string');

const data = JSON.parse(res.body.message);
expect(data).to.have.a.property('result').that.is.an('array');
expect(data.result.length).to.equal(1);
expect(data.result[0]).to.have.property('userId', credentials['X-User-Id']);
});
});
});

describe('simple message and thread where the room message was read by the invited user but the thread message was not', () => {
before("should read all main room's messages with the invited user", async () => {
await request
.post(methodCall('readMessages'))
.set(userCredentials)
.send({
message: JSON.stringify({
id: 'id',
msg: 'method',
method: 'readMessages',
params: [room._id, true],
}),
});
});

it("should return both the sender's and the invited user's read receipt for a message sent in the main room", async () => {
await request
.post(methodCall('getReadReceipts'))
.set(credentials)
.send({
message: JSON.stringify({
method: 'getReadReceipts',
params: [{ messageId: firstMessage._id }],
id: 'id',
msg: 'method',
}),
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.a.property('success', true);
expect(res.body).to.have.a.property('message').that.is.a('string');

const data = JSON.parse(res.body.message);
expect(data).to.have.a.property('result').that.is.an('array');
expect(data.result.length).to.equal(2);

const receiptsUserIds = [data.result[0].userId, data.result[1].userId];
expect(receiptsUserIds).to.have.members([credentials['X-User-Id'], user._id]);
});
});

it("should return only the sender's read receipt for a message sent in a thread", async () => {
await request
.post(methodCall('getReadReceipts'))
.set(credentials)
.send({
message: JSON.stringify({
method: 'getReadReceipts',
params: [{ messageId: firstThreadMessage._id }],
id: 'id',
msg: 'method',
}),
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.a.property('success', true);
expect(res.body).to.have.a.property('message').that.is.a('string');

const data = JSON.parse(res.body.message);
expect(data).to.have.a.property('result').that.is.an('array');
expect(data.result.length).to.equal(1);
expect(data.result[0]).to.have.property('userId', credentials['X-User-Id']);
});
});
});

describe('simple message and thread where both was read by the invited user', () => {
before('should read thread messages with the invited user', async () => {
await request
.post(methodCall('getThreadMessages'))
.set(userCredentials)
.send({
message: JSON.stringify({
id: 'id',
msg: 'method',
method: 'getThreadMessages',
params: [
{
tmid: firstMessage._id,
},
],
}),
});
});

it("should return both the sender's and invited user's read receipt for a message sent in a thread", async () => {
await request
.post(methodCall('getReadReceipts'))
.set(credentials)
.send({
message: JSON.stringify({
method: 'getReadReceipts',
params: [{ messageId: firstThreadMessage._id }],
id: 'id',
msg: 'method',
}),
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.a.property('success', true);
expect(res.body).to.have.a.property('message').that.is.a('string');

const data = JSON.parse(res.body.message);
expect(data).to.have.a.property('result').that.is.an('array');
expect(data.result.length).to.equal(2);

const receiptsUserIds = [data.result[0].userId, data.result[1].userId];
expect(receiptsUserIds).to.have.members([credentials['X-User-Id'], user._id]);
});
});
});

describe('simple message and thread marked as read by the invited user', () => {
let otherMessage = null;
let otherThreadMessage = null;

before('should send another message and create a thread', async () => {
otherMessage = (await sendSimpleMessage({ roomId: room._id })).body.message;
otherThreadMessage = (await sendSimpleMessage({ roomId: room._id, tmid: otherMessage._id })).body.message;
});

before('should mark the thread as read by the invited user', async () => {
await request
.post(methodCall('readThreads'))
.set(userCredentials)
.send({
message: JSON.stringify({
method: 'readThreads',
params: [otherMessage._id],
id: 'id',
msg: 'method',
}),
});
});

it("should return both the sender's and invited user's read receipt for a message sent in the main room", async () => {
await request
.post(methodCall('getReadReceipts'))
.set(credentials)
.send({
message: JSON.stringify({
method: 'getReadReceipts',
params: [{ messageId: otherThreadMessage._id }],
id: 'id',
msg: 'method',
}),
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.a.property('success', true);
expect(res.body).to.have.a.property('message').that.is.a('string');

const data = JSON.parse(res.body.message);
expect(data).to.have.a.property('result').that.is.an('array');
expect(data.result.length).to.equal(2);

const receiptsUserIds = [data.result[0].userId, data.result[1].userId];
expect(receiptsUserIds).to.have.members([credentials['X-User-Id'], user._id]);
});
});

it("should return both the sender's and invited user's read receipt for a message sent in a thread", async () => {
await request
.post(methodCall('getReadReceipts'))
.set(credentials)
.send({
message: JSON.stringify({
method: 'getReadReceipts',
params: [{ messageId: otherThreadMessage._id }],
id: 'id',
msg: 'method',
}),
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.a.property('success', true);
expect(res.body).to.have.a.property('message').that.is.a('string');

const data = JSON.parse(res.body.message);
expect(data).to.have.a.property('result').that.is.an('array');
expect(data.result.length).to.equal(2);

const receiptsUserIds = [data.result[0].userId, data.result[1].userId];
expect(receiptsUserIds).to.have.members([credentials['X-User-Id'], user._id]);
});
});
});
});
});

describe('[@getMessages]', () => {
let rid = false;
let firstMessage = false;
Expand Down

0 comments on commit afdcad7

Please sign in to comment.